Skip to content

fix: correct parallel chunk boundary across punctuation trailing runs… - #69

Merged
AlonKejzman merged 1 commit into
mainfrom
fix/issue-67-o200k-chunk-boundary
Sep 9, 2026
Merged

fix: correct parallel chunk boundary across punctuation trailing runs…#69
AlonKejzman merged 1 commit into
mainfrom
fix/issue-67-o200k-chunk-boundary

Conversation

@AlonKejzman

Copy link
Copy Markdown
Collaborator

… (#67)

The fused scanner splits a buffer into chunks at newline boundaries so segments can be scanned in parallel, on the invariant that a newline always ends a pretoken. That breaks when a pattern's punctuation pretoken trails with a class beyond [\r\n]: o200k trails with [\r\n/]* (Kimi with [\r\n]*), so a / right after a newline — e.g. .\n/ — is still part of the same pretoken, with the newline in its middle. Splitting after the newline cut that pretoken across chunks, so multithreaded o200k tokenization diverged from the single-threaded / HF result (issue #67, sample 143 of the GPT-OSS-120B run).

Thread ScanKind through tokenize_scanned / tokenize_scanned_with_bounds into newline_chunk_bounds, and advance the boundary past the punctuation trailing run. The trailing class is defined once per kind in punct_trailing_bytes (mirroring scan_core's trailing loop) and consumed uniformly, so the fix is generic across kinds rather than an o200k special case: that run is the only place any alternative carries a non-newline byte after a newline, so extending past it is necessary and sufficient for every kind. For Kimi the run after the last newline is empty, so the advance is a no-op. Where the run instead spans a \s*[\r\n]+ token followed by a separate punctuation token, advancing merely moves that complete token into the earlier chunk — same tokenization either way.

Adds a focused regression test (.\n/ split across a 2-way boundary) and extends the whole-vs-chunked corpus with trailing-run punctuation. Both fail before this change (o200k only) and pass after. Also verified end-to-end with the real GPT-OSS-120B tokenizer vs the HF tokenizers reference on a ~198 KB input: mismatch before, exact match after.

…#67)

The fused scanner splits a buffer into chunks at newline boundaries so segments
can be scanned in parallel, on the invariant that a newline always ends a
pretoken. That breaks when a pattern's punctuation pretoken trails with a class
beyond `[\r\n]`: o200k trails with `[\r\n/]*` (Kimi with `[\r\n]*`), so a `/`
right after a newline — e.g. `.\n/` — is still part of the same pretoken, with
the newline in its middle. Splitting after the newline cut that pretoken across
chunks, so multithreaded o200k tokenization diverged from the single-threaded /
HF result (issue #67, sample 143 of the GPT-OSS-120B run).

Thread ScanKind through tokenize_scanned / tokenize_scanned_with_bounds into
newline_chunk_bounds, and advance the boundary past the punctuation trailing
run. The trailing class is defined once per kind in `punct_trailing_bytes`
(mirroring scan_core's trailing loop) and consumed uniformly, so the fix is
generic across kinds rather than an o200k special case: that run is the only
place any alternative carries a non-newline byte after a newline, so extending
past it is necessary and sufficient for every kind. For Kimi the run after the
last newline is empty, so the advance is a no-op. Where the run instead spans a
`\s*[\r\n]+` token followed by a separate punctuation token, advancing merely
moves that complete token into the earlier chunk — same tokenization either way.

Adds a focused regression test (`.\n/` split across a 2-way boundary) and
extends the whole-vs-chunked corpus with trailing-run punctuation. Both fail
before this change (o200k only) and pass after. Also verified end-to-end with
the real GPT-OSS-120B tokenizer vs the HF `tokenizers` reference on a ~198 KB
input: mismatch before, exact match after.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@AlonKejzman
AlonKejzman merged commit e6eab86 into main Sep 9, 2026
19 checks passed
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