Skip to content

perf: bundle all ongoing optimization work - #2272

Closed
SBrandeis wants to merge 13 commits into
feat/train_encode_splitfrom
perf/all-optims
Closed

perf: bundle all ongoing optimization work#2272
SBrandeis wants to merge 13 commits into
feat/train_encode_splitfrom
perf/all-optims

Conversation

@SBrandeis

@SBrandeis SBrandeis commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

PipelineTokenizer benchmark

10 / 10 models supported — PipelineTokenizer vs tokenizers v0.23.1 (latest release) · ~10 kB inputs · add_special_tokens on · single thread + 1/2/4/8/max-thread sweep

972adc0f4 · 2026-08-01 12:50 UTC · Intel(R) Xeon(R) Platinum 8375C CPU @ 2.90GHz · 16 cores

Per-model encode throughput vs latest release

vs base branch (d183afea5) — per-model geomean ×speedup of this PR's PipelineTokenizer against the base branch's; regressions in red.

Per-model encode throughput vs base branch

Per-model memory footprint

Minimal encode binary size

Decode

Round-trip: v0.23.1 encode_fast produces the id streams (same fixtures, add_special_tokens=true); both implementations decode those SAME ids with skip_special_tokens=false. MB/s counts decoded text bytes.

Per-model decode throughput vs latest release

Per-model decode memory footprint

bert-base-uncased — normalizer-heavy WordPiece · ×5.22 vs v0.23.1 · ×1.04 vs base · decode pending bert-base-uncased speedup bert-base-uncased stage decomposition bert-base-uncased thread scaling bert-base-uncased decode speedup bert-base-uncased decode thread scaling

Memory (RSS MB, load+encode): v0.23.1 12+0 (peak 12) · Pipeline 8+2 (peak 17)

Fixture Group v0.23.1 MB/s Pipeline MB/s Speedup Δ base added-token normalize pre-tokenize model post Ids
amh_Ethi lang 7.6 26.5 ×3.47 ×0.96 3% (1.2) 72% (27.1) 12% (4.7) 12% (4.5) 0% (0.2) match
arb_Arab lang 4.1 26.4 ×6.40 ×1.06 3% (1.2) 72% (27.6) 8% (3.2) 15% (5.6) 1% (0.5) match
ben_Beng lang 5.9 37.0 ×6.30 ×1.07 4% (1.2) 72% (19.2) 11% (2.9) 13% (3.4) 0% (0.1) match
cmn_Hani lang 3.8 19.7 ×5.17 ×1.05 2% (1.2) 75% (38.0) 10% (5.0) 12% (6.1) 0% (0.0) match
ell_Grek lang 3.7 25.5 ×6.85 ×1.07 3% (1.2) 74% (28.7) 9% (3.4) 15% (5.8) 0% (0.0) match
eng_Latn lang 4.3 19.4 ×4.47 ×1.06 5% (2.5) 76% (38.5) 9% (4.3) 10% (5.3) 0% (0.1) match
heb_Hebr lang 4.1 20.8 ×5.02 ×1.04 2% (1.2) 78% (37.7) 7% (3.6) 12% (6.0) 0% (0.0) match
hin_Deva lang 6.3 28.3 ×4.46 ×1.04 3% (1.2) 77% (27.1) 8% (2.9) 11% (3.8) 0% (0.0) match
jpn_Jpan lang 4.2 28.2 ×6.77 ×1.03 3% (1.2) 68% (23.4) 13% (4.5) 16% (5.6) 0% (0.0) match
kat_Geor lang 6.0 29.0 ×4.81 ×1.03 3% (1.2) 76% (26.3) 9% (3.0) 11% (3.7) 1% (0.4) match
kor_Hang lang 2.4 18.9 ×7.99 ×1.07 2% (1.2) 68% (35.2) 14% (7.0) 15% (7.9) 0% (0.1) match
rus_Cyrl lang 3.6 26.7 ×7.39 ×1.13 3% (1.2) 74% (27.5) 8% (3.1) 15% (5.5) 0% (0.0) match
tam_Taml lang 6.9 39.3 ×5.73 ×1.03 5% (1.2) 74% (18.7) 10% (2.5) 12% (3.0) 0% (0.1) match
tha_Thai lang 8.1 33.2 ×4.07 ×1.00 4% (1.2) 83% (25.2) 7% (2.1) 6% (1.9) 0% (0.0) match
added_normalized_dense modalities 6.6 19.8 ×2.99 ×1.01 3% (1.3) 82% (40.5) 14% (7.0) 1% (0.5) 0% (0.0) match
added_normalized_sparse modalities 5.3 19.0 ×3.62 ×1.04 4% (1.9) 78% (40.1) 14% (7.0) 4% (2.1) 0% (0.1) match
added_special_dense modalities 5.3 37.5 ×7.11 ×0.98 22% (5.7) 41% (10.4) 34% (8.6) 4% (1.1) 0% (0.0) match
added_special_sparse modalities 3.9 22.0 ×5.60 ×1.04 9% (4.1) 63% (28.2) 19% (8.6) 8% (3.5) 0% (0.0) match
agentic-traces modalities 3.8 19.2 ×5.07 ×1.06 4% (2.3) 74% (38.5) 9% (4.7) 12% (6.4) 0% (0.1) match
agentic_swe modalities 4.0 20.1 ×4.99 ×1.03 4% (1.9) 79% (38.7) 7% (3.5) 10% (5.1) 0% (0.0) match
code_mixed modalities 3.9 19.9 ×5.14 ×1.05 4% (2.1) 77% (38.4) 8% (4.1) 10% (5.1) 0% (0.1) match
math_latex modalities 4.0 19.3 ×4.87 ×1.06 5% (2.5) 75% (38.4) 9% (4.7) 12% (5.9) 0% (0.0) match
deepseek-v4 — deepseek 3-regex split-heavy byte-level BPE · ×28.90 vs v0.23.1 · ×6.94 vs base · decode pending deepseek-v4 speedup deepseek-v4 stage decomposition deepseek-v4 thread scaling deepseek-v4 decode speedup deepseek-v4 decode thread scaling

Memory (RSS MB, load+encode): v0.23.1 62+0 (peak 68) · Pipeline 84+0 (peak 84)

Fixture Group v0.23.1 MB/s Pipeline MB/s Speedup Δ base added-token normalize pre-tokenize model post Ids
amh_Ethi lang 4.3 103.3 ×23.80 ×3.10 8% (0.6) 0% (0.0) 45% (3.6) 48% (3.9) 0% (0.0) match
arb_Arab lang 4.2 135.5 ×32.64 ×8.14 10% (0.6) 0% (0.0) 33% (2.0) 58% (3.5) 0% (0.0) match
ben_Beng lang 6.3 149.4 ×23.87 ×8.45 11% (0.6) 0% (0.0) 44% (2.5) 47% (2.7) 0% (0.0) match
cmn_Hani lang 3.6 117.3 ×32.18 ×7.23 11% (0.8) 0% (0.0) 46% (3.3) 42% (3.0) 0% (0.0) match
ell_Grek lang 4.7 137.0 ×29.35 ×7.70 10% (0.6) 0% (0.0) 33% (2.0) 60% (3.6) 0% (0.0) match
eng_Latn lang 3.1 105.1 ×34.05 ×8.20 23% (1.9) 0% (0.0) 22% (1.9) 55% (4.7) 0% (0.0) match
heb_Hebr lang 3.8 130.0 ×34.11 ×9.98 9% (0.6) 0% (0.0) 31% (2.0) 59% (3.8) 0% (0.0) match
hin_Deva lang 5.8 145.1 ×25.06 ×6.82 10% (0.6) 0% (0.0) 40% (2.4) 52% (3.1) 0% (0.0) match
jpn_Jpan lang 4.2 133.2 ×31.88 ×7.50 11% (0.7) 0% (0.0) 51% (3.1) 44% (2.7) 0% (0.0) match
kat_Geor lang 5.9 152.4 ×25.87 ×8.41 11% (0.6) 0% (0.0) 42% (2.2) 47% (2.5) 0% (0.0) match
kor_Hang lang 3.5 100.2 ×28.45 ×5.11 7% (0.6) 0% (0.0) 28% (2.3) 65% (5.4) 0% (0.0) match
rus_Cyrl lang 4.2 139.0 ×32.81 ×9.60 10% (0.6) 0% (0.0) 33% (2.0) 57% (3.4) 0% (0.0) match
tam_Taml lang 6.2 160.8 ×26.03 ×9.13 12% (0.6) 0% (0.0) 44% (2.2) 46% (2.3) 0% (0.0) match
tha_Thai lang 6.9 199.9 ×29.14 ×13.72 15% (0.6) 0% (0.0) 55% (2.2) 29% (1.1) 0% (0.0) match
added_normalized_dense modalities 6.2 204.5 ×32.87 ×8.79 20% (0.9) 0% (0.0) 28% (1.2) 56% (2.4) 0% (0.0) match
added_normalized_sparse modalities 5.5 161.7 ×29.42 ×8.35 23% (1.3) 0% (0.0) 24% (1.4) 53% (2.9) 0% (0.0) match
added_special_dense modalities 3.7 66.2 ×18.07 ×1.79 49% (7.1) 0% (0.0) 33% (4.8) 18% (2.6) 1% (0.1) match
added_special_sparse modalities 4.1 74.9 ×18.44 ×3.66 34% (4.3) 0% (0.0) 41% (5.2) 25% (3.1) 1% (0.1) match
agentic-traces modalities 2.9 98.6 ×33.97 ×6.91 19% (1.8) 0% (0.0) 24% (2.2) 58% (5.4) 0% (0.0) match
agentic_swe modalities 3.0 109.4 ×36.70 ×7.33 15% (1.3) 0% (0.0) 29% (2.4) 54% (4.5) 2% (0.1) match
code_mixed modalities 3.4 107.8 ×31.56 ×6.96 18% (1.5) 0% (0.0) 26% (2.2) 54% (4.6) 1% (0.1) match
math_latex modalities 2.8 101.0 ×36.64 ×7.49 21% (1.9) 0% (0.0) 23% (2.1) 56% (5.0) 0% (0.0) match

Pre-tokenize: our split vs regex engines. ns/byte, lower better. split is the splitter this model's route actually runs, straight off the stage ladder. scalar-cls swaps only the classify pass for its scalar version. It is not the split without SIMD, since a regex-shaped fsm is a boundary-mask scanner and carries SIMD of its own. ×vs = engine ÷ our split (shipped / scalar-classify); onig & pcre2 (JIT) are C, fancy is pure-Rust fancy-regex, logos is a compile-time DFA lexer (approximate grammar; n/a for deepseek).

Fixture classify SIMD classify scalar split (shipped) split (scalar-cls) onig fancy pcre2 logos ×vs onig ×vs fancy ×vs pcre2 ×vs logos
amh_Ethi 2.59 3.10 3.62 4.13 42.0 20.3 9.2 11.6× / 10.2× 5.6× / 4.9× 2.5× / 2.2×
arb_Arab 1.00 2.78 2.02 3.80 49.1 23.0 10.3 24.3× / 12.9× 11.4× / 6.1× 5.1× / 2.7×
ben_Beng 1.46 2.65 2.49 3.67 35.9 16.3 7.6 14.4× / 9.8× 6.5× / 4.4× 3.0× / 2.1×
cmn_Hani 1.13 2.01 3.26 4.15 61.2 34.6 14.3 18.8× / 14.8× 10.6× / 8.3× 4.4× / 3.5×
ell_Grek 0.58 2.81 1.97 4.20 47.0 21.1 9.6 23.8× / 11.2× 10.7× / 5.0× 4.9× / 2.3×
eng_Latn 0.10 1.18 1.87 2.96 65.8 40.0 16.1 35.1× / 22.2× 21.4× / 13.5× 8.6× / 5.5×
heb_Hebr 1.00 2.84 2.01 3.85 51.1 24.3 10.7 25.4× / 13.3× 12.1× / 6.3× 5.3× / 2.8×
hin_Deva 1.37 2.78 2.36 3.77 38.3 19.2 8.5 16.3× / 10.2× 8.2× / 5.1× 3.6× / 2.3×
jpn_Jpan 1.55 3.14 3.12 4.71 53.2 27.6 11.8 17.1× / 11.3× 8.8× / 5.9× 3.8× / 2.5×
kat_Geor 1.39 2.17 2.25 3.03 32.7 15.1 7.1 14.5× / 10.8× 6.7× / 5.0× 3.2× / 2.3×
kor_Hang 1.08 2.50 2.31 3.73 50.0 27.3 12.1 21.6× / 13.4× 11.8× / 7.3× 5.2× / 3.2×
rus_Cyrl 1.03 2.76 1.98 3.71 46.9 21.2 9.5 23.7× / 12.7× 10.7× / 5.7× 4.8× / 2.6×
tam_Taml 0.92 2.62 2.22 3.92 31.8 13.9 6.6 14.3× / 8.1× 6.3× / 3.5× 3.0× / 1.7×
tha_Thai 1.37 2.21 2.17 3.01 26.6 10.3 5.2 12.3× / 8.8× 4.7× / 3.4× 2.4× / 1.7×
added_normalized_dense 0.08 1.18 1.18 2.27 42.2 20.3 9.1 35.7× / 18.5× 17.2× / 8.9× 7.7× / 4.0×
added_normalized_sparse 0.08 1.18 1.35 2.45 48.7 25.5 11.3 35.9× / 19.9× 18.8× / 10.4× 8.4× / 4.6×
added_special_dense 0.08 1.18 4.78 5.87 173.3 98.2 37.7 36.3× / 29.5× 20.6× / 16.7× 7.9× / 6.4×
added_special_sparse 0.08 1.18 5.20 6.30 101.8 57.8 23.4 19.6× / 16.2× 11.1× / 9.2× 4.5× / 3.7×
agentic-traces 0.57 1.18 2.24 2.85 80.2 53.6 20.1 35.8× / 28.1× 24.0× / 18.8× 9.0× / 7.0×
agentic_swe 0.51 1.15 2.43 3.07 95.2 66.6 23.7 39.1× / 31.0× 27.4× / 21.7× 9.7× / 7.7×
code_mixed 0.07 1.15 2.23 3.31 73.6 54.7 18.7 33.0× / 22.2× 24.5× / 16.5× 8.4× / 5.6×
math_latex 0.56 1.18 2.09 2.71 78.5 48.6 19.6 37.6× / 29.0× 23.2× / 17.9× 9.4× / 7.2×
gemma-4 — byte-fallback BPE, Metaspace-style split (gemma-4) · ×15.22 vs v0.23.1 · ×8.54 vs base · decode pending gemma-4 speedup gemma-4 stage decomposition gemma-4 thread scaling gemma-4 decode speedup gemma-4 decode thread scaling

Memory (RSS MB, load+encode): v0.23.1 304+0 (peak 371) · Pipeline 275+0 (peak 370)

Fixture Group v0.23.1 MB/s Pipeline MB/s Speedup Δ base added-token normalize pre-tokenize model post Ids
amh_Ethi lang 9.9 132.5 ×13.38 ×5.32 11% (0.7) 18% (1.1) 14% (0.8) 55% (3.3) 1% (0.1) match
arb_Arab lang 6.6 127.8 ×19.29 ×12.17 9% (0.6) 20% (1.3) 15% (1.0) 56% (3.6) 0% (0.0) match
ben_Beng lang 9.6 178.8 ×18.59 ×11.07 14% (0.6) 22% (0.9) 15% (0.6) 49% (2.1) 0% (0.0) match
cmn_Hani lang 11.2 58.2 ×5.19 ×2.07 4% (0.6) 2% (0.3) 1% (0.1) 96% (14.0) 0% (0.0) match
ell_Grek lang 7.2 126.5 ×17.56 ×9.50 10% (0.6) 21% (1.3) 15% (0.9) 52% (3.1) 1% (0.1) match
eng_Latn lang 3.6 79.0 ×21.94 ×16.71 18% (2.0) 20% (2.2) 16% (1.8) 44% (4.9) 3% (0.3) match
heb_Hebr lang 7.4 122.0 ×16.40 ×7.95 9% (0.6) 19% (1.3) 15% (1.0) 56% (3.8) 1% (0.1) match
hin_Deva lang 9.3 159.6 ×17.22 ×10.31 12% (0.6) 24% (1.2) 17% (0.9) 49% (2.4) 0% (0.0) match
jpn_Jpan lang 11.9 44.9 ×3.78 ×1.86 3% (0.6) 1% (0.2) 1% (0.1) 96% (19.3) 0% (0.0) match
kat_Geor lang 11.8 185.2 ×15.68 ×8.00 15% (0.6) 20% (0.8) 14% (0.6) 54% (2.2) 0% (0.0) match
kor_Hang lang 9.3 108.5 ×11.67 ×4.86 8% (0.6) 18% (1.3) 13% (1.0) 60% (4.4) 1% (0.1) match
rus_Cyrl lang 6.6 139.9 ×21.19 ×15.08 10% (0.6) 21% (1.2) 14% (0.8) 52% (3.0) 2% (0.1) match
tam_Taml lang 10.5 198.2 ×18.88 ×11.09 15% (0.6) 19% (0.7) 14% (0.6) 46% (1.8) 5% (0.2) match
tha_Thai lang 13.2 252.8 ×19.14 ×11.87 22% (0.6) 18% (0.5) 13% (0.4) 44% (1.2) 2% (0.1) match
added_normalized_dense modalities 4.9 141.2 ×28.88 ×20.35 12% (0.7) 24% (1.4) 19% (1.1) 45% (2.7) 1% (0.0) match
added_normalized_sparse modalities 4.4 101.2 ×23.01 ×16.06 16% (1.3) 24% (2.1) 18% (1.6) 41% (3.6) 1% (0.1) match
added_special_dense modalities 4.6 32.5 ×7.01 ×1.56 34% (10.0) 41% (12.0) 11% (3.1) 13% (3.8) 1% (0.3) match
added_special_sparse modalities 6.9 46.6 ×6.74 ×4.73 27% (5.5) 35% (7.1) 16% (3.3) 21% (4.3) 0% (0.0) match
agentic-traces modalities 4.1 88.4 ×21.77 ×15.98 17% (1.8) 20% (2.1) 18% (1.9) 42% (4.3) 2% (0.2) match
agentic_swe modalities 3.8 82.8 ×21.79 ×12.84 12% (1.3) 23% (2.5) 30% (3.3) 37% (4.0) 0% (0.0) match
code_mixed modalities 3.9 87.7 ×22.22 ×14.24 15% (1.5) 23% (2.4) 27% (2.8) 35% (3.6) 0% (0.0) match
math_latex modalities 3.9 84.1 ×21.79 ×16.02 18% (1.9) 20% (2.2) 16% (1.7) 44% (4.7) 3% (0.3) match
gpt2 — gpt2 ByteLevel regex · ×33.61 vs v0.23.1 · ×4.16 vs base · decode pending gpt2 speedup gpt2 stage decomposition gpt2 thread scaling gpt2 decode speedup gpt2 decode thread scaling

Memory (RSS MB, load+encode): v0.23.1 25+2 (peak 27) · Pipeline 28+0 (peak 28)

Fixture Group v0.23.1 MB/s Pipeline MB/s Speedup Δ base added-token normalize pre-tokenize model post Ids
amh_Ethi lang 3.9 102.3 ×26.30 ×2.34 9% (0.7) 0% (0.0) 42% (3.0) 48% (3.5) 1% (0.1) match
arb_Arab lang 3.7 125.4 ×34.10 ×4.85 9% (0.6) 0% (0.0) 22% (1.4) 68% (4.4) 1% (0.1) match
ben_Beng lang 2.8 106.0 ×37.73 ×2.34 7% (0.6) 0% (0.0) 24% (2.1) 68% (6.0) 0% (0.0) match
cmn_Hani lang 3.6 121.1 ×33.50 ×4.31 10% (0.6) 0% (0.0) 31% (2.0) 55% (3.5) 3% (0.2) match
ell_Grek lang 4.1 137.5 ×33.25 ×4.70 10% (0.6) 0% (0.0) 24% (1.4) 66% (3.8) 0% (0.0) match
eng_Latn lang 3.3 116.6 ×35.46 ×8.37 26% (2.0) 0% (0.0) 14% (1.0) 59% (4.5) 1% (0.1) match
heb_Hebr lang 3.7 125.4 ×33.79 ×4.21 9% (0.6) 0% (0.0) 22% (1.4) 69% (4.4) 0% (0.0) match
hin_Deva lang 3.0 114.2 ×38.21 ×2.76 7% (0.6) 0% (0.0) 25% (2.0) 67% (5.5) 0% (0.0) match
jpn_Jpan lang 4.4 149.5 ×33.93 ×6.93 12% (0.6) 0% (0.0) 38% (1.9) 49% (2.4) 0% (0.0) match
kat_Geor lang 4.5 156.5 ×34.77 ×2.35 12% (0.6) 0% (0.0) 35% (1.7) 51% (2.5) 2% (0.1) match
kor_Hang lang 3.2 106.7 ×33.45 ×2.52 8% (0.6) 0% (0.0) 21% (1.6) 72% (5.5) 0% (0.0) match
rus_Cyrl lang 4.0 137.8 ×34.87 ×5.33 11% (0.6) 0% (0.0) 24% (1.4) 66% (3.7) 0% (0.0) match
tam_Taml lang 2.6 119.3 ×45.69 ×1.85 8% (0.6) 0% (0.0) 26% (2.1) 65% (5.1) 1% (0.1) match
tha_Thai lang 3.4 123.9 ×36.33 ×3.25 9% (0.6) 0% (0.0) 29% (1.8) 61% (3.9) 1% (0.1) match
added_normalized_dense modalities 5.8 231.5 ×40.00 ×9.05 19% (0.7) 0% (0.0) 17% (0.7) 62% (2.4) 2% (0.1) match
added_normalized_sparse modalities 5.0 176.5 ×35.26 ×8.23 24% (1.3) 0% (0.0) 16% (0.8) 58% (3.0) 3% (0.2) match
added_special_dense modalities 3.9 80.3 ×20.41 ×1.77 50% (6.0) 0% (0.0) 32% (3.9) 17% (2.0) 1% (0.2) match
added_special_sparse modalities 4.1 85.5 ×20.69 ×3.60 35% (3.8) 1% (0.1) 39% (4.3) 24% (2.6) 2% (0.2) match
agentic-traces modalities 3.0 106.3 ×35.40 ×6.49 21% (1.8) 0% (0.0) 14% (1.2) 66% (5.7) 0% (0.0) match
agentic_swe modalities 3.3 120.9 ×37.02 ×4.81 17% (1.3) 0% (0.0) 15% (1.1) 67% (5.0) 1% (0.1) match
code_mixed modalities 3.4 118.9 ×35.08 ×5.70 20% (1.5) 0% (0.0) 13% (1.0) 66% (5.1) 1% (0.1) match
math_latex modalities 3.1 109.8 ×35.50 ×7.16 23% (1.9) 0% (0.0) 15% (1.3) 61% (5.0) 1% (0.1) match

