Prhub

#42778 [Model Runner V2] Fix prompt logprobs calculation `Sizes of tensors must match` error

原始 PR 作者 yewentao256 合并时间 2026-05-18 23:27 文件变更 1 提交数 1 评论 0 代码增减 +8 / -2

执行摘要

修复 V2 模型运行器中 prompt logprobs 张量形状不匹配错误

该 PR 是 Model Runner V1 迁移到 V2(Issue #41286)的一部分。当启用 VLLM_USE_V2_MODEL_RUNNER=1 并运行 tests/v1/sample/test_logprobs.py 中的特定测试时,由于批量请求的 num_prompt_logprobs 不同,原始代码试图直接拼接不同形状的张量,导致 RuntimeError: Sizes of tensors must match

值得精读用于理解 Model Runner V2 中 prompt logprobs 的处理流程,特别是跨请求变长张量切片的处理模式。该 PR 本身逻辑清晰简单,可作为参考学习。

讨论亮点

该 PR 无人工 review 评论讨论,gemini-code-assist[bot] 仅提供了代码变更摘要而未提出问题。njhill 直接给予了批准。

实现拆解

此 PR 仅修改 vllm/v1/worker/gpu/sample/prompt_logprob.py 中的一处核心逻辑,共 +8/-2 行。

  1. 提取每个请求的 num_prompt_logprobs:在遍历 input_batch.req_ids 的循环中,新增 req_num_prompt_logprobs = int(num_prompt_logprobs[i]),获取当前请求实际需要的 logprobs 个数。

  2. 计算当前请求的宽度 width:新增 width 变量,若 req_num_prompt_logprobs == -1(表示请求所有 logprobs),则宽度取 prompt_logprobs.shape[1](即全列数);否则宽度为 req_num_prompt_logprobs + 1(+1 是因为 logprobs 包含当前 token 的预测概率,后续逻辑会去掉最后一项)。这是修复的核心:将原先固定的全列切片改为动态宽度。

  3. 使用 :width 进行切片:在构造 LogprobsTensors 对象时,对 logprob_token_idslogprobs 两个张量均使用 [start_idx:end_idx, :width] 切片,而非原来的 [start_idx:end_idx]selected_token_ranks 的切片保持不变(仍为 [start_idx:end_idx]),因为其维度含义不同。

该改动仅修改源码,未涉及测试配置或部署文件,但 PR body 中提及已通过原有测试验证。

文件 模块 状态 重要度
vllm/v1/worker/gpu/sample/prompt_logprob.py 采样器 modified 5.51

关键符号

compute_prompt_logprobs

关键源码片段

vllm/v1/worker/gpu/sample/prompt_logprob.py core-logic

修复逻辑所在的核心源码文件,修改了 `compute_prompt_logprobs` 函数中的张量切片逻辑。

# vllm/v1/worker/gpu/sample/prompt_logprob.py
# 在 compute_prompt_logprobs 方法中,关键的修复如下:req_is_prompt_chunked = is_prompt_chunked[i]
req_num_prompt_logprobs = int(num_prompt_logprobs[i]) # 获取当前请求的 num_prompt_logprobs
start_idx = query_start_loc_np[i]
end_idx = query_start_loc_np[i + 1]
# 省略断言和 end_idx 调整 ...# 计算当前请求的切片宽度:-1 表示请求所有列,否则为 num_prompt_logprobs + 1
width = (
    prompt_logprobs.shape[1]
    if req_num_prompt_logprobs == -1
    else req_num_prompt_logprobs + 1
)logprobs = (
    None
    if start_idx >= end_idx
    else LogprobsTensors(
        # 关键修复:使用 :width 切片,而非整列切片
        logprob_token_ids=prompt_token_ids[start_idx:end_idx, :width],
        logprobs=prompt_logprobs[start_idx:end_idx, :width],
        selected_token_ranks=prompt_ranks[start_idx:end_idx],
    )
)

评论区精华

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

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

风险与影响

风险非常低。变更只涉及单个文件中的 8 行逻辑,且是典型的张量切片边界修复。selected_token_ranks 保持一维切片不变,预期行为正确。若 num_prompt_logprobs 值异常(如为 0 或小于 -1),可能产生空切片,但已有 start_idx >= end_idx 的保护检查会返回 None。该路径仅在启用 VLLM_USE_V2_MODEL_RUNNER 时生效,不影响默认的 Model Runner V1。

影响范围局限于 Model Runner V2 下的 prompt logprobs 计算,仅影响启用该功能的用户。影响程度为修复性,无破坏性变更。对系统性能无影响(仅修复正确性)。

关联 Issue

#41286 [Feature]: Migration from Model Runner v1 to Model Runner v2

完整报告

参与讨论