Repository navigation
fix(bpe): merge like HF when a byte has no ByteLevel token - #89
Merged
Merged
Conversation
tencent/Hy3's vocab has no token for `\r` (U+010D `č`), and the model has no unk_token or byte fallback, so any text with a carriage return failed with "byte 0x0d has no token in vocabulary". HF's `merge_word` drops the char instead (or emits its byte-fallback tokens or the unk token), and the bytes around it may then merge with each other. The model now records whether a byte that can occur in UTF-8 has no initial token, and `merge_all_raw_into` merges a pretoken holding one from its ByteLevel text through `merge_all_encoded_into`, which follows `merge_word`. Models with all 256 byte tokens only check the flag. Fixes #88. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Merged
6 tasks done
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #88.
Problem
tencent/Hy3's byte-level vocab has no token for\r(its ByteLevel charč), and the BPE has nounk_tokenand no byte fallback. Every raw-byte merge routine inbpe.rsassumes each byte has a token, so any text with a carriage return failed withbyte 0x0d has no token in vocabulary. HF'smerge_worddrops the char instead, or emits its byte-fallback tokens or the unk token when the model has them, and the bytes on either side may then merge with each other.Change
Bperecords at load whether a byte that can occur in UTF-8 has no initial token. Hy3 lacks 14 bytes, but only0x0Dcan occur; the others (0xC0,0xC1,0xF5–0xFF) are ignored.merge_all_raw_into, the one entry every byte-level path goes through, merges a pretoken holding such a byte from its ByteLevel text viamerge_all_encoded_into. That path already followsmerge_word(drop, byte fallback, unk,fuse_unk).\rtake the char-based path.Testing
byte_level_bpe_without_a_byte_token_matches_huggingface, against thetokenizerscrate. It uses a byte-level BPE without a\rtoken, in four variants (dropped, unk, fused unk, byte fallback), each with and without regex splitting, and its merges join the bytes around the gap. It fails onmainand passes here.cargo test: 401 passed, 9 ignored.cargo clippy -- -D warningsandcargo fmt --checkare clean.tokenizers0.23.3 through the Python binding:[64, 65],[2020, 926, 185, 2020, 1230]and[].\r(plus one > 256 KiB) each fortencent/Hy3(revisiona960ebc),Hy3-previewandHy4-preview, Hy3 with a single ByteLevel pre-tokenizer (forcing merges across the gap), and six synthetic variants.encode_batchmatches too.\r\ntext as fast as\ntext: 2.1 ms median each on 3.3M chars, where HF takes ~1.1 s.🤖 Generated with Claude Code