AI 快讯Liquid AI 出手治 LLM 的"复读病":FTPO 只惩罚最后那个 token
开发心得

Liquid AI 出手治 LLM 的"复读病":FTPO 只惩罚最后那个 token

2026-07-07T18:03:47.468Z
Liquid AI 出手治 LLM 的"复读病":FTPO 只惩罚最后那个 token

Liquid AI 提出 Final Token Preference Optimization(FTPO),针对模型陷入循环输出的"Doom Loop"痼疾,只对触发重复的那个 token 做偏好优化,训练成本更低、副作用更小。

Liquid AI 上周甩出一篇技术博客,讲他们怎么治 LLM 的老毛病——Doom Loop(复读机死循环)。方法叫 FTPO(Final Token Preference Optimization),思路简单粗暴:出问题的往往就是一个 token,那就只惩罚这一个 token,别搞连坐。

如果你调过小模型的 API,尤其是让它写长文、跑 agent 多轮推理,大概率见过这种场面:模型突然开始鬼打墙,同一句话循环输出,直到把 max_tokens 撞穿。开源社区里大家的土办法基本就三招——调高 temperature、加 repetition_penalty、上 DRY sampler。都能缓解,但都治标。Liquid AI 这次是想从训练环节根治。

Doom Loop 到底是怎么发生的

先说现象。Liquid 团队在博客里给了几个典型例子:模型输出一段代码后,突然开始把某个函数名重复几十遍;或者在回答一个开放性问题时,卡在某个句式上出不来,"总之,...总之,...总之,..."没完没了。

这不是新问题。早年 GPT-2 时代就有,工程上一般归因于两点:

  1. 训练分布的尾部塌陷——模型在某个上下文下把概率质量过度集中在了少数几个 token 上,采样时一旦踩中,就很难跳出
  2. 自我强化——一旦复读了一次,这段重复内容本身又成为上下文的一部分,进一步抬高了下一次复读的概率

第二点是关键。它是一个正反馈过程,temperature 只能延缓爆发,不能阻止。

Doom Loop 触发过程示意图,展示概率分布如何在重复输出中逐步塌陷

已有方案为什么不够用

DPO(Direct Preference Optimization)本来是最自然的选择:拿好的输出当 chosen,坏的(有复读的)当 rejected,一顿对齐。但 Liquid 团队指出 DPO 在这个场景下有几个硬伤。

第一,惩罚粒度太粗。DPO 是在整个 rejected 序列上算 loss,模型学到的是"这一整段都不好",但其实这段里可能 95% 的 token 都没问题,只是最后那一下滑进了循环。全序列惩罚会把好的部分也一起推低概率,副作用就是模型输出风格漂移,多样性下降。

第二,训练效率低。你得为每个 rejected 样本准备一个 chosen 对照,还得跑长序列的对数概率计算。为了修一个 token 的问题,付出的代价太高。

第三,也是最微妙的,过度对齐会把模型"抹平"。之前学术界已经有 DivPO 这类工作在提醒:偏好优化如果不考虑多样性,模型会越训越"标准化",创造力和长尾表达都会掉。

FTPO 的做法:外科手术式惩罚

FTPO 的核心洞察就一句话:Doom Loop 的形成通常可以追溯到某一个具体的 token 决策。那个 token 一旦选错,后面就是雪崩。所以训练时只要盯着这一个 token 做偏好优化就够了。

具体流程大致是:

  • 采样一批模型输出,用检测器(比如 n-gram 重复率)找出发生 Doom Loop 的样本
  • 定位到"临界 token"——也就是循环真正开始的那一步
  • 在这一步上,构造一个偏好对:当前采到的 token 是 rejected,某个替代 token(可以是次高概率的,也可以是从参考模型采的)是 chosen
  • 只在这个 token 位置上算 preference loss,其他位置的梯度不动

这么做有几个直接的好处:

训练信号极度稀疏但精准。相当于告诉模型"你其他都做得挺好,就这一步别这么走",模型不会为了修一个 bug 把整个人格重塑一遍。

样本利用率高。一条长输出里可能只有一个临界 token,但 FTPO 就针对这一个训。不用配对完整的 chosen 序列,工程复杂度和显存占用都下来了。

多样性保留得更好。这一点和 DivPO 的思路有异曲同工之处——你不动那些"没错"的 token,模型的输出分布就不会被大面积扭曲。

实测效果和一些限制

Liquid 在博客里给的评估结果,主要看两个指标:Doom Loop 触发率、以及在通用 benchmark 上的分数变化。前者显著下降,后者基本持平——这在偏好优化里是很难得的,因为大多数 alignment 手段都会在通用能力上掉一点。

但也要看到,FTPO 不是万能药。有几个明显的边界:

  • 临界 token 的定位依赖检测器。如果检测器把非重复的"重复模式"(比如列表输出、代码里的重复结构)误判成 Doom Loop,训练信号就会错
  • 对语义层面的"隐性复读"效果有限。有些模型会换着说法重复同一个意思,这种 semantic loop 不是靠单 token 惩罚能解决的
  • 需要在训练后期做。Liquid 建议把 FTPO 放在 SFT+DPO 之后作为收尾步骤,如果直接在 pretrain 后用,可能会因为基础对齐不够而效果打折

对开发者的实际意义

如果你在做基于开源模型的产品,尤其是长文本生成、agent、代码助手这类场景,FTPO 这套思路值得抄。它不需要你重新训基础模型,只要在你现有的 fine-tuning pipeline 后面加一个针对 Doom Loop 的"补丁训练"就行。

伪代码大概长这样:

# 1. 生成一批样本,找出发生 doom loop 的
loop_samples = detect_doom_loops(model.generate(prompts))

# 2. 定位临界 token 位置
for sample in loop_samples:
    critical_idx = find_loop_start(sample.tokens)
    rejected_token = sample.tokens[critical_idx]
    chosen_token = pick_alternative(sample.logits[critical_idx], exclude=rejected_token)
    
    # 3. 只在这个位置算 preference loss
    loss = ftpo_loss(
        logits_at=critical_idx,
        chosen=chosen_token,
        rejected=rejected_token,
    )
    loss.backward()

工程上的一个隐藏收益是:这套方法对显存非常友好。传统 DPO 要跑两个模型(policy 和 reference)的完整前向,序列一长直接爆显存。FTPO 因为只关心一个 token 位置,可以做很多优化,比如只保留临界 token 附近的 hidden states。

放到更大的图景里看

这两年偏好优化领域一直在往"更细粒度"的方向卷。从最早整段的 RLHF,到 DPO 的成对偏好,到 KTO 只需要单侧标签,再到 step-level 的 Process Reward Model,现在 FTPO 直接把粒度压到单 token。

这个趋势背后其实是一个共识正在形成:模型的错误往往是局部的,但我们的训练信号一直是全局的,中间浪费了大量学习效率。FTPO 只是这个大方向上的一个具体应用,可以预期后面会有更多针对特定失败模式的"局部偏好优化"方法冒出来——比如针对幻觉的 hallucination-token PO,针对拒答的 refusal-token PO 等等。

Liquid AI 这家公司本身走的就是效率路线,之前的 LFM 系列小模型也一直强调用更少的参数打更好的效果。FTPO 这套做法很符合他们的一贯风格:不追求宏大叙事,就盯着一个具体问题,用最经济的手段解决掉。

对国内开发者来说,如果你在用 Qwen、DeepSeek、GLM 这些开源模型做产品,遇到复读问题不用再只靠 repetition_penalty 硬扛了。抄一下 FTPO 的思路,花几百条标注数据做一轮针对性微调,收益可能比你想象的大。

参考来源

相关推荐

查看全部

联系我们

我们通常在工作时间快速响应

扫码添加微信

专属客服:Hub 助手

微信号: