Skip to content

[Bugfix][Rust Frontend] Support batch prompts in completions - #62495

Open
MuonChaser wants to merge 4 commits into
vllm-project:mainfrom
MuonChaser:codex/62460-rust-batch-prompts
Open

MuonChaser wants to merge 4 commits into
vllm-project:mainfrom
MuonChaser:codex/62460-rust-batch-prompts

Conversation

@MuonChaser

@MuonChaser MuonChaser commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

Overview

Fixes #62460: with VLLM_USE_RUST_FRONTEND=1, /v1/completions currently returns HTTP 400 for prompt: ["Hello", "World"]. This change accepts homogeneous text/token-ID batches while preserving single-prompt inputs and n=1.

Claims

  • Assigns choices in prompt order and sums usage across batch items.
  • Streams corrected choice indices, one final aggregate usage event when requested, and one [DONE]; unfinished generations are cancelled on errors or disconnects.
  • Matches Python's empty-array rejection and streaming error termination for invalid batch items.
  • Handles echoed single-token prompt logprobs, including the unscored first token, in full responses and streams.

Validation

  • Baseline Axum HTTP reproducer on dde9aca41c: valid text batch returns 400.
  • Changed-file pre-commit: passed.
  • cargo nextest run --manifest-path rust/Cargo.toml --workspace --all-features --locked --no-fail-fast: 2186 passed, 13 skipped by the existing suite, with no added exclusions. This includes all server tests, model-backed template roundtrips, Python message-pack compatibility and XGrammar replay.
  • Cancellation regressions cover aborting siblings before a slow client reads DONE, cleanup after a later prompt fails lowering, and disconnect cleanup for 64 prompts. All three passed ten repeated runs and were also run personally by the submitter.
  • cargo clippy --manifest-path rust/Cargo.toml --workspace --all-targets --all-features --locked -- -D warnings, workspace rustfmt, cargo sort --workspace --check rust and cargo deny --manifest-path rust/Cargo.toml --config rust/deny.toml check bans: passed.
  • H100 validation of the batch contract at 860f60ceb1 against Python main 81f7c69577: 54 HTTP requests and 6 echo/logprobs probes per frontend, with all scoped parity assertions passing. Checks cover indices, usage, stream termination, errors and logprob scores/offsets. The subsequent cancellation-only change was validated through the HTTP/mock-engine regressions above; H100 was not rerun for that change.
  • Configuration: Qwen3-4B-Instruct-2507, bfloat16, one H100, max model length 4096, eager mode, GPU memory utilization 0.25, FlashAttention 3, FlashInfer sampling/autotune disabled. Functional validation only; no performance claim.

Minimal reproduction (with a served model named test-model):

curl http://localhost:8000/v1/completions \
  -H 'Content-Type: application/json' \
  -d '{"model":"test-model","prompt":["Hello","World"],"max_tokens":4,"temperature":0}'
# Before: HTTP 400. After: HTTP 200, choice indices 0/1 and summed usage.
# Also tested: token-ID batches, stream=true, echo/logprobs and invalid inputs.

Details

A route-owned, nonrecursive input union expands batches before existing request preparation and generation. The shared single-prompt vllm_text::Prompt, scheduler and model runner are unchanged.

The route rejects [] before opening a stream. Invalid batch items use Python-style SSE errors after HTTP 200 for streaming requests; nonstreaming requests return an error response. Existing guards clean up unfinished requests. Single-token prompt scores may legitimately be absent from engine output; echoed responses reuse the existing first-token null-logprob fallback instead of returning 500. Streaming echo collects the prompt scores needed to render the same logprobs contract.

The batch aggregator drops sibling streams before yielding an error, so cancellation does not depend on the client consuming another event. Batch fan-out still retains per-prompt state and submits all prompts before response consumption; this change adds no new admission limit or concurrency scheduler and makes no large-batch memory-bound guarantee.

