——
最近大模型训练越来越“玄学”?明明代码没改、数据没动、超参也没调,但一跑强化学习(RL)微调,模型就莫名其妙地崩掉,奖励值剧烈震荡,甚至直接跑飞?更离谱的是,训练时看着一切正常,一部署上线,性能断崖式下跌——这到底是AI在耍你,还是你没摸清它的脾气?
别急,这个问题,不止你一个人头疼。全球最顶尖的AI实验室,也一直在为这事儿挠头:为什么训练和推理阶段的行为对不上?为什么同样的模型,在训练时聪明伶俐,一上线就“变傻”?这背后,其实藏着一个被我们忽视多年、看似微不足道却致命的细节——数值精度格式。
最近,Sea AI Lab和新加坡国立大学的研究团队,在经历无数次RL训练崩溃后,终于决定“回头看看”。他们放弃堆砌复杂的算法补丁,回归计算机最底层——浮点数怎么表示?结果发现,一个简单的切换——从现在业界流行的BF16,切回“老掉牙”的FP16——竟然彻底解决了长期存在的训练-推理不一致问题。更让人震惊的是,连前特斯拉AI总监Andrej Karpathy都在自己的nanochat项目里实测采用,效果立竿见影!
今天,我们就用最接地气的方式,把这篇硬核技术研究掰开揉碎,讲清楚:为什么BF16在RL里“翻车”?FP16到底强在哪?这个“返祖”操作,凭什么能拯救AI训练?
——
第一部分:RL训练为啥总崩?问题不在算法,在“数字怎么写”
强化学习微调大模型,比如用PPO、DPO或者最近火出圈的ORPO,本质上是在让模型通过“试错+奖励”学会更好的回答策略。训练时,模型一边生成文本(推理路径),一边根据这些文本的奖励信号更新参数(训练路径)。理想情况下,这两个路径应该完全一致——毕竟用的是同一个模型。
但现实很骨感。训练和推理,往往跑在不同的计算路径上。比如,推理可能走的是高度优化的TensorRT或vLLM引擎,而训练还在用标准的PyTorch+BF16混合精度。虽然看起来都是同一个模型,但底层的浮点运算精度、舍入方式、甚至硬件指令集都可能不同。
这就导致了一个致命问题:训练-推理不一致(Train-Inference Mismatch)。
举个例子:模型在推理阶段生成了一个回答,概率是0.6789;但当这个回答被送回训练阶段计算梯度时,由于精度差异,这个概率可能变成了0.6792。别看只差0.0003,但在高维概率空间里,这种微小偏差会被指数级放大,最终导致梯度方向错误——模型不是在优化真实策略,而是在优化一个“幻影策略”。
这会引发两大恶果:
第一,梯度偏置(Biased Gradient)。模型更新所依赖的梯度,是基于推理阶段生成的样本计算出来的。如果推理和训练对同一个动作的概率判断不一致,那这个梯度就不是无偏估计,模型越训越歪。
第二,部署断层(Deployment Gap)。训练结束时,你得到的是“在训练引擎下最优”的模型;但上线时,模型跑在推理引擎上,两者对参数的解读方式不同,性能自然打折扣。你辛辛苦苦调了两周的超参,上线后效果还不如蒸馏模型,心态直接崩了。
过去,大家怎么解决这个问题?主流思路有两个:
一是用重要性采样(Importance Sampling),通过概率比值对样本加权,理论上能消除偏差。但实际中,概率比值极其不稳定,尤其在策略差异大时,方差爆炸,反而让训练更不稳。
二是用更高精度(比如FP32)跑关键层,或者手动对齐训练和推理的代码路径。但这些方法要么牺牲速度,要么工程复杂度飙升,而且效果有限——因为根本问题没解决:BF16本身的结构,就不适合RL!
——
第二部分:BF16和FP16,16位浮点数背后的“设计哲学”大战
要理解为什么BF16在RL里“水土不服”,得先搞清楚BF16和FP16到底长啥样。
两者都是16位浮点数,但设计目标完全不同。
BF16(Brain Floating Point 16),名字听着就很“AI范儿”,是Google为TPU量身打造的。它的结构是:1位符号位 + 8位指数位 + 7位尾数位。重点来了——它保留了和FP32(32位单精度浮点)一样的指数范围,但把尾数从23位砍到7位。这意味着什么?BF16能表示极大或极小的数(比如1e-38到1e38),但精度非常粗糙。它适合做大规模矩阵乘加,因为指数范围大不容易溢出,精度损失在前向传播中影响不大。
FP16(Half Precision Floating Point),则是IEEE标准的老将,结构是:1位符号位 + 5位指数位 + 10位尾数位。它的指数范围小很多(大约1e-5到6e4),但尾数精度更高。也就是说,FP16在表示“中等大小”的数值时,更细腻、更准确。
听起来BF16更“先进”,为啥RL反而要用FP16?
关键在于:RL对概率分布的微小变化极其敏感,而BF16的低尾数精度会放大这种扰动。
在语言模型的RL微调中,策略网络输出的是一个概率分布(比如下一个token是“猫”的概率是0.32)。这些概率值通常落在0到1之间,属于“中等大小”的数值区间——这正是FP16最擅长的区间!而BF16虽然能表示这个范围,但7位尾数意味着它只能用128个离散值来近似0到1之间的连续分布,精度严重不足。
更致命的是,BF16在Softmax这类归一化操作中会产生显著的舍入误差。比如,一组logits经过exp()和归一化后,BF16可能把两个原本接近的概率变成显著不同的值,导致策略突变。而在训练阶段,这些突变被累积进梯度,最终引发训练崩溃。
反观FP16,10位尾数提供了1024个离散值来表示0-1区间,精度是BF16的8倍!虽然它的指数范围小,但在RL微调这种数值动态范围有限的场景下,完全够用,甚至更稳。
——
第三部分:实验证明——FP16让RL训练稳如老狗
Sea AI Lab团队在多个RL基准上做了对比实验,包括LLaMA-2-7B、Mistral-7B等主流模型,使用PPO和DPO两种主流算法。
结果惊人:只要把训练精度从BF16切换为FP16,训练曲线立刻变得平滑,奖励值稳步上升,不再出现剧烈震荡甚至崩溃。
更关键的是,部署一致性大幅提升。用FP16训练的模型,在推理引擎上跑出来的性能,几乎和训练时一致。而BF16训练的模型,上线后奖励平均下降15%以上。
他们还做了一个极端测试:在BF16训练中强制对齐推理路径的精度(比如用FP16做推理采样),结果训练依然不稳定——因为更新参数时还是BF16,梯度计算已经“污染”了。只有端到端全程FP16,才能根治问题。
Andrej Karpathy在自己的nanochat项目中也验证了这一点。他原本用BF16训练RLHF,发现奖励波动极大;切换FP16后,仅用几个epoch就收敛,效果远超预期。他在X上直言:“FP16在RL中被严重低估了。”
——
第四部分:FP16的优势不止稳定,还有生态兼容性
除了数值稳定性,FP16还有一个隐藏优势:硬件友好+生态成熟。
NVIDIA GPU从Volta架构开始就原生支持FP16,Tensor Core对FP16的计算效率极高。而BF16虽然是为TPU设计的,在NVIDIA上属于“后加支持”,实际性能并不如FP16。尤其在A100/H100上,FP16的吞吐量和能效比普遍优于BF16。
此外,主流推理框架如vLLM、TGI、TensorRT-LLM对FP16的支持非常成熟,部署时几乎无需额外适配。而BF16在某些旧框架中甚至不被识别,需要额外转换。
这意味着:用FP16,你不仅训练更稳,部署更快,还能省下一大笔调试时间。
——
第五部分:FP16不是万能药,这些限制你必须知道
当然,FP16也不是银弹。它最大的短板是动态范围小。当模型激活值或梯度出现极大值(比如训练初期或某些极端任务),FP16容易溢出,导致NaN。
解决方案有两个:
一是配合梯度裁剪(Gradient Clipping) 和 损失缩放(Loss Scaling),这是混合精度训练的标准操作,能有效防止溢出。
二是关键层保留FP32。比如输出层的logits或价值函数头,可以用FP32计算,其余部分用FP16。这样既保证精度,又控制动态范围。
另外,FP16对超参更敏感。学习率、batch size等需要微调,不能直接套用BF16的配置。但比起训练崩溃,这点调参成本完全可以接受。
——
第六部分:行业已开始行动,FP16正在回归RL舞台中央
目前,多个开源项目已开始默认采用FP16进行RL微调。比如TRL(Transformer Reinforcement Learning)库在最新版本中增加了FP16训练的推荐配置;Axolotl等热门微调框架也加入了FP16支持。
硬件厂商也在跟进。NVIDIA在NeMo框架中强调FP16在PPO训练中的优势;AMD则在其MI300系列中优化了FP16的内存带宽。
可以预见,在未来半年内,FP16将成为RL微调的事实标准。而BF16,或许更适合预训练这类对动态范围要求高、对概率精度不敏感的阶段。
——
结语:有时候,进步不是往前冲,而是往回看
在这个人人都在追新算法、新架构、新MoE的时代,Sea AI Lab团队用一个“返祖”操作,提醒我们:别忘了计算机科学的根基。浮点数怎么表示,从来不只是硬件工程师的事,它直接影响AI模型的行为逻辑。
RL训练不稳?别急着改算法。先检查你的精度格式——也许,答案就在FP16这个“老朋友”身上。
技术没有新旧之分,只有合适与否。在AI基础设施这场马拉松里,真正的赢家,往往是那些愿意低头看路、回归本质的人。
——
参考文献与延伸阅读
- Sea AI Lab & NUS Technical Report: “FP16 over BF16 for Stable Reinforcement Learning Fine-Tuning” (2025)
- Andrej Karpathy’s X post on FP16 in nanochat
- IEEE 754 Standard for Floating-Point Arithmetic
- NVIDIA Mixed Precision Training Best Practices
- TRL Library Documentation on FP16 Support