AI 编程模型架构

LLM 代码生成为什么看起来该对但经常不对

先说结论:Apple 这篇 ML-SSD 论文——Embarrassingly Simple Self-Distillation Improves Code Generation——对普通终端用户的直接相关性有限。如果你主要通过 Claude Code、Cursor 这类产品写代码,你接触不到 temperature 之类的解码参数,产品已经把这些旋钮藏起来了。但它仍然值得花十分钟理解,因为它提供了一个简洁的框架来解释 LLM 代码生成的内部约束、失败模式和当前能力边界。理解这些,有助于你判断模型什么时候可信、什么时候需要人工介入。

论文注意到了什么问题

Apple 这篇 Embarrassingly Simple Self-Distillation Improves Code Generation(下文简称 SSD)的出发点是一个实践者熟悉的现象:同一个模型,有时能写出完全正确的代码,换个场景或多试几次又错得离谱。

论文 claim:这个现象的一个重要来源是全局解码策略(一个 temperature 从头用到尾)与代码 token 级需求之间的粒度不匹配。代码生成中存在两类截然不同的位置:

Lock position——语法和语义把下一个 token 的合理选择压缩到很小的范围。比如 for i in range( 后面几乎只能跟数字、变量或函数调用。在这类位置,模型的概率分布应当高度集中,但实际上往往残留一条 distractor tail:那些语法上勉强合法但语义上错误的 token 仍然分到了不可忽略的概率,采样时偶尔会把生成拉偏。

Fork position——多个延续方向都合理,对应不同的解题路径。比如面对一道图论题,用 DFS 还是 BFS 都说得通。在这类位置,模型需要保持足够的概率分散度来探索不同解法。

冲突就在这里:lock 需要精确(压制长尾),fork 需要探索(保持分散),但全局 temperature 只能在 sequence 级别做一个固定折中。调低有利于 lock 但伤害 fork,调高则反过来。论文认为这种粒度不匹配是代码生成的一个关键瓶颈。

提出的解法直觉

SSD 的方法极度简单:从冻结的 base model 采样大量代码(不做任何过滤或验证),用这些原始输出对同一个模型做标准 fine-tuning,评估时使用单独调节的 temperature。全程不用 verifier、teacher 或 RL。

论文 claim:这个看似自说自话的过程实现了 context-dependent 的分布重塑。微调后,模型在 lock position 上的概率分布变得更集中(distractor tail 被压制),在 fork position 上有意义的多样性被保留。原来只能靠全局 temperature 做的粗粒度 tradeoff,被部分转移到模型参数里,变成按上下文自适应的细粒度调节。

我们的理解:可以这样直觉化——base model 在 pretraining 后学到了大量 code pattern,但这些 pattern 的表达强度比较均匀,没有根据”此处需要确定还是需要发散”来差异化调节各个位置的输出分布。SSD 的自蒸馏过程相当于让模型把已有知识按局部上下文的实际需求重新对焦。

论文还做了一个关键消融实验:在 base model 上进行充分的全局 temperature 搜索,能达到的最佳 pass@1 仍然显著低于 SSD 微调后的结果(Qwen3-30B-Instruct 在 LiveCodeBench v6 上,42.4% vs 55.3%)。这排除了”SSD 只是间接找到了更好的全局 temperature”这个解释,支持了论文关于参数空间内局部化调节的核心论点。

为什么这套直觉有助于理解当前 LLM 的限制

即使你从不直接调 temperature,lock/fork 框架也提供了一个有用的心智模型:

LLM 写代码时,有些位置它几乎不可能出错(lock),有些位置它需要做出高层选择(fork)。当前不少产品(包括 Claude Code、Cursor 等)的底层生成过程,仍然会受到全局解码策略的明显影响,这意味着模型在这两类位置上的表现存在内生的张力。当你观察到模型在简单语法上犯低级错误,或者在需要创造性选择的地方过于保守,lock/fork 框架提供了一个解释方向:这可能源于全局解码策略在 token 级别的折中,而非模型”不懂”这段代码。

这也解释了一个常见经验:让模型多试几次(多次采样)在很多场景下比精调单次输出更有效。如果瓶颈确实在于 lock/fork 的折中,那么多次采样本质上是在用 sample 数量来缓解单次解码策略无法同时满足两类需求的问题。

证据状态与边界

论文在代码生成域内的证据链比较完整:多模型验证、decode-only gap 消融、分布分析、以及一个坏数据压力测试(在包含错误代码的自生成数据上做 SSD 仍然有效,进一步支持增益来自分布重塑而非数据质量)。

需要注意的边界:代码仓库已开放(github.com/apple/ml-ssd),但截至 2026 年 4 月模型 checkpoint 未发布,广泛的独立复现尚未出现。SSD 能否推广到代码以外的生成任务(如数学推理),论文没有给出实验证据。当前这套解释框架值得认真对待,但外部验证仍在早期阶段。

相关资源:论文全文(arXiv)HTML 版代码仓库

鸭哥每日手记

日更的深度AI新闻和分析