[Bug]: Text PEFT LoRAs can silently no-op for wrapper models whose LM is mounted under language_model

在 vLLM 中给 Qwen3-VL 等“文本主干挂在 language_model 下”的多模态 wrapper 模型加载纯文本 PEFT LoRA 时,适配器可能静默失效(no-op),加载日志无明显报错但输出等同基座模型。优先排查该模型的 hf_to_vllm_mapper 是否缺少裸 mod

快速结论:在 vLLM 中给 Qwen3-VL 等“文本主干挂在 language_model 下”的多模态 wrapper 模型加载纯文本 PEFT LoRA 时,适配器可能静默失效(no-op),加载日志无明显报错但输出等同基座模型。优先排查该模型的 hf_to_vllm_mapper 是否缺少裸 model. 前缀规则。

适用环境:Issue 中确认的环境为:Ubuntu 24.04.4 LTS(x86_64)、Python 3.11.4、PyTorch 2.11.0+cu130、CUDA runtime 12.0.140、NVIDIA A10G(驱动 580.159.03)。已确认受影响的模型包括 Qwen3-VL、llava、llava_next、llava_next_video、pixtral、gemma3_mm、fuyu、minicpmv4_6、lightonocr、rvl。

最快修复方案:暂无已合并的确认一步修复。可优先尝试:在该模型 mapper 的 orig_to_new_prefix 末尾追加裸 "model.": "language_model.model." 规则(Issue 中 PR #48022 已对 qwen3_vl.py 验证此写法)。

注意事项:该前缀必须追加在最后,因为 WeightsMapper._map_name 按顺序应用前缀规则且不在首个匹配处中断,放在前面会抢先吞掉 model.visual. 等键、影响基座权重加载。Issue 中的列表是搜索所得的下界,并非全部受影响模型;另一提案(从 _language_model_names/get_language_model() 自动推导)尚未落地。

问题场景

用户在 vLLM 中加载 Qwen3-VL 这类 wrapper 多模态模型(Qwen3VLForConditionalGeneration,其语言模型挂载在 self.language_model),再附加一个针对普通 HF CausalLM checkpoint 训练出的纯文本 PEFT LoRA。服务可以正常启动、LoRA 也显示已加载,但推理输出与未加载 LoRA 时一致。同类问题在 llava、pixtral 等模型上复现。

报错原文

[Bug]: Text PEFT LoRAs can silently no-op for wrapper models whose LM is mounted under language_model

该问题没有抛异常;典型表现为 LoRA 模块绑定数为 0,例如 Issue 中验证的文本 LoRA 绑定从 0/8 变为 8/8。

原因分析

文本 PEFT 适配器的键形如 base_model.model.model.layers.0.self_attn.q_proj.lora_A.weight,去掉标准前缀 base_model.model. 后变为 model.layers.0.self_attn.q_proj...。但 Qwen3-VL 的 hf_to_vllm_mapper 只包含 model.visual.、lm_head.、model.language_model. 三个前缀,没有裸 model. 规则。于是该键不被任何规则改写,parse_fine_tuned_lora_name 解析出的 model.layers.0.self_attn.q_proj 模块并不存在(真实路径在 language_model.model. 下),适配器因此没有绑定到任何模块,静默等于基座模型。

对照 qwen2_vl.py 等已正确处理该情况的模型,它们在特定规则之后追加了裸 "model." 规则,可正常工作。

环境排查

  • 确认 vLLM 版本以及是否已包含对应修复(Issue 中 PR #48022 仅覆盖 qwen3_vl.py)。
  • 确认所用模型是否属于 Issue 列出的受影响范围(Qwen3-VL、llava、llava_next、llava_next_video、pixtral、gemma3_mm、fuyu、minicpmv4_6、lightonocr、rvl)。
  • 确认 LoRA 是否为纯文本适配器,键前缀是否为 base_model.model.model.layers...。
  • 确认模型 hf_to_vllm_mapper 中是否存在置于末尾的裸 "model." 规则。
  • Issue 未给出 CUDA/PyTorch 与版本的强绑定关系,不建议以升级驱动作为排查手段。

解决步骤

  1. 在启用 LoRA 的情况下跑一次推理,记录 LoRA 模块绑定数量。Issue 中的现象是文本 LoRA 绑定数为 0/8。
  2. 检查目标模型文件中 hf_to_vllm_mapper 的 orig_to_new_prefix 字典,确认是否缺少裸 "model." 规则。
  3. 可优先尝试:按 qwen2_vl.py 的写法,在所有特定前缀之后追加 "model.": "language_model.model.",例如:
    hf_to_vllm_mapper = WeightsMapper(
        orig_to_new_prefix={
            "model.visual.": "visual.",
            "lm_head.": "language_model.lm_head.",
            "model.language_model.": "language_model.model.",
            "model.": "language_model.model.",  # route bare text keys under the LM
        }
    )
  4. 不要改动特定规则(如 model.visual.、model.vision_tower.、model.multi_modal_projector.)的顺序,确保它们先匹配。
  5. 若关注长期方案,可跟踪 Issue 中提出的自动推导方案(从 _language_model_names/get_language_model() 生成规则),该方案尚未验证。

验证方法

重新加载同一文本 LoRA,观察模块绑定数应从 0/8 变为 8/8;同时确认基座权重映射结果不变(视觉、projector、lm_head 等键的映射输出与修改前一致)。最后用同一提示对比加/不加 LoRA 的输出,确认 LoRA 已实际生效。

参考来源

vllm-project/vllm #48019

GamsGo AI

AI 工具推荐

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

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

了解 GamsGo AI

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

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 29398

发表回复

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