Pre-tokenize: our split vs regex engines. ns/byte, lower better. split is the splitter this model's route actually runs, straight off the stage ladder. scalar-cls swaps only the classify pass for its scalar version. It is not the split without SIMD, since a regex-shaped fsm is a boundary-mask scanner and carries SIMD of its own. ×vs = engine ÷ our split (shipped / scalar-classify); onig & pcre2 (JIT) are C, fancy is pure-Rust fancy-regex, logos is a compile-time DFA lexer (approximate grammar; n/a for deepseek).

Fixture classify SIMD classify scalar split (shipped) split (scalar-cls) onig fancy pcre2 logos ×vs onig ×vs fancy ×vs pcre2 ×vs logos
amh_Ethi 2.60 3.09 3.03 3.53 27.9 22.1 5.8 4.8 9.2× / 7.9× 7.3× / 6.3× 1.9× / 1.6× 1.6× / 1.4×
arb_Arab 1.00 2.80 1.41 3.21 33.0 26.1 6.8 5.2 23.4× / 10.3× 18.5× / 8.1× 4.8× / 2.1× 3.7× / 1.6×
ben_Beng 1.46 2.64 2.13 3.31 67.9 56.4 14.0 4.0 31.8× / 20.5× 26.5× / 17.0× 6.6× / 4.2× 1.9× / 1.2×
cmn_Hani 1.12 2.01 1.98 2.86 26.9 22.0 5.9 2.4 13.6× / 9.4× 11.1× / 7.7× 3.0× / 2.1× 1.2× / 0.8×
ell_Grek 0.59 2.83 1.40 3.64 28.6 22.3 6.0 4.8 20.5× / 7.9× 15.9× / 6.1× 4.3× / 1.6× 3.4× / 1.3×
eng_Latn 0.12 1.16 1.02 2.06 45.2 44.0 12.0 3.8 44.5× / 22.0× 43.3× / 21.4× 11.8× / 5.9× 3.8× / 1.9×
heb_Hebr 1.00 2.87 1.42 3.29 31.7 26.9 6.9 3.0 22.4× / 9.7× 19.0× / 8.2× 4.8× / 2.1× 2.1× / 0.9×
hin_Deva 1.37 2.77 2.03 3.44 64.5 55.9 13.6 4.2 31.7× / 18.7× 27.5× / 16.3× 6.7× / 4.0× 2.1× / 1.2×
jpn_Jpan 1.56 3.12 1.92 3.48 23.9 18.3 5.0 3.9 12.4× / 6.9× 9.5× / 5.3× 2.6× / 1.4× 2.0× / 1.1×
kat_Geor 1.39 2.20 1.71 2.53 18.0 14.9 4.2 2.0 10.5× / 7.1× 8.7× / 5.9× 2.4× / 1.6× 1.1× / 0.8×
kor_Hang 1.07 2.47 1.57 2.97 33.0 28.5 7.6 3.7 21.1× / 11.1× 18.2× / 9.6× 4.9× / 2.6× 2.3× / 1.2×
rus_Cyrl 1.02 2.77 1.39 3.15 27.7 22.1 5.8 2.4 19.9× / 8.8× 15.8× / 7.0× 4.2× / 1.8× 1.8× / 0.8×
tam_Taml 0.92 2.63 2.06 3.76 71.5 60.3 14.4 3.8 34.8× / 19.0× 29.4× / 16.0× 7.0× / 3.8× 1.8× / 1.0×
tha_Thai 1.36 2.22 1.83 2.69 40.9 32.7 8.8 3.2 22.3× / 15.2× 17.8× / 12.2× 4.8× / 3.3× 1.7× / 1.2×
added_normalized_dense 0.06 1.18 0.67 1.80 23.7 23.3 6.2 1.9 35.2× / 13.2× 34.5× / 13.0× 9.2× / 3.5× 2.9× / 1.1×
added_normalized_sparse 0.06 1.18 0.84 1.96 31.9 30.9 8.4 2.7 38.0× / 16.3× 36.9× / 15.8× 10.0× / 4.3× 3.2× / 1.4×
added_special_dense 0.06 1.18 3.89 5.01 95.0 98.0 20.3 3.0 24.4× / 19.0× 25.2× / 19.6× 5.2× / 4.1× 0.8× / 0.6×
added_special_sparse 0.06 1.18 4.30 5.42 61.7 62.6 14.1 3.4 14.3× / 11.4× 14.5× / 11.5× 3.3× / 2.6× 0.8× / 0.6×
agentic-traces 0.58 1.18 1.16 1.75 59.8 61.3 15.3 4.7 51.4× / 34.1× 52.8× / 35.0× 13.2× / 8.7× 4.1× / 2.7×
agentic_swe 0.52 1.16 1.08 1.72 62.2 69.1 14.6 3.6 57.8× / 36.2× 64.2× / 40.2× 13.5× / 8.5× 3.4× / 2.1×
code_mixed 0.10 1.16 0.99 2.06 59.0 68.0 15.1 4.1 59.4× / 28.7× 68.5× / 33.1× 15.3× / 7.4× 4.2× / 2.0×
math_latex 0.57 1.18 1.27 1.88 54.4 51.7 13.9 4.2 42.9× / 28.9× 40.8× / 27.5× 11.0× / 7.4× 3.3× / 2.2×
gpt-oss — o200k-regex byte-level BPE (gpt-oss) · ×26.20 vs v0.23.1 · ×5.20 vs base · decode pending gpt-oss speedup gpt-oss stage decomposition gpt-oss thread scaling gpt-oss decode speedup gpt-oss decode thread scaling

Memory (RSS MB, load+encode): v0.23.1 241+0 (peak 315) · Pipeline 234+0 (peak 316)

Fixture Group v0.23.1 MB/s Pipeline MB/s Speedup Δ base added-token normalize pre-tokenize model post Ids
amh_Ethi lang 3.5 103.7 ×29.46 ×4.35 8% (0.6) 0% (0.0) 43% (3.5) 50% (4.1) 0% (0.0) match
arb_Arab lang 4.1 130.3 ×31.72 ×7.41 10% (0.6) 0% (0.0) 36% (2.2) 59% (3.6) 0% (0.0) match
ben_Beng lang 6.4 109.0 ×17.15 ×6.25 7% (0.6) 0% (0.0) 61% (5.3) 29% (2.5) 3% (0.2) match
cmn_Hani lang 4.3 126.4 ×29.19 ×10.91 10% (0.6) 0% (0.0) 42% (2.6) 49% (2.9) 0% (0.0) match
ell_Grek lang 4.8 143.6 ×30.06 ×8.96 10% (0.6) 0% (0.0) 31% (1.8) 62% (3.6) 0% (0.0) match
eng_Latn lang 3.7 108.9 ×29.33 ×2.75 24% (2.0) 0% (0.0) 19% (1.5) 56% (4.6) 0% (0.0) match
heb_Hebr lang 4.2 134.9 ×32.27 ×7.95 10% (0.6) 0% (0.0) 30% (1.8) 63% (3.9) 0% (0.0) match
hin_Deva lang 6.7 108.2 ×16.26 ×4.11 7% (0.6) 0% (0.0) 64% (5.4) 30% (2.5) 0% (0.0) match
jpn_Jpan lang 5.2 151.2 ×28.93 ×12.11 11% (0.6) 0% (0.0) 48% (2.5) 45% (2.4) 0% (0.0) match
kat_Geor lang 6.3 160.4 ×25.54 ×11.37 12% (0.6) 0% (0.0) 41% (2.1) 48% (2.5) 0% (0.0) match
kor_Hang lang 3.6 98.3 ×27.39 ×6.76 7% (0.6) 0% (0.0) 25% (2.1) 64% (5.5) 4% (0.3) match
rus_Cyrl lang 4.8 146.9 ×30.61 ×9.62 10% (0.6) 0% (0.0) 31% (1.8) 55% (3.2) 3% (0.2) match
tam_Taml lang 6.6 119.6 ×18.07 ×9.02 8% (0.6) 0% (0.0) 64% (4.6) 30% (2.1) 0% (0.0) match
tha_Thai lang 7.6 144.6 ×19.05 ×13.00 10% (0.6) 0% (0.0) 70% (4.1) 20% (1.2) 0% (0.0) match
added_normalized_dense modalities 5.2 211.5 ×40.63 ×8.43 18% (0.7) 0% (0.0) 24% (1.0) 60% (2.5) 0% (0.0) match
added_normalized_sparse modalities 5.3 164.8 ×30.93 ×3.99 23% (1.3) 0% (0.0) 21% (1.1) 57% (3.1) 0% (0.0) match
added_special_dense modalities 4.3 74.4 ×17.38 ×1.03 45% (5.7) 0% (0.0) 37% (4.7) 18% (2.3) 0% (0.0) match
added_special_sparse modalities 4.4 78.4 ×17.70 ×1.05 32% (3.8) 0% (0.0) 46% (5.4) 22% (2.6) 0% (0.0) match
agentic-traces modalities 3.5 104.8 ×29.76 ×2.86 19% (1.8) 0% (0.0) 19% (1.7) 61% (5.5) 0% (0.0) match
agentic_swe modalities 3.7 115.0 ×30.96 ×4.31 16% (1.3) 0% (0.0) 26% (2.0) 58% (4.6) 0% (0.0) match
code_mixed modalities 3.8 117.5 ×31.11 ×2.39 20% (1.5) 0% (0.0) 22% (1.7) 59% (4.6) 0% (0.0) match
math_latex modalities 3.3 104.1 ×31.19 ×2.82 22% (1.9) 0% (0.0) 19% (1.7) 60% (5.1) 0% (0.0) match

Pre-tokenize: our split vs regex engines. ns/byte, lower better. split is the splitter this model's route actually runs, straight off the stage ladder. scalar-cls swaps only the classify pass for its scalar version. It is not the split without SIMD, since a regex-shaped fsm is a boundary-mask scanner and carries SIMD of its own. ×vs = engine ÷ our split (shipped / scalar-classify); onig & pcre2 (JIT) are C, fancy is pure-Rust fancy-regex, logos is a compile-time DFA lexer (approximate grammar; n/a for deepseek).

Fixture classify SIMD classify scalar split (shipped) split (scalar-cls) onig fancy pcre2 logos ×vs onig ×vs fancy ×vs pcre2 ×vs logos
amh_Ethi 2.60 3.09 3.46 3.95 29.9 14.8 7.1 4.7 8.6× / 7.6× 4.3× / 3.8× 2.1× / 1.8× 1.4× / 1.2×
arb_Arab 1.00 2.78 2.18 3.96 34.2 16.2 7.5 5.1 15.7× / 8.6× 7.4× / 4.1× 3.4× / 1.9× 2.3× / 1.3×
ben_Beng 1.46 2.63 5.28 6.45 24.0 11.3 5.4 2.9 4.5× / 3.7× 2.1× / 1.8× 1.0× / 0.8× 0.5× / 0.4×
cmn_Hani 1.13 2.02 2.55 3.44 22.0 11.1 5.5 2.4 8.6× / 6.4× 4.3× / 3.2× 2.1× / 1.6× 1.0× / 0.7×
ell_Grek 0.58 2.82 1.79 4.03 30.4 15.9 7.1 5.0 17.0× / 7.5× 8.9× / 4.0× 3.9× / 1.8× 2.8× / 1.3×
eng_Latn 0.10 1.19 1.54 2.63 43.7 30.5 13.8 4.2 28.4× / 16.6× 19.8× / 11.6× 8.9× / 5.2× 2.7× / 1.6×
heb_Hebr 1.00 2.93 1.85 3.79 34.1 17.6 8.0 2.8 18.4× / 9.0× 9.5× / 4.6× 4.4× / 2.1× 1.5× / 0.7×
hin_Deva 1.36 2.80 5.38 6.81 26.3 13.0 6.3 3.2 4.9× / 3.9× 2.4× / 1.9× 1.2× / 0.9× 0.6× / 0.5×
jpn_Jpan 1.56 3.11 2.53 4.09 20.6 9.3 4.7 3.7 8.1× / 5.0× 3.7× / 2.3× 1.9× / 1.2× 1.5× / 0.9×
kat_Geor 1.39 2.18 2.08 2.87 19.3 10.3 4.6 2.0 9.3× / 6.7× 4.9× / 3.6× 2.2× / 1.6× 1.0× / 0.7×
kor_Hang 1.08 2.50 2.14 3.56 34.1 19.8 8.9 3.5 16.0× / 9.6× 9.3× / 5.6× 4.2× / 2.5× 1.7× / 1.0×
rus_Cyrl 1.02 2.75 1.79 3.53 29.1 15.2 6.6 4.8 16.2× / 8.3× 8.5× / 4.3× 3.7× / 1.9× 2.7× / 1.4×
tam_Taml 0.92 2.62 4.59 6.28 19.3 8.9 4.2 3.0 4.2× / 3.1× 1.9× / 1.4× 0.9× / 0.7× 0.7× / 0.5×
tha_Thai 1.36 2.24 4.12 5.00 13.3 5.7 2.7 2.2 3.2× / 2.7× 1.4× / 1.1× 0.7× / 0.5× 0.5× / 0.4×
added_normalized_dense 0.06 1.18 1.00 2.12 32.5 17.4 11.2 2.1 32.5× / 15.3× 17.4× / 8.2× 11.2× / 5.3× 2.1× / 1.0×
added_normalized_sparse 0.06 1.18 1.13 2.25 35.9 20.5 11.5 2.9 31.8× / 16.0× 18.2× / 9.1× 10.2× / 5.1× 2.5× / 1.3×
added_special_dense 0.06 1.18 4.67 5.79 84.9 67.5 24.6 3.3 18.2× / 14.7× 14.5× / 11.7× 5.3× / 4.2× 0.7× / 0.6×
added_special_sparse 0.06 1.18 5.36 6.48 57.4 40.8 17.3 3.6 10.7× / 8.8× 7.6× / 6.3× 3.2× / 2.7× 0.7× / 0.6×
agentic-traces 0.56 1.18 1.75 2.37 52.3 42.8 17.4 4.9 29.9× / 22.1× 24.5× / 18.1× 9.9× / 7.3× 2.8× / 2.0×
agentic_swe 0.52 1.16 2.02 2.66 52.4 49.5 17.3 3.6 25.9× / 19.7× 24.5× / 18.6× 8.5× / 6.5× 1.8× / 1.3×
code_mixed 0.07 1.15 1.72 2.80 55.5 47.4 17.2 4.2 32.2× / 19.8× 27.6× / 16.9× 10.0× / 6.1× 2.5× / 1.5×
math_latex 0.71 1.20 1.65 2.15 50.1 37.2 15.8 4.5 30.3× / 23.3× 22.5× / 17.3× 9.5× / 7.3× 2.7× / 2.1×
glm-5.2 — cl100k-variant regex byte-level BPE (glm-5.2) · ×26.60 vs v0.23.1 · ×4.13 vs base · decode pending glm-5.2 speedup glm-5.2 stage decomposition glm-5.2 thread scaling glm-5.2 decode speedup glm-5.2 decode thread scaling

Memory (RSS MB, load+encode): v0.23.1 169+0 (peak 231) · Pipeline 170+0 (peak 232)

Fixture Group v0.23.1 MB/s Pipeline MB/s Speedup Δ base added-token normalize pre-tokenize model post Ids
amh_Ethi lang 4.0 100.3 ×25.03 ×2.18 15% (1.2) 0% (0.0) 39% (3.2) 48% (4.0) 0% (0.0) match
arb_Arab lang 4.3 130.1 ×30.09 ×7.51 19% (1.2) 0% (0.0) 26% (1.6) 57% (3.6) 0% (0.0) match
ben_Beng lang 4.2 134.7 ×32.05 ×4.95 17% (1.2) 0% (0.0) 34% (2.3) 49% (3.3) 0% (0.0) match
cmn_Hani lang 4.7 126.0 ×26.93 ×9.08 19% (1.2) 0% (0.0) 36% (2.2) 45% (2.7) 0% (0.0) match
ell_Grek lang 5.1 137.2 ×26.85 ×7.02 19% (1.2) 0% (0.0) 26% (1.6) 53% (3.2) 2% (0.1) match
eng_Latn lang 3.8 105.0 ×27.75 ×2.48 31% (2.5) 0% (0.0) 17% (1.4) 53% (4.3) 0% (0.0) match
heb_Hebr lang 4.1 116.8 ×28.76 ×4.63 17% (1.2) 0% (0.0) 23% (1.6) 61% (4.3) 0% (0.0) match
hin_Deva lang 3.8 126.1 ×32.97 ×4.14 16% (1.2) 0% (0.0) 30% (2.2) 54% (3.9) 0% (0.0) match
jpn_Jpan lang 5.6 145.2 ×26.06 ×9.39 22% (1.2) 0% (0.0) 41% (2.2) 38% (2.0) 0% (0.0) match
kat_Geor lang 6.2 148.1 ×23.77 ×6.51 21% (1.2) 0% (0.0) 35% (1.9) 43% (2.3) 1% (0.1) match
kor_Hang lang 3.7 96.6 ×26.26 ×5.33 14% (1.2) 0% (0.0) 22% (1.8) 66% (5.5) 0% (0.0) match
rus_Cyrl lang 4.7 139.1 ×29.65 ×7.69 20% (1.2) 0% (0.0) 28% (1.6) 56% (3.2) 0% (0.0) match
tam_Taml lang 3.7 125.4 ×33.50 ×3.54 16% (1.2) 0% (0.0) 29% (2.1) 55% (4.0) 0% (0.0) match
tha_Thai lang 4.8 128.7 ×26.58 ×6.16 19% (1.2) 0% (0.0) 32% (2.0) 51% (3.2) 0% (0.0) match
added_normalized_dense modalities 5.9 204.7 ×34.54 ×7.66 30% (1.3) 0% (0.0) 20% (0.9) 50% (2.2) 0% (0.0) match
added_normalized_sparse modalities 5.2 156.0 ×30.08 ×3.69 32% (1.8) 0% (0.0) 18% (1.0) 52% (2.9) 0% (0.0) match
added_special_dense modalities 4.2 46.6 ×11.16 ×0.99 63% (13.2) 0% (0.0) 22% (4.7) 14% (2.9) 1% (0.2) match
added_special_sparse modalities 4.3 63.3 ×14.65 ×1.13 49% (7.3) 1% (0.1) 32% (4.8) 17% (2.6) 1% (0.1) match
agentic-traces modalities 3.5 100.5 ×28.81 ×2.86 27% (2.5) 0% (0.0) 17% (1.6) 55% (5.0) 1% (0.1) match
agentic_swe modalities 3.8 111.4 ×29.43 ×4.09 23% (1.9) 0% (0.0) 22% (1.8) 54% (4.4) 0% (0.0) match
code_mixed modalities 3.9 113.3 ×29.02 ×2.56 28% (2.2) 0% (0.0) 19% (1.5) 54% (4.3) 0% (0.0) match
math_latex modalities 3.7 101.4 ×27.08 ×2.76 27% (2.5) 0% (0.0) 17% (1.5) 56% (5.1) 0% (0.0) match

Pre-tokenize: our split vs regex engines. ns/byte, lower better. split is the splitter this model's route actually runs, straight off the stage ladder. scalar-cls swaps only the classify pass for its scalar version. It is not the split without SIMD, since a regex-shaped fsm is a boundary-mask scanner and carries SIMD of its own. ×vs = engine ÷ our split (shipped / scalar-classify); onig & pcre2 (JIT) are C, fancy is pure-Rust fancy-regex, logos is a compile-time DFA lexer (approximate grammar; n/a for deepseek).

