Skip to content

No alloc normalizers#2133

Merged
SBrandeis merged 7 commits into
feat/train_encode_splitfrom
no-alloc-normalizers
Jul 7, 2026
Merged

No alloc normalizers#2133
SBrandeis merged 7 commits into
feat/train_encode_splitfrom
no-alloc-normalizers

Conversation

@SBrandeis

@SBrandeis SBrandeis commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

PipelineTokenizer benchmark

1 / 4 models supported · geomean ×2.52 across supported · 18 fixtures each — ~10 kB inputs · single thread

6f8926800 · 2026-07-06 21:45 UTC · Intel(R) Xeon(R) Platinum 8375C CPU @ 2.90GHz · 8 cores

Not yet supported: deepseek-v4 (BPE · Split+ByteLevel), llama-3 (BPE · Split+ByteLevel), t5-base (Unigram · WhitespaceSplit+Metaspace) — roadmap cards below.

bert-base-uncased speedup

Not yet supported

deepseek-v4 not supported llama-3 not supported
t5-base not supported
Per-fixture results

bert-base-uncased — WordPiece · Bert

Fixture Group Tokenizer MB/s Pipeline MB/s Speedup Ids
cmn_Hani lang 3.5 13.0 ×3.70 match
eng_Latn lang 4.1 15.0 ×3.66 match
amh_Ethi lang 7.5 20.1 ×2.69 match
jpn_Jpan lang 4.0 10.7 ×2.67 match
hin_Deva lang 6.0 14.3 ×2.39 match
ben_Beng lang 5.5 12.4 ×2.23 match
tam_Taml lang 6.7 14.5 ×2.17 match
arb_Arab lang 3.8 8.2 ×2.15 match
heb_Hebr lang 3.8 7.9 ×2.10 match
ell_Grek lang 3.5 6.9 ×2.00 match
rus_Cyrl lang 3.3 6.3 ×1.88 match
kat_Geor lang 5.8 10.8 ×1.86 match
kor_Hang lang 2.2 3.9 ×1.74 match
tha_Thai lang 8.2 13.3 ×1.63 match
agentic-traces modalities 3.5 13.4 ×3.81 match
math_latex modalities 3.7 13.7 ×3.66 match
agentic_swe modalities 3.8 13.8 ×3.63 match
code_mixed modalities 3.7 12.3 ×3.36 match

@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.

@ArthurZucker ArthurZucker left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you publish the bench + try to pre-allocate the string that will be written in ?

Comment on lines +42 to +46
let table = &*BYTES_CHAR_LOOKUP;
let mut out = String::with_capacity(input.len());
for &b in input.as_bytes() {
out.push(table[b as usize]);
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO but can probably leverage SIMD

}

impl pipeline::Normalizer for Prepend {
fn normalize<'a>(&self, input: &'a str) -> Cow<'a, str> {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IDK how viable but:

    buf.clear();
    buf.reserve(self.prepend.len() + input.len());
    buf.push_str(&self.prepend);
    buf.push_str(input);
    buf.as_str()

with a buffer part of the "scratch"

@SBrandeis SBrandeis force-pushed the plumbing-pretokenizers branch 2 times, most recently from 6371e9c to 89a1d19 Compare July 2, 2026 22:56
Base automatically changed from plumbing-pretokenizers to feat/train_encode_split July 3, 2026 09:13
@SBrandeis SBrandeis force-pushed the no-alloc-normalizers branch 3 times, most recently from bd4e27d to 2426fed Compare July 3, 2026 10:30
@SBrandeis SBrandeis force-pushed the no-alloc-normalizers branch from 2426fed to 001304a Compare July 3, 2026 13:44
@SBrandeis

Copy link
Copy Markdown
Contributor Author

Let's merge this version and iterate on the suggested fixes as a follow-up?

@SBrandeis SBrandeis marked this pull request as ready for review July 3, 2026 13:54
Comment on lines +29 to +32
pub trait Normalizer {
fn normalize<'a>(&self, input: &'a str) -> Cow<'a, str>;
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The main change: bypass the NormalizedString and return a Cow instead

compact_str = { version = "0.9", features = ["serde"] }
ptr_hash = { version = "1.1.0" }
memchr = "2.8.2"
unicode-normalization = "0.1.25"

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Required to get the is_nfkd_quick checks in unicode normalizers

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mm fine for now, we'll skim this later on anyways when we work on bytes directly

@SBrandeis SBrandeis merged commit 89ff7df into feat/train_encode_split Jul 7, 2026
30 of 41 checks passed
@SBrandeis SBrandeis deleted the no-alloc-normalizers branch July 7, 2026 12:09
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