Skip to content

unicode: stop shared pre-tokenizer regex from blowing the stack - #26966

Open
ioworker0 wants to merge 1 commit into
ggml-org:masterfrom
ioworker0:fix/deepseek-v4-flash-tokenizer-stack-overflow
Open

ioworker0 wants to merge 1 commit into
ggml-org:masterfrom
ioworker0:fix/deepseek-v4-flash-tokenizer-stack-overflow

Conversation

@ioworker0

@ioworker0 ioworker0 commented Aug 12, 2026 •

Copy link
Copy Markdown

Overview

DeepSeek V4 Flash 0731 shares a pre-tokenizer regex with the DeepSeek V3, Hunyuan Dense, and JoyAI presets. Without a custom implementation, it falls back to std::regex.

Long letter runs can trigger recursive backtracking in libstdc++, accumulating tens of thousands of stack frames and crashing a server thread before inference starts.

This change routes the exact regex through a non-recursive scanner while preserving Unicode property handling and number grouping from earlier passes.

Additional information

Validation performed:

  • Compared short inputs against std::regex.
  • Verified identical output before and after the change: 8,624 token IDs for a 17,368-byte DeepSeek V4 Flash 0731 corpus.
  • Verified that 51,294-byte, 51,295-byte, and 128 KiB letter runs complete without crashing.

Requirements

  • I have read and agree with the contributing guidelines
  • AI usage disclosure: YES — AI usage disclosure: YES — AI was used to help create the initial version of this change. I completed the final implementation and verified the test results.

DeepSeek V4 Flash 0731 uses a pre-tokenizer regex shared by
DeepSeek V3, Hunyuan Dense, and JoyAI presets. No custom path means
falling through to std::regex.

Long letter runs send libstdc++ into recursive backtracking. Large
tool output can pile up tens of thousands of frames and blow a server
thread's stack before inference gets a shot.

Route this exact regex through a non-recursive scanner. Keep Unicode
property handling and number groups from earlier passes intact.

Check short inputs against std::regex, then hammer custom path with
128 KiB letter runs. DeepSeek V4 Flash 0731 produces identical 8,624
token IDs for a 17,368-byte corpus before and after this change.
Patched 51,294-, 51,295-, and 131,072-byte runs finish without a crash.

Signed-off-by: Lance Yang <lance.yang@linux.dev>
@ioworker0

Copy link
Copy Markdown
Author

Issue: #26965

@ggml-gh-bot

ggml-gh-bot Bot commented Aug 12, 2026

Copy link
Copy Markdown

Hi @ioworker0, thanks for your contribution!

Per our contribution guidelines, the automated PR checker found the following issue(s) that need your attention:

  • PR Template not respected: Please respect the template when creating a new pull request. Make sure to fill out all required sections.

Please note that maintainers reserve the right to make final decisions on PRs. If you believe there is a mistake, please comment below.

@ggml-gh-bot ggml-gh-bot Bot added the draft PR will be changed to draft by github-actions bot label Aug 12, 2026
@github-actions
github-actions Bot marked this pull request as draft August 12, 2026 13:45
@github-actions github-actions Bot added testing Everything test related and removed draft PR will be changed to draft by github-actions bot labels Aug 12, 2026
@ioworker0
ioworker0 marked this pull request as ready for review August 13, 2026 02:32

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

testing Everything test related

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant