ITADN

[Bug]: System crash: Rust frontend aborts the process on prompt logprobs for a zero-token prompt

#51420OpenYunzez 创建于 11 天前
bug
Y
Yunzezcommented
### Your current environment `vllm/collect_env.py` output is not included: this reproduces entirely against the Rust workspace under `rust/`, driven by `cargo run` and no engine at all. The vLLM Python package is not installed on the repro machine and there is no GPU, so `collect_env.py` would report `N/A` for essentially every field it exists to collect. Nothing in the affected code path touches torch, CUDA, or the Python runtime. Happy to provide a full dump from a GPU install if that is needed for triage. ``` vLLM commit e2fa28594f7baad142a426b0b6a2cfe2c79201c7 (2026-08-02) Toolchain rustc 1.95.0 (59807616e 2026-04-14) <- pinned by rust-toolchain.toml OS Ubuntu 26.04 LTS, Linux 7.0.0-27-generic, x86_64 ``` <details> <summary>The output of <code>python collect_env.py</code></summary> ```text Your output of `python collect_env.py` here ``` </details> ### 🐛 Describe the bug `decode_prompt_logprobs` assumes the prompt has at least one token and enforces that with `.expect()`. If prompt logprobs arrive for a zero-token prompt, the Rust frontend panics, and because the workspace sets `panic = "abort"` in the release profile, the process aborts rather than the request failing. The panic cannot be contained by catch_unwind or a tower CatchPanicLayer, the process terminates, taking every other in-flight request on that server with it. A single request that reaches this line is a full outage until the server is restarted. ```rust // rust/src/text/src/output/logprobs.rs:89 let first_token_id = prompt_token_ids .first() .copied() .expect("prompt logprobs require at least one prompt token"); ``` - **Component:** `rust/src/text/src/output/logprobs.rs:89` - **Reached from:** `decoded_text_event_stream` when the first engine output carries `prompt_info` with prompt logprobs and empty `prompt_token_ids`. - **Found by:** fuzzing `decoded_text_event_stream` with request-controlled decode options. ## Reproduction Single self-contained repro script : [empty_prompt_logprobs.rs](https://gist.github.com/Yunzez/51d4a8a4bdd1c76140f418f870492010) ```bash mkdir -p rust/src/text/examples cp empty_prompt_logprobs.rs rust/src/text/examples/ cd rust cargo run --release -p vllm-text --example empty_prompt_logprobs ``` ``` [control] prompt of 1 token(s) + prompt logprobs ... [control] -> Ok [empty prompt] prompt of 0 token(s) + prompt logprobs ... thread 'main' panicked at src/text/src/output/logprobs.rs:89:10: prompt logprobs require at least one prompt token ``` Only the prompt length differs between the two cases. The control runs first so its success is visible even though the second case aborts. The Python side *does* have this check `vllm/v1/engine/input_processor.py:405`: ```python if prompt_len == 0 and prompt_type == "decoder": raise VLLMValidationError(f"The {prompt_type} prompt cannot be empty") ``` but `InputProcessor` is constructed and driven by `AsyncLLM` (`vllm/v1/engine/async_llm.py:138`), the component the Rust frontend replaces. `core.py` neither imports nor calls it. ## Suggested fix - Simply return an error instead of `.expect()` in `decode_prompt_logprobs`, the caller already propagates `Result`, so a decode error surfaces as a failed request rather than an abort. - Or maybe better, we can reject earlier: extend `TextRequest::validate` to cover the *tokenized* prompt (or add an emptiness check after tokenization in `lower_text_request`), so an empty prompt fails with a clear 400. ### Before submitting a new issue... - [x] Make sure you already searched for relevant issues, and asked the chatbot living at the bottom right corner of the [documentation page](https://docs.vllm.ai/en/latest/), which can answer lots of frequently asked questions.
0 条评论