用过 ChatGPT、Claude 或本地部署的开源模型的人,大概率都见过下面这类现象:模型本来在正常回答,突然开始重复同一个词、同一句话,像卡住了一样无限循环;或者突然输出一堆无法显示的乱码、控制字符、纯数字串;更极端的情况,输出直接变成空或截断,模型像是「死」在了某一步。这些现象不是某个模型的质量问题,也不是 prompt 写得不够好------几乎所有 Decoder-only 大语言模型在足够长的推理中都会表现出退化倾向,只是触发条件和严重程度不同。
这个问题在工业界和学术界有几个常用名称:模型退化(degeneration)、文本循环(text repetition)、模型崩溃(model collapse)。虽然叫法不同,但它们指向同一个根因:自回归 Transformer 在推理时,注意力机制、Causal Mask、解码策略和数值精度形成了一个正反馈回路,微小偏差被循环放大,最终导致输出彻底失控。
理解这个问题不是出于学术好奇心。任何在生产环境中使用大模型的人都需要知道:为什么加一个 repetition_penalty 参数就能缓解?为什么长对话比短问答更容易出事?为什么量化模型比全精度模型更容易输出乱码?为什么有时候不是改模型而是要刷新 KV Cache?这些问题答案都藏在退化机制里。
本篇能让你学会三件事:
- 为什么自回归 Transformer 在推理时会自发退化,以及 QKV 计算、Softmax 和 Causal Mask 各自扮演什么角色;
- 死循环、乱码、无意义数字三种退化形态背后的不同机制------它们不是同一种 bug;
- 从架构设计、数值工程、解码策略到运行时监控,生产环境中如何分层防御推理退化。
在进入正文之前先说明边界:本篇讨论的是推理阶段的退化 ,不是训练阶段的 loss spike 或梯度爆炸(那部分见 36|训练稳定性)。推理退化发生在模型权重已经固定、纯粹做前向计算的时候。它的触发条件往往不是模型「训坏了」,而是输入上下文、解码参数或数值路径恰好踩进了模型的脆弱区间。
一、注意力坍塌:Softmax 的马太效应与 QKV 退化
退化现象的数学根源在注意力机制本身。要理解这一点,需要回到 self-attention 的核心公式:
Attention(Q,K,V)=softmax(dk QKT+M)V
其中 M 是 Causal Mask 矩阵(未来位置设 −∞)。一切正常时, QKT 产生一个合理的相似度矩阵,softmax 给出平滑的注意力权重分布,加权求和后的输出包含丰富的上下文信息。退化发生时,这个链条上的每一步都在出问题。
Softmax 的固有倾向:赢家通吃
Softmax 有一个经常被忽略的数学性质:它对输入的尺度极其敏感。设两个 logit 之差为 Δ,当 Δ 较大时,softmax 输出几乎完全集中在最大值上。这不是 bug,而是指数函数的自然行为------但它在自回归循环中变成了危险源。
在正常推理中,每个位置的注意力分布通常分散在多个相关 token 上------前面的主语、最近的动词、关键的修饰语,各自分到合理的权重。但一旦某个 token 因为某种原因(可能是上下文语义恰好强烈指向它,可能是数值扰动,也可能是某个罕见 token 的 embedding 恰好和当前 query 对齐得特别好)获得了略高的注意力分数,softmax 会把这个微弱优势指数放大。
这个放大效应在单步中可能无害------一个位置的注意力稍微集中一点,输出 token 的 embedding 稍微偏一点,都在正常范围内。问题在于自回归生成会把这一步的输出变成下一步的输入。
QKV 映射的低维坍塌
经过数十层 Transformer 的线性变换,Q 和 K 的向量表示可能逐渐退化到一个低维子空间。这不是推理独有的问题------训练中也会发生,但训练时有梯度信号往回修正,推理时没有。一旦 Q 和 K 的内积在某个子空间之外失去了区分能力,无论当前上下文是什么,softmax 之前的注意力分数矩阵就会在某个固定模式上始终最高。
这个模式往往对应序列开头的一两个 token。Xiao 等人在 2023 年的「Efficient Streaming Language Models with Attention Sinks」中系统论证了这一点:Transformer 在训练中学会了把大量注意力权重分配给开头的几个 token(尤其是 [BOS] 或第一个词),这些 token 充当了「注意力泄洪区」(attention sink)------即使它们在语义上对当前预测没有贡献,模型也会稳定地把一部分注意力丢给它们。
当上下文变长、KV Cache 膨胀时,attention sink 现象会加剧。过多的历史 token 稀释了有效语义信息的注意力权重,模型越来越依赖开头的 sink token 和最近生成的几个 token。此时如果最近生成的 token 恰好触发了某种重复模式,整个注意力分布就会锁定在这个模式上。
Causal Mask 的双重角色
Causal Mask 在这里的角色非常微妙。它的设计目标是防止模型在预测时偷看未来------这个目标它完成得很好。但它同时制造了一个结构性困境:一旦过去的上下文被重复、无意义的 token 污染,模型在计算当前 token 的 Q 与历史的 K 时,无法通过「看向未来」来跳出这个污染区。它只能看过去,而过去已经坏掉了。
打个比方:Causal Mask 像一辆只有后视镜的车。正常情况下,看后视镜就够了,因为道路是连续的。但如果后视镜里开始出现重复的、失真的画面,司机既不能转头看前方(没有未来信息),也不能停车重置(自回归生成必须继续)。他只能根据已经坏掉的后视镜继续做决策,而每一个新决策又会进一步污染后视镜里的画面。
二、为什么是死循环:自回归反馈与概率陷阱
退化最常见也最容易触发的一种形态是死循环------模型反复输出同一个词、同一句话或同一段模式。
贪婪解码的致命正反馈
Holtzman 等人在 2020 年的「The Curious Case of Neural Text Degeneration」中对这一现象做了系统分析。他们发现,即使模型在每一步的概率分布是合理的,贪婪解码(greedy decoding)也会导致文本退化。原因在于:自然语言中,同一个词连续出现的真实概率通常很低,但模型学到的条件概率分布可能会给「重复前一个词」分配不低的分值------因为训练数据中确实存在少量重复(强调、口吃、诗歌等)。
在贪婪解码中,只要 P(xt=w∣xt−1=w) 在所有候选中最高, w 就会被再次选中。选中之后,上下文变成了「......w w」,此时模型看到连续两个 w,它学到的模式可能是「连续重复通常继续重复」,于是 P(xt+1=w) 反而更高。这就形成了自增强循环。
关键点在于:这不是某一步概率估计错了,而是贪婪解码把一个小概率偏差锁定成了确定性路径。 在概率分布上,模型可能给 w 分配了 0.15,给其他 token 分配了 0.03 × 20。0.15 不高,但它是最高的。采样有 85% 的概率不选 w,而贪婪 100% 选 w。
注意力权重在循环中的雪崩
贪婪解码只是触发器,真正把循环锁死的是注意力机制的正反馈。当一个 token w 被重复生成,它在 KV Cache 中的 K 和 V 向量会快速堆积。到下一步,当前 Q 和这些大量重复的 K 做点积时,由于 w 的 K 向量和自己高度相似(同一个 token 的 key 向量天然相近),注意力分数会在这些位置上集中。
softmax 之后,最近几个重复的 w 获得了压倒性的注意力权重。模型从上下文中提取到的信息几乎完全被「前面一直在说 w」主导,其他语义信息被淹没。于是模型继续输出 w,循环加固。
这个过程的可怕之处在于它的自我加速特性:一旦开始循环,上下文中的有效信息占比就迅速下降,模型会更快地走向循环。循环不是逐步建立的------往往在 3 到 5 个 token 内就从正常输出切换到不可逆的死循环。
为什么重复惩罚有效
重复惩罚(repetition penalty)的机制直接针对上述正反馈:在采样前,对已经出现过的 token 的 logits 施加惩罚。Keskar 等人在 2019 年 CTRL 模型中引入了这一技术。设惩罚系数为 θ>1,对已出现 token 的 logit zi 做 zi/θ 缩放,使其概率下降。
这相当于在概率分布层面强行打破「同一个词连续出现概率最高」的循环条件。但 θ 不是越大越好------过大的惩罚会让模型不敢重复任何词,包括应该重复的(比如专有名词、术语、代词),导致输出别扭甚至语法错误。
三、为什么是乱码:数值溢出与词表边缘
死循环至少还能看到可读的文字。乱码比死循环更危险------输出变成无法显示的字符、控制码、纯数字序列,或者直接空的------因为它往往意味着数值计算本身出了问题,而不仅仅是概率分布的偏差。
FP16/BF16 的溢出路径
大模型推理普遍使用 FP16 或 BF16 来减少显存占用和加速计算。这两种精度的表示范围是有限的:FP16 的最大正常值约 65504,BF16 约 3.39×1038。在 attention 计算的关键路径上,以下操作都可能触发溢出:
-
QKT 的内积累积 :当序列很长, Q 和 K 的维度很大(通常 64 到 128),做 dk 次乘加后,结果可能超出 FP16 范围。 dk 1 的缩放因子正是为此设计的,但在极端值情况下可能不够。
-
Softmax 的指数运算 : exp(x) 在 x>11 左右就在 FP16 下溢出到 Inf。虽然标准实现会先减最大值( exp(xi−max(x)))来稳定计算,但如果所有值都很大且相近,这个 trick 只能保 softmax 输出不崩,不能保梯度或中间值不崩。
-
残差连接的累积 :如 24|残差连接 中讨论的,每层都往 residual stream 里加东西。如果尺度没有控制好,长序列下的残差累积可能让某些维度的值进入 FP16 的危险区间。
-
KV Cache 中的错误累积:在长对话或长文本生成中,KV Cache 中存储的历史 K/V 可能已经包含接近溢出边界的值。新 token 的 Q 和这些边界值做点积,就是溢出事故的高发场景。
一旦某个张量中出现了 NaN 或 Inf,它会沿着后续计算路径快速扩散。一层 softmax 出了 NaN,所有 attention head 的输出全是 NaN;残差路径把 NaN 加进主干,后面所有层的输出全是 NaN。最后的 logits 向量变成一堆 NaN,经过 softmax 变成无效的概率分布。
NaN 之后的概率分布长什么样
当 logits 全是 NaN 时,softmax 的输出在数学上是未定义的。不同框架的处理方式不同:有的返回全零向量,有的返回均匀分布,有的返回随机值。无论哪种,模型都没办法正常选 token------它会随机跳进词表中罕见或从未在正常上下文中出现的 token 区域。
这些区域包括:控制字符(如 \x00、\x01、Unicode 不可见字符)、原始数字 token(训练数据中残留的数字串)、词表碎片(tokenization 产生的罕见字节组合)。一旦模型误入这些区域,这些 token 在训练时极少作为正样本出现,它们的 embedding、K/V 映射都没有学到有意义的表示。接下来的每一步,Q 和 K 的内积都会彻底失序,输出完全随机。
这就是为什么乱码通常不会自己恢复。一旦进入了词表的边缘地带,模型就像掉进了信息的真空------周围的 token 都是它不认识的,它只能继续乱跳,直到被外部停止条件(max_length、EOS 侥幸触发)截断。
量化模型为什么更脆弱
INT4/INT8 量化模型推理退化更频繁,本质原因是量化引入了额外的数值噪声。量化把连续的浮点值映射到离散的整数格点,这个过程在 Attention 的 softmax 附近和 FFN 的激活函数附近尤其容易引入相对误差。在正常推理中,这些误差通常被模型的鲁棒性吸收。但在长序列中,量化误差会逐步累积进 KV Cache,叠加 attention 的正反馈放大效应,比 FP16 模型更快触碰到退化阈值。
量化不是原罪------它在大多数推理中工作良好------但它确实降低了安全边界。对于长上下文推理或开放域对话,量化模型需要更保守的解码参数才能保持稳定。
四、解码策略如何放大或抑制退化
前文多次提到解码策略在退化中的作用,这里单独拿出来系统化地讲。
贪婪解码是退化放大器
贪婪解码之所以危险,不是因为概率分布本身有问题,而是因为它让模型在每一步都失去探索其他路径的机会。在正常文本生成中,每个位置通常有 5 到 20 个合理候选,贪婪只取第一个。统计上,连续 100 步都选到合理候选的概率并不低------大部分时候模型确实表现正常。但只要某一步陷入前文描述的注意力偏置陷阱,贪婪就没有回头路。
Holtzman 等人 2020 年的核心发现是:人类文本中,同一个 token 的重复概率远低于模型预测的概率。 模型在训练中看到了足够多的不重复样本,学会了「通常不重复」,但它在单步概率上仍然系统性地高估了重复的可能性。贪婪解码把这个系统偏差变成了确定性行为。
Top-P 和 Top-K:给模型留退路
Top-P(nucleus sampling)和 Top-K 采样的共同机制是限制候选集合,然后从中随机采样。这个「随机」是关键的退路------即使某个 token 的概率是集合内最高,它也只有一定概率被选中。当模型有一个微弱的「重复」倾向时,采样有概率选择其他候选,从而阻断循环进入正反馈。
但这不意味着采样可以完全防止退化。当注意力的正反馈足够强时,所有合理候选可能都指向类似的方向------语义上不是完全相同的词,但仍然在同一个狭窄区域内打转。这就是所谓的「语义退化」:文字不完全重复,但内容在原地兜圈,没有推进。
Temperature 的双刃剑
提高 temperature 让分布更平坦,低概率 token 更容易被采到。这能帮助模型跳出局部循环------但也会增加选到词表边缘 token 的概率,反而可能触发乱码形态的退化。降低 temperature 让分布更尖锐,接近贪婪,可能触发循环形态的退化。
没有对所有模型、所有上下文都最优的 temperature 值。生产系统通常按任务分别调参,并在检测到退化迹象时动态调整。
五、工程解法:从架构到运行时的多层防线
理解了退化机制之后,解法就变得清晰了------它们是分层部署的,从架构设计到运行时监控,每一层解决一类问题。
架构层的防御:让注意力不容易坍塌
Attention Sink 的工程化处理 。既然模型天生需要把一部分注意力丢给「无关紧要的位置」,不如给它指定的 sink token。在推理时,显式地在 prompt 开头加入一两个专用的 sink token(如特殊的占位符),让这些 token 吸收那些没有明确语义目标的「溢出注意力」。这比让模型自己找 [BOS] 或第一个词当 sink 更可控。Xiao 等人的 StreamingLLM 工作证明了保留 attention sink 对于长文本流式推理的稳定性至关重要。
滑动窗口注意力(Sliding Window Attention) 。限制每个 token 的注意力回溯范围------只看最近的 W 个 token,不看全部历史。Beltagy 等人在 2020 年的 Longformer 中提出了滑动窗口 + 全局注意力的混合模式,Mistral 等模型在实践中使用了纯滑动窗口。这种设计从结构上切断了「远古重复污染当下」的路径:即使几百步之前有过一段重复,滑动窗口之外的历史在 attention 计算中不可见,无法直接影响当前。
滑动窗口的代价也很明显:它丢失了窗口之外的全局信息。对于需要长程依赖的任务(理解整个文档、追踪远距离的指代),纯滑动窗口不够。这就是为什么 Mistral 的滑动窗口和 Llama 的全局注意力会做出不同取舍------没有免费午餐。
RoPE 的外推与修正 。旋转位置编码(RoPE, Su et al. 2021)在长文本场景下的外推是另一个关键点。当推理长度超过训练时的最大长度,RoPE 的旋转频率可能导致 Q 和 K 在长距离上的内积失去区分能力------所有远距离 token 看起来都一样。YaRN(Peng et al. 2023)等方法通过动态调整 RoPE 的频率基值,让位置编码在未见过的长度上仍然保持区分度。这些技术同时解决了长文本的退化问题和位置外推问题。详见 41|位置编码演进。
数值工程层:不让 NaN 出现
关键计算的 FP32 保护。在混合精度推理中,对 softmax、LayerNorm/RMSNorm 等敏感操作强制提升到 FP32 计算,算完再切回 FP16/BF16。这是性价比最高的防 NaN 手段------额外开销很小(通常不到 5% 的计算量),但能从源头上杜绝 softmax 溢出和归一化除零。
FlashAttention 的原始实现(Dao et al. 2022)就在 kernel 内部做了类似的数值保护:online softmax 在分块计算时保持了数值稳定性,避免了全精度 attention matrix 的存储和计算。FlashAttention 主要解决的是 I/O 瓶颈,但它的数值策略同时也降低了溢出的概率。
激活值裁剪(Activation Clipping)。对隐藏层输出进行截断------一旦某个维度超过预设阈值,就硬截到阈值。这相当于在每一层的输出端装了一个限幅器。Clip 值的选择需要实验确定:太大则没有保护效果,太小则会损害正常推理的质量。实践中通常按分位数设置。
解码层:运行时拦截
这部分的原理在 48|从 logits 到文本 中有详细展开,这里仅从退化防御角度总结关键策略:
- 重复惩罚(Repetition Penalty)和 N-gram 阻断(No Repeat N-gram):后者直接规定「已经出现过的连续 n 个 token 的组合不能再次出现」。比重复惩罚更暴力,但防止 n-gram 级别的重复模式尤其有效。
- Logits Processor 过滤:在 logits 到 token 的路径上插一层过滤器,黑名单机制禁止输出非打印字符、控制字符、已知的乱码 token。即使模型内部已经半崩,输出层可以被工程强行把守。
- 动态 Early Stopping:监控输出流,检测到连续重复次数超过阈值、连续出现控制字符、token 生成概率下降到异常低水平等信号时,自动触发 EOS 或优雅终止。
- 自适应参数调整:部分推理框架会根据输出的熵、重复率等指标,在生成过程中动态调整 temperature 或 repetition_penalty。
运行时层:KV Cache 管理与上下文裁剪
在长对话和 Agent 场景中,退化常常不是一次性事件,而是上下文的持续污染。KV Cache 把历史 token 的所有 K/V 都保留在显存中------这包括了退化已经开始但还未明显体现在文本上的那些中间表示。
当监控系统检测到模型有退化迹象(输出质量下降、重复率上升、困惑度异常),一个有效的恢复手段是:裁剪掉最近一段疑似污染的上下文,丢弃对应的 KV Cache 片段,重新生成。 部分推理引擎还支持自动做上下文摘要------把长历史压缩成摘要,放进系统提示或前缀,减少 KV Cache 总量和对远历史的注意力依赖。
这些方案本质上是承认退化无法完全避免------Transformer 的自回归结构决定了这是一个概率问题而非确定性问题------然后在系统层面建立检测→干预→恢复的闭环。
六、关键概念回顾
- 推理退化(Inference Degeneration):推理阶段输出质量自发下降,表现为重复、循环、语义漂移、乱码或截断。
- Attention Sink:模型倾向于把大量注意力分配给序列开头几个 token 的现象,这些 token 充当注意力的「泄洪区」。
- QKV 低维坍塌:Q 和 K 的向量表示在某个子空间之外失去区分度,导致注意力分布锁定在固定模式上。
- Softmax 马太效应:微小的 logit 差异被指数函数放大为巨大的概率差异,使赢家通吃。
- 自回归正反馈:输出 token 成为下一步的输入,循环放大微小的概率偏差,使退化自我加速。
- KV Cache 污染:退化 token 的 K/V 进入 cache 后,持续影响后续所有 token 的注意力计算。
- 数值溢出路径 : QKT 累积→指数运算→残差累加→KV Cache 边界值,任一环节溢出可能导致 NaN/Inf 扩散。
- 多层防线:架构层(sink/sliding/RoPE)→数值层(FP32 保护/clipping)→解码层(penalty/filter/monitor)→运行时层(cache 管理/上下文裁剪)。
七、常见误解
7.1 「退化说明模型训坏了」
退化不是训练失败的结果。即使训练完美的模型,在足够长的推理中也会表现出退化倾向。退化是 Transformer 自回归结构的固有属性,就像热力学第二定律------熵增是系统的内在趋势,不是制造缺陷。
7.2 「调高 temperature 就能解决循环」
提高 temperature 可能帮助跳出循环,但也增加了乱码风险。循环和乱码的解法有时互相矛盾------循环需要更多随机性来打破,乱码需要更少随机性来保持稳定。正确的做法是根据退化形态选择策略,或者直接上重复惩罚和 n-gram 阻断。
7.3 「换了更大的模型就不会退化了」
模型规模主要影响退化的触发点,不是从根本上消灭退化。更大模型的注意力分布通常更平滑,陷入极端循环的概率更低,但数学模型是一样的。量化、长上下文、极端温度下,大模型一样会退化。
7.4 「退化只在推理时发生,和训练无关」
训练阶段的稳定性问题(见 36|训练稳定性)和推理退化共享一些底层机制(数值精度、注意力坍塌),但触发条件和应对策略不同。一个可以平稳训练的模型,推理时如果参数和上下文不匹配,一样可能退化。
八、下一步
本篇解释了 Transformer 推理退化的机制和防御策略,但它聚焦在「单次推理」的视角。退化的另一个加速器是多轮对话和 Agent 场景中的上下文持续膨胀------这直接和 49|KV Cache 相关。
从更宏观的视角看,退化是 Transformer 自回归结构的深层代价之一。55|Transformer 的根本局限 讨论了为什么 O(n2) 是终极瓶颈,退化可以视为这个瓶颈在推理质量维度的表现。状态空间模型(56|SSM)和线性注意力(57|RWKV / RetNet / 线性注意力)试图从根本上改变序列建模的计算图,从而绕开这组问题。
九、参考文献
论文
- Holtzman, A., Buys, J., Du, L., Forbes, M., & Choi, Y. "The Curious Case of Neural Text Degeneration." ICLR 2020. 系统分析了语言模型文本退化的统计特征,提出了 nucleus sampling(top-p)。
- Xiao, G., Tian, Y., Chen, B., Han, S., & Lewis, M. "Efficient Streaming Language Models with Attention Sinks." arXiv 2023. 发现并论证了 attention sink 现象,提出了 StreamingLLM。
- Keskar, N. S., McCann, B., Varshney, L. R., Xiong, C., & Socher, R. "CTRL: A Conditional Transformer Language Model for Controllable Generation." arXiv 2019. 引入了 repetition penalty 技术。
- Su, J., Lu, Y., Pan, S., Murtadha, A., Wen, B., & Liu, Y. "RoFormer: Enhanced Transformer with Rotary Position Embedding." arXiv 2021. RoPE 的原始论文。
- Peng, B., Quesnelle, J., Fan, H., & Shippole, E. "YaRN: Efficient Context Window Extension of Large Language Models." arXiv 2023. RoPE 的 YaRN 外推方法。
- Dao, T., Fu, D. Y., Ermon, S., Rudra, A., & Ré, C. "FlashAttention: Fast and Memory-Efficient Exact Attention with IO-Awareness." NeurIPS 2022. FlashAttention 的原始论文,包含 online softmax 数值策略。
- Beltagy, I., Peters, M. E., & Cohan, A. "Longformer: The Long-Document Transformer." arXiv 2020. 滑动窗口注意力的代表性工作。
- Vaswani, A., Shazeer, N., Parmar, N., Uszkoreit, J., Jones, L., Gomez, A. N., Kaiser, Ł., & Polosukhin, I. "Attention Is All You Need." NeurIPS 2017.
← 上一篇:58|后 Transformer 时代 | 系列首页:Transformer 与注意力机制 系列总览 →