恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
DeepL押注FP8:大模型训练与推理统一精度实战解析
首页
资讯中心
/
DeepL押注FP8:大模型训练与推理统一精度实战解析
DeepL押注FP8:大模型训练与推理统一精度实战解析
发布时间:2026/10/1 18:23:49
DeepL 2025 年的这波操作圈内讨论度很高新一代 LLM 不仅在训练阶段全面切换 FP8推理阶段也基本跑在 FP8 上。搞翻译、做多语言理解的朋友大多知道DeepL 对译文质量的要求近乎偏执能把训练和推理同时押在一个低精度格式上光凭勇气是不够的背后一定有一整套数值补偿和工程兜底。这篇就顺着 FP8 训练与推理的技术主线把选型逻辑、实操细节、踩坑经验摊开讲给想跟进这个方向但不清楚从哪下手的团队做个参考。全文不涉及 DeepL 未公开的内部实现所有结论都来自可复现的公开方法论和实际工程经验。1. 为什么 DeepL 押注 FP8训练和推理共享同一套数值血统1.1 核心思路一个精度贯穿全生命周期先看动机。传统 LLM 流水线里训练用 FP16/BF16推理阶段为了省显存再单独做 INT8/FP8 量化两套精度体系各管各的。问题在于训练时模型学习到的数值分布和推理时实际运行的数值分布不一致于是需要一个校准集去修补这种偏差校准集选得不好某些语言会莫名其妙变差。DeepL 的做法是让训练和推理都跑 FP8。这个决策的精妙之处在于数值血统从训练第一步就确定下来推理只是把同一套分布原样搬过去训练和推理之间的精度鸿沟被直接抹平。再加上 FP8 在 H100/B200 上有硬件级 GEMM 加速所以它不是单纯的精度妥协而是一种从底层算力到模型行为的整体设计。从工程角度看统一精度还带来一个隐性红利离线量化、在线推理、训练恢复这些环节可以共用同一套缩放因子计算逻辑省掉了大量重复开发。我见过太多团队在推理量化阶段花几周调校准集最后效果还不如训练时顺手加一个 FP8 开关。DeepL 把这一步前置本质上是把压缩从推理阶段的工作提前变成了训练阶段的设计约束。1.2 选型背后的算力账本省显存、降带宽、提吞吐FP8 最直观的收益是数值宽度减半。相比 BF16/FP16模型权重、激活、KV cache 都可以砍掉一半内存占用这对动辄几十 B 的翻译模型来说非常实在。假设一个 70B 参数模型用 BF16 训练单参数占 2 字节光权重就是 140GB换 FP8 后一个参数占 1 字节权重立刻变成 70GB。显存省下来可以直接换成更大的 batch、更长的上下文或者塞进更多的 MoE expert。带宽同样重要。大规模训练里all-reduce 通信量和参数规模成正比FP8 让梯度通信量直接减半。推理侧更明显一个 token 生成要反复读取权重和 KV cache显存带宽往往是吞吐的瓶颈。用 FP8 之后单位时间能塞进计算单元的字节翻倍batch size 可以开得更大吞吐能力一般能提升 1.5 到 2 倍。对 DeepL 这种要支撑海量在线翻译请求的产品这意味着同样的 GPU 集群能扛住更多的并发翻译单位请求的算力成本直接下降。但这里要提醒一句省钱的前提是硬件和软件栈都到位。A100 那一代对 FP8 没有原生支持硬跑模拟收益很有限H100、H200、B200 以及配套的 Transformer Engine、vLLM、TensorRT-LLM 生态成熟之后FP8 才谈得上真正的性价比。所以这个账本不是所有团队都能抄的下面几节会具体展开怎么做。2. 训练侧实战FP8 不是把 dtype 换掉那么简单2.1 格式选型E4M3 负责前向E5M2 收留梯度FP8 有两种主流编码格式E4M3 和 E5M2。E4M3 是 1 个符号位、4 个指数位、3 个尾数位动态范围相对小但尾数精度更高E5M2 是 1 个符号位、5 个指数位、2 个尾数位动态范围更大但精度明显下降。拿生活类比E4M3 像一把刻度细的尺子能量得很准但量程有限E5M2 像一把粗刻度的大秤量程很宽但读不出精细数值。实际训练里通常的做法是前向传播的权重和激活用 E4M3因为 GEMM 的精度主要依赖尾数反向传播的梯度用 E5M2因为梯度的动态范围经常跨越好几个数量级E4M3 那点量程很容易溢出。这个分工不是拍脑袋是 FP8 混合精度训练论文和 NVIDIA Transformer Engine 默认行为里沉淀下来的经验。如果没有特殊理由直接照这个分工走最稳。还有一个容易忽略的点量化误差是在每个线性层前向/反向时引入的。Transformer 里大部分计算量集中在 QKV 投影、MLP 的线性层这些层用 FP8 收益最大。像 LayerNorm、softmax 这种逐元素算子计算量小但对数值敏感一般保留 BF16/FP32。也就是说FP8 训练不是全模型降精度而是关键计算路径上选择性降精度。这一点和很多人以为的一键低精度训练完全不是一回事。2.2 master weights、优化器状态与梯度通信的混合编排FP8 训练里最核心的数值安全网是 master weights。模型真正参与 GEMM 的权重虽然是 FP8但优化器更新的目标必须是高精度副本通常用 BF16 或 FP32 保存。每一轮迭代的逻辑是从 master weights 读高精度权重cast 成 FP8 喂给 GEMM反向拿到 FP8 梯度后先回存到高精度空间再做优化器状态更新。这样即使 FP8 的舍入误差反复累积master weights 也能提供干净的数值锚点。优化器状态更不用说了。Adam 的一阶矩和二阶矩如果也扔进 FP8基本等于自找苦吃尤其是二阶矩动态范围极大FP8 根本接不住。实际工程里优化器状态保留 BF16/FP32这是所有主流框架的共识。很多人以为 FP8 训练能省全部显存其实省的是参与 GEMM 的激活和权重缓存master weights 和优化器状态这块高精度家底还是得留着。梯度通信是另一个被低估的环节。数据并行训练里各 rank 的梯度要做 all-reduce通信量和精度直接相关。FP8 梯度可以让通信字节减半但有一个隐患如果每个 rank 的缩放因子不一致all-reduce 前必须先对齐缩放因子否则聚合出的梯度会失真。一种稳妥的做法是在 reduce 前先把梯度统一 cast 回 BF16通信仍然省了毕竟 FP8 到 BF16 再回传本质上没有省通信更常见的做法是利用硬件支持的 FP8 梯度聚合但所有 rank 共享同一组全局缩放因子。设计通信方案时要把这个对齐逻辑提前写进框架而不是等炸了再排查。2.3 损失缩放与 scaling factor 怎么设block-wise 动态缩放经验FP8 的动态范围天然有限激活和梯度稍微极端一点就会溢出。解决思路和 FP16 时代很像用 scaling factor 把原始数值映射到 FP8 能表达的区间。FP16 时代是一个全局 loss scalerFP8 训练里缩放粒度可以更细从 per-tensor 到 per-row、per-block 都有。per-tensor scaling 最简单整个 tensor 一个缩放因子内存开销小但怕 outlier。Transformer 激活分布里经常出现少数极端大的值一个 outlier 就能把缩放因子带偏导致大量正常值精度损失。per-block scaling 把 tensor 切成小块每块单独计算缩放因子对 outlier 的容忍度显著提高代价是元数据多、实现复杂。实际使用中大多数团队会选 per-block或者至少对激活做 per-row 级别缩放。缩放因子的更新节奏也讲究。Transformer Engine 常用的 delayed scaling是用前若干步的统计值来预测当前步的缩放因子避免每一步同步计算带来的开销。但延迟意味着遇到分布突变时会滞后典型表现就是 loss 突然 spike。我见过一个案例训练语料里混入了异常长的段落激活分布瞬间变化delayed scaling 没跟上直接跑出 NaN。后来自带恢复逻辑每步对比当前统计和历史统计的偏差超过阈值就强制重算缩放因子并回退几步优化器状态问题才稳住。总之fp8 训练不是简单改几个配置而是要在框架层面重新设计数值健康检查机制。3. 推理侧工程在 KV cache 和 GEMM 里抠出性价比3.1 FP8 KV cache压缩内存换更长的上下文翻译场景有个特点很多用户传的是一整篇文档动辄几千词甚至上万词。LLM 逐 token 生成时要不断读取历史 token 的 K 和 VKV cache 的显存占用和序列长度成正比长文档下它会从小负担变成主要负担。把 KV cache 从 BF16 切成 FP8直接省一半内存这意味着同样的显存可以支持更长的上下文或者更大的并发 batch。KV cache 量化有一点需要注意V 的精度直接影响最终输出分布K 的精度则影响 attention 分数的计算。两者都量化到 FP8 时常见的问题是长序列后段质量悄悄变差。原因在于 attention logits 在量化过程中累积了微小误差生成早期察觉不到生成到几百 token 之后误差被逐步放大。我在推理 FP8 的实际项目里遇到过开头很好长文到一半开始胡译的情况后来排查发现是 K cache 的缩放因子对某一层特别不友好把那层的 K cache 单独保留 BF16问题立刻消失。这种部分回退策略在工程上非常实用比整体回滚损失小得多。3.2 分组 GEMM 与张量并行MoE 模型怎么分配通信新一代 LLM 越来越多采用 MoE 结构DeepL 这一代模型大概率也没绕开。MoE 的推理跟前两年 dense 模型有个巨大差异每个 token 只会激活一小部分 expert所以常规矩阵乘法要改成分组 GEMM把同一批 token 按路由结果分成多组每组和不同的 expert 权重做矩阵乘。FP8 在分组 GEMM 上的加速很直接H100 及以上硬件的 FP8 张量核心对标准 GEMM 和分组 GEMM 都有优化算得快之外权重减半意味着从一个 expert 切到另一个 expert 时的显存换入换出压力更小。对推理服务来说MoE 模型喂给每个 expert 的 token 数不均衡会出现某些 GPU 忙死、某些 GPU 闲死的情况。FP8 让单个 expert 的权重占用变小张量并行下切分权重的颗粒度更细给负载均衡留了更多操作空间。真正费心思的是通信。MoE 推理里 token 需要按照路由结果在 expert 之间迁移也就是 all-to-all 通信通信量和模型宽度强相关。FP8 的权重和激活占用的字节少all-to-all 传的数据量对应也少延迟直接受惠。但注意expert 并行里不同 rank 的中间激活如果也用 FP8路由统计和负载均衡模块读取的分布信息可能与高精度版本有偏差一般会保留少量关键统计量用高精度计算避免路由决策漂移。3.3 质量敏感的算子哪些层要留在更高精度即使不在训练阶段引入 FP8只做推理阶段量化也会发现模型内部并非所有层对精度一视同仁。实操中一个干净的分类是嵌入层输出和最终 logits 附近尽量用高精度attention 里的 QKV 投影视校准结果而定FFN 的中间层通常对 FP8 比较宽容。嵌入层值得警惕的原因是token embedding 的维度通常很高且每个 token 对应的向量直接参与后续语义计算量化误差会沿着序列传播输出 logits 层则直接决定下一个 token 的概率分布softmax 前很小的 logit 差都可能翻转生成结果。这两种层即使只占很少的 FLOPs也值得保留 BF16。FFN 中间层因为计算密集、参与者是通过激活函数后的特征网络本身对它的噪声容忍度更高适合大量压到 FP8。怎么判断哪些层敏感一个比较可靠的手段是逐层置换实验把某一层的权重单独量化成 FP8其余层保持高精度跑一套固定的评测集看质量指标掉多少。这样能画出一张敏感度热力图敏感层回退不敏感层压紧。比盲目把整网切 FP8 靠谱得多也是我在多人项目里推荐的标准流程。4. 质量兜底精度降了翻译不能跟着降4.1 评测矩阵BLEU COMET 还不够加一轮语言对分层抽样翻译模型的评测没法只看一个数字。BLEU 对语序敏感、对词汇多样性惩罚明显很多语言尤其是形态丰富的语言BLEU 分数低但实际翻译可接受COMET 这类基于神经模型的指标更接近人工判断但也会被量化误差干扰。所以 FP8 改造后建议同时盯 BLEU 和 COMET还要看细分的语言对表现。更重要的一个维度是语言对分层抽样。DeepL 覆盖的语言很多主流的英德、英法、英日翻译反复训练、数据量充足量化误差可能完全看不出来但低资源语言对比如某些北欧小语种或东欧语言训练数据少模型输出分布会比较集中FP8 带来的噪声影响往往更明显。我的习惯是把语言对按资源充足程度分成三档每档随机抽样若干句子分别计算 BLEU/COMET并和基准模型做 delta 分析。只看总体均值容易掩盖低资源语言的质量崩坏。还有一个常被忽略的场景术语表。专业翻译用户的术语表往往是硬约束比如FP8 必须译为 FP8 低精度浮点格式。量化误差虽然一般不会翻转术语但会让术语周围的结构复杂化导致术语匹配失败。评测集里要专门加一组带术语约束的句子别等线上用户投诉才发现。4.2 校准集与量化误差的可视化排查推理 FP8 通常需要一个校准集来确定缩放因子校准集的选择在很大程度上决定了量化质量。很多人直接用训练集里抽几万条这是错的。校准集应该尽量贴近真实线上分布包含长文档、短句、术语表、数字日期、代码块、多语言混合段落而不是平均意义上的自然语言。校准之后要做的第一件事不是跑评测而是把量化误差可视化。具体做法用同一批输入分别跑 FP8 模型和 BF16 基准模型收集每一层激活或权重的最大绝对值、缩放因子数值、量化前后的相对误差。通常你会发现误差集中在少数几层这恰恰是敏感度热力图最直接的输入。我习惯用直方图看缩放因子分布如果某个 tensor 的缩放因子在全量范围内跳了好几个数量级说明 per-tensor scaling 不适合要立刻换成 per-block。另外一个小技巧观察解码时的 logits 分布。把 FP8 模型和前向高精度模型的 logits 画在一起看哪些 token 位置的偏差最大。如果偏差集中在句子开头或者标点符号附近通常是 embedding 和输出层的问题如果集中在长句后半段优先检查 KV cache。这比一点点黑盒调参效率高很多。4.3 术语表与超长文档场景的专项回归翻译质量评估里最怕的是平均分很高但特定场景用户天天投诉。专项回归能补上这个缺口。第一轮回归跑术语表场景用上千条带术语约束的句对检查术语命中率和译文流畅度第二轮跑超长文档场景构造 2000 到 8000 token 的段落观察生成稳定性。超长文档有个内在矛盾上下文越长KV cache 量化误差的累积风险越高。FP8 下很可能出现前 500 token 完美中间开始重复末尾出现幻觉。专项回归时一定要设置分位数检查比如统计生成到 25%、50%、75%、95% 位置时的忠实度评分而不是只看整篇文档的最终分数。如果末尾段的评分显著低于开头就按前面说的把 K cache 或特定层回退到更高精度。还有一个实操建议把 FP8 推理模型的输出和 BF16 基准模型输出做逐句 diff统计修改率。如果一篇文章里 80% 的句子一字未改只有 20% 的句子有轻微词序变化通常可以接受如果大范围改词就要考虑是不是缩放因子校准没做对。这个 diff 过程比看评测分数直观得多也是我每次上线前必跑的检查。5. 踩坑实录从 NaN 到坏权重一张排查速查表5.1 训练崩溃loss spike、梯度异常与缩放因子漂移FP8 训练在规模不大的时候可能一切正常一旦把 batch 调大、序列拉长各种怪问题就来了。最常见的是 loss 突然变成 NaN而且不是训练刚开始而是稳定跑了几千步之后突然炸。这种晚发 NaN大概率不是代码 bug而是缩放因子漂移导致的梯度溢出。排查路径可以这样走先看当日训练日志里 gradient norm 的变化曲线如果 NaN 前几步出现梯度从 1e-2 到 1e4 的跳跃基本确定是缩放因子没有跟上分布。再查 E5M2 梯度 tensor 的缩放因子范围如果超过 E5M2 动态范围上限就该把缩放因子调小或者给梯度加一个 clip。训练里还要保留 checkpoint 的自动回退机制遇到 NaN 时回退到几步前的状态同时强制重算缩放因子。没有这个机制一次 NaN 就能浪费一整天的 GPU 时数。另一个隐蔽问题梯度通信后缩放因子不一致。数据并行下如果每个 rank 按照自己的激活统计计算缩放因子reduce 过后的梯度会夹杂多种尺度的数值结果就是更新方向被污染。我们的解决方式是在 all-reduce 前统一交换缩放因子以全局最大值或者固定策略为基准确保所有 rank 拿到的梯度处于同一尺度。5.2 推理劣化为什么总是某些语言先坏推理侧同样问题不少。一个经典现象整体 BLEU 只掉 0.3但内部看语言对英语到德语几乎没变化英语到某种低资源语言直接掉了 2 分。这不是玄学。低资源语言的 token 分布更尖锐激活里 outlier 占比更高FP8 的缩放因子被少数极端值拉偏大量普通 token 的精度就保不住。处理办法是在校准集里按语言和资源丰富度加权采样而不是均匀采样。均匀采样的校准集会偏向数据量大的语言低资源语言在统计上被淹没。另一个办法是为低资源语言单独设置缩放因子或者在推理时对这些语言启用更高精度的回退分支。这听起来奢侈但 DeepL 这种规模的产品为关键语言保留少量高精度路径完全合理。还有一种劣化是间歇性劣化同一句话翻译三遍两次正常一次跑偏。遇到这种问题优先检查 batch 内的序列长度 padding 和 KV cache 复用逻辑。FP8 下注意力 mask 的处理稍有不同个别序列边界上缩放因子没对齐就会概率性出错。这种问题用确定性 seed 复现比较难最好直接在推理框架里加断言检查缩放因子在 batch 内是否保持一致。5.3 可复现性与离线验证的坑FP8 GEMM 在 GPU 上不是完全确定性的。cublas 和 cutlass 的 FP8 实现可能因为分块方式不同产生极小的浮点差异同一个模型在不同框架版本里跑结果也可能对不上。追求可复现的团队必须锁定 CUDA、cuBLAS、Transformer Engine 和框架版本并且把量化算法和缩放因子计算逻辑固定下来不能依赖框架默认值悄悄改变。另一个离线验证的常见坑是离线批量推理用的小 batch在线服务实际是大 batch。FP8 张量核心在某些分块大小下大 batch 和小 batch 的数值行为并不完全一致。离线评测全过一上线大并发请求就出现偶发质量问题往往就是这个原因。建议离线验证时就模拟线上 batch size 和 KV cache 长度不要用一个和生产环境差异很大的配置测完就算数。我整理了一张速查表适合打印出来贴工位症状可能原因首选排查动作训练中途 loss 变 NaN缩放因子漂移或 E5M2 溢出看梯度 norm 曲线强制回退几步梯度 all-reduce 后更新方向异常各 rank 缩放因子不一致通信前统一全局缩放因子推理长文后半段质量下降K cache 或部分层量化误差累积逐层置换定位敏感层并回退低资源语言明显变差校准集采样偏向高资源语言校准集按语言资源加权单独缩放同句多次推理结果不稳batch 内缩放因子未对齐检查 padding 和 KV cache 复用逻辑离线通过但线上异常batch 大小不同导致 GEMM 行为差异用生产 batch size 重新离线验证5.4 别忽视小模型FP8 在 1B 以下的收益有限最后说一个经常被忽略的工程事实FP8 的收益和模型规模强相关。对小模型1B 参数以下显存省一半带来的收益可能抵消不了精度损失因为小模型本身容量小量化噪声相对更容易干扰 representation。我在小模型上做 FP8 推理经常遇到质量下降明显、吞吐提升却一般的情况。如果你现在维护的是 10B 以上的模型FP8 是值得投入的方向如果是 1B 左右的轻量模型不如先试 INT8 或者保持 BF16。FP8 是给大且满的模型准备的红利模型不够大这个红利很难兑现。6. 给团队的迁移建议和我的个人体会6.1 什么时候值得上 FP8什么时候先别动综合上面的经验我的判断标准是三条硬件是否原生支持 FP8模型是否大于 10B推理延迟和显存是否构成瓶颈。三条都满足可以放心推进有一条不满足就得仔细权衡。特别是只有 A100 的团队FP8 硬件加速缺位模拟 FP8 的收益和成本不成正比不如把精力放在其他优化上。推进顺序也重要。我的建议是先从推理侧 KV cache 量化开始这一步改动小、风险可控、收益立竿见影。跑通了再考虑权重和激活的 FP8 GEMM然后才是训练侧的完整 FP8 流程。一上来就全量改造训练流程一旦两侧同时出问题排查难度会翻好几倍。DeepL 这次能训练、推理一起上说明他们的数值稳定性体系和评测体系已经相当成熟。对大多数团队来说把训练和推理统一到 FP8 是个目标但不应该是第一天就达成的目标分阶段推进、每阶段都建立质量基线才是稳的路子。6.2 最后分享一个小技巧我个人在实际项目里最值得推荐的一个习惯是每次调整 FP8 配置都把 BF16 基准模型的输出和 FP8 模型的输出存成对照样本做成一个可以按语言、按文档长度、按术语数量筛选的评测集。这个评测集比任何单一指标都能更快暴露问题。另一个小技巧是给缩放因子做健康检查。无论训练还是推理定时打印各层缩放因子的 min/max/均值观察它是否在合理范围内缓慢变化。如果某个缩放因子出现阶跃式突变那基本就是 outlier 或者数据分布漂移的前兆趁早处理能避掉后面一连串 NaN 和质量劣化。这个习惯花不了多少算力却能省下不少排查时间。