2026-07-27
Thoughtbubbles 在 Transformer 中间层 fork 或删除残差流,让需要更多算力的 token 长出并行计算的「气泡」,全程只用语言建模损失预训练。半数训练预算下 perplexity 和多数 zero-shot 指标打过标准解码器基线。
扩大 Transformer 的推理算力,主流做法是让它先吐一段显式的思维链(chain-of-thought)再给答案。这条路有两个硬约束:思维链的 token 是自然语言、串行生成,而且这类训练只能加在后训练阶段,塞不进预训练。Thoughtbubbles 想换一种扩算力的方式:让模型在潜空间里、在网络中间层,自己决定哪些 token 需要更多计算,并为它们分出并行的计算流。这件事在预训练阶段只用语言建模损失就能学会,不需要任何监督信号。
核心操作是「fork」。在特定的 fork 层(放在第 3、7、11 层之后),模型可以选择复制或删除残差流(residual stream,Transformer 里贯穿各层的那条信息通道)。一个 token 需要更多计算时,就在它旁边 fork 出若干条克隆残差,形成一个「气泡」,气泡在后续层里各自演化,最后再把结果汇总回主路。
具体怎么决定 fork 多少,被设计成一个有预算的分配问题。每条残差流带一个 0 到 1 的累积分数 pcum,可以理解成「这条流存在」的程度。fork 层为每条残流算两个分:pfork(新开一份)和 pkeep(更新当前流),累积相乘后取 top-k,只保留分数最高的 κ 条。κ 设为输入块大小的 2 倍或 4 倍,这就是算力预算。最右侧的原始 token 被强制保留(p̂=1),保证至少有一份实例存活。
为了让「分数」不只是装饰,作者用三处设计逼着模型把分数当成真实信号:分数调制注意力,分数进到注意力掩码和值里,分数低的残流在 attention 里被压低;衰减的残差更新,注意力和 MLP 的输出也乘上分数,迫使模型给重要残流更高分数;输出平均,同一输入 token 的多条残流按分数加权平均后解码(1.9B 模型为省算力用了更便宜的近似)。
为什么叫「无监督」:全程只有交叉熵语言建模损失,没有任何 CoT 数据或额外标签。模型靠着上面三处梯度通路,自己学会把更多计算预算分给需要的 token。作者还发现模型确实把预算更多地分给了不确定度高的位置,呈现一条凹抛物线。
主结果(1.9B,40B token 预训练加 2B token 中期训练)里,关键对比是「半数训练预算」:Thoughtbubbles 用 20B token,基线用 40B。Perplexity 上 Thoughtbubbles 12.68、基线 15.03;HellaSwag 50.04 vs 47.29;PIQA 73.42 vs 71.79;GSM8K 31.50 vs 31.46。
关键在于它只用了一半训练算力:Thoughtbubbles 在 perplexity 和绝大多数 zero-shot 指标上仍打过用满算力的基线。这种「半算力反超」在 150M 到 1.9B 多个规模上成立,而且 319M 规模的 Thoughtbubbles 在 OpenWebText 上的 perplexity(20.55)低于 772M 规模的基线(21.22)。代价是推理更慢:单次前向-反向在 H100 上 327ms,基线 234ms,但比把块大小直接翻倍的基线(380ms)便宜。GSM8K 上,用一半的 token 预算就能拿到和基线相当的结果。
思路是把「扩推理算力」从「显式吐自然语言」挪到「隐式、可预训练的潜空间并行」。如果成立,adaptive compute 可以在预训练就介入,不必等后训练再教模型「思考」,训练期和测试期的算力扩展也就有望统一到同一套机制上。对一个还在快速演进的架构方向,这篇给出了从 150M 到 1.9B 的连续证据。
也要清醒:1.9B 还远不算大,「半算力反超」是在这个规模上成立的,放到几十亿上百亿参数还说不说得通,论文没回答。
作者自己列了几处。最实际的是训练-推理分布失配:训练时 fork 预算固定,自回归推理时输入变长,得动态按比例放大预算(κ 随输入大小)才能缓解,作者明确提醒要小心标定。BLiMP 这类语法任务对计算匹配的基线没有优势,说明并行计算对句法帮助有限。模型还把相对更少的预算分给不确定度最高的 token(凹抛物线的另一头),作者猜测分句边界、共指这些位置多算无益。
工程上,单次前向仍比基线慢约 40%,完整 logit 混合做输出平均很贵,1.9B 只能用近似。实验规模也只到 1.9B。