Prhub

#49963 [Bugfix] Restore truncate_prompt_tokens for Jina rerank/score online

原始 PR 作者 umut-polat 合并时间 2026-07-27 22:52 文件变更 2 提交数 1 评论 2 代码增减 +69 / -1

执行摘要

修复 Jina rerank/score 在线路径 truncate_prompt_tokens 字段丢失

truncate_prompt_tokens 是 Jina rerank/score 请求的重要参数,用于控制提示截断。PR #49153 重构引入的代理模式漏掉了该字段的转发,导致用户在请求中指定 truncate_prompt_tokens 时被 HTTP 400 拒绝。作者在 PR body 中明确指出这是一个回归。

该 PR 是典型的回归修复案例,值得阅读以理解代理模式下的字段透传陷阱。讨论了 _truncate_scoring_datatruncate_prompt_tokens 的职责分离,对理解 vLLM 的提示处理管线有参考价值。

讨论亮点

审核者 noooop 在代码行 795 处提出疑问:_truncate_scoring_data 是否已经覆盖了截断逻辑?作者 umut-polat 详细解释了 _truncate_scoring_data 只处理 max_tokens_per_query/max_tokens_per_doc 的文档级截断,而 truncate_prompt_tokens 作用于格式化后的完整提示,两者正交,不能互相替代。此讨论澄清了设计意图,验证了修复的必要性。

实现拆解

  1. vllm/entrypoints/pooling/scoring/io_processor.pyget_request_factory_online 方法中,将 PoolingCompletionRequest 构造调用从仅传 taskinput 扩展为也传入 truncate_prompt_tokenstruncation_side,这两个值直接从原始 request 对象中读取。
  2. 新增单元测试文件 tests/entrypoints/pooling/scoring/test_jina_ranking_io_processor_unit.py,使用 monkeypatch 将基类的 get_request_factory_online 替换为 spy 函数,捕获代理请求中的 truncate_prompt_tokenstruncation_side 断言其与原始请求一致。
文件 模块 状态 重要度
vllm/entrypoints/pooling/scoring/io_processor.py 入口层 modified 5.77
tests/entrypoints/pooling/scoring/test_jina_ranking_io_processor_unit.py 测试 added 6.12

关键符号

JinaRankingIOProcessor.get_request_factory_online

关键源码片段

vllm/entrypoints/pooling/scoring/io_processor.py core-logic

核心修复文件,在 proxy 构造中补传 truncate_prompt_tokens 和 truncation_side。

# vllm/entrypoints/pooling/scoring/io_processor.py
# 修改后的 ctx.request 构造:转发 truncate_prompt_tokens/truncation_side
# 防止基类工厂读取 ctx.request 时丢失这些字段
ctx.request = PoolingCompletionRequest(
    task="token_embed",
    input=prompts,
    # 必须从原始 request 转发,否则基类工厂读取 ctx.request 时
    # truncate_prompt_tokens/truncation_side 默认为 None
    truncate_prompt_tokens=request.truncate_prompt_tokens,
    truncation_side=request.truncation_side,
)
requests = PoolingIOProcessor.get_request_factory_online(self, ctx)
ctx.request = request # 恢复原始请求
return requests
tests/entrypoints/pooling/scoring/test_jina_ranking_io_processor_unit.py test-coverage

新增单元测试,确保 proxy 携带了正确的 truncation 字段。

# tests/entrypoints/pooling/scoring/test_jina_ranking_io_processor_unit.py
def test_online_forwards_truncate_prompt_tokens_to_proxy(monkeypatch):
    """验证代理请求携带 truncate_prompt_tokens/truncation_side"""
    proc = JinaRankingIOProcessor.__new__(JinaRankingIOProcessor)
    # Mock 必要方法和属性
    proc.valid_inputs_online = MagicMock(
        return_value=ScoringData(data_1=["query"], data_2=["doc"]))
    proc._get_token_limits = MagicMock(return_value=(0, 0))
    proc.ensure_str = MagicMock(side_effect=lambda data: list(data))
    proc.format_docs_prompts_func = MagicMock(return_value="formatted prompt")
​
    captured: dict[str, object] = {}
​
    def _spy_base(self, ctx):
        # 捕获代理请求的字段
        captured["truncate_prompt_tokens"] = ctx.request.truncate_prompt_tokens
        captured["truncation_side"] = ctx.request.truncation_side
        return []
​
    monkeypatch.setattr(
        PoolingIOProcessor, "get_request_factory_online", _spy_base)
​
    # 构造一个带有截断参数的请求
    request = RerankRequest(
        model="m", query="query", documents=["doc"],
        truncate_prompt_tokens=512, truncation_side="left",
    )
    ctx = MagicMock()
    ctx.request = request
    ctx.prompt_extras = None
​
    proc.get_request_factory_online(ctx)
​
    # 验证代理中字段值与原始请求一致
    assert captured["truncate_prompt_tokens"] == 512
    assert captured["truncation_side"] == "left"
    # 验证 ctx.request 最终恢复为原始请求
    assert ctx.request is request

评论区精华

校验 _truncate_scoring_data 是否已覆盖 truncation 设计

noooop 询问 `_truncate_scoring_data` 是否已经处理了截断逻辑。umut-polat 解释了 `_truncate_scoring_data` 只处理文档级截断,而 `truncate_prompt_tokens` 作用于格式化后的完整提示,两者正交。

结论:确认需要本修复,二者分工明确。 · 已解决

风险与影响

本 PR 只改动了一行核心代码(传递两个额外参数),且类型匹配,回归风险极低。新增的单元测试直接验证了修复的正确性。但缺少端到端集成测试(需要 Jina 模型在 CI 中),无法覆盖运行时全链路。

修复了 Jina rerank/score 在线路径的回归 bug,影响所有使用 truncate_prompt_tokens 参数的 Jina scoring 请求。其他嵌入路径(embed、bi/cross-encoder)不受影响,因为它们在之前的重构中已正确处理了这些字段。

缺少端到端集成测试 回归修复

关联 Issue

未识别关联 Issue

当前没有检测到明确关联的 Issue 链接,后续同步到相关引用后会出现在这里。

完整报告

参与讨论