Written before the run (2026-09-19).
When two candidate teachers tie under the likelihood statistic, "which one" is the wrong question. Can we estimate proportions of teacher styles in a student's generations, with a confidence interval, so that "about half R1, half Qwen3-like" is itself reportable evidence?
Reuse the H3 style classifier (trained on the five teacher sets with a uniform prior). For a set of student samples, run EM prior adjustment (Saerens et al. 2002) on the classifier posteriors: the re-estimated class prior is the mixture estimate. Bootstrap over samples for a 95% interval. Apply to S (the R1 distill) and C (control instruct). Script: mixture_em.py.
This is a style mixture, not a training-data mixture; the two coincide only to the extent that style is inherited. The Phase 1 testbed (students distilled from known 70/30 and 50/50 teacher mixes) is the real test of calibration.
Phase 1 showed a 50/50 R1+Qwen3 student reads as 0.24 r1_orig by style (reasoning-only). Train two more students from the same base and recipe with 70/30 and 30/70 R1/Qwen3 data, estimate their style mixtures, and fit a monotone map from style weight to data weight through the five points (data r1 share 1.0, 0.7, 0.5, 0.3, 0.0 from S_r1, S_mix70, S_mix, S_mix30, S_qwen3).
| Data share r1_orig | 0.00 (S_qwen3) | 0.30 (S_mix30) | 0.50 (S_mix) | 0.70 (S_mix70) | 1.00 (S_r1) |
|---|---|---|---|---|---|
| Style EM weight r1_orig, reasoning-only [95% CI] | 0.079 [0.04, 0.12] | 0.116 [0.06, 0.17] | 0.244 [0.17, 0.31] | 0.370 [0.29, 0.45] | 0.698 [0.61, 0.77] |
| Style EM weight, full text | 0.088 | 0.115 | 0.190 | 0.310 | 0.460 |
| Likelihood r1_orig top-1 wins / 199 (exact-lineage reference) | 22 (0.11) | 44 (0.22) | 67 (0.34) | 85 (0.43) | 129 (0.65) |
results_calibration_head800.json, results_calibration_full.json.The calibration map failed to transfer because the real distill is a far stronger distillation than 800-example students. Add strength as a second axis with two more R1-only students from the same base and recipe: S_r1_8k (8,000 original-R1 traces from OpenR1-Math-220k, 3 epochs) and S_r1_e9 (the same 800 s1K traces, 9 epochs). With S_r1 (800 x 3) that gives three strength levels for a pure teacher.
Interim (S_r1_e9 done; trained on an L40S in 37 min after the H100 pool ran dry, loss 0.996): likelihood r1_orig 128/71 with mean alignment +0.190 (vs +0.159 at 3 epochs); style reasoning-only 139/60, r1_orig weight 0.78 [0.70, 0.84] (vs 0.70). Monotone so far, but three times the epochs bought only +0.08 in style weight; still far from the real distill's 0.998. S_r1_8k pending (first attempt OOM'd on the L40S at batch 4; relaunched on an H100 at batch 2).
| Student | Data | Sample-passes | Train loss | Likelihood r1_orig: mean f, wins | Style r1_orig weight (reasoning-only) |
|---|---|---|---|---|---|
| S_r1 | 800 s1K-1.1 R1 traces x 3 ep | 2,400 | 1.05 | +0.159, 129/199 | 0.70 [0.61, 0.77] |
| S_r1_e9 | same x 9 ep | 7,200 | 1.00 | +0.190, 128/199 | 0.78 [0.70, 0.84] |
| S_r1_8k | 8,000 OpenR1-Math R1 traces x 3 ep | 24,000 | 0.66 | +0.205, 78/199 (qwen3 121) | 0.66 [0.57, 0.75] |
../h3_idiolect/results/source_*.json): adding an r1_openr1 class (200 OpenR1 traces) to the style classifier shows the two R1 sources are separable from each other at 0.91 CV on full text (0.76 on reasoning-only 800 words): the same checkpoint, sampled on different prompts through a different pipeline, has a measurably different fingerprint, though far closer to each other than to Qwen3 (0.95). With both classes present, S_r1_8k's generations go to r1_openr1 138 vs 16 (its actual source); S_r1 and S_r1_e9 also lean r1_openr1 (124 vs 29, 127 vs 38), and the real distill splits 100 vs 89. The 8k student's absolute likelihood alignment did rise with strength (+0.159 -> +0.190 -> +0.205), but Qwen3's rose more because the OpenR1 register is closer to Qwen3's than the s1K register is.M3, held-out recovery (train on half of each teacher's texts, estimate the other half): every teacher recovered at 0.99 to 1.00 weight, on both full text and reasoning-only 800-word text. Files results/h3/m3_full.json, m3_head800.json on the i9.
M3b, synthetic blends of held-out halves (reasoning-only 800 words, 100 texts per blend):
| True blend | Estimated |
|---|---|
| r1_orig 0.70 / qwen3_32b 0.30 | 0.73 / 0.27 |
| r1_orig 0.50 / qwen3_32b 0.50 | 0.52 / 0.48 |
| r1_orig 0.30 / qwen3_32b 0.70 | 0.34 / 0.66 |
| r1_orig 0.50 / r1 (API) 0.50 | 0.50 / 0.50 |
| qwen3_32b 0.80 / gpt_oss_120b 0.20 | 0.79 / 0.20 (r1_orig 0.01) |
Within 4 points on every blend, including the hard pair. M3 met.
M1 / M2, student and control (EM prior adjustment on the H3 classifier posteriors, 200 generations each, 500-sample bootstrap):
| Text used | S mixture (95% CI) | C mixture (95% CI) |
|---|---|---|
| full output | r1_orig 1.000 [0.98, 1.00]; qwen3_32b 0.000 [0.00, 0.02]; others 0 | llama33_70b 0.994 [0.98, 1.00]; r1_orig 0.006 [0.00, 0.02] |
| reasoning only, 800 words | r1_orig 0.997 [0.97, 1.00]; qwen3_32b 0.003 [0.00, 0.03] | llama33_70b 1.000 [1.00, 1.00]; r1_orig 0.000 |
M1 met (r1_orig largest, CI excludes 0.20 by a wide margin). M2 met (control's r1_orig weight CI within [0, 0.02]). Together with M3/M3b, the style-mixture estimator is calibrated on known blends and gives an honest, interval-bounded proportion on real students. Files: ../h3_idiolect/results/h2_mixture_full.json, h2_mixture_head800.json.