Prhub

#46733 [Bugfix][Rust Frontend] Reject min_tokens above max_tokens

原始 PR 作者 reidliu41 合并时间 2026-06-26 11:41 文件变更 6 提交数 3 评论 4 代码增减 +153 / -28

执行摘要

在 Rust 共享降层中拒绝 min_tokens 超过 max_tokens

Python SamplingParams 已视 min_tokens > max_tokens 为无效,但 Rust 前端仅在 chat completions 路由检查,其他路径如 /v1/completions 和 /generate 可能传递错误采样配置到引擎。PR 描述: 'adds the validation to the shared Rust text lowering layer so all paths using it reject the invalid combination consistently.'

值得精读。展示了在 Rust 中通过共享降层函数统一验证入口、通过错误枚举方法统一错误分类,以及正确映射 gRPC 错误码的设计模式。对于 Rust 前端贡献者具有学习价值。

讨论亮点
  • Codex bot 在评论中指出,新加的验证错误在 gRPC 路径中被 Status::internal 包装(mod.rs:58-59,106-107),导致客户端验证失败误报为内部错误。作者后续添加了 text_error_to_status 函数将其映射为 InvalidArgument
  • BugenZhao 在 review 中建议将 is_request_validation_error 提取为 vllm_text::Error 的方法,避免与 HTTP 路由的重复函数。第三个 commit 由 BugenZhao 实现该重构。

实现拆解

  1. rust/src/text/src/error.rs 中新增 Error::MinTokensExceedsMaxTokens 变体,并在 Error 上实现 is_request_validation_error() 方法,统一判断请求验证错误。
  2. rust/src/text/src/lower.rslower_sampling_params 函数中,在解析 min_tokensmax_tokens 后添加检查:若 min_tokens > max_tokens 则返回新错误。该函数被所有文本请求路径共享,因此一次添加覆盖所有入口。
  3. rust/src/server/src/error.rs 中,将原有的自由函数 is_request_validation_error 替换为直接调用 error.is_request_validation_error(),并简化 chat_submit_error 的匹配逻辑;同时新增测试用例 min_tokens_above_max_tokens_maps_to_invalid_request
  4. rust/src/server/src/grpc/mod.rs 中新增 text_error_to_status 函数,根据 is_request_validation_error 将错误映射为 InvalidArgumentInternal,并将 unary/streaming 处理器中的错误处理替换为此函数,修复了之前所有文本错误都被映射为 Internal 的问题。
  5. rust/src/chat/src/error.rs 中为 vllm_chat::Error 添加 is_request_validation_error() 方法,代理到内部 Text 错误的同名方法,确保聊天路径也能正确分类。
  6. 测试配套:在 lower.rs 内新增单元测试 lower_sampling_params_rejects_min_tokens_above_resolved_max_tokens;在 grpc/tests.rs 新增两个集成测试 unary_generate_min_tokens_above_max_tokens_returns_invalid_argumentstreaming_generate_min_tokens_above_max_tokens_returns_invalid_argument,验证 gRPC 路径行为。
文件 模块 状态 重要度
rust/src/text/src/lower.rs 文本降层 modified 6.92
rust/src/text/src/error.rs 文本错误 modified 6.41
rust/src/server/src/error.rs 服务器错误 modified 6.92
rust/src/server/src/grpc/mod.rs gRPC 接口 modified 6.13
rust/src/server/src/grpc/tests.rs gRPC 测试 modified 6.79
rust/src/chat/src/error.rs 聊天错误 modified 5.36

关键符号

lower_sampling_params text_error_to_status is_request_validation_error (on vllm_text::Error) is_request_validation_error (on vllm_chat::Error)

关键源码片段

rust/src/text/src/lower.rs core-logic

共享文本降层的核心函数 lower_sampling_params,添加了 min_tokens > max_tokens 的检查,所有路径都经过此函数。

// lower_sampling_params 核心部分:解析 max_tokens 后检查 min_tokens
// 前面的参数 fallback 省略
let max_tokens = resolve_max_tokens(
    max_tokens,
    default_max_tokens,
    sampling_limits.max_model_len,
    prompt_len,
)?;
let min_tokens = min_tokens.unwrap_or(0);
// [ 关键添加 ] 拒绝 min_tokens 超过 max_tokens 的请求
if min_tokens > max_tokens {
    return Err(Error::MinTokensExceedsMaxTokens {
        min_tokens,
        max_tokens,
    });
}
// 后续参数处理(thinking_token_budget, frequency_penalty 等)
rust/src/text/src/error.rs core-logic

新增 Error::MinTokensExceedsMaxTokens 变体,实现 is_request_validation_error 方法,为所有错误分类提供统一接口。

#[error(
    "`min_tokens` must be less than or equal to `max_tokens`, \
     got min_tokens={min_tokens}, max_tokens={max_tokens}"
)]
MinTokensExceedsMaxTokens { min_tokens: u32, max_tokens: u32 },impl Error {
    /// Whether this error represents invalid user request parameters.
    pub fn is_request_validation_error(&self) -> bool {
        match self {
            Self::PromptTooLong { .. }
            | Self::EmptyPromptTokenIds { .. }
            | Self::Logprobs(_)
            | Self::TokenIds(_)
            | Self::MinTokensExceedsMaxTokens { .. }
            | Self::InvalidThinkingTokenBudget
            // 空 prompt 可能通过 Llm wrapper 传递
            | Self::Llm(LlmError::EmptyPromptTokenIds { .. }) => true,
            _ => false,
        }
    }
}

评论区精华

gRPC 错误映射应为 INVALID_ARGUMENT 正确性

Codex bot 指出,新验证错误通过 TextLlm::generate 返回后,gRPC 处理器(mod.rs:58-59,106-107)使用 Status::internal 包装,导致客户端验证失败误报为内部错误。

结论:作者添加 text_error_to_status 函数,使用 is_request_validation_error 判断并将验证错误映射为 InvalidArgument。 · 已解决

将 is_request_validation_error 提取为 Error 方法 设计

BugenZhao 在 review 中建议,HTTP 路由和 gRPC 错误分类中重复的 is_text_request_validation_error 函数应作为 vllm_text::Error 的方法,以避免重复。

结论:BugenZhao 在第三个 commit 中实现了提取,将 is_request_validation_error 添加为 Error 枚举的方法,并在所有地方使用。 · 已解决

风险与影响

  • 错误映射从之前的 Internal 改为 InvalidArgument,可能影响依赖 500 状态码的 gRPC 客户端,但这是正确的行为修复,且测试已覆盖。
  • 新错误变体被 is_request_validation_error 涵盖,确保不会意外泄漏到 500 响应中。
  • 测试覆盖了 unary 和 streaming 路径以及单元验证,回归风险较低。
  • 用户影响:之前未正确拒绝的 min_tokens > max_tokens 请求现在会收到清晰的 400 错误或 gRPC INVALID_ARGUMENT,避免了引擎执行不可能配置带来的不可预测行为。
  • 系统影响:统一了验证逻辑,消除了不同路径之间的不一致;错误分类代码重复减少。
  • 团队影响:新增验证错误只需在 is_request_validation_error 中添加匹配臂,维护成本低。
错误映射变更但不兼容已有 gRPC 客户端 测试覆盖充分,回归风险低

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论