Prhub

#53170 [Bugfix] Load untied Gemma LM head weights

原始 PR 作者 khluu 合并时间 2026-08-21 08:47 文件变更 2 提交数 1 评论 2 代码增减 +58 / -2

执行摘要

修复 Gemma 未绑定 LM head 的加载失败

在 PR #51665 之后,vLLM 改为根据 safetensors 元数据决定是否解绑 lm_head,当配置声明绑定但检查点包含实际 lm_head.weight 时,会将 tie_word_embeddings 翻转为 False 以加载物理头。但 GemmaForCausalLM 未构造 lm_head,导致 GPTQ Gemma 检查点加载失败,报错 There is no module or parameter named 'lm_head'。该 PR 旨在修复此回归。

值得精读,尤其是关注 ParallelLMHead 的 tie_weights 用法与 logits_processor 的配合。该修复模式(检查点驱动解绑 + 动态构造头)可推广至其他硬编码绑定的模型(如 gemma2、commandr 等)。

讨论亮点

该 PR 无实质性 review 讨论,仅 hmellor 批准通过,claude[bot] 发出自动提醒。

实现拆解

  1. 构造输出头:在 vllm/model_executor/models/gemma.py 的 GemmaForCausalLM.__init__ 中新增 self.lm_head = ParallelLMHead(...),并导入 ParallelLMHead。
  2. 绑定逻辑:当 config.tie_word_embeddings 为真时,调用 self.lm_head.tie_weights(self.model.embed_tokens) 将输出头与输入嵌入绑定。
  3. 更新 logits 计算:将 compute_logits 中的 self.logits_processor(self.model.embed_tokens, ...) 改为 self.logits_processor(self.lm_head, ...),确保使用新构造的头。
  4. 新增测试:在 tests/models/language/generation/test_gemma.py 中添加 test_checkpoint_lm_head_can_override_tied_config,通过 stub 模型验证解绑配置下物理头能正确加载。
文件 模块 状态 重要度
vllm/model_executor/models/gemma.py 模型层 modified 6.71
tests/models/language/generation/test_gemma.py 测试 modified 6.23

关键符号

GemmaForCausalLM.__init__ GemmaForCausalLM.compute_logits

关键源码片段

vllm/model_executor/models/gemma.py core-logic

核心源码修改,构造并绑定输出头,更新 logits 计算

# 在 GemmaForCausalLM.__init__ 中新增输出头构造与绑定
self.lm_head = ParallelLMHead(
    config.vocab_size,
    config.hidden_size,
    quant_config=quant_config,
    prefix=maybe_prefix(prefix, "lm_head"),
)
# 若配置声明绑定词嵌入,则将输出头与输入嵌入共享权重
if config.tie_word_embeddings:
    self.lm_head = self.lm_head.tie_weights(self.model.embed_tokens)

评论区精华

没有提炼出高价值讨论线程

当前评论区没有形成足够清晰的争议点或结论,后续有更多讨论时会体现在这里。

风险与影响

风险较低。主要风险是 compute_logits 变更可能影响已绑定场景的输出,但测试已覆盖绑定与非绑定情况。另外,tie_weights 的行为可能受量化配置影响,需注意与 ParallelLMHead 的兼容性。测试在 CPU 上运行,未包含 GPU 量化场景,但 PR 描述中已通过 H200 量化模型测试验证。

影响范围限于 Gemma 模型族。修复后,含物理 lm_head 的 Gemma 检查点(如 GPTQ 量化版)可正常加载,提高了兼容性。对已绑定的标准 Gemma 模型无影响,因为 tie_weights 会保持绑定。

核心路径变更 测试覆盖不足(GPU 量化)

完整报告

参与讨论