快速结论:该报错发生在 Transformers 库中 PPFormulaNet 模型训练时,原因是 ForCausalLMLoss 默认对 labels 左移一位,但 PPFormulaNet 是 encoder-decoder 架构,logits 与 labels 已对齐,导致训练标签错位、丢失最后一个目标 token。优先排查是否使用了包含修复(PR #46903)的 Transformers 版本。
适用环境:Hugging Face Transformers 库,涉及 PPFormulaNetForConditionalGeneration 模型(基于 Florence2 架构)。Issue 中未提供具体的操作系统、Python、CUDA、显卡或依赖版本信息。
最快修复方案:升级到包含 PR #46903 的 Transformers main 分支(该 PR 于 2026-07-23 合并,已修复此问题)。如果无法升级,可修改源码,在调用 loss_function 时传入 shift_labels=labels 参数,禁止其内部左移。
注意事项:上述代码修复方案已在 main 分支验证,但未在已发布的稳定版本中确认;自行修改源码时需同步修改 modular_pp_formulanet.py 和生成的 modeling_pp_formulanet.py 两个文件。
问题场景
用户使用 Transformers 库训练或微调 PPFormulaNetForConditionalGeneration 模型时,发现训练损失异常(训练-loss bug)。问题定位在 modular_pp_formulanet.py 第 491 行的 self.loss_function() 调用:由于 PPFormulaNet 继承了 Florence2 的架构但重写了 forward() 方法,导致 Florence2 在 PR #46898 中已应用的修复未能传递到 PPFormulaNet。
报错原文
PPFormulaNet training-loss bug — ForCausalLMLoss incorrectly shifts labels in encoder-decoder model
The problem: PPFormulaNetForConditionalGeneration.forward() uses self.loss_function() which maps to ForCausalLMLoss. ForCausalLMLoss internally shifts labels left by 1 (labels[..., 1:]), but PPFormulaNet is an encoder-decoder model where the logits are already aligned with labels — no shift is needed.
原因分析
根本原因已确认:ForCausalLMLoss 内部默认执行 labels[..., 1:] 左移操作,这是为因果语言模型(causal LM)设计的。然而 PPFormulaNet 是 encoder-decoder 模型,其输出的 logits 与输入的 labels 已经对齐,不需要额外移位。两次移位(或说一次多余的移位)导致模型训练时 labels 错位,最终丢失最后一个目标 token。此问题与 issue #46901 描述相同,均由 PR #46903 修复。
环境排查
- 确认 Transformers 库版本:检查是否低于包含 PR #46903(2026-07-23 合并)的版本。
- 确认是否从源码构建:Issue 中提到从
main分支构建并阅读当前代码后确认修复已存在。 - 如需自行修改,确认同时修改了两个文件:
modular_pp_formulanet.py和modeling_pp_formulanet.py(后者为生成文件,手动修改后注意不要被重新生成覆盖)。
解决步骤
- 首选方案(已验证):升级 Transformers 库到包含 PR #46903 的
main分支或更新的发布版本。该 PR 修复了此问题,并已确认在main分支中生效。 - 备选方案(代码修改):如果无法升级,找到
modular_pp_formulanet.py第 491 行附近的loss_function调用,将代码修改为:loss = self.loss_function( logits=logits, labels=None, vocab_size=self.config.text_config.vocab_size, shift_labels=shift_labels if shift_labels is not None else labels, **kwargs, )注意:此处的
shift_labels=shift_labels if shift_labels is not None else labels是修复后的最终形态。若你的代码版本较旧,可先尝试 Issue 中提出的中间方案shift_labels=labels,但建议直接对齐最终修复代码。 - 同步生成文件:手动修改
modeling_pp_formulanet.py(生成的模型文件)中对应的loss_function调用,确保与modular文件一致。
验证方法
从源码构建 main 分支后,读取 modeling_pp_formulanet.py 中 loss_function 调用处,确认已包含 shift_labels=shift_labels if shift_labels is not None else labels 参数。或直接重新运行训练,观察 loss 是否恢复正常、最后一个目标 token 是否参与训练。
参考来源
huggingface/transformers #47317
AI 工具推荐
想把多个 AI 模型放在一个入口?
GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。
推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。
这个方案解决了吗?
可以继续搜索完整报错,或查看同一工具的其他排查指南。