Fixture classify SIMD classify scalar split (shipped) split (scalar-cls) onig fancy pcre2 logos ×vs onig ×vs fancy ×vs pcre2 ×vs logos
amh_Ethi 2.60 3.11 3.24 3.75 26.6 16.5 6.0 4.7 8.2× / 7.1× 5.1× / 4.4× 1.8× / 1.6× 1.5× / 1.3×
arb_Arab 1.00 2.79 1.63 3.42 30.4 20.0 7.0 5.2 18.6× / 8.9× 12.2× / 5.8× 4.3× / 2.0× 3.2× / 1.5×
ben_Beng 1.46 2.61 2.28 3.44 43.8 29.2 10.6 3.8 19.2× / 12.8× 12.8× / 8.5× 4.6× / 3.1× 1.7× / 1.1×
cmn_Hani 1.12 2.01 2.20 3.09 19.3 11.6 4.7 2.4 8.8× / 6.3× 5.3× / 3.8× 2.1× / 1.5× 1.1× / 0.8×
ell_Grek 0.58 2.81 1.59 3.82 27.5 18.0 6.3 4.8 17.3× / 7.2× 11.3× / 4.7× 4.0× / 1.7× 3.0× / 1.2×
eng_Latn 0.09 1.16 1.36 2.43 42.1 33.9 12.6 3.8 30.9× / 17.3× 24.8× / 13.9× 9.2× / 5.2× 2.8× / 1.5×
heb_Hebr 1.00 2.83 1.62 3.45 29.8 20.4 7.1 3.0 18.4× / 8.6× 12.6× / 5.9× 4.4× / 2.0× 1.9× / 0.9×
hin_Deva 1.37 2.79 2.17 3.60 46.4 30.7 11.5 4.1 21.4× / 12.9× 14.1× / 8.5× 5.3× / 3.2× 1.9× / 1.1×
jpn_Jpan 1.56 3.13 2.17 3.75 18.0 10.1 4.1 3.7 8.3× / 4.8× 4.6× / 2.7× 1.9× / 1.1× 1.7× / 1.0×
kat_Geor 1.39 2.18 1.87 2.67 16.6 11.4 4.2 2.1 8.9× / 6.2× 6.1× / 4.3× 2.2× / 1.6× 1.1× / 0.8×
kor_Hang 1.08 2.49 1.85 3.26 30.3 21.7 7.7 3.8 16.4× / 9.3× 11.8× / 6.7× 4.2× / 2.4× 2.0× / 1.2×
rus_Cyrl 1.02 2.77 1.58 3.33 26.3 17.1 5.9 2.6 16.6× / 7.9× 10.8× / 5.1× 3.8× / 1.8× 1.6× / 0.8×
tam_Taml 0.92 2.62 2.10 3.80 43.1 27.5 10.1 3.5 20.5× / 11.3× 13.1× / 7.2× 4.8× / 2.7× 1.6× / 0.9×
tha_Thai 1.36 2.22 1.98 2.83 27.5 16.9 6.8 3.0 13.9× / 9.7× 8.5× / 6.0× 3.4× / 2.4× 1.5× / 1.1×
added_normalized_dense 0.06 1.18 0.86 1.98 22.2 16.9 6.4 1.9 25.8× / 11.2× 19.6× / 8.5× 7.5× / 3.2× 2.2× / 0.9×
added_normalized_sparse 0.06 1.18 1.03 2.15 29.5 22.9 8.9 2.6 28.8× / 13.8× 22.3× / 10.7× 8.7× / 4.2× 2.5× / 1.2×
added_special_dense 0.06 1.18 4.71 5.83 90.4 72.7 21.1 3.2 19.2× / 15.5× 15.4× / 12.5× 4.5× / 3.6× 0.7× / 0.5×
added_special_sparse 0.06 1.18 4.82 5.94 57.7 45.3 15.1 3.4 12.0× / 9.7× 9.4× / 7.6× 3.1× / 2.5× 0.7× / 0.6×
agentic-traces 0.56 1.21 1.56 2.20 50.6 46.7 15.3 4.6 32.5× / 23.0× 30.0× / 21.2× 9.8× / 6.9× 2.9× / 2.1×
agentic_swe 0.54 1.16 1.84 2.46 52.8 52.7 16.0 3.4 28.7× / 21.5× 28.6× / 21.4× 8.7× / 6.5× 1.8× / 1.4×
code_mixed 0.06 1.15 1.54 2.63 50.5 51.6 15.8 4.0 32.7× / 19.2× 33.4× / 19.6× 10.3× / 6.0× 2.6× / 1.5×
math_latex 0.56 1.19 1.52 2.15 48.9 40.5 14.4 4.1 32.1× / 22.7× 26.6× / 18.8× 9.4× / 6.7× 2.7× / 1.9×
llama-2 — model-bounded BPE, no pre-tokenizer · ×14.68 vs v0.23.1 · ×3.90 vs base · decode pending llama-2 speedup llama-2 stage decomposition llama-2 thread scaling llama-2 decode speedup llama-2 decode thread scaling

Memory (RSS MB, load+encode): v0.23.1 19+0 (peak 23) · Pipeline 23+0 (peak 23)

Fixture Group v0.23.1 MB/s Pipeline MB/s Speedup Δ base added-token normalize pre-tokenize model post Ids
amh_Ethi lang 4.7 119.0 ×25.41 ×2.77 1% (0.0) 27% (1.6) 14% (0.8) 57% (3.5) 2% (0.1) match
arb_Arab lang 10.2 115.3 ×11.34 ×2.34 0% (0.0) 28% (1.9) 15% (1.0) 57% (3.8) 0% (0.0) match
ben_Beng lang 10.8 157.1 ×14.50 ×1.87 1% (0.0) 30% (1.3) 15% (0.7) 54% (2.5) 0% (0.0) match
cmn_Hani lang 9.1 104.5 ×11.46 ×1.68 1% (0.1) 5% (0.4) 2% (0.1) 93% (7.2) 0% (0.0) match
ell_Grek lang 10.4 119.7 ×11.56 ×2.05 1% (0.0) 29% (1.9) 15% (0.9) 56% (3.6) 0% (0.0) match
eng_Latn lang 4.1 75.1 ×18.34 ×11.96 0% (0.0) 38% (4.4) 16% (1.8) 46% (5.3) 0% (0.0) match
heb_Hebr lang 10.0 113.8 ×11.33 ×1.87 1% (0.0) 28% (1.9) 15% (1.0) 57% (3.9) 0% (0.0) match
hin_Deva lang 12.0 140.5 ×11.68 ×1.71 1% (0.0) 31% (1.7) 16% (0.9) 53% (2.9) 0% (0.0) match
jpn_Jpan lang 12.9 121.0 ×9.40 ×1.51 1% (0.0) 5% (0.3) 2% (0.1) 92% (6.3) 1% (0.1) match
kat_Geor lang 14.3 173.3 ×12.10 ×1.96 1% (0.0) 31% (1.2) 15% (0.6) 52% (2.1) 1% (0.0) match
kor_Hang lang 7.4 98.4 ×13.34 ×1.87 1% (0.1) 25% (1.9) 13% (1.0) 60% (4.7) 1% (0.1) match
rus_Cyrl lang 7.8 133.2 ×17.01 ×8.23 1% (0.0) 30% (1.7) 14% (0.8) 57% (3.3) 0% (0.0) match
tam_Taml lang 12.6 175.9 ×14.01 ×1.93 1% (0.0) 30% (1.2) 15% (0.6) 53% (2.0) 1% (0.0) match
tha_Thai lang 15.7 265.6 ×16.97 ×3.12 1% (0.0) 35% (0.8) 16% (0.4) 49% (1.1) 0% (0.0) match
added_normalized_dense modalities 5.5 135.6 ×24.59 ×15.59 0% (0.0) 37% (2.3) 19% (1.1) 44% (2.7) 0% (0.0) match
added_normalized_sparse modalities 4.7 98.4 ×20.84 ×13.66 0% (0.0) 41% (3.8) 17% (1.6) 41% (3.9) 1% (0.1) match
added_special_dense modalities 3.7 35.8 ×9.55 ×1.45 25% (6.6) 46% (12.2) 15% (4.1) 14% (3.6) 0% (0.0) match
added_special_sparse modalities 5.4 47.0 ×8.75 ×4.26 14% (2.9) 45% (8.9) 19% (3.7) 22% (4.4) 0% (0.1) match
agentic-traces modalities 4.4 83.2 ×18.94 ×11.94 1% (0.1) 37% (3.8) 19% (1.9) 45% (4.7) 0% (0.0) match
agentic_swe modalities 3.9 73.3 ×18.83 ×10.56 0% (0.0) 39% (4.8) 27% (3.4) 32% (4.0) 0% (0.0) match
code_mixed modalities 4.0 80.4 ×19.88 ×11.55 0% (0.0) 39% (4.3) 25% (2.8) 35% (3.8) 0% (0.0) match
math_latex modalities 4.2 79.1 ×18.67 ×12.01 1% (0.1) 37% (4.1) 15% (1.7) 46% (5.1) 2% (0.2) match
llama-3 — cl100k-regex byte-level BPE (llama-3), single regex · ×27.60 vs v0.23.1 · ×4.31 vs base · decode pending llama-3 speedup llama-3 stage decomposition llama-3 thread scaling llama-3 decode speedup llama-3 decode thread scaling

Memory (RSS MB, load+encode): v0.23.1 73+0 (peak 95) · Pipeline 93+0 (peak 95)

Fixture Group v0.23.1 MB/s Pipeline MB/s Speedup Δ base added-token normalize pre-tokenize model post Ids
amh_Ethi lang 4.5 110.2 ×24.36 ×2.41 9% (0.7) 0% (0.0) 44% (3.3) 46% (3.4) 1% (0.1) match
arb_Arab lang 4.9 145.2 ×29.83 ×8.88 11% (0.6) 0% (0.0) 29% (1.6) 60% (3.4) 0% (0.0) match
ben_Beng lang 4.1 131.5 ×31.71 ×4.15 9% (0.6) 0% (0.0) 33% (2.3) 58% (3.9) 0% (0.0) match
cmn_Hani lang 5.3 142.2 ×26.63 ×9.29 12% (0.7) 1% (0.0) 39% (2.1) 47% (2.5) 0% (0.0) match
ell_Grek lang 5.3 151.2 ×28.33 ×8.11 12% (0.6) 0% (0.0) 30% (1.6) 59% (3.1) 0% (0.0) match
eng_Latn lang 4.3 114.2 ×26.63 ×2.98 26% (2.0) 0% (0.0) 18% (1.4) 56% (4.3) 0% (0.0) match
heb_Hebr lang 4.5 130.1 ×29.16 ×5.29 10% (0.6) 0% (0.0) 26% (1.6) 66% (4.1) 0% (0.0) match
hin_Deva lang 4.6 151.0 ×33.03 ×2.07 10% (0.6) 0% (0.0) 36% (2.1) 54% (3.2) 0% (0.0) match
jpn_Jpan lang 5.9 161.7 ×27.29 ×10.55 13% (0.6) 0% (0.0) 47% (2.2) 41% (1.9) 0% (0.0) match
kat_Geor lang 5.9 157.9 ×26.94 ×4.38 12% (0.6) 0% (0.0) 39% (1.9) 48% (2.3) 0% (0.0) match
kor_Hang lang 4.3 108.2 ×25.04 ×6.27 8% (0.6) 0% (0.0) 24% (1.8) 68% (5.1) 0% (0.0) match
rus_Cyrl lang 5.3 152.2 ×28.71 ×9.91 12% (0.6) 0% (0.0) 30% (1.6) 58% (3.0) 0% (0.0) match
tam_Taml lang 4.1 135.3 ×32.82 ×3.83 9% (0.6) 0% (0.0) 31% (2.1) 60% (4.0) 0% (0.0) match
tha_Thai lang 5.5 152.0 ×27.60 ×7.85 11% (0.6) 0% (0.0) 37% (2.0) 51% (2.7) 1% (0.0) match
added_normalized_dense modalities 6.3 236.0 ×37.70 ×8.77 20% (0.7) 0% (0.0) 22% (0.8) 59% (2.2) 0% (0.0) match
added_normalized_sparse modalities 5.6 176.1 ×31.34 ×4.16 27% (1.4) 0% (0.0) 19% (1.0) 57% (2.9) 0% (0.0) match
added_special_dense modalities 4.3 68.8 ×15.98 ×0.97 44% (5.7) 0% (0.0) 34% (4.4) 21% (2.7) 1% (0.2) match
added_special_sparse modalities 4.5 82.0 ×18.17 ×1.16 33% (3.7) 0% (0.0) 41% (4.7) 24% (2.8) 2% (0.2) match
agentic-traces modalities 3.7 109.6 ×29.90 ×3.16 22% (1.8) 0% (0.0) 19% (1.5) 59% (4.8) 0% (0.0) match
agentic_swe modalities 4.2 122.3 ×29.12 ×4.51 17% (1.3) 0% (0.0) 24% (1.8) 58% (4.3) 1% (0.0) match
code_mixed modalities 4.3 122.5 ×28.43 ×2.76 21% (1.5) 0% (0.0) 21% (1.5) 58% (4.2) 0% (0.0) match
math_latex modalities 3.9 108.5 ×27.72 ×2.95 23% (1.9) 0% (0.0) 19% (1.5) 58% (4.7) 0% (0.0) match

Pre-tokenize: our split vs regex engines. ns/byte, lower better. split is the splitter this model's route actually runs, straight off the stage ladder. scalar-cls swaps only the classify pass for its scalar version. It is not the split without SIMD, since a regex-shaped fsm is a boundary-mask scanner and carries SIMD of its own. ×vs = engine ÷ our split (shipped / scalar-classify); onig & pcre2 (JIT) are C, fancy is pure-Rust fancy-regex, logos is a compile-time DFA lexer (approximate grammar; n/a for deepseek).

Fixture classify SIMD classify scalar split (shipped) split (scalar-cls) onig fancy pcre2 logos ×vs onig ×vs fancy ×vs pcre2 ×vs logos
amh_Ethi 2.62 3.09 3.27 3.74 27.1 16.4 5.8 4.7 8.3× / 7.3× 5.0× / 4.4× 1.8× / 1.6× 1.5× / 1.3×
arb_Arab 1.00 2.79 1.62 3.40 31.0 19.2 6.9 5.2 19.2× / 9.1× 11.8× / 5.6× 4.3× / 2.0× 3.2× / 1.5×
ben_Beng 1.46 2.63 2.26 3.43 45.1 27.6 10.5 3.8 20.0× / 13.2× 12.2× / 8.1× 4.6× / 3.1× 1.7× / 1.1×
cmn_Hani 1.13 2.00 2.10 2.98 19.8 11.9 4.7 2.5 9.4× / 6.7× 5.7× / 4.0× 2.2× / 1.6× 1.2× / 0.8×
ell_Grek 0.58 2.81 1.56 3.78 28.3 17.1 6.1 4.8 18.1× / 7.5× 11.0× / 4.5× 3.9× / 1.6× 3.1× / 1.3×
eng_Latn 0.09 1.16 1.36 2.43 43.7 32.9 12.2 3.7 32.1× / 18.0× 24.2× / 13.5× 9.0× / 5.0× 2.7× / 1.5×
heb_Hebr 1.00 2.84 1.60 3.45 30.3 19.9 7.1 3.0 18.9× / 8.8× 12.4× / 5.8× 4.4× / 2.1× 1.9× / 0.9×
hin_Deva 1.37 2.80 2.15 3.58 47.5 30.9 11.2 4.1 22.1× / 13.3× 14.4× / 8.6× 5.2× / 3.1× 1.9× / 1.1×
jpn_Jpan 1.55 3.15 2.19 3.78 18.5 9.8 4.1 3.8 8.4× / 4.9× 4.5× / 2.6× 1.9× / 1.1× 1.7× / 1.0×
kat_Geor 1.39 2.20 1.86 2.67 17.0 11.2 4.2 2.1 9.1× / 6.3× 6.0× / 4.2× 2.3× / 1.6× 1.1× / 0.8×
kor_Hang 1.07 2.50 1.80 3.23 30.9 21.4 7.4 3.8 17.2× / 9.6× 11.9× / 6.6× 4.1× / 2.3× 2.1× / 1.2×
rus_Cyrl 1.02 2.80 1.56 3.35 26.7 16.7 5.9 2.6 17.1× / 8.0× 10.7× / 5.0× 3.8× / 1.8× 1.6× / 0.8×
tam_Taml 0.92 2.65 2.10 3.82 44.2 26.2 9.9 3.4 21.1× / 11.6× 12.5× / 6.9× 4.7× / 2.6× 1.6× / 0.9×
tha_Thai 1.36 2.21 1.96 2.81 27.9 16.2 6.7 3.0 14.2× / 9.9× 8.2× / 5.7× 3.4× / 2.4× 1.5× / 1.1×
added_normalized_dense 0.06 1.18 0.83 1.95 23.0 16.9 6.4 1.9 27.7× / 11.8× 20.4× / 8.7× 7.7× / 3.3× 2.3× / 1.0×
added_normalized_sparse 0.06 1.18 0.98 2.10 30.6 22.6 8.7 2.6 31.2× / 14.6× 23.1× / 10.8× 8.8× / 4.1× 2.6× / 1.2×
added_special_dense 0.06 1.18 4.43 5.55 93.0 76.1 21.0 3.2 21.0× / 16.8× 17.2× / 13.7× 4.7× / 3.8× 0.7× / 0.6×
added_special_sparse 0.06 1.18 4.69 5.81 59.9 46.0 15.1 3.6 12.8× / 10.3× 9.8× / 7.9× 3.2× / 2.6× 0.8× / 0.6×
agentic-traces 0.57 1.18 1.54 2.15 52.0 44.7 14.9 4.6 33.7× / 24.2× 29.0× / 20.8× 9.7× / 6.9× 3.0× / 2.1×
agentic_swe 0.52 1.15 1.81 2.44 53.7 51.4 15.5 3.4 29.7× / 22.0× 28.4× / 21.1× 8.6× / 6.4× 1.9× / 1.4×
code_mixed 0.06 1.15 1.51 2.60 51.7 50.0 15.1 4.0 34.2× / 19.9× 33.1× / 19.3× 10.0× / 5.8× 2.6× / 1.5×
math_latex 0.61 1.22 1.53 2.14 50.2 39.7 14.0 4.2 32.8× / 23.4× 25.9× / 18.5× 9.2× / 6.5× 2.7× / 2.0×
mistral-small-4 — tekken byte-level BPE, 1k added specials (mistral-small-4) · ×23.22 vs v0.23.1 · ×4.58 vs base · decode pending mistral-small-4 speedup mistral-small-4 stage decomposition mistral-small-4 thread scaling mistral-small-4 decode speedup mistral-small-4 decode thread scaling

Memory (RSS MB, load+encode): v0.23.1 152+0 (peak 194) · Pipeline 109+0 (peak 195)

Fixture Group v0.23.1 MB/s Pipeline MB/s Speedup Δ base added-token normalize pre-tokenize model post Ids
amh_Ethi lang 4.0 99.3 ×25.01 ×2.48 15% (1.2) 0% (0.0) 42% (3.4) 43% (3.5) 0% (0.0) match
arb_Arab lang 5.0 128.4 ×25.94 ×6.22 18% (1.2) 0% (0.0) 31% (2.1) 50% (3.3) 1% (0.1) match
ben_Beng lang 6.9 104.8 ×15.14 ×5.58 13% (1.2) 0% (0.0) 59% (5.2) 26% (2.3) 1% (0.1) match
cmn_Hani lang 5.1 126.3 ×24.79 ×7.38 18% (1.2) 0% (0.0) 37% (2.5) 41% (2.8) 5% (0.3) match
ell_Grek lang 5.4 135.5 ×25.31 ×7.39 19% (1.2) 0% (0.0) 32% (2.0) 49% (3.0) 1% (0.1) match
eng_Latn lang 4.0 103.5 ×26.14 ×2.86 30% (2.5) 0% (0.0) 17% (1.4) 53% (4.5) 1% (0.0) match
heb_Hebr lang 4.7 127.4 ×27.01 ×8.22 17% (1.2) 0% (0.0) 27% (1.8) 55% (3.6) 1% (0.1) match
hin_Deva lang 6.4 102.2 ×15.89 ×4.02 13% (1.2) 2% (0.1) 57% (5.1) 27% (2.4) 2% (0.2) match
jpn_Jpan lang 5.7 144.1 ×25.35 ×8.91 21% (1.2) 0% (0.0) 49% (2.7) 29% (1.6) 1% (0.0) match
kat_Geor lang 6.7 151.5 ×22.55 ×10.06 21% (1.2) 2% (0.1) 35% (1.9) 41% (2.3) 1% (0.0) match
kor_Hang lang 4.2 98.0 ×23.10 ×5.24 14% (1.2) 0% (0.0) 25% (2.1) 61% (5.1) 0% (0.0) match
rus_Cyrl lang 5.1 136.5 ×26.78 ×8.36 19% (1.2) 0% (0.0) 29% (1.7) 51% (3.1) 2% (0.1) match
tam_Taml lang 7.0 113.1 ×16.10 ×7.57 15% (1.2) 0% (0.0) 58% (4.5) 26% (2.0) 2% (0.1) match
tha_Thai lang 8.2 136.5 ×16.64 ×9.27 18% (1.2) 0% (0.0) 63% (4.1) 18% (1.2) 1% (0.1) match
added_normalized_dense modalities 5.8 191.7 ×32.91 ×6.64 27% (1.3) 0% (0.0) 20% (1.0) 51% (2.5) 2% (0.1) match
added_normalized_sparse modalities 5.5 152.5 ×27.71 ×3.66 30% (1.8) 0% (0.0) 19% (1.2) 51% (3.1) 2% (0.1) match
added_special_dense modalities 4.4 76.1 ×17.48 ×1.09 46% (5.7) 0% (0.0) 38% (4.7) 18% (2.2) 0% (0.0) match
added_special_sparse modalities 4.5 77.2 ×17.19 ×1.21 35% (4.2) 0% (0.0) 45% (5.4) 20% (2.4) 1% (0.1) match
agentic-traces modalities 3.5 98.2 ×28.01 ×2.97 25% (2.3) 0% (0.0) 18% (1.6) 56% (5.2) 1% (0.1) match
agentic_swe modalities 3.5 105.4 ×29.71 ×4.34 22% (1.9) 0% (0.0) 22% (1.9) 59% (5.1) 0% (0.0) match
code_mixed modalities 3.8 107.6 ×28.07 ×2.58 25% (2.1) 0% (0.0) 19% (1.7) 53% (4.5) 2% (0.2) match
math_latex modalities 3.7 99.4 ×26.77 ×2.64 27% (2.5) 0% (0.0) 18% (1.6) 54% (4.8) 1% (0.1) match

Pre-tokenize: our split vs regex engines. ns/byte, lower better. split is the splitter this model's route actually runs, straight off the stage ladder. scalar-cls swaps only the classify pass for its scalar version. It is not the split without SIMD, since a regex-shaped fsm is a boundary-mask scanner and carries SIMD of its own. ×vs = engine ÷ our split (shipped / scalar-classify); onig & pcre2 (JIT) are C, fancy is pure-Rust fancy-regex, logos is a compile-time DFA lexer (approximate grammar; n/a for deepseek).

Fixture classify SIMD classify scalar split (shipped) split (scalar-cls) onig fancy pcre2 logos ×vs onig ×vs fancy ×vs pcre2 ×vs logos
amh_Ethi 2.60 3.09 3.44 3.93 28.3 14.7 6.7 8.2× / 7.2× 4.3× / 3.7× 2.0× / 1.7×
arb_Arab 1.01 2.77 2.07 3.84 34.5 16.6 7.3 16.6× / 9.0× 8.0× / 4.3× 3.5× / 1.9×
ben_Beng 1.46 2.62 5.18 6.34 22.6 11.1 5.2 4.4× / 3.6× 2.1× / 1.8× 1.0× / 0.8×
cmn_Hani 1.13 2.01 2.46 3.34 21.7 11.9 5.5 8.8× / 6.5× 4.8× / 3.6× 2.2× / 1.6×
ell_Grek 0.58 2.81 1.95 4.18 28.5 15.8 6.6 14.6× / 6.8× 8.1× / 3.8× 3.4× / 1.6×
eng_Latn 0.09 1.19 1.40 2.50 40.6 30.5 13.2 28.9× / 16.3× 21.7× / 12.2× 9.4× / 5.3×
heb_Hebr 1.00 2.86 1.77 3.63 31.7 17.9 7.7 17.9× / 8.7× 10.1× / 4.9× 4.4× / 2.1×
hin_Deva 1.36 2.78 5.13 6.55 24.4 13.3 6.1 4.8× / 3.7× 2.6× / 2.0× 1.2× / 0.9×
jpn_Jpan 1.56 3.10 2.74 4.28 20.2 9.8 8.7 7.4× / 4.7× 3.6× / 2.3× 3.2× / 2.0×
kat_Geor 1.41 2.16 1.93 2.67 18.6 10.4 4.4 9.6× / 6.9× 5.4× / 3.9× 2.3× / 1.7×
kor_Hang 1.08 2.50 2.06 3.49 32.2 19.9 8.6 15.6× / 9.2× 9.7× / 5.7× 4.2× / 2.5×
rus_Cyrl 1.02 2.76 1.74 3.48 27.6 15.4 6.4 15.9× / 7.9× 8.9× / 4.4× 3.7× / 1.8×
tam_Taml 0.92 2.60 4.52 6.20 18.4 9.0 4.2 4.1× / 3.0× 2.0× / 1.5× 0.9× / 0.7×
tha_Thai 1.36 2.22 4.08 4.94 13.2 6.0 2.8 3.2× / 2.7× 1.5× / 1.2× 0.7× / 0.6×
added_normalized_dense 0.08 1.18 0.97 2.06 30.0 18.0 11.4 31.0× / 14.5× 18.7× / 8.8× 11.8× / 5.5×
added_normalized_sparse 0.09 1.18 1.17 2.26 31.9 20.9 11.3 27.4× / 14.2× 17.9× / 9.3× 9.7× / 5.0×
added_special_dense 0.06 1.18 4.71 5.83 81.0 68.5 23.7 17.2× / 13.9× 14.5× / 11.8× 5.0× / 4.1×
added_special_sparse 0.09 1.18 5.36 6.45 52.8 41.8 15.9 9.9× / 8.2× 7.8× / 6.5× 3.0× / 2.5×
agentic-traces 0.57 1.18 1.64 2.25 51.3 44.8 16.9 31.3× / 22.8× 27.4× / 19.9× 10.3× / 7.5×
agentic_swe 0.52 1.15 1.89 2.52 55.4 54.0 18.6 29.4× / 22.0× 28.6× / 21.4× 9.9× / 7.4×
code_mixed 0.06 1.15 1.66 2.74 50.7 48.8 17.1 30.6× / 18.5× 29.4× / 17.8× 10.3× / 6.2×
math_latex 0.56 1.19 1.58 2.21 48.2 38.8 15.6 30.5× / 21.9× 24.6× / 17.6× 9.9× / 7.1×
t5-base — Unigram + Metaspace · ×5.82 vs v0.23.1 · ×2.24 vs base · decode pending t5-base speedup t5-base stage decomposition t5-base thread scaling t5-base decode speedup t5-base decode thread scaling

Memory (RSS MB, load+encode): v0.23.1 34+2 (peak 36) · Pipeline 61+2 (peak 66)

Fixture Group v0.23.1 MB/s Pipeline MB/s Speedup Δ base added-token normalize pre-tokenize model post Ids
amh_Ethi lang 5.4 37.1 ×6.93 ×2.42 3% (0.6) 84% (21.6) 5% (1.3) 8% (2.1) 0% (0.0) match
arb_Arab lang 4.2 30.9 ×7.37 ×2.46 2% (0.6) 87% (26.9) 3% (0.9) 9% (2.6) 0% (0.0) match
ben_Beng lang 7.4 35.0 ×4.75 ×1.73 2% (0.6) 89% (24.6) 3% (0.9) 6% (1.7) 0% (0.0) match
cmn_Hani lang 12.4 48.8 ×3.92 ×2.09 3% (0.6) 81% (16.8) 1% (0.3) 10% (2.1) 4% (0.9) match
ell_Grek lang 4.6 30.8 ×6.72 ×2.31 2% (0.6) 87% (27.2) 3% (0.8) 9% (2.9) 0% (0.0) match
eng_Latn lang 2.5 19.9 ×8.12 ×3.52 4% (1.9) 83% (40.3) 3% (1.4) 10% (4.9) 1% (0.3) match
heb_Hebr lang 4.2 33.9 ×8.15 ×2.62 2% (0.6) 85% (23.8) 3% (0.9) 10% (2.8) 0% (0.0) match
hin_Deva lang 6.1 34.7 ×5.71 ×1.70 2% (0.6) 88% (24.5) 4% (1.0) 7% (1.9) 0% (0.0) match
jpn_Jpan lang 13.7 42.2 ×3.07 ×1.72 3% (0.6) 83% (19.9) 2% (0.5) 10% (2.5) 2% (0.4) match
kat_Geor lang 7.7 43.9 ×5.73 ×2.14 3% (0.6) 87% (18.8) 4% (0.8) 7% (1.5) 0% (0.0) match
kor_Hang lang 4.3 31.6 ×7.31 ×2.59 2% (0.6) 83% (24.8) 3% (0.8) 12% (3.7) 0% (0.1) match
rus_Cyrl lang 4.2 30.2 ×7.22 ×3.55 2% (0.6) 85% (27.0) 2% (0.7) 10% (3.3) 1% (0.2) match
tam_Taml lang 9.0 44.6 ×4.93 ×2.02 3% (0.6) 88% (18.9) 3% (0.6) 7% (1.4) 0% (0.0) match
tha_Thai lang 12.6 46.6 ×3.69 ×1.91 3% (0.6) 91% (19.0) 3% (0.6) 3% (0.7) 0% (0.0) match
added_normalized_dense modalities 4.6 23.9 ×5.24 ×1.95 2% (0.7) 90% (36.8) 1% (0.6) 7% (3.0) 0% (0.0) match
added_normalized_sparse modalities 3.9 22.2 ×5.72 ×1.74 3% (1.4) 111% (49.4) 0% (0.0) 7% (3.2) 0% (0.1) match
added_special_dense modalities 6.4 38.2 ×5.93 ×1.13 22% (5.8) 63% (16.7) 10% (2.6) 6% (1.7) 0% (0.0) match
added_special_sparse modalities 4.2 21.8 ×5.18 ×1.38 8% (3.8) 74% (33.5) 9% (4.1) 9% (4.0) 0% (0.0) match
agentic-traces modalities 2.9 20.7 ×7.23 ×3.71 4% (1.7) 85% (39.8) 2% (0.9) 10% (4.6) 0% (0.0) match
agentic_swe modalities 4.2 23.6 ×5.62 ×2.77 3% (1.3) 90% (37.2) 2% (0.6) 6% (2.3) 0% (0.0) match
code_mixed modalities 3.7 21.9 ×5.90 ×2.82 3% (1.5) 87% (38.8) 2% (0.8) 7% (3.2) 0% (0.0) match
math_latex modalities 2.7 20.1 ×7.57 ×3.41 4% (1.9) 84% (40.3) 3% (1.4) 11% (5.2) 0% (0.0) match

@SBrandeis
SBrandeis changed the base branch from main to feat/train_encode_split July 31, 2026 16:28
@HuggingFaceDocBuilderDev

Copy link
Copy Markdown

The docs for this PR live here. All of your documentation changes will be reflected on that endpoint. The docs are available until 30 days after the last update.

SBrandeis and others added 9 commits August 1, 2026 01:37
A set-associative cache keyed on the word bytes, plus a scratch pile
reused across encode calls, so BPE, WordPiece and Unigram all stop
re-tokenizing words they have already seen.

Squashed from feat/bpe-cache-min, which also carries #2261
(perf(scratch): reuse Scratch buffers across encode() calls).
A vectorized literal scanner in atomsplit, wired into the Replace
normalizer and the Split pre-tokenizer so literal patterns stop going
through the regex engine.

