Skip to content

Pipeline-only tk-encode + tk-train on the pipeline (thin deps) — replaces #2200#2207

Draft
ArthurZucker wants to merge 8 commits into
feat/train_encode_splitfrom
refactor/tk-encode-thindeps-v2
Draft

Pipeline-only tk-encode + tk-train on the pipeline (thin deps) — replaces #2200#2207
ArthurZucker wants to merge 8 commits into
feat/train_encode_splitfrom
refactor/tk-encode-thindeps-v2

Conversation

@ArthurZucker

Copy link
Copy Markdown
Collaborator

What

Pipeline-only, thin-deps tk-encode + a pipeline-based tk-train + a pipeline-only python binding. This is the re-port of #2200 onto feat/train_encode_split#2200's original base (remove-char-repr-bpe) was merged & deleted, so that PR retargeted into an unmergeable 100-commit state; this replaces it, re-authored cleanly on the current base (only one conflict the whole way).

Changes

  • tk-train trains through the pipelinetokenizer::pipeline::TrainingPretokenizer (normalize + atomsplit split + GPT-2 byte-level remap); TokenizerTrainExt retargeted off the legacy Normalizer/PreTokenizer trait runtime onto the concrete config wrappers.
  • Legacy engine removed from tk-encode — the encode*/decode*/DecodeStream/post_process engine, decoders/, processors/, tokenizer/encoding.rs, utils/{padding,truncation}.rs. TokenizerImpl<M,N,PT,PP,D><M,N,PT>. AddedVocabulary slimmed to a data store (daachorse matcher gone). Tokenizer keeps loading + config accessors + add_tokens/get_vocab/save. Models (incl. no alloc model, follow-ups #2175's scratch tokenize_pipeline + feat: other data structure for WordPiece (yada) #2183 yada) and normalizers (pipeline Cow path) are kept.
  • Umbrella tokenizers — re-exports trimmed to the pipeline-only surface.
  • bindings/python → pipeline-only inference — Py Tokenizer wraps tk_encode::Tokenizer + PipelineTokenizer; keeps from_file/from_str/from_pretrained/save, encode/encode_batch → ids, get_vocab/token_to_id/id_to_token/add_tokens, component get/set. Removed decoders.rs/processors.rs/encoding.rs/utils/pretokenization.rs.
  • Vendored-slim ptr_hashtokenizers/vendor/ptr_hash with the non-optional colored/mem_dbg/tempfile deps stripped, [patch.crates-io]-ed. MPHF byte-exact (vocab tests pass).
  • thin release profileopt-level=z + codegen-units=1 + panic=abort + strip, for on-device footprint testing (cargo build --profile thin).

Deps dropped

daachorse, monostate, derive_builder, compact_str, plus colored/mem_dbg/tempfile (via the vendored ptr_hash).

Green

cargo build -p tk-encode -p tk-train -p tokenizers ✅ · cargo test -p tk-train ✅ 10/10 · cargo test -p tk-encode --lib 197 pass (1 env failure: gitignored precompiled fixture) · bindings/python cdylib builds (5.68 MB stripped).

Intentionally deferred (follow-up)

  • node binding untouched — does not build (rewire in a follow-up, same as Pipeline-only tk-encode + tk-train on the pipeline (thin deps) #2200).
  • The heavy regex/unicode-*/spm/yada deps stay — they're anchored by the kept normalizers/models, not the removed encode path (dropping them needs the pipeline to grow the full Encoding/offset contract first).

Replaces #2200.

opt-level=z + codegen-units=1 + panic=abort + strip (inherits fat LTO).
For on-device footprint testing: cargo build --profile thin.
Minimal encode binary: 1.90 MB -> 1.27 MB (-33%) vs release.
…ile)

Upstream ptr_hash 2.0.1 forces colored, mem_dbg (+ its mem_dbg-derive -> syn/quote/
proc-macro2 chain) and tempfile as NON-optional deps, though they only serve CLI/
debug/on-disk-sharding paths we never hit. Vendor a copy under vendor/ptr_hash with
those three removed (MemSize derives stripped, colored .bold() dropped, a std TempDir
shim for the unused disk-sharding path) and [patch.crates-io] to it.

tk-encode normal deps 85 -> 74. MPHF build/query unchanged: vocab tests 25/25 pass.
Add tk_encode pipeline::TrainingPretokenizer (normalize + atomsplit split, with the
byte-level alphabet remap the encode-path TryFrom drops). Retarget TokenizerTrainExt
from the legacy generic TokenizerImpl<M,N,PT,PP,D> (which drove training through the
legacy Normalizer/PreTokenizer trait runtime) onto the concrete config wrappers, and
feed the trainer from TrainingPretokenizer instead of pre_tokenize_for_training.
Remove the legacy inference path so tk-encode is pipeline-first:
- delete decoders/ and processors/ modules, tokenizer/encoding.rs, utils/{padding,truncation}.rs
- collapse TokenizerImpl<M,N,PT,PP,D> -> <M,N,PT>; Tokenizer keeps only loading
  (from_file/from_bytes/from_pretrained/from_str), config accessors, add_tokens,
  get_vocab and save; drop encode*/decode*/DecodeStream/post_process/padding/truncation
- slim AddedVocabulary to a data store: drop the daachorse matcher + regex word-boundary
  logic (find_matches/split_with_indices/extract_and_normalize); keep add_tokens id
  assignment, get_added_tokens_decoder, is_special_token and serde
- drop the legacy Decoder/PostProcessor traits + their component impls (ByteLevel,
  Metaspace, Replace); keep the pipeline (Cow/span) impls
- serialization: emit/parse the pipeline fields only; ignore truncation/padding/
  post_processor/decoder sections on load
- tk-train: target the collapsed TokenizerImpl<M,NormalizerWrapper,PreTokenizerWrapper>

Umbrella crate + python/node bindings intentionally break here (follow-up).
Remove daachorse (legacy AddedVocabulary matcher), monostate + derive_builder +
itertools (decoders/processors), and compact_str (unused). regex stays for now —
it is still anchored by the kept legacy Whitespace/Split pretokenizers + Replace
normalizer; moving those onto SysRegex/atomsplit is a follow-up.
- fixture_bench: the pipeline correctness gate now compares against the released
  tokenizers crate (the in-tree Tokenizer no longer encodes)
- move daachorse to dev-dependencies (buckets special-token-matcher comparison test)
- drop the metaspace decode() unit test (Decoder impl removed)
…code

Drop the decoders/processors re-exports (modules removed) and update the
crate doc example to the PipelineTokenizer load+encode path.
Rewire the Python Tokenizer onto the thin tk-encode: encode/encode_batch return
token ids via PipelineTokenizer (built from the tokenizer.json serde round-trip);
keep from_file/from_str/from_buffer/from_pretrained/save, get_vocab, token_to_id,
id_to_token, add_tokens/add_special_tokens, and model/normalizer/pre_tokenizer
get+set. Drop the removed surface: decoders.rs, processors.rs, encoding.rs,
utils/pretokenization.rs, decode/padding/truncation/post_process, and Encoding/
offsets. TokenizerImpl generic collapses to <PyModel,PyNormalizer,PyPreTokenizer>.
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