快速结论:当你用 Transformers v4.48.0 及以上版本加载原始 Gemma 1.0 系列 checkpoint(如 google/gemma-2b、google/gemma-7b、google/codegemma-2b)时,模型会静默地使用精确 erf GELU(GELUActivation)而不是训练时使用的 gelu_pytorch_tanh,导致输出数值偏差。核心原因是 Gemma 1 checkpoints silently use exact GELU instead of gelu_pytorch_tanh since v4.48.0 (#35235 removed the hidden_activation guard)。优先排查你加载的模型仓库是否属于受影响的 Gemma 1.0 列表,以及当前 Transformers 版本是否 ≥ 4.48.0。
适用环境:Issue 中确认的环境为 transformers 5.1.0、torch 2.10.0+cu130、Python 3.14、Windows 11;同时版本 bisect 表明 guard 在 v4.47.1 仍存在,v4.48.0 起消失。模型:google/gemma-2b(revision 9cf48e52b224239de00d483ec8eb84fb8d0f3a3a)。
最快修复方案:Issue 中明确给出的 workaround 是加载前覆盖 config 的 activation:
from transformers import AutoConfig, AutoModelForCausalLM
config = AutoConfig.from_pretrained("google/gemma-2b")
config.hidden_act = "gelu_pytorch_tanh"
model = AutoModelForCausalLM.from_pretrained("google/gemma-2b", config=config)
注意事项:该 workaround 仅修正推理时的激活函数,不会改写 Hub 上的原始 config。在部分高精度场景(CPU F32、CUDA F32)下 top-10 排名可能不变,但 BF16 下排名会移动(CUDA BF16 出现 7/30 top-10 索引不一致)。此外 hidden_activation 字段在 v5.0.0 已从 GemmaConfig 移除,因此早期依赖该字段的写法在新版本上不可用。
问题场景
用户在使用 Transformers 加载并推理原始 Gemma 1.0 系列 checkpoint 时触发该问题,涉及仓库包括 google/gemma-2b、google/gemma-2b-it、google/gemma-7b、google/gemma-7b-it、google/codegemma-2b。Gemma 1.1、CodeGemma 7B-it 与 Gemma 2 不受影响。该问题由对照独立 Rust 实现 candle-mi 0.2.1 的 tests/validate_gemma_forward.rs 时暴露。用户在运行普通前向推理(如文本生成、logits 比对)时就会命中,没有异常抛出,只有数值差异。
报错原文
Gemma 1 checkpoints silently use exact GELU instead of gelu_pytorch_tanh since v4.48.0 (#35235 removed the hidden_activation guard)
原因分析
最可能的原因是 PR #35235(”All attention refactor”,commit 2c47618c,2024-12-18)在 modeling_gemma.py 与 modular_gemma.py 中删除了针对 config.hidden_activation 的 legacy guard,改为直接 ACT2FN[config.hidden_act]。原始 Gemma 1.0 的 config.json 中携带的是 "hidden_act": "gelu",而 ACT2FN 将其映射为精确 erf 形式的 GELUActivation,并非这些模型训练时所用的 tanh 近似。该 guard 原本正是为此类错误 config 而存在(由 #29402 引入、#29995 完善)。Gemma 1.1 及之后在 config 中修正了该值,但 1.0 系列仓库未更新,仍依赖已删除的 guard。hidden_activation 字段在 v5.0.0 被移除后,该覆盖路径彻底不可达。同一次提交中 gemma2/modeling_gemma2.py 保留了 ACT2FN[config.hidden_activation],因此只有 Gemma 1 丢失了 fallback。另外,GemmaConfig.hidden_act 仍默认 "gelu_pytorch_tanh",但文档串直到 v5.1.0 仍称其会被已不存在的 hidden_activation 覆盖,库内部表述自相矛盾。
环境排查
- 确认
transformers版本是否 ≥ 4.48.0(该版本起 guard 被移除)。 - 确认加载的模型仓库是否属于受影响的 Gemma 1.0 列表(
google/gemma-2b、gemma-2b-it、gemma-7b、gemma-7b-it、codegemma-2b)。 - 检查模型
config.json中的hidden_act字段是否为"gelu"。 - 确认运行设备与精度(Issue 在 CPU F32、CUDA F32、CUDA BF16 下均有测量,BF16 下影响更明显)。
- 确认
torch版本(Issue 使用 2.10.0+cu130)与 attention 实现(Issue 使用 eager attention)。
解决步骤
- 加载 config 时覆盖激活函数(Issue 中作为 workaround 明确给出,可优先尝试):
from transformers import AutoConfig, AutoModelForCausalLM config = AutoConfig.from_pretrained("google/gemma-2b") config.hidden_act = "gelu_pytorch_tanh" model = AutoModelForCausalLM.from_pretrained("google/gemma-2b", config=config) - 如果只是做数值验证,可以按 Issue 的做法加载模型后,在推理前将每个
mlp.act_fn就地替换为gelu_pytorch_tanh,再执行前向。Issue 指出act_fn是无状态的,替换后的第二次前向等价于”激活正确时”模型应有的输出。 - 等待或跟踪修复 PR:#49061 与 #49063 均被提出。Issue 中测量结果显示两者都能让数值与参考位级一致(bit-identical),差异在于 #49061 会把
config.hidden_act载入后解析为gelu_pytorch_tanh并写回save_pretrained、在 config 与模型加载时都告警,且check_modular_conversion通过;#49063 保持config.hidden_act为gelu、不在 config 加载时告警,且check_modular_conversion失败。讨论中倾向的修复位置是 config 的 post-init(PretrainedConfig.__post_init__已有torch_dtype→dtype的先例),因为它在from_dict之后执行,可覆盖从 Hub 加载的 config。
验证方法
在相同设备和精度下,将修正激活后的前向输出与”正确参考”(例如对 mlp.act_fn 统一替换为 gelu_pytorch_tanh 的第二遍前向)对比。Issue 的对照方法可作为参考:先做激活控制(比较 gelu 与 gelu_pytorch_tanh 在 [-8, 8] 上 160001 个点的最大差为 4.734992980957031e-4),再做确定性控制(不改动连跑两次,应位级一致),最后比较修正前后 top-1 logits、top-10 最大绝对差以及 top-10 索引是否一致。Issue 中在 F32(CPU/CUDA)下 top-10 索引不一致为 0/30,但 CUDA BF16 下为 7/30,说明 BF16 下更易观察到排名变化。
参考来源
huggingface/transformers #49051
AI 工具推荐
想把多个 AI 模型放在一个入口?
GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。
推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。
这个方案解决了吗?
可以继续搜索完整报错,或查看同一工具的其他排查指南。
![[Bug]: pytorch rocm 6.0 with 7600xt = HSA_STATUS_ERROR_INVALID_ISA](https://www.chat-gpts.plus/wp-content/uploads/2026/09/15434-1e9b08ba-768x403.jpg)