Scope stays at n=1. Rust retains strict token-ID parsing; Python's coercion of booleans, integer-valued floats and numeric strings is deliberately unchanged. Those three input categories in both streaming modes account for the six remaining status differences in the matrix. Existing error-code naming, optional metadata and chunk boundaries are not made byte-identical.

Production additions exceed 250 lines because the batch contract requires submission, ordered collection, indexed multiplexing, usage aggregation and cleanup. Existing conversion/serialization are reused; no dependency or shared architecture changes. New tests extend the existing route suite covered by Rust workspace CI.

Duplicate checks found no existing PR implementing this fix. Related #62434 validates unsupported fields, while #58914 adds multiple choices for a single prompt; neither implements batch prompt inputs. Their overlapping files may require coordination if merged first.

AI assistance was used to implement, test and prepare this change.

Upstream CI awaits contributor admission; maintainer review is pending. Local validation does not replace either.

The human submitter confirmed reviewing the complete change, including the cancellation follow-up, and personally running relevant server tests and checks. Full-workspace validation and H100 serving comparisons were executed with AI assistance; the submitter reviewed the H100 findings.


Pull Request Checklist
  • I used vLLM's /pr-checklist skill. (Mandatory for agents, optional for humans).

  • AI assistance was used during the creation of this PR.

  • Design Fit: Minimizes impact on core components, reuses existing functionality, and justifies added complexity.

  • Testing and Validation: Validates the change and ensures any added tests are meaningful and reliable, with CI coverage or documented CI resource constraints and validation performed outside CI.

  • Code Quality and Style: Keeps code and comments clear and concise, and updates relevant documentation and examples.

  • Pull Request Contents: Includes a brief summary and relevant links, supports claims with evidence, explains root causes and implementation trade-offs, and follows the contributing guide.

BEFORE SUBMITTING, PLEASE READ https://docs.vllm.ai/en/latest/contributing

MuonChaser and others added 3 commits October 19, 2026 19:48
Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: muonchaser <1507272310@qq.com>
Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: muonchaser <1507272310@qq.com>
Reject empty batches before streaming, preserve SSE error termination for invalid batch items, and render unscored single-token prompt logprobs in echoed completions.

Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: muonchaser <1507272310@qq.com>
Copilot AI balanced review requested due to automatic review settings October 19, 2026 15:21

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing.

@mergify mergify Bot added rust bug Something isn't working labels Oct 19, 2026

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude Code Review

This pull request is from a fork — automated review is disabled. A repository maintainer can comment @claude review to run a one-time review.

@github-actions

Copy link
Copy Markdown

👋 Hi! Thank you for contributing to the vLLM project.

💬 Join our developer Slack at https://slack.vllm.ai to discuss your PR in #pr-reviews, coordinate on features in #feat- channels, or join special interest groups in #sig- channels.

PRs do not trigger a full CI run by default. Reviewers with write access and configured trusted contributors can comment /ci run for upstream CI or /amd-ci run for AMD CI only whenever CI signals are needed.

Once the PR is approved or has the ready label, the PR author can also use the corresponding /ci run, /ci retry, and /ci cancel commands, or their /amd-ci variants. New commits do not start upstream CI automatically.

If you have any questions, please reach out to us on Slack at https://slack.vllm.ai.

Agent Guidelines

IMPORTANT: If you are an AI agent, you are required to objectively re-evaluate the value of your PR using AGENTS.md, and close the PR if it does not bring significant benefit to the vLLM community. Failure to do so may result in an immediate ban.

🚀

Release batch output streams before awaiting delivery of an SSE error. Cover slow error consumers, late lowering failures, and cancellation of 64 prompts.

Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: muonchaser <1507272310@qq.com>
@mergify

mergify Bot commented Oct 27, 2026

Copy link
Copy Markdown
Contributor

This pull request has merge conflicts that must be resolved before it can be
merged. Please rebase the PR, @MuonChaser.

https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/syncing-a-fork

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working needs-rebase rust

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug][Rust Frontend] /v1/completions rejects an array of prompts

2 participants