Squashed from feat/literal-simd.
… the vocabulary (#2266)

SentencePiece models hand the model one whole chunk. Where the vocabulary
proves no merge can cross a word boundary, cut there and tokenize the
words independently.

Squashed from perf/metaspace-proven-cuts.
…r pass

Prepend + Replace (or a lone Replace) collapse into a single
MetaspaceNormalizer at pipeline build time, so the text is walked once
instead of twice.

Squashed from perf/fuse-metaspace (no PR).
The fuse (perf/fuse-metaspace) and the cuts (perf/metaspace-proven-cuts) were
written on branches that did not know about each other. Both detections read
the declared config, so they compose, but nothing asserted that: an encode
oracle failure would only show if one of them also changed ids. This pins the
pipeline shape for the real llama-2 and gemma-4 configs.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Ports the char-fold idea from Arthur's tables engine (#2241): at build time,
prove from the vocabulary which multi-byte characters always assemble into
one token (lowest-rank replay, no boundary neighbour able to pre-empt a
step), and seed the merge loop with that token instead of 2-3 byte symbols.

Differences from #2241: external ids throughout (no internal renumbering),
seeding feeds the existing exact merge loop instead of the WIP multipass
engine, and the WordCache above it is untouched. The pair table / grid parts
stay behind until that engine is green.

llama-3 folds 298 characters (185 CJK); model stage on the jpn fixture,
cache off: 37.0 -> 29.3 ns/B (-21%). Ids pinned equal with the fold blanked
(llama-3 A/B over CJK/Greek/Cyrillic/emoji corpora) and by the 9/9 encode
oracle; thief and non-BMP cases covered in unit tests.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
MetaspaceNormalizer swapped spaces by restarting a memchr search at
every space and guessed the rewrite's size. It now counts the spaces
first (count_matches), so the rewrite is sized exactly and a text
without spaces is handed back without a scan of its own, and streams
the swap through for_each_match. Normalize stage 4-7% faster on
llama-2/gemma-4, e2e +3-5% (4 interleaved process rounds), ids
unchanged. The drop_whitespace path sizes its rewrite from the word
spans instead of the same guess.

split_literal in pipeline.rs is now the one streaming literal split:
Split's plain-string arm and CharDelimiterSplit both call it.
CharDelimiterSplit loses its per-call span buffer (one heap Vec per
chunk) and atomsplit's memchr-restart recipe struct, which the SIMD
Literal scanner superseded, is deleted.

Gates: 352 tk-encode + 20 atomsplit tests green, pipeline_oracle 9/9
against released 0.23.1, fmt and clippy clean (the 8 parallelism.rs
dead-code warnings predate this change).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
pack_word built its u128 key by zeroing a 16-byte buffer and copying the
word in with a variable length, which LLVM lowers to a memset and a
memcpy libcall. One pair per looked-up word put a third of gpt2's whole
encode inside libsystem_platform (samply: 27.5% memset + 6.4% memmove,
both under WordCache::lookup). Two fixed-width reads, one from each end
of the word, produce the same value with no calls: the overlapped middle
bytes are identical, so or-ing the halves is harmless, and every byte
above the length stays zero for key equality.

pack_word_matches_the_buffer_form pins the new form to the old one for
every packable length and byte pattern.

Measured (interleaved process rounds, ids identical, oracle 9/9):
gpt2 +38/+30% (eng/agentic), llama-3 +39/+33%, glm +33/+31%,
gpt-oss +23/+19%, mistral +5/+21%, llama-2 +16/+5%, gemma-4 +15/+12%.
An 8-way co-runner test holds per-process throughput within 3% of solo,
so the encode loop stays core-bound, not memory-bound.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The staged path collects every span of a chunk into a buffer, then walks
the buffer calling the model through the per-span (model, scratch)
dispatch match: a span-buffer round trip and a dispatch per word. Every
FSM-routed pre-tokenizer over a BPE model (the gpt2, cl100k-family,
o200k, tekken and deepseek shapes: all eight byte-level benchmark
models but the two SentencePiece ones) now runs fused instead: encode
drives the scan_* form of the FSM, which hands each span to the model
the moment it is cut. No span buffer, dispatch settled once per chunk,
and the model reads each word while its bytes are still hot from the
scan.

Every fsm_* keeps its no-push slice form as a thin wrapper over the new
scan_* (one emit closure writing spans in place), so the existing
byte-exactness tests keep pinning both forms at once.

PipelineBPE::tokenize_span is the per-word body factored out of the
Model trait impl, so the fused and staged paths share one body and the
ignore_merges branch keeps living in exactly one place. Routing asks
the pre-tokenizer itself: Split::native_fsm and Sequence::native_fsm
apply the same recognition their pre_tokenize applies (deepseek's
three-Split composition, the identity-children collapse), so the fused
check cannot disagree with the split it bypasses.

Measured with a flat encode loop, interleaved process rounds
(eng_Latn / agentic_swe): gpt2 +17%, llama-3 +15/+16%, glm-5.2
+14/+15%, gpt-oss +14/+15%, mistral-small-4 +12/+17%, deepseek-v4
+11/+9%. llama-2 and gemma-4 do not route (ProvenCuts / literal splits)
and are unchanged. Ids identical on every fixture; oracle 9/9.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
SBrandeis and others added 2 commits August 1, 2026 12:21
Replace the per-run scalar walk of every regex-shaped pre-tokenizer FSM
(byte-level, cl100k at digit caps 1/3/unbounded, o200k, tekken,
deepseek) with 64-byte batch scanners behind one shared walker: per-
class bitmasks built from the classify tag stream, token starts computed
by shifted-mask algebra in u64 registers (transcribed per scheme from
gigatoken's scanners, MIT), and everything the algebra cannot prove
locally deferred to the scheme's scalar advance, extracted from each
scan so both paths share one body. Feeding the masks from tags instead
of raw bytes keeps non-ASCII batches on the fast path. Bad zones:
char-counted digit groups over multi-byte chars, mark chars (run-
contextual class), upper-after-caseless case splits, contraction and
whitespace batch-edge straddles, multi-byte whitespace, and any deepseek
batch containing a CJK-range char (tested before the tag masks are
built, so CJK text degenerates to the scalar scan plus one test). The
walker interleaves proven starts with bad zones: a span must never be
emitted across one. The per-target surface is one 64-byte block
classifier each for NEON, SSE2 and wasm32 simd128; other targets fall
back to the scalar scans.

FSM stage on eng_Latn/agentic_swe: byte_level 3.5x/2.5x, cl100k
2.8x/1.9x, o200k 3.2x/1.9x, tekken 3.3x/2.1x, deepseek 3.1x/1.7x;
cmn_Hani 1.2-1.9x with deepseek at parity by construction. Encode e2e,
process-alternated rounds with identical token streams: gpt2 249 -> 321
MB/s eng (+29%), +11% swe; llama-3 +28%/+16% (cmn -1.6%, noise);
glm-5.2 +27%/+13%; gpt-oss +49%/+26%; mistral +46%/+25%; deepseek
+52%/+23% (fancy-regex builds both sides). Byte-exactness pinned per
scheme by padding-sweep differentials (every 64-byte-edge offset, also
run on x86_64) and byte-exact spans over three full fixtures;
pipeline_oracle 9/9 vs the released crate.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ting them

A normalizer whose rewrite changes the text one character at a time does
not have to write it: positions map one to one, so downstream stages can
read the rewritten form off the raw text. `PendingRewrite` names that
class of rewrite (every `from` reads as `to`, one may be prepended), and
`Normalizer::pending_rewrite` lets every normalizer say whether it is
one: the fused MetaspaceNormalizer (the SentencePiece space swap) and a
single-character literal Replace are, everything else keeps writing.
`NormalizedText::from_chain` runs the chain and hands a trailing pending
rewrite back unwritten; `write` produces the text for consumers that
need the bytes, and MetaspaceNormalizer's own swap now goes through the
same writer.

The consumer is the zero-copy encode path, built when a chain ends in
the space swap over proven cuts into a char-atom BPE with no
`normalized` added tokens (llama-2, gemma-4). `ZeroCopyMetaspace` finds
the same cuts on the raw text (one memchr2 pass over `from` and `to`),
and the model reads each raw span through a `CharSwap`, seeding the
delimiter's id for every raw `from`. The word cache keys on the raw
bytes; a rewritten form never holds a `from`, so overlapping keys always
agree on their ids. Only the one word a prepend touches is still
rewritten for real. The scan compares single bytes, not runtime-length
slices: a slice compare of run-time width compiles to a memcmp call per
candidate, measured at 15-20% of the whole win.

The veto is taken at its prefilter's word: a cut whose preceding byte
could open a veto piece is skipped instead of checked against rewritten
bytes this path never builds. Skipping a cut never changes the ids, and
the byte fires for under 1% of spaces on the worst corpus (gemma-4's one
piece, code text).

Same-binary interleaved A/B (examples/normalize_claims.rs, 512 kB per
corpus, warm cache): llama-2 +10-64%, gemma-4 +29-75% encode throughput
across eng/cmn/code at 10 kB and per-line inputs. Ids match the written
path over every corpus, and the released-crate oracle stays green 9/9.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…akes

The stage breakdown drove `encode_generic::<STAGE>`, which gated the fused scan
at `STAGE_MODEL` and the zero-copy route at `STAGE_POSTPROCESS`. Below those the
ladder fell back to the staged array FSM, so on every native-FSM model the
`pre_tokenize` bar timed a splitter no shipping encode uses, and the `model` bar
was a subtraction across two different pipelines (fused split+model minus
unfused split), clamped at zero so the pathology never showed. The same held for
the metaspace models: their whole zero-copy win landed in `post` or vanished
into the clamp. `pretok_vs_regex` inherited the bad number and undersold the
split against onig/fancy/pcre2/logos by roughly 2x.

Both routes are now STAGE-aware, so every rung runs the route a full encode
runs. A fused pipeline's split rung drives the same masked FSM scan the model
rung does and emits each span into `pre_tokens`; a zero-copy pipeline's split
rung is its proven-cut pass, with neither the rewrite write nor the added-token
scan over rewritten text that the route never performs. That last one also fixes
the frame rung, which was charging zero-copy models for a normalized
added-token scan they never run.

Measured on gpt2 (10 kB warm chunks, 5 reps, M3 Max), ns/byte:

  pre_tokenize   eng 1.73 -> 0.57    swe 1.28 -> 0.61    cmn 1.23 -> 1.20
  vs onig        eng ~20x -> 63.8x

Production throughput is unchanged: threading `pre_tokens` into the fused emit
adds a closure capture that folds away in the `STAGE_MODEL` specialization.
Alternating two binaries at process level over 5 rounds x 7 reps, 4 models x 2
fixtures, the spread is -1.6% to +2.5% with no systematic direction, inside this
bench's noise floor.

Also reported so the chart cannot be read as more complete than it is:

- `route` per model, since the three decompose differently.
- `clamped`, the residual the five stages do not account for. A rung at or below
  the noise floor goes negative and clamps, and a `clamped` far from zero means
  that fixture's breakdown should not be trusted.
- `alloc`, the per-chunk output/span buffer allocation `encode` pays and the
  reused-buffer rungs do not. It measures 0.07 to 0.11 ns/byte on gpt2, so `Vec`
  growth is not the gap between the ladder's total and the throughput phase.
  Timing the real `encode` to close that gap was tried and dropped: phase 2
  shares one pipeline across fixtures, its scratch pool saturates, and the delta
  came out at +0.9 to +7.2 ns/byte measuring cache eviction rather than call
  overhead. The remainder is left stated and unattributed instead.

The split rung pays one span write per pre-token that a fused encode does not,
worth 0.03 to 0.07 ns/byte (scan with a span push 0.638 vs with an xor 0.610 on
gpt2/eng), and the model rung carries the checked `&str` slice, worth 0.15 to
0.27. Both are documented on `stage_secs`.

Rendering the chart then turned up three readability defects the JSON hid. A
row's stages sum past 100% wherever a rung clamped, and the bars were drawn
against a fixed `PLOT_W`, so those rows ran off the right edge: ell_Grek at 108%
and added_normalized_sparse at 109% were cut off, which reads as a broken chart
rather than as noise. The plot is now scaled by the widest row, so an overflowing
bar crosses the 100% gridline instead of leaving the canvas, and the subtitle
carries the mean parts-sum. The header claimed "each bar = 100%", never quite
true for the same reason, and now says 100% is that fixture's total. The new
route note pushed the subtitle past the SVG width and clipped its tail, so
stages under 2% mean go unlisted (on gpt2 that was "post 1% · normalize 0%").

Three tests pin the ladder, since `pipeline_oracle` only ever drives
`STAGE_POSTPROCESS` and so proves ids without proving which path made them. The
fused one asserts `encode_fused` returns true at `STAGE_SPLIT` rather than only
comparing spans: the staged FSM produces identical spans, so span equality alone
would not have caught this bug. Verified red by making the fused scan decline
below `STAGE_MODEL`.

370 lib tests, `pipeline_oracle` 9/9 against released 0.23.1, clippy and fmt
clean. `zero_copy_is_built_for_the_real_sentencepiece_configs` was already red
at ac50768 and is untouched here.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HorT6V8fzJXUmdJwJPXfS5
@ArthurZucker

Copy link
Copy Markdown
Collaborator

Superseded by #2279, which is the same intent — one tree with the ongoing optimization work — rebuilt on the current cache stack (feat/bpe-cache-min) and measured end to end against gigatoken on the same machine and corpora.

Geomean vs gigatoken there: gpt2 1.14×, llama-3 1.24×, i.e. ahead overall; 3.3× the base branch on English. The pieces are also split into reviewable PRs underneath it: #2276, #2277, #2278.

Closing in favour of that — happy to reopen if there is anything in here it does not cover.

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.

3 participants