Skip to content

plumbing: full pipeline#2130

Merged
SBrandeis merged 22 commits into
feat/train_encode_splitfrom
plumbing-pretokenizers
Jul 3, 2026
Merged

plumbing: full pipeline#2130
SBrandeis merged 22 commits into
feat/train_encode_splitfrom
plumbing-pretokenizers

Conversation

@SBrandeis

@SBrandeis SBrandeis commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

TL;DR

Implement a new encode loop using the optimized blocks from other PRs

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

Comment on lines +569 to +590
impl PipelinePatternMatcher for AddedVocabulary {
fn get_next_special_token(
&self,
input: &str,
normalized: bool,
) -> Option<((usize, usize), u32)> {
if input.is_empty() {
return None;
}
let trie = if normalized {
self.split_normalized_trie.as_ref()
} else {
self.split_trie.as_ref()
}?;
let matched = trie.leftmost_find_iter(input).next()?;
let start = matched.start();
let end = matched.end();
let token_id = matched.value();

Some(((start, end), token_id))
}
}

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.

cc @ArthurZucker this is where to plug the new added_vocab matching logic

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.

I need an offset on the string to be able to do lstrip / rstrip and single word falgs

Comment on lines +37 to +45
impl PreTokenizer for PipelinePreTokenizer {
fn pre_tokenize(&self, text: &str, out: &mut Vec<Split>) -> Result<()> {
match self {
Self::None => Ok(()),
Self::Bert(pretok) => pretok.pre_tokenize(text, out),
Self::Whitespace(pretok) => pretok.pre_tokenize(text, out),
}
}
}

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.

cc @McPatate we just add an entry to the enum per pre-tokenizer we implement

@SBrandeis SBrandeis marked this pull request as ready for review July 2, 2026 12:44
{
type Item = Segment<'a>;

fn next(&mut self) -> Option<Self::Item> {

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 we document what we are ddoing?
Like why dod we store the special for example

Comment thread tokenizers/tk-encode/src/tokenizer/pipeline.rs
Comment on lines +569 to +590
impl PipelinePatternMatcher for AddedVocabulary {
fn get_next_special_token(
&self,
input: &str,
normalized: bool,
) -> Option<((usize, usize), u32)> {
if input.is_empty() {
return None;
}
let trie = if normalized {
self.split_normalized_trie.as_ref()
} else {
self.split_trie.as_ref()
}?;
let matched = trie.leftmost_find_iter(input).next()?;
let start = matched.start();
let end = matched.end();
let token_id = matched.value();

Some(((start, end), token_id))
}
}

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.

I need an offset on the string to be able to do lstrip / rstrip and single word falgs

@SBrandeis SBrandeis force-pushed the plumbing-pretokenizers branch from 6af5ebf to 1954de7 Compare July 2, 2026 15:10

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.

Ping @ArthurZucker to own these changes

@SBrandeis SBrandeis Jul 2, 2026

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.

jeopardized by #2129

SBrandeis and others added 20 commits July 3, 2026 00:17
Rebased onto feat/train_encode_split, which parked the #2129 fast path
(BucketVocabStore / Buckets / bucket_added_vocabulary) and restored the legacy
Tokenizer as the A/B baseline. This collapses the three stale fixup commits
("rebase", "attempt to fix", "apply normalizer in legacy tokenizer") from the
previous rebase — they targeted the pre-park base — into one coherent step:

- bucket_added_vocabulary.rs: the final fast AddedVocabulary (Buckets-backed,
  extract_next / extract_and_normalize, impl PipelinePatternMatcher).
- PipelineTokenizer uses the bucket AddedVocabulary; the base Tokenizer stays
  legacy. TryFrom<&Tokenizer> rebuilds the bucket AV from the tokenizer's added
  tokens in id order, so ids are preserved (model-present tokens reuse their
  model id) and the pipeline emits the same ids as the reference tokenizer.

pipeline_oracle passes: identical ids on big.txt (English) and wagahai
(Japanese) at 1kB/10kB chunks. Full tk-encode/tk-train suites green; fmt +
clippy -D warnings clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The PipelineTokenizer drives special-token matching through `extract_next`
(`PipelinePatternMatcher`) + `SpecialSegmentIterator`, so the bucket AV's
`extract_and_normalize` / `split_on_matches` pair is dead code (only its own
test used it). Drop them and the now-unused `Range`/`PreTokenizedString`/`Token`
imports. The shared helpers (`is_ws`, `is_single_word`, `skip_whitespace_*`)
stay — `extract_next` uses them.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Drop the test-only `extract_segments` / `extract_two_pass` / `owned` helpers and
the 7 extraction tests built on them. `extract_two_pass` reimplemented
`PipelineTokenizer::encode`'s two-pass loop inside the test module (a drift-prone
duplicate); `extract_next`'s matching behavior is exercised end-to-end by
pipeline_oracle. Kept the AV-level unit tests that don't go through the harness:
can_add_tokens, can_add_special_tokens, normalized_tokens_are_stored_by_normalized_form.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@SBrandeis SBrandeis force-pushed the plumbing-pretokenizers branch from 6371e9c to 89a1d19 Compare July 2, 2026 22:56
Restore the extract_next coverage dropped with the extract_two_pass harness, but
drive the real `SpecialSegmentIterator` instead of a parallel reimplementation.
Five single-pass tests over a bucket `AddedVocabulary`: raw added-token carving,
single_word, lstrip/rstrip span absorption, the encode_special_tokens toggle, and
raw-vs-normalized matcher selection. `SpecialSegmentIterator::new` is now
pub(crate) so the AV tests can construct it.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

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

nuce

Comment on lines +404 to +407
if self.encode_special_tokens && metadata.special {
search = match_end;
continue;
}

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.

yep abosolutely

Comment on lines +296 to +309
struct FixedMatcher(Vec<((usize, usize), u32)>);
impl PipelinePatternMatcher for FixedMatcher {
fn extract_next(
&self,
_bytes: &[u8],
search_offset: usize,
_normalized: bool,
) -> Option<((usize, usize), u32)> {
self.0
.iter()
.find(|((start, _), _)| *start >= search_offset)
.copied()
}
}

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.

Fixed is naive? we could / should use daachorse as replacement

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.

Just a test fixture even

@SBrandeis SBrandeis merged commit 05292dc into feat/train_encode_split Jul 3, 2026
33 of 42 checks passed
@SBrandeis SBrandeis deleted the plumbing-pretokenizers branch July 3, 2026 09:13
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