Qwen2.5-VL-7B-Instruct Batch 推理异常 Debug 记录

📅 时间:2025-09
💡 主题:解决 Qwen2.5-VL-7B-Instruct 在 Batch 推理时输出异常(带有 prompt / addCriterion 等奇怪字符)的问题。


背景

在做多模态批量推理(Batch Inference)时,我遇到一个怪问题:

  • 单条输入时模型回答正常;
  • batch size > 1 时,输出里经常混入 prompt 片段,甚至出现 addCriterion 等意料之外的 token。

一开始以为是 图片数量不一致导致 padding 错切,但深入排查后发现,真正原因其实是 环境版本不匹配 + tokenizer 默认方向错误


复现问题

from transformers import AutoProcessor, Qwen2_5_VLForConditionalGeneration
from qwen_vl_utils import process_vision_info
import torch

model = Qwen2_5_VLForConditionalGeneration.from_pretrained(
    "Qwen/Qwen2.5-VL-7B-Instruct", torch_dtype="auto", device_map="auto"
)
processor = AutoProcessor.from_pretrained("Qwen/Qwen2.5-VL-7B-Instruct")

messages = [
    [
        {"role": "user", "content": [
            {"type": "image", "image": "img1.png"},
            {"type": "image", "image": "img2.png"},
            {"type": "text", "text": "What are the common elements in these pictures?"}
        ]}
    ],
    [
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "Who are you?"}
    ]
]

texts = [processor.apply_chat_template(m, tokenize=False, add_generation_prompt=True) for m in messages]
image_inputs, _ = process_vision_info(messages)

inputs = processor(
    text=texts, images=image_inputs, padding=True, return_tensors="pt"
).to("cuda")

out = model.generate(**inputs, max_new_tokens=128)
print(processor.batch_decode(out, skip_special_tokens=True))

现象:第二条回答经常会夹带上第一条 prompt 的部分内容。


问题定位

  1. 怀疑输入长度切片不一致 ❌

    • 最开始以为 len(in_ids) 不同 → 生成结果错切。
    • 但调试后发现即使统一切片,问题依旧存在。
  2. 真实原因:版本兼容问题 ✅

    • Qwen2.5-VL 对 transformersqwen-vl-utils 的依赖非常严格。
    • 我的环境里 transformers 版本过新,导致 batch decode 时行为异常。
  3. 另一个关键:padding_side 默认值 ✅

    • 默认 padding_side="right"
    • 在多模态 batch 推理时,右 padding 会让生成位置和 prompt 错位。
    • 改成 左对齐 (left) 后,推理对齐才正确。

解决方案

1. 固定依赖版本

pip install transformers==4.51.3 accelerate
pip install 'qwen-vl-utils[decord]'

⚠️ 其他版本(尤其是 4.52+)会导致 batch 解码错乱。


2. 设置 tokenizer 左对齐

processor.tokenizer.padding_side = "left"
pad_id = processor.tokenizer.pad_token_id or processor.tokenizer.eos_token_id
eos_id = processor.tokenizer.eos_token_id

model.generation_config.pad_token_id = pad_id
model.generation_config.eos_token_id = eos_id

这样保证 batch 内不同长度的输入都能从右边补 pad,不会影响生成对齐。


最终效果

  • 问题修复:batch 内再也不会出现 prompt 残留或 addCriterion 异常 token。
  • 兼容性强:无论 batch 内图片数量是否一致,输出都稳定。
  • 实践建议:多模态推理时一定要手动设置 padding_side="left",并固定版本。

总结

  • 根因:不是 prompt,不是图片数量,而是 transformers 版本 + padding_side 默认错误

  • 核心修复

    1. 用官方推荐版本 transformers==4.51.3
    2. 手动 processor.tokenizer.padding_side="left"
  • 经验教训:多模态模型对齐细节很脆弱,一旦环境和配置不对,就会出现“幻觉 bug”。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