ForQuestionAnswering heads fail to load base model weights due to base_model_prefix=”transformer” (Llama family)

用 LlamaForQuestionAnswering 或 AutoModelForQuestionAnswering 从 Llama 家族基础模型/CausalLM 检查点加载时,加载器无法把 model.* 权重映射到 QA 头的 transformer.* 参数,导致主干层静默随机初始化。优先

快速结论:用 LlamaForQuestionAnswering 或 AutoModelForQuestionAnswering 从 Llama 家族基础模型/CausalLM 检查点加载时,加载器无法把 model.* 权重映射到 QA 头的 transformer.* 参数,导致主干层静默随机初始化。优先检查加载报告中的 UNEXPECTED / MISSING 键是否呈现 model.* 对 transformer.* 的错配。

适用环境:Issue 报告环境为 transformers 5.21.0.dev0、macOS-15.7.9-arm64、Python 3.14.2、PyTorch 2.14.1(无加速器)、huggingface_hub 2.2.0、safetensors 0.8.0、accelerate 1.15.0,未安装 DeepSpeed,未使用分布式/并行。复现分析在 CPU 上用小型随机权重 Llama 完成,未依赖受限下载。ForQuestionAnswering 头最早经由 PR #28777 引入,此版本的代码行为是该问题发生的前提。

最快修复方案:暂无确认的一步修复方案。Issue 讨论中提出的修复思路是在 _build_checkpoint_conversion_mapping() 中为受影响类添加 WeightRenaming(r"^model\.", "transformer.") 映射,但该方案尚处于讨论/PR 阶段,未被合并验证,可优先尝试自行实现。

注意事项:该问题不会抛出异常,只在加载报告中体现为大量 UNEXPECTED/MISSING,主干权重被静默丢弃,因此只看到“加载成功”并不代表权重正确。即使修复映射,qa_outputs.weight、qa_outputs.bias 仍会正常随机初始化以供下游微调。同时,该行为在历史上从未被支持,官方在讨论中表示不希望支持此用法,因此后续是否修复取决于维护者判断。

问题场景

用户使用 Transformers 的 LlamaForQuestionAnswering.from_pretrained("meta-llama/Llama-2-7b-hf") 或 AutoModelForQuestionAnswering.from_pretrained(...),从标准 Llama 基础模型检查点(或 ForCausalLM 检查点)加载问答头。加载完成后打印的加载报告显示主干层既存在 UNEXPECTED 又存在 MISSING,实际加载进 QA 头的主干参数是随机初始化的,而不是检查点中的数值。

报错原文

[transformers] LlamaForQuestionAnswering LOAD REPORT from: meta-llama/Llama-2-7b-hf
Key                                                         | Status     | 
------------------------------------------------------------+------------+-
model.layers.{0...31}.input_layernorm.weight                | UNEXPECTED | 
model.layers.{0...31}.self_attn.q_proj.weight               | UNEXPECTED | 
...
model.embed_tokens.weight                                   | UNEXPECTED | 
model.norm.weight                                           | UNEXPECTED | 
lm_head.weight                                              | UNEXPECTED | 
transformer.layers.{0...31}.self_attn.q_proj.weight         | MISSING    | 
...
qa_outputs.weight                                           | MISSING    | 
qa_outputs.bias                                             | MISSING    | 
transformer.embed_tokens.weight                             | MISSING    | 
transformer.norm.weight                                     | MISSING    | 

Notes:
- UNEXPECTED:	can be ignored when loading from different task/architecture; not ok if you expect identical arch.
- MISSING:	those params were newly initialized because missing from the checkpoint. Consider training on your downstream task.

原因分析

根因在 Issue 讨论中已定位:LlamaForQuestionAnswering(仿照 BloomForQuestionAnswering)覆盖了 base_model_prefix = "transformer",而 GenericForQuestionAnswering.__init__ 通过 setattr(self, self.base_model_prefix, ...) 把主干保存在 self.transformer 下。但所有 Llama 家族检查点(基础模型和 ForCausalLM)都把主干权重存为 model.*。

core_model_loading.py 中 rename_source_key 的前缀桥接只能剥离或添加模型自身的 base_model_prefix(即 transformer),无法把 model. 重写为 transformer.。因此每个 model.* 检查点键都匹配不到参数(记为 UNEXPECTED),而每个 transformer.* 参数都找不到来源(记为 MISSING),主干被静默随机初始化。

受影响的是覆盖了前缀的 GenericForQuestionAnswering 子类:Arcee、DiffLlama、Exaone4、Llama、Ministral、Nemotron、Qwen2、Qwen3、Qwen3Moe、Qwen3Next、SeedOss、SmolLM3。保持默认 base_model_prefix = "model" 的类(Mistral、Mixtral、Qwen2Moe、Ministral3、MiniMax、Ultrabert)不受影响;检查点主干确实存为 transformer.* 的家族(GPT-2、Bloom、GPT-Neo 等)也不受影响。

环境排查

  • 确认 transformers 版本:Issue 基于 5.21.0.dev0;较早版本行为可能不同。
  • 确认是否使用 LlamaForQuestionAnswering 或 AutoModelForQuestionAnswering 加载 Llama 家族检查点,而不是普通的 ForCausalLM。
  • 检查加载时是否开启 output_loading_info=True 或是否打印了 LOAD REPORT,确认是否存在 model.* UNEXPECTED 与 transformer.* MISSING 的成对错配。
  • 确认检查点文件中的参数命名是 model.* 还是 transformer.*(Safetensors 可查看键名)。
  • 核对 Python、PyTorch、accelerate、safetensors 版本;Issue 报告环境中 PyTorch 2.14.1、Python 3.14.2,但根因与这些版本无直接关系。

解决步骤

  1. 先用最小复现验证问题是否与你的模型、权重无关:用 LlamaConfig 构造小型随机权重 LlamaForCausalLM,save_pretrained 到临时目录,再用 LlamaForQuestionAnswering.from_pretrained(tmp, output_loading_info=True) 加载。若出现主干参数 MISSING、model.* UNEXPECTED,即命中该 Issue。
  2. 确认你的模型属于受影响类(如 Llama 家族)且确实覆盖了 base_model_prefix = "transformer"。
  3. 可优先尝试(尚未合并验证的修复思路):在 _build_checkpoint_conversion_mapping() 中为对应 QA 类增加类级重命名映射,例如 "LlamaForQuestionAnswering": [WeightRenaming(r"^model\.", "transformer.")],并对其他 11 个受影响类做同样处理。该方案在讨论中被验证可用于从 model.* 检查点正确加载主干,同时保留从旧式 transformer.* 检查点加载的向后兼容性。
  4. 如需自行打补丁,注意保存方向的往返:仅加载时实际匹配到的转换才会用于保存,从 model.* 加载的模型会保存回 model.*,从 transformer.* 加载的会保存回 transformer.*。
  5. 若无法修改库代码,可考虑先加载 LlamaForCausalLM 再手动迁移主干权重到 QA 模型,但 Issue 中并未给出或验证该变通步骤,需自行确认参数映射。

验证方法

加载时开启 output_loading_info=True,确认 missing_keys 中不再包含任何主干参数(transformer.layers.*、transformer.embed_tokens.weight、transformer.norm.weight 等),且仅剩 qa_outputs.weight、qa_outputs.bias 为预期的新初始化项;UNEXPECTED 中仅剩 lm_head.weight 这类换头时正常丢弃的键。进一步可对比主干张量数值与检查点中对应张量是否一致,因为“加载报告干净”本身不足以排除静默丢弃。

参考来源

huggingface/transformers #49973

GamsGo AI

AI 工具推荐

想把多个 AI 模型放在一个入口?

GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。

了解 GamsGo AI

推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 31125

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注