Skip to content

fix: prevent infinite thinking loop from cross-chunk tag truncation in Qwen3 streaming#31119

Open
HH1162 wants to merge 4 commits into
sgl-project:mainfrom
HH1162:fix/qwen3-streaming-truncation
Open

fix: prevent infinite thinking loop from cross-chunk tag truncation in Qwen3 streaming#31119
HH1162 wants to merge 4 commits into
sgl-project:mainfrom
HH1162:fix/qwen3-streaming-truncation

Conversation

@HH1162

@HH1162 HH1162 commented Jul 14, 2026

Copy link
Copy Markdown

Problem

When deploying Qwen3 models with reasoning capabilities via SGLang's streaming mode, the client occasionally enters an "infinite thinking" state. The model continuously generates reasoning content without transitioning to the final answer phase, causing request timeouts and GPU resource exhaustion.

Root Cause

In streaming scenarios, the engine's chunking mechanism can physically split the thinking tags (and) across different network chunks. Traditional regex or naive string matching on individual chunks fails to detect the complete tag boundary. As a result, the parser never receives the "end of thinking" signal, causing the state machine to hang indefinitely. This is an application-layer chunking boundary issue, not a network MTU problem.

Solution

Introduce a robust streaming parser (ProductionQwen3Detector) based on a strict state machine and prefix buffering mechanism:

  1. Cross-Chunk Prefix Buffering: _calculate_safe_length() inspects chunk tails for partial tag prefixes (e.g., < or </th) and retains them in a buffer until the next chunk arrives, preventing tag fragmentation.
  2. Physical Slicing State Machine: A while loop continuously consumes concatenated text. Once a complete tag is found, it performs precise slicing (before_tag / after_tag), ensuring matched tags are completely discarded and never linger in the buffer.
  3. Request-Scoped Isolation: Each streaming request instantiates a fresh parser with a mandatory reset() at pipeline entry, preventing worker reuse from polluting cross-request state.

Impact

  • Affected Models: All models using the qwen3 reasoning parser (e.g., Qwen3, QwQ).
  • Affected Requests: All streaming requests (stream: true).
  • Compatibility: Adds reasoning_content and content fields to streaming responses; existing fields remain unchanged. No breaking changes.

Testing

  • Unit tests cover cross-chunk truncation (start/end tags), empty chunks, and non-thinking modes.
  • Live verification confirms the fix resolves the hanging issue under high-latency and low-MTU conditions.

CI States

Latest PR Test (Base): ❌ Run #29313189894
Latest PR Test (Extra): ❌ Run #29313189851

@gemini-code-assist

Copy link
Copy Markdown
Contributor

Warning

You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again!

@HH1162

HH1162 commented Jul 14, 2026

Copy link
Copy Markdown
Author

Fixes #31118

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.

1 participant