执行摘要
- 一句话:修复 Plamo2 在 transformers v5 下的 HF runner 崩溃
- 推荐动作:可快速合入。该 PR 是 Transformers v5 升级跟踪的一部分,修复方式合理,逻辑清晰,可作为未来类似兼容问题的修复模板。
功能与动机
关联 Issue #38379(Transformers v5 升级跟踪)中记录了 Plamo2 在 transformers v5 下的测试失败。PR body 指出,HfRunner.from_pretrained() 在 transformers v5 中因 _tied_weights_keys 类型不匹配而抛出 AttributeError: 'list' object has no attribute 'keys'。生产代码不受影响(vLLM 通过 config.tie_word_embeddings 标志处理权重绑定),但测试基础设施不可用。
实现拆解
-
在 tests/conftest.py 新增 _fix_v4_tied_weights_keys 函数:该函数接收一个模型类,检查其 _tied_weights_keys 是否为非空 list,若是则转换为 dict[str, str] 格式(将包含 "lm_head" 且以 ".weight" 结尾的键映射到 "model.embed_tokens.weight"),并通过 setattr 就地修改类属性,该修改通过 sys.modules 缓存保留到 from_pretrained() 中。
-
在 HfRunner.__init__() 中集成修复:在调用 auto_cls.from_pretrained() 之前,通过 try_get_class_from_dynamic_module 获取模型类,并应用 _fix_v4_tied_weights_keys。只处理当前 auto_cls 对应的 auto_map 条目,避免影响其他模型。
-
在 tests/models/registry.py 中移除 Plamo2 的版本限制:删除 max_transformers_version="4.57" 及对应的原因说明,使 Plamo2 能在 transformers v5 下参与测试。
关键文件:
tests/conftest.py(模块 测试工具;类别 test;类型 test-coverage;符号 _fix_v4_tied_weights_keys): 新增 _fix_v4_tied_weights_keys 函数并在 HfRunner.__init__() 中调用,是修复的核心逻辑。
tests/models/registry.py(模块 测试注册;类别 test;类型 test-coverage): 移除 Plamo2 的 max_transformers_version 限制,使测试在 transformers v5 下运行。
关键符号:_fix_v4_tied_weights_keys
关键源码片段
tests/conftest.py
新增 _fix_v4_tied_weights_keys 函数并在 HfRunner.__init__() 中调用,是修复的核心逻辑。
def _fix_v4_tied_weights_keys(model_cls: type) -> None:
"""Convert a v4 list-format _tied_weights_keys to the transformers v5 dict form."""
tied = getattr(model_cls, "_tied_weights_keys", None)
# 仅在属性为 list 且非空时执行转换
if not isinstance(tied, list) or not tied:
return
# 将包含 "lm_head" 且以 ".weight" 结尾的键映射为 v5 的 dict 格式
result = {
k: "model.embed_tokens.weight"
for k in tied
if "lm_head" in k and k.endswith(".weight")
}
if result:
setattr(model_cls, "_tied_weights_keys", result)
class HfRunner:
def __init__(
self,
model_name: str,
dtype: str = "auto",
*,
revision: str | None = None,
model_kwargs: dict[str, Any] | None = None,
trust_remote_code: bool = True,
is_sentence_transformer: bool = False,
is_cross_encoder: bool = False,
...
):
...
else:
# 在 from_pretrained 之前,对使用了 remote code 的模型修补 _tied_weights_keys
if trust_remote_code and hasattr(self.config, "auto_map"):
cls_ref = self.config.auto_map.get(auto_cls.__name__)
if cls_ref is not None:
from vllm.transformers_utils.dynamic_module import (
try_get_class_from_dynamic_module,
)
model_cls = try_get_class_from_dynamic_module(
cls_ref,
model_name,
trust_remote_code=trust_remote_code,
warn_on_fail=False,
)
if model_cls is not None:
_fix_v4_tied_weights_keys(model_cls)
model = cast(nn.Module, auto_cls.from_pretrained(...))
评论区精华
该 PR 没有 review 评论,但有 7 个提交的演进历史体现了关键决策:
风险与影响
- 风险:变更仅限测试基础设施,不影响 vLLM 生产代码。风险极低:
_fix_v4_tied_weights_keys 仅当 _tied_weights_keys 为 list 且包含 "lm_head" 时才生效,其他模型不受影响。
- 使用
try_get_class_from_dynamic_module 失败时返回 None,不会引发异常。
- 删除版本限制后,Plamo2 测试在 transformers v5 下可能因其他依赖(如
causal_conv1d / mamba_ssm)而失败,但属于已有问题,与本次变更无关。
- 影响:影响范围小:仅改变测试基础架构,使 Plamo2 模型能在 transformers v5 环境中运行测试。对其他模型或生产部署无影响。
- 风险标记:暂无
关联脉络
- PR #38379 Upgrade to Transformers v5: 本 PR 是 #38379 的子任务,专门修复 Plamo2 在 transformers v5 下的兼容问题。
- PR #44282 PR #44282: 同样是 #38379 的子任务,处理 MiniCPMV 等模型的 transformers v5 兼容性。
参与讨论