Skip to content

fix(dsv41): enforce native required and named tool prefixes - #37

Open
swbiggart wants to merge 1 commit into
bertholomus:deepseek-v41-zig-tp4from
swbiggart:fix/native-dsml-forced-tools
Open

swbiggart wants to merge 1 commit into
bertholomus:deepseek-v41-zig-tp4from
swbiggart:fix/native-dsml-forced-tools

Conversation

@swbiggart

Copy link
Copy Markdown

Problem and change

Native DeepSeek rejects tool_choice: "required" and named function choices because its tool-call opener spans text and a DSML token, while the server expects a single vocabulary token. Native CUDA also does not advertise or wire call-gate enforcement.

Recognize the split opener and enable a request-local call gate for the native CUDA DeepSeek family. Add first tool-call prefix and offered-function-name enforcement across serial, speculative, and concurrent generation. Named choices use the narrowed tool list; thinking stays unconstrained until it closes. auto and none do not install a gate.

The gate enforces the first call's opening and offered function name. The gate does not enforce valid argument JSON, argument-schema conformance, later calls, or completion when a token limit, stop condition, or cancellation ends generation. No transport optimization or SGLang changes are included.

Base and implementation

Based directly on deepseek-v41-zig-tp4 at b8b115e7ed6c86d81b7575caa6f3d4ade52b323c. Benchmarked source: 253c38ca4a30fca8e0fe242d5599844e84cc187c; the receipt amendment changes no code.

The gate checks tokens before subsequent forwarding or drafting, cuts speculative output at the first invalid token, and tracks only committed tokens. Provenance and Apache-2.0 attribution are recorded in ATTRIBUTION.md.

Validation and performance

132 lane, 375 server, five JSON and 170 engine API tests pass; Linux ARM64
compile passes all seven steps. Astra reviewed the implementation. Golden: 309/319 equal, ten known differences, zero unexpected.
The full macOS suite remains blocked by inherited SO.BUSY_POLL; lean findings
remain 1,615, unchanged from base.

Matched upstream/patched/upstream/patched benchmark on four GB10s, using the
same checkpoint, runtime and four-stream ring workloads:

Workload Upstream tok/s Patched tok/s Change
Four-stream burst 132.40 132.81 +0.311%
30-second steady 147.97 147.73 -0.162%
90-second sustained 169.84 169.59 -0.150%

No meaningful performance reduction was observed. All 96 measured burst replies
and 36 token/text qualification replies match. All 18 tool-choice feature cases
pass. A separate matched active-call workload passes all 84 calls, with
required/named throughput within 0.33% of auto and identical output tokens.

See the validation receipt
for commands, build provenance, per-load data and measurement scope.

@swbiggart

Copy link
Copy Markdown
Author

Failing check appears to be coming from upstream. Let me know if you want to enable this functionality and/or need any changes. Cheers!

@bertholomus

Copy link
Copy Markdown
Owner

Thank you @swbiggart for this and for the careful receipt! The owner will decide on this one.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants