GrimBoost-01 / tests /test_tokenizer_bytes.py
cheezeborger's picture
Claude Code
Publish GrimBoost-01 model card, FP32 drafter, and runtime
60e7bb5 verified
Raw History Blame Contribute Delete
2.85 kB
import random
from pathlib import Path
import pytest
from grimboost.tokenization.byte_bpe import ByteBPETokenizer, train_byte_bpe
CORPUS = [
"The quick brown fox jumps over the lazy dog. ",
"def f(x):\n return x + 1\n",
"中文测试:字节级分词必须精确往返。",
"Emoji 🙂🚀 and accents café naïve. ",
"Special markers <|im_start|>user<|im_end|> are ordinary text here. ",
"Tabs\tand multiple spaces and\nnewlines.\n",
]
def _iter_corpus():
for _ in range(200):
for line in CORPUS:
yield line
@pytest.fixture(scope="module")
def tokenizer(tmp_path_factory: pytest.TempPathFactory) -> ByteBPETokenizer:
path = tmp_path_factory.mktemp("tok") / "bpe.json"
return train_byte_bpe(
_iter_corpus(),
vocab_size=320,
save_path=path,
min_frequency=1,
)
def test_roundtrip_all_examples(tokenizer: ByteBPETokenizer):
for text in CORPUS:
ids = tokenizer.encode(text)
assert tokenizer.decode_bytes(ids) == text.encode("utf-8")
assert tokenizer.decode(ids) == text
def test_encode_with_spans(tokenizer: ByteBPETokenizer):
for text in CORPUS:
data = text.encode("utf-8")
ids, spans = tokenizer.encode_with_spans(data)
assert spans[0][0] == 0
assert spans[-1][1] == len(data)
for (a, b), (c, _) in zip(spans, spans[1:]):
assert b == c
assert b"".join(tokenizer.token_bytes(i) for i in ids) == data
def test_random_unicode_roundtrip(tokenizer: ByteBPETokenizer):
rng = random.Random(0)
alphabet = "abc XYZ\n\t.,!?é中🙂🚀0123456789"
for _ in range(50):
text = "".join(rng.choice(alphabet) for _ in range(rng.randint(1, 80)))
ids = tokenizer.encode(text)
assert tokenizer.decode_bytes(ids) == text.encode("utf-8")
def test_save_load(tokenizer: ByteBPETokenizer, tmp_path: Path):
path = tmp_path / "saved.json"
tokenizer.save(path)
loaded = ByteBPETokenizer.load(path)
text = "roundtrip café 中文 🙂"
assert loaded.decode_bytes(loaded.encode(text)) == text.encode("utf-8")
assert loaded.vocab_size == tokenizer.vocab_size
def test_special_tokens_have_no_bytes(tokenizer: ByteBPETokenizer):
for idx in tokenizer.special_ids:
assert tokenizer.token_bytes(idx) is None
def test_encode_bytes_exact_with_invalid_tail(tokenizer: ByteBPETokenizer):
samples = [
b"hello \xe4\xb8", # truncated CJK
b"abc\xff\xfe", # invalid bytes
b"abc",
b"\xf0\x9f\x99", # truncated emoji
]
for data in samples:
ids, spans = tokenizer.encode_bytes_exact(data)
recon = b"".join(tokenizer.token_bytes(i) for i in ids)
assert recon == data
assert spans[0][0] == 0
assert spans[-1][1] == len(data)