Skip to content

[Bugfix] Implicitly close DeepSeek DSML parameters - #54838

Merged
chaunceyjiang merged 2 commits into
vllm-project:mainfrom
sfeng33:fix/deepseek-implicit-param-close
Sep 2, 2026
Merged

chaunceyjiang merged 2 commits into
vllm-project:mainfrom
sfeng33:fix/deepseek-implicit-param-close

Conversation

@sfeng33

@sfeng33 sfeng33 commented Sep 1, 2026 •

Copy link
Copy Markdown
Member

Purpose

Partially fix #53227.
Allow a DeepSeek DSML parameter to end implicitly when the next parameter begins. This prevents a missing parameter closer from swallowing the following parameter. The shared converter also applies this behavior to DeepSeek V3.2.

Test Plan

Unit tests

pytest tests/parser/ tests/tool_parsers/test_deepseekv4_tool_parser.py
       tests/tool_parsers/test_deepseekv32_tool_parser.py -q

Live server validation

Validated against a live deepseek-ai/DeepSeek-V4-Flash server.

End-to-end: 8 prompt shapes (parallel calls, 3-param calls, values containing </XML markup, multi-line values, unicode, numeric/bool params, long values) × {streaming, non-streaming} × {tool_choice: auto, required} — 32 request pairs. No DSML markup in arguments, all arguments valid JSON, all keys within the tool schema.

Chunk-boundary correctness: the server only exercises one token split, so 64 raw generations were captured unparsed (via /tokenize → /v1/completions) and replayed through the parser at splits of 1/2/3/7/17 chars plus randomized splits — 704 replays per corpus — asserting chunk-size invariance and no terminal leakage.

Corpus main this PR
64 real generations, 704 replays pass pass
same, one </|DSML|parameter> dropped, 704 replays 421 failures pass
parameter recovery across the 64 malformed samples 64 lost/corrupted 64 recovered

Signed-off-by: sfeng33 <4florafeng@gmail.com>
@mergify mergify Bot added deepseek Related to DeepSeek models tool-calling labels Sep 1, 2026
@mergify mergify Bot added the bug Something isn't working label Sep 1, 2026
Signed-off-by: sfeng33 <4florafeng@gmail.com>
@sfeng33
sfeng33 force-pushed the fix/deepseek-implicit-param-close branch from dc3ff2d to 99059db Compare September 1, 2026 21:17
@sfeng33
sfeng33 marked this pull request as ready for review September 1, 2026 21:26

@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.

@Manny7717 Manny7717 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.

Verified locally on head 99059db (worktree, VLLM_TARGET_DEVICE=cpu, mock-tokenizer parser tests).

Bug is real on base (merge-base cdefd9d): _PARAM_RE in vllm/parser/deepseek_v4.py only terminated a parameter at </|DSML|parameter>, so a model output that omits the closer (issue #53227 class) swallowed the NEXT parameter's opening tag into the previous value. Executed probe on base: <param name="location">Paris <param name="date">tomorrow</param> parses as {"location": "Paris <|DSML|parameter name=\"date\" string=\"true\">tomorrow"} — date never materializes.

Fix is correct: _PARAM_RE now terminates at either </parameter> or a lookahead for the next <parameter name= (implicit close); _dsml_arg_converter handles the split; DSML_PARAM_START is wired into both deepseek_v4 and deepseek_v32 configs (v3.2 imports the shared converter, so the shared fix applies there too — covered by the new v32 streaming test).

Regression-proven (executed): all 5 new tests FAIL on the base worktree with the exact bug class above (incl. streaming split-tag case leaking <|DSML|parameter into arguments) and PASS on head. Full tests/parser/engine 3806 passed; tests/parser + tests/tool_parsers/test_deepseekv4_tool_parser.py 4078 passed / 285 teardown errors — the errors are torch.accelerator CUDA-less fixture noise, byte-identical on base (verified same-file 20e/20p on both).

Lint: ruff pinned in CI (v0.14.0) passes clean on all 4 files; pre-commit CI green.

Edge behavior noted (fine): a literal <parameter name= sequence inside a value would now split — that is the DSML grammar itself, and the malformed-text test confirms non-tag text like </|DSML|parameter\n is still preserved literally. No test plan gaps found.

@sfeng33

sfeng33 commented Sep 2, 2026

Copy link
Copy Markdown
Member Author

/ci run

@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown

✅ Triggered Buildkite CI #86755 for commit 99059db020ea.

jsolman pushed a commit to jsolman/vllm that referenced this pull request Sep 2, 2026
…ross delegation'

Superseded by the upstream parser fixes for DSML parameter streaming and
implicit close (vllm-project#52865, vllm-project#54838, vllm-project#54686 subset): with those in place the
recovered tool call surfaces through the normal delegation path, so the
experimental whitespace/tool-call forwarding is unnecessary and regressed
kimi_k2 and deepseek_v4 replay whitespace tests.

This reverts commit a59cb3a.

Signed-off-by: Jeff Solinsky <logicalfinality@proton.me>

@chaunceyjiang chaunceyjiang 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.

Thanks~

@chaunceyjiang
chaunceyjiang merged commit 300f688 into vllm-project:main Sep 2, 2026
65 checks passed
@sfeng33
sfeng33 deleted the fix/deepseek-implicit-param-close branch September 2, 2026 06:19
@wtdcode wtdcode mentioned this pull request Sep 2, 2026
3 of 4 tasks
mylibrar pushed a commit to tanyuqian/vllm that referenced this pull request Sep 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working deepseek Related to DeepSeek models tool-calling

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

[Bug]: DeepSeek V4 streaming tool calls leak DSML markup into arguments

4 participants