Fractus / src /fractus /tokenizer.py
thefinalboss's picture
Upload src/fractus/tokenizer.py with huggingface_hub
fd3e507 verified
Raw
History Blame Contribute Delete
2.28 kB
"""BPE tokenizer for Fractus-1B (byte-level, GPT-2 compatible).
Wraps the HuggingFace `tokenizers` library. Builds or loads a byte-level BPE
tokenizer with vocab_size ~50k, suitable for multi-language code/math/text.
Usage:
tok = FractusTokenizer.build_or_load()
ids = tok.encode("def hello(): pass")
text = tok.decode(ids)
"""
import os
from typing import List, Optional
from tokenizers import Tokenizer
from tokenizers.models import BPE
from tokenizers.trainers import BpeTrainer
from tokenizers.pre_tokenizers import ByteLevel
from tokenizers.decoders import ByteLevel as ByteLevelDecoder
from tokenizers.processors import TemplateProcessing
DEFAULT_VOCAB_SIZE = 50257
DEFAULT_TOKENIZER_PATH = os.path.join(
os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))),
"data", "tokenizer", "fractus_bpe.json",
)
class FractusTokenizer:
"""Wrapper around a byte-level BPE tokenizer."""
def __init__(self, tokenizer: Tokenizer):
self.tokenizer = tokenizer
self.vocab_size = tokenizer.get_vocab_size()
@classmethod
def gpt2_compatible(cls) -> "FractusTokenizer":
"""Load a GPT-2-compatible tokenizer from HF (same vocab, same byte-level BPE).
This gives us a ready-to-use 50k vocab without training our own."""
from tokenizers import Tokenizer
tok = Tokenizer.from_pretrained("gpt2")
return cls(tok)
@classmethod
def build_or_load(cls, path: Optional[str] = None) -> "FractusTokenizer":
"""Load from path if exists, else use GPT-2 compatible."""
path = path or DEFAULT_TOKENIZER_PATH
if os.path.exists(path):
tok = Tokenizer.from_file(path)
return cls(tok)
return cls.gpt2_compatible()
def encode(self, text: str) -> List[int]:
return self.tokenizer.encode(text).ids
def encode_batch(self, texts: List[str]) -> List[List[int]]:
return [enc.ids for enc in self.tokenizer.encode_batch(texts)]
def decode(self, ids: List[int]) -> str:
return self.tokenizer.decode(ids)
def save(self, path: Optional[str] = None):
path = path or DEFAULT_TOKENIZER_PATH
os.makedirs(os.path.dirname(path), exist_ok=True)
self.tokenizer.save(path)