不需要老师、不需要验证器、不需要 RL——苹果这篇论文让我重新思考代码后训练
核心摘要:苹果(Apple)的一篇论文给出了一种堪称"令人发指的简单"的自蒸馏方法 SSD:让模型自己采样答案、自己当老师,再用标准 SFT 喂回去。在 LiveCodeBench v6 上,Qwen3-30B-Instruct 从 42.4% 涨到 55.3%(pass@1 涨 12.9 个点,相对提升 30%),收益集中在难题上,且在 4B/8B/30B 多种规模上稳定复现。更让人吃惊的是:作者用一个压力测试证明——就算把训练数据采样到几乎全是乱码(62% 抽不出可执行代码),SSD 仍然能让模型涨 5.7 个点。这篇论文最值钱的地方不在于它做了一件新事,而在于它给出了一个反直觉的洞察:代码生成里藏着"锁"和"分叉"两种位置,它们对解码的需求是矛盾的,单一全局温度无法调和,SSD 之所以能 work,是因为它恰好在这个冲突上做了非对称的重塑。
论文信息
| 项目 | 内容 |
|---|---|
| 标题 | Embarrassingly Simple Self-Distillation Improves Code Generation |
| 作者 | Ruixiang Zhang*、Richard He Bai*、Huangjie Zheng*、Navdeep Jaitly、Ronan Collobert、Yizhe Zhang(* 共同一作) |
| 机构 | Apple |
| arXiv | 2604.01193v2 |
| 代码 | github.com/apple/ml-ssd |
| v1 投稿 | 2026 年 4 月 1 日;v2 修订 2026 年 6 月 24 日 |
0. 读这篇论文之前,先把脑子里的"自蒸馏"清空
我自己在看这篇论文之前,脑子里有一堆根深蒂固的"自蒸馏"印象——什么 Rejection Sampling Fine-Tuning(RFT)啊,STaR 啊,Self-Rewarding LM 啊,Self-Play Fine-Tuning(SPIN)啊。这些方法几乎都有同一个味道:"让模型自己生成一堆答案,再想办法挑出好的来当训练数据"。挑好的方法各不相同——RFT 用正确性验证器、STaR 留能解出答案的、SPIN 拿上一轮的负样本当对比。
SSD 不是这套玩法。
它甚至连"挑"这一步都没有。论文里的原话非常直白:
SSD samples solutions from the model with certain temperature and truncation configurations, then fine-tunes on those samples with standard supervised fine-tuning. SSD uses no RL, verifier, teacher, or code execution environment.
也就是说:采样,喂回去,完事。没有正确性过滤、没有执行验证、没有奖励信号、没有任何形式的"打分"。所有采样出来的 raw output——不管对不对——统统当 SFT 数据。
我第一反应是:这不是把模型往沟里带吗?
读完之后我承认被打脸了。而且打得挺服气。
1. 这篇论文想解决的真实问题
在聊方法之前,先看看背景:当前要让 LLM 在代码生成上变强,工程界主流的路径大概有三种。
第一条:堆高质量监督数据。但 human-written solution 又贵又少(HumanEval、Mbpp、APPS 这类数据集加起来也就那么点),人类写代码的速度永远追不上模型消耗数据的速度。
第二条:Teacher distillation。用一个更强的老师(比如 GPT-4o、Claude、Gemini)来教学生。但天花板被老师锁死,而且强老师 API 贵得离谱;并且学生再怎么学,原则上也不可能超过老师。
第三条:RL with verifiable reward(RLVR)。这两年最热的方向。代码能跑就是 reward,跑不通就是负反馈。DeepSeek-R1、OpenAI o-series 用的都是这套思路。但 RL 有两个让人头疼的问题: - 操作复杂(要搞 reward model、要 rollout、要做 advantage estimation、要小心 KL 散度崩盘) - 容易 reward hacking 或者训练不稳定
苹果这篇文章在引言里就摆明了一个问题:
"Can a model improve itself without leveraging any external labeled data or verification at all?"
他们想看看纯靠模型自己、自给自足这条路到底能走多远。
这种"无外部监督的自改进"在 2025 年其实已经有一波人在玩了——unsupervised RLVR、entropy minimization、majority voting、self-certainty。论文里点了一串名字(Zuo et al. 2025、Agarwal et al. 2025、Prabhudesai et al. 2025)。但这些方法都还在 reward hacking 和 entropy collapse 之间挣扎,没有一个稳定、可复现、能跨模型家族的方案。
SSD 的野心就在这:用一个最朴素的方法,干掉所有这些工程复杂度。
2. SSD 到底是什么:三步看懂
方法部分作者用了不到一页纸,节奏快到让人怀疑是不是漏了什么。我把它拆成三步:
第一步:数据合成。给一批 prompt(这里用的是 rSTARcoder 论文里的 seed 子集,去重后约 10K 道竞赛题),让模型自己采样答案。采样的解码配置是 \((T_{\text{train}}, \rho_{\text{train}})\)——温度和截断(top-k / top-p)。这里有一个让人意外的点:每个 prompt 只采一个样本(\(N=1\))就够了。
第二步:训练。直接拿这些 raw sample(不验证、不筛选、不过滤)做标准的 SFT,用 cross-entropy loss。训练完之后模型记为 \(p_{\theta^*}\)。
第三步:推理。用一组新的解码配置 \((T_{\text{eval}}, \rho_{\text{eval}})\) 解码出最终答案。
# 算法伪代码(核心就这么多)
# 1. 采样
y = base_model.decode(x, T_train, rho_train) # 单个样本,不验证
# 2. 训练
for batch in dataloader:
loss = cross_entropy(model(x, y[:-1]), y[1:]) # 标准 SFT
loss.backward(); opt.step()
# 3. 推理
y_hat = finetuned_model.decode(x, T_eval, rho_eval) # T_eval 可与 T_train 不同
就这。三步加起来不超过 30 行 Python。
等等,这里有个关键问题:训练温度 \(T_{\text{train}}\) 和推理温度 \(T_{\text{eval}}\) 是什么关系?为什么作者要分开定义?
答案在 3.4 节揭晓:它们是"组合关系"。SSD 学到的新分布在 \((T_{\text{train}}, T_{\text{eval}})\) 网格上有个漂亮的"有效温度带" \(T_{\text{eff}} = T_{\text{train}} \times T_{\text{eval}}\),best pass@1 出现在 \(T_{\text{eff}}\) 大致为 1.0–1.5 的位置(详见 Figure 3)。你想想看,你训练时把分布拉平了,推理时就不能用太低的温度去"压回去"。这一点的物理直觉我们在第 4 节拆。
3. 实验结果:跨家族、跨规模、跨推理风格全涨
3.1 主结果(Table 2)
最直接的数据是 Table 2。6 个模型全部涨,从 4B 到 30B,从 instruct 到 thinking,从 Qwen 到 Llama 再到 GPT-OSS。我把核心数据整理成下表:
| 模型 | 类型 | LCB v6 Pass@1 (Base → +SSD) | Pass@5 (Base → +SSD) | 关键观察 |
|---|---|---|---|---|
| Qwen3-30B-Instruct | MoE 30B/3B | 42.4 → 55.3(+12.9 pp) | 53.5 → 71.6(+18.1 pp) | 头条案例,相对提升 30% |
| Qwen3-4B-Instruct | Dense 4B | 34.0 → 41.5 (+7.5) | 45.0 → 60.8 (+15.8) | 4B 模型也稳定 |
| Qwen3-30B-Thinking | MoE 30B/3B | 66.1 → 68.2 (+2.1) | 76.7 → 80.2 (+3.5) | thinking 模型涨幅小 |
| Qwen3-4B-Thinking | Dense 4B | 54.5 → 57.8 (+3.3) | 67.5 → 71.4 (+3.9) | 同上 |
| Llama-3.1-8B-Instruct | Dense 8B | 12.7 → 16.2 (+3.5) | 23.0 → 24.9 (+1.9) | baseline 本身很低,涨绝对值不多 |
| GPT-OSS-20B | MoE 21B/3.6B | 69.1 → 74.4 (+5.3) | 86.1 → 88.0 (+1.9) | 已有强模型,仍有 5+ 点 |
下面这张 Figure 1 来自论文,它把整个方法的"傻瓜流程"和"全模型家族涨点"放在一张图上,信息密度相当高:

图 1:左侧是 SSD 的三步流程(Sample → Fine-tune → Decode),没有任何 RL、verifier、teacher、execution 步骤;右侧是 LiveCodeBench v6 上的总体、Medium、Hard 三个难度上 4B 和 30B 模型的 pass@1(橙色 4B、蓝色 30B,斜线为 baseline、实心为 +SSD),下方汇总了 6 个模型都涨、Qwen3-30B-Instruct 相对涨 30%、收益集中在难题上。
几个我特别注意到的规律:
-
Pass@5 的涨幅通常比 Pass@1 还大。30B-Instruct 上 Pass@1 涨 12.9、Pass@5 涨 18.1;4B-Instruct 上 Pass@1 涨 7.5、Pass@5 涨 15.8。Pass@5 涨得多意味着多样性不仅没被破坏,反而改善了。这一点和很多 self-training 方法(容易塌缩到单一模式)形成鲜明对比。
-
Hard 题的涨幅最猛。30B-Instruct 在 LCB v6 上:Easy +6.5、Medium +14.2、Hard +15.3。Pass@5 那边 Easy +6.6、Medium +19.6、Hard +23.0。越是模型原本觉得"难"的位置,SSD 带来的提升越大。
-
Thinking 模型比 Instruct 模型涨幅小。30B-Thinking 只涨 2.1,4B-Thinking 涨 3.3。合理推测:因为 thinking 模型已经经过 RL/post-training,分布本身已经比较"整齐",留给 SSD 重塑的空间不大。
-
LCB v5 也涨。在另一时间窗(2024.08–2025.02)的 v5 集上同样涨——这排除了"过拟合 LCB v6 时间窗内特定题源"的可能性。
下面是完整的 Table 2 截图(每个模型都按 Easy/Medium/Hard 拆开):

图 2:Table 2 全表。绿色单元格代表 +SSD 提升、红色代表下降。每个模型分两行:base 和 +SSD。最关键的两行是 Qwen3-30B-Instruct:42.4 → 55.3(Overall pass@1),以及 Llama-3.1-8B-Instruct:12.7 → 16.2(涨幅不大但 baseline 极低,4B 量级以下的指令模型本来就挣扎)。
3.2 关键反证:纯调解码参数能不能 match SSD?
作者问了一个非常尖锐的问题:会不会只是 base model 没调对推理超参?
答案是:不会。Figure 2 把 6 个 base model 的解码温度从 0.5 扫到 1.4,再叠加不同截断,最好的 pass@1 跟 SSD 相比仍然有 1.1–11.8 个点的差距:

图 3:3 个模型 × {Pass@1, Pass@5} × {ALL, HARD} = 12 个 panel。橙色曲线是 base model 在不同 \(T_{\text{eval}}\) 下的表现(曲线很平,30B-Instruct 的 pass@1 只在 41.3%–43.5% 范围内波动,跨度 2.2pp),蓝色横线是 SSD 的结果。阴影部分是 SSD 相对 base model 的优势区间,阴影是虚线边框时表示 Hard 子集。最右两列的 Hard Pass@5 上,SSD 比 base model 在最佳 \(T_{\text{eval}}\) 下还多 13.6–19.4 个点。
我在看到 Figure 2 之前的第一反应其实是怀疑:是不是 base model 没用对的 prompt format?或者哪个超参没设对? 但论文里写明他们 follow 了每个模型的官方推荐采样设置,并把温度从 0.5 扫到 1.4。base model 的最优 pass@1 在 2–3 pp 区间内波动,再怎么调也摸不到 SSD 的地板。这排除了"用 decode-only trick 就能复现"的解释。
3.3 训练-推理温度的组合关系(Figure 3)
另一个非常有意思的发现是 \(T_{\text{eff}} = T_{\text{train}} \times T_{\text{eval}}\)。

图 4:(a) Qwen3-30B-Instruct 在 LCB v6 上 pass@1 vs \(T_{\text{eff}}\)。灰色 = no truncation,橙色 = top-k=5、绿色 = top-k=10 的截断采样。点是一次 run,曲线是二次拟合。Base 是 42.4% 的虚线。没有截断时(灰色曲线)峰值在 \(T_{\text{eff}} \approx 1.0\)(49.7%),加截断后峰值上移到 \(T_{\text{eff}} \approx 1.2\)(49.5%)且最优点更平。(b) Qwen3-4B-Thinking 在 LCB v6 上 best pass@1 关于 \((T_{\text{train}}, T_{\text{eval}})\) 的热图,最优 57.8% 出现在 \(T_{\text{train}}=1.1\)、\(T_{\text{eval}}=0.8\) 这种"\(T_{\text{eff}} \approx 0.88\)"附近。
简单总结:\(T_{\text{train}}\) 和 \(T_{\text{eval}}\) 大致是"乘法合成"的,best point 出现在 \(T_{\text{eff}}\) 大约 1.0–1.5 的范围内。这个组合关系是 SSD 的关键超参提示,不能瞎设。
3.4 一些其他细节
- 训练超参:8 × B200 GPU、AdamW、peak LR \(5 \times 10^{-6}\)、cosine decay、global batch size 32、seq length 65,536。Instruct 模型训 2500 步、thinking 模型只训 300 步。
- 数据:rSTARcoder 的 seed 子集去重后约 10K 道题。
- 推理引擎:vLLM v0.11.0。
- 评测:LCB v6(2025.02–2025.05)做主、LCB v5(2024.08–2025.02)做辅;按 Easy/Medium/Hard 分桶;Pass@1 和 Pass@5 都报。
4. 为什么它能 work——论文里最有价值的部分
到这里为止我们看完了"是什么"和"效果如何"。但为什么一个完全不看答案质量的方法能让模型涨十几个点?论文用了 4、5 两整章回答这个问题,这是全文最值钱的部分。我个人读完之后,感觉对"LLM 解码中 precision 和 exploration 的本质冲突"这件事有了更清楚的认识。
4.1 核心假设:precision-exploration conflict(精度-探索冲突)
作者把代码生成里每个 token 位置分成两类(Figure 4 给了直观图示):
Lock(锁位):分布很尖,只有一两个 token 拿到绝大部分概率,其余都是语法上合理但语义上错的"distractor tail"。典型例子:if n == 后面模型心知肚明应该输出什么,但仍然会给 0, len, max, None, 1 等等一系列"看起来像答案"的 token 留点残羹。
Fork(分叉位):分布真正铺开在多个合理选项上,每条路通往不同的解题方向。典型例子:函数体开头可以是 for 循环、递归调用、或者数据结构初始化。

图 5:代码生成里两种 token 位置的对比。左上是函数体开头(Fork):函数体里可以用 quicksort、insertion sort 或者直接 arr.sort() 三种合理实现,分布铺开。右上(Fork,低 \(T_{\text{eval}}\)):模型死死咬住最高概率的"mid = "那个 token,pivot / sorted / def 这些合理替代品都被压扁了——"low exploration"。左下(Lock,低 \(T_{\text{eval}}\)):"mid"一个 token 拿到绝大部分概率,其余都是"没意义"的尾。右下(Lock,高 \(T_{\text{eval}}\)):尾被温度推上来,正确的"mid"和错的"n, len, 1, 0"重新混在一起——"low precision"。
关键洞察:这两个位置对解码的需求是矛盾的。
- Lock 想要 precision:压扁尾、让模型坚定地选对的那个 token。
- Fork 想要 exploration:把概率铺开,让模型有概率走到其他合理路径。
而温度 \(T\) 是个全局参数——你不能在 fork 位置用 \(T=1.2\) 同时在 lock 位置用 \(T=0.7\)。这就是论文反复强调的 conflict:
Locks demand precision: commit to the dominant token and suppress the tail. Forks demand exploration: spread mass across viable alternatives to avoid missing the good paths.
调低温度能保护 Lock、压住 distractor,但同时也掐死了 Fork 的多样性;调高温度能给 Fork 留出空间,但 Lock 处的 distractor 又会卷土重来。
任何单一的全局温度都是一个折中。
这才是 SSD 真正想解决的问题:它不是要让模型"更准",而是要让模型在 Lock 和 Fork 两种位置上有不对称的解码行为。
4.2 玩具实验:把"锁-分叉"隔离出来单独看
为了验证这个假设,作者构造了一个玩具 FSM:成功路径必须经过 1 个 Fork + 3 个 Lock 才能到达 PASS,错一个就 FAIL。每个 transition 都明确指定了,成功的概率可以用闭式表达直接算出来。
玩具里看到的现象(Figure 5):

图 6:横轴是 token rank(按概率从高到低),纵轴是概率质量。斜线柱/虚线是 base model,实心柱/实线是 SSD 后,红色虚线是 SSD 训练时的截断线。左图(Fork):base model 的分布有长长的尾(rank 5 之后还有不少概率),SSD 把尾截断,但前几个 token 之间变得更平——一个"高 exploration"的小平台。右图(Lock):同样的截断规则把尾切得更狠,主导 token 集中了绝大部分质量——一个"高 precision"的尖刺。
这张图是整篇论文我最喜欢的一张。同一个截断规则,在不同位置产生完全不同的效果:
- 在 Fork:top 几个合理选项都还在,且相互之间概率更平均——形成"探索平台"。
- 在 Lock:top 1 之外的尾巴被干净地切掉——形成"精度尖刺"。
这就是为什么"训练和推理是互补的":训练让 Lock 不再脆弱、让 Fork 不再有 useless tail;推理时调温度,能用更自由的解码带宽去探索 Fork 而不会重新打开 Lock 的 distractor。
4.3 真实模型上的证据(Figure 6)
把同样的分析搬到 Qwen3-30B-Instruct 上,作者在两个签名上验证了机制:
- Token 概率的累积分布升得更快:base model 在 top 1 之后还有不少概率被分散在 distractor tail,SSD 之后的累积分布更陡——head 更干净、tail 更弱。
- 同一 \(T_{\text{eval}}\) 下 SSD 留住的 token 集合更大:base model 的 surviving set 接近 singleton(top 1),SSD 的 surviving set 经常有 2-3 个候选。温度在 SSD 上能做的事远多于 base model。
第二个签名很关键。它解释了为什么 Figure 3 里 \(T_{\text{eff}} = T_{\text{train}} \times T_{\text{eval}}\) 出现"组合关系"——因为 SSD 后的分布在 head 附近已经"展开"了,再叠加 \(T_{\text{eval}}\) 的效果就被放大了。
4.4 理论视角:SSD 损失的三项分解
论文第 4.3 节给了一个很漂亮的目标函数分解(公式 4)。SSD 拟合的分布可以写成:
三项的作用很清晰:
- Support compression:压住保留集 \(S\) 之外的质量——这就是"切尾巴"的物理来源。
- Within-support reshaping:\(1 - T\) 系数乘上 Rényi entropy \(H_{1/T}\)——当 \(T > 1\) 时此项为负(最小化),会让保留集内的分布更平;当 \(T < 1\) 时此项为正(最大化),会让保留集内的分布更尖。这就是"在 Fork 变平、在 Lock 变尖"的机制来源。
- Alignment:和 base model 保持 KL 距离有限,防止崩。
这套分解漂亮地解释了为什么 \(T_{\text{train}} > 1\) 起关键作用——它让公式第二项变成"最小化 \(H_{1/T}\)",强制让保留集内的分布扁平化。这一步在 Fork 位置产生了"探索平台"。
4.5 decode-only 为什么打不过 SSD(Appendix B.5)
论文还给了一个有意思的证明:标准 decoding pipeline(temperature → top-k → top-p → sample)是个 normal form,任何参数顺序都能 collapse 到同一族策略直白讲,纯调 \(T_{\text{eval}}\) 和 \(\rho_{\text{eval}}\) 不能引入任何新的分布结构,它只是 base model 分布的 deterministic reparametrization。
而 SSD 训练改的是模型本身——产生了一个 base model 不可能达到的分布形状。这是结构性的差异,decode-only 永远追不上。
5. 最让人惊掉下巴的实验:Bad Data, Good Results
到这里故事本来已经很完整了。但 Section 4.4 给了个"故意把事情搞砸"的 stress test,把我的认知又推了一把。
作者把 \(T_{\text{train}}\) 拉到 2.0、彻底关掉截断(让 \(\rho_{\text{train}}\) vacuous),看看采样出来的东西是什么质量。
结果:训练数据里约 62% 抽不出可执行代码。图 7(a) 展示了一个真实样本——前半段还能看懂(def solve():、weights = list(...)),到了第 13 行突然开始吐多语言乱码:
"# the number convinced lô be Fall
Memorizzazione rethinkknowledge Past
found librore re inherently carry (
Serv pull excitedtonspector franch danger money seasons domestic unicorn. complexity"
按任何常规 SFT 标准,这就是废数据。直接拿去训 base model,reward 不变负就不错了。
但 SSD 的结果还是涨了:Pass@1 42.4 → 48.1(+5.7),Pass@5 53.5 → 64.0(+10.5)。且增长同样集中在 hard 子集:Hard Pass@1 +7.3、Hard Pass@5 +13.8。

图 7:(a) \(T_{\text{train}}=2.0\) 无截断时的一个真实样本。前面还能看出 Python 框架,第 13 行开始彻底乱掉——多语言乱码、symbol 混杂。62% 的样本类似或更糟。(b) 即便如此,base 42.4%/53.5% → +SSD 48.1%/64.0%。
这个实验的真正意义:
它强烈暗示 SSD 的收益主要不是来自"训练在正确解上",而是来自"训练采样过程对 token 概率分布的形状改造"。哪怕答案本身是错的,只要采样过程经过温度和截断的"塑形",SFT 就能学到一个更利于后续推理的分布。
这是整篇论文我读完最坐直的一刻。
我们一直默认"自蒸馏需要先有正确的数据"——RLHF 要 prefer、STaR 要 verifiable、ReST 要 gold answer。SSD 直接说:这个假设是错的。在 lock 位置,你不需要答案"对",你只需要"模型的 top-1 是不是对"。而在 fork 位置,你甚至不需要"答案"——你只需要 top 几个候选被均匀对待。
这对 RLVR 路线是釜底抽薪的拷问。如果"训练在错误数据上"都能涨,那 RLVR 涨的到底是"正确答案的监督信号",还是"reward shaping 对分布的副作用"?这是后续研究该回答的问题。
6. 我对这篇论文的判断
6.1 亮点
- 极简到让人觉得是错的。三步法、没验证、没筛选、没奖励——SFT 完事。这种"减法做到位"的研究风格在 2026 年其实很稀缺。
- 机制解释扎实。作者没有止步于"涨点就完事",而是把 lock / fork 的 precision-exploration 冲突讲透了,配套玩具 FSM + 真实模型分析 + 目标函数分解 + decode-only 不可复现的证明。这套解释链能说服一个怀疑者。
- 可复现且跨家族。Qwen、Llama、GPT-OSS 三大家族、4B/8B/30B 多种规模、instruct / thinking 两种风格,结论一致。不是某模型特供。
- Bad Data 实验的反直觉冲击力。把"自蒸馏需要正确答案"这一隐含前提直接打掉。
6.2 需要打折看的地方
- 数据规模有限。10K 题目、每个 1 个 sample——相对 rSTARcoder 的 418K verified solution 数据集小了一个数量级。论文承认这是个 limitation:成本低、收益也未必能 scaling。
- thinking 模型涨幅有限。30B-Thinking 只涨 2.1,4B-Thinking 涨 3.3——远低于 instruct 模型的 12.9。最强的模型收益最小。这条规律在 RLHF/RLVR 路线上其实也常见(好模型天花板高、边际收益小),但对"用 SSD 替代 RLVR"的叙事是个折扣。
- 对 base 模型能力有依赖。Llama-3.1-8B-Instruct base 12.7% 的水准,SSD 之后也只到 16.2%——没有把"弱鸡模型救活"的能力。SSD 是给"还行的 base model"做精修,不是给"白纸"开智。
- Pass@5 涨 18 但 Pass@1 只涨 12.9。说明 SSD 改善了多样性,但 pass@1(用户最常用的指标)的提升没 Pass@5 那么夸张。实际部署中如果你只做 greedy,可能捞不到完整收益。
- OOD 通用知识评测里 4B 模型有退步。Table 5 里 Qwen3-4B-Instruct 在 MMLU 上从 76.4 掉到 73.8,3-4 个点的回退;30B 模型则更稳。这暗示 4B 量级上 SFT 数据确实"挤占"了部分通用能力(虽然数学/代码不退)。
- 理论分析虽然漂亮但有 scope 限制。公式 4 的三项分解在 toydata 上 work,但作者也承认 real model 里 entropy 的变化不完全符合理论预测。理论是"引导直觉",不是"严格证明"。
6.3 跟同期工作的对比
| 路线 | 代表工作 | 监督信号 | 复杂度 | 本文相对位置 |
|---|---|---|---|---|
| Teacher distillation | Kim & Rush '16、Hsieh et al. '23、Agarwal et al. '24 | 强老师输出 | 中(要强老师) | SSD 不需要老师 |
| RFT / Self-Rewarding | Yuan et al. '24、SPIN | 正确性 filter / self-judge | 高(要 reward) | SSD 不需要 filter |
| STaR / ReST | Zelikman '22、Singh et al. '24 | 推理路径 + 答案 | 中(要 gold answer) | SSD 不需要 gold answer |
| Unsupervised RLVR | Zuo '25、Agarwal '25、Prabhudesai '25 | 内在 reward (entropy / majority) | 高(要训 reward) | SSD 不需要 reward model |
| RLVR | DeepSeek-R1、OpenAI o-series | 执行 / 答案正确 | 极高(要 RL pipeline) | SSD 复杂度 ≈ 标准 SFT |
一句话总结:SSD 在"信号源"和"训练复杂度"两个维度上做到了最简,但在"涨点幅度"上没有超过 RLVR。它适合的场景是:已经有不错 base model、想用极低成本做小幅精修、不愿意维护 RL pipeline。
6.4 工程落地建议
如果要把 SSD 用到你自己的项目里,几个实操建议:
- 数据:用你手头已有的 prompt 集(不需要答案),让 base model 采样。每个 prompt 采 1 个就够——别浪费算力在 N>1。
- 温度:\(T_{\text{train}} \in [1.0, 1.2]\) 是个稳妥起点,配上 \(T_{\text{eval}} \in [0.8, 1.0]\)。先扫 \((T_{\text{train}}, T_{\text{eval}})\) 网格的 4×4 找到你模型的 \(T_{\text{eff}}\) 峰值。
- 截断:一定要用,top-k=5 或 top-p=0.95。Bad Data 实验证明无截断时收益骤降。
- 训练:标准 SFT 即可,无需新 loss。Apple 用 8 × B200 + peak LR \(5 \times 10^{-6}\) + 2500 步。
- 预期收益:Instruct 模型 4B 量级 +5–8pp,30B 量级 +10–13pp;thinking 模型 +2–4pp。强 base 别期待太大。
7. 一些更深的问题
读完后我脑子里还转着几个问题,没在论文里找到答案,但觉得值得抛出来:
-
SSD + RLVR 能组合吗? 比如先 SSD 做 distribution reshaping,再做小规模 RLVR。理论上前者给了"更整齐的 base distribution",后者给"更精准的策略优化",看起来是互补的。值得做。
-
数学推理/通用 chat 上 work 吗? 论文只在 code 上验证,但 lock / fork 的二元结构在 reasoning chain(CoT 里每个 step 也有 commit 时刻和分支时刻)里同样存在。这个机制是否跨 domain?这关系到"SSD 是一个 code-specific trick,还是一个 general post-training 范式"。
-
\(N>1\) 的 marginal value。论文坚持 \(N=1\) 就够。直觉上 \(N>1\) 应该更好(更多样),但作者说"实测没明显收益"——这反直觉。
-
"Bad data, good results" 的边界在哪?\(T_{\text{train}}=2.0\) 无截断是乱码,\(T_{\text{train}}=3.0\) 可能就是更烂的乱码,到某个点肯定要崩。这个边界在哪?论文没系统扫。
-
对 MoE 的特殊影响。Qwen3-30B-A3B 是 MoE(30B 总参 / 3B active),GPT-OSS-20B 也是 MoE。SSD 在 MoE 上的训练和 dense 上有什么不同?这关系到"未来如果 scaling 到 100B+ MoE,SSD 还有没有效"。
8. 结语
苹果这篇论文给我的最大启发不是"自蒸馏这么简单就能涨 13 个点"——而是它给了一个非常扎实的"precision-exploration conflict"框架。我们做 LLM 后训练的时候,太多讨论都把"采样温度"当成一个可调超参,没人把"同一个温度对 lock 和 fork 效果相反"这件事挑明。
SSD 不是一个"更优的训练算法"。它是一个"承认全局温度不够、然后用自蒸馏去重塑分布结构"的工程方案。它的简洁性是它的美德——让任何有 base model 的人都能在几小时算力内做一遍。
但也别神话它。它涨 13 个点是在 Qwen3-30B-Instruct 这样的强 base + 干净 prompt 上。Llama-3.1-8B-Instruct 上只有 3.5pp;GPT-OSS-20B 上只有 5.3pp。这是"锦上添花"不是"雪中送炭"。
不过那个 Bad Data 实验我会记很久。62% 乱码数据训出 5.7pp 提升这件事,把"自监督自改进"这条路上一个根深蒂固的假设("必须要有正确答案")直接掀了。
如果以后有人问我"RLVR 是不是必须的",我大概率会先反问一句:你看过 SSD 的 bad data 实验没?
觉得有启发的话,欢迎点赞、在看、转发。跟进最新 AI 前沿,关注我。