执行摘要
- 一句话:修复 MRV2 与多种模型和配置的兼容性问题
- 推荐动作:建议相关开发者重点阅读 model_runner.py 中
input_ids 置 None 的条件逻辑以及 encoder_runner.py 中 is_embed 累加的修正,这是典型的边缘情况处理。整体 PR 可作为 MRV2 兼容性修复的参考模式。
功能与动机
这些修复来源于 PR#44443 的 CI 故障分析,旨在解决 MRV2 在 CohereASR、Whisper 等模型以及 external_launcher + PP 配置下无法正常运行的问题。
实现拆解
-
input_ids 在输入嵌入时置 None:在 vllm/v1/worker/gpu/model_runner.py 的 execute_model 方法中,当 inputs_embeds 非 None 且模型声明 requires_raw_input_tokens 为 False 时,将 input_ids 设为 None。
-
补充 intermediate_tensors 默认值:在同一方法的 model_inputs 字典中始终设置 "intermediate_tensors": None,因为部分模型的前向函数期望该参数但未提供默认值。
-
修复多模态 is_embed 累加:在 vllm/v1/worker/gpu/mm/encoder_runner.py 的 gather_mm_embeddings 中将一行 = 改为 |=,确保当同一条请求有多个多模态特征区域时,is_mm_embed 标记正确累积而不被覆盖。
-
修复 Whisper 全 CUDA 图的请求数:在 vllm/v1/worker/gpu/model_states/whisper.py 的 prepare_attn 中将 _get_encoder_seq_lens 调用改为传递 num_reqs(已填充后的值),而非内部从 req_ids 推导。
-
回退到 MRV1 对于 external_launcher + PP:在 vllm/config/vllm.py 的 _get_v2_model_runner_unsupported_features 中新增条件,当 distributed_executor_backend 为 external_launcher 且 pipeline_parallel_size > 1 时,将该组合标记为 MRV2 不支持,并自动回退到 MRV1。
关键文件:
vllm/v1/worker/gpu/model_runner.py(模块 模型运行器;类别 source;类型 data-contract;符号 execute_model): 核心变更:在 input_embeds 非 None 时传递 input_ids=None,并始终提供 intermediate_tensors=None 默认值,影响 MRV2 所有请求的输入组装。
vllm/config/vllm.py(模块 配置检查;类别 source;类型 core-logic;符号 _get_v2_model_runner_unsupported_features): 添加 external_launcher + PP 为 MRV2 不支持特性,自动回退到 MRV1,确保该配置下 V2 引擎不会崩溃。
vllm/v1/worker/gpu/model_states/whisper.py(模块 Whisper状态;类别 source;类型 data-contract;符号 prepare_attn, _get_encoder_seq_lens): 修复 Whisper 全 CUDA 图模式下使用填充后请求数,使 Whisper 模型在 MRV2 下能正常使用 full cudagraph。
vllm/v1/worker/gpu/mm/encoder_runner.py(模块 MM编码器;类别 source;类型 core-logic;符号 gather_mm_embeddings): 一行修正:将 is_mm_embed 的赋值改为或赋值,避免多区域重复覆盖,修复多模态嵌入标志累积错误。
关键符号:execute_model, _get_v2_model_runner_unsupported_features, prepare_attn, _get_encoder_seq_lens, gather_mm_embeddings
关键源码片段
vllm/v1/worker/gpu/model_runner.py
核心变更:在 input_embeds 非 None 时传递 input_ids=None,并始终提供 intermediate_tensors=None 默认值,影响 MRV2 所有请求的输入组装。
# 在 execute_model 方法中,首先获取 input_ids
input_ids = input_batch.input_ids
inputs_embeds = None
if self.supports_mm_inputs and self.is_first_pp_rank:
# 多模态嵌入处理 ...
inputs_embeds = self.model_state.get_mm_embeddings(
scheduler_output.scheduled_encoder_inputs, input_batch
)
# 如果模型不需要原始 token IDs(如输入全是嵌入),则将 input_ids 置为 None
if inputs_embeds is not None and not self.model.requires_raw_input_tokens:
input_ids = None
model_inputs = {
"input_ids": input_ids, # 可能是 None
"positions": input_batch.positions,
"inputs_embeds": inputs_embeds,
"intermediate_tensors": None, # 始终提供默认值,避免某些模型缺少默认参数
**self.model_state.prepare_inputs(input_batch, self.req_states),
}
# 对非首 PP rank,更新为 None 并准备 intermediate_tensors
if not self.is_first_pp_rank:
model_inputs["input_ids"] = None
model_inputs["inputs_embeds"] = None
# 准备 intermediate_tensors...
vllm/v1/worker/gpu/mm/encoder_runner.py
一行修正:将 is_mm_embed 的赋值改为或赋值,避免多区域重复覆盖,修复多模态嵌入标志累积错误。
# 在 gather_mm_embeddings 方法中,累加 is_mm_embed 标志
# 修复前:直接赋值会覆盖之前的嵌入标记
# is_mm_embed[req_start_pos + start_idx : req_start_pos + end_idx] = (
# 修复后:使用或赋值,累加多个区域的嵌入标记
is_mm_embed[req_start_pos + start_idx : req_start_pos + end_idx] |= (
True if is_embed is None else is_embed
)
评论区精华
审核人 yewentao256 最初要求提供复现示例和错误信息,看到多个修复合并在一个 PR 后表示理解并批准。另一个讨论线程关注 CUDA 图捕获时是否需要额外处理 input_ids 和 intermediate_tensors,作者 njhill 回应称 prepare_dummy_inputs 已处理相关逻辑。最终获得两位审核人批准。
- 要求描述中补充复现命令和错误信息 (question): 作者未在评论中直接回复,但 PR body 已包含足够描述,随后 yewentao256 批准。
- CUDA 图捕获时 input_ids 和 intermediate_tensors 的处理 (correctness): njhill 回复称
prepare_dummy_inputs 已处理这些情况,无需额外修改。
风险与影响
- 风险:虽然变更量少,但存在以下风险:
1) input_ids 置 None 可能影响依赖原始 ID 的下游逻辑,需确保 requires_raw_input_tokens 标志设置正确。
2) is_embed 改为 |= 若原本覆盖行为是被依赖的,则可能引入回归。
3) Whisper 的 num_reqs 改为 padded 值,若其他模式(非 full cudagraph)也需要 padded 但未使用,可能失效。
4) external_launcher + PP 回退到 MRV1 是临时方案,可能隐藏 V2 的真正限制。整体风险较低,因为变更被 CI 验证。
- 影响:受益模型包括 CohereASR、Whisper 及其他需要
intermediate_tensors 默认参数的模型。受益配置为 external_launcher 与流水线并行组合。这些修复使 MRV2 能覆盖更广泛的模型和部署场景,推动 V2 模型运行器的生产就绪程度。
- 风险标记:核心路径变更, 缺少测试覆盖, 多模态累加逻辑修复, 回退到旧版本
关联脉络
- PR #44443 [Core][ModelRunnerV2] Add model runner v2: 本 PR 修复了从此 PR 的 CI 失败中发现的多个 MRV2 兼容性问题。
参与讨论