"""
Production Cloud Tokenizer Training Runner - ViuMini-MoE-242M
=============================================================
Architecture: Byte-Level BPE (48,000 Vocabulary)
Pre-Tokenizer: Llama-3 / Indic Regex with Unicode Combining Marks (\p{M})
Data Corpus: ViuAI/viu-mini-raw-pretrain (>105B Tokens Pretraining Corpus)
Ratio: 45% Devanagari Hindi + 35% Hinglish + 20% English & Reasoning
Special Tokens: 13 tokens including , , <|user|>, <|assistant|>
Designed for high-speed execution in Google Colab (CPU or T4) / Kaggle Notebooks.
Execution time: ~4-5 minutes on cloud 10 Gbps network.
"""
import os
import sys
import time
from pathlib import Path
# Ensure dependencies are available
try:
import datasets
import tokenizers
import huggingface_hub
except ImportError:
print("[setup] Installing required cloud dependencies...")
os.system("pip install -q tokenizers datasets huggingface_hub pyarrow")
from huggingface_hub import HfApi
from tokenizers import Tokenizer, Regex
from tokenizers.models import BPE
from tokenizers.trainers import BpeTrainer
from tokenizers.pre_tokenizers import Split, ByteLevel, Sequence
from tokenizers.decoders import ByteLevel as ByteLevelDecoder
from tokenizers.normalizers import NFC, Sequence as NormSequence
from datasets import load_dataset
# Configuration
HF_DATASET_REPO = "ViuAI/viu-mini-raw-pretrain"
VOCAB_SIZE = 48000
TOTAL_TRAIN_LINES = 500000
OUTPUT_TOKENIZER_PATH = "tokenizer.json"
def _get_hf_token():
# SECURITY: token kabhi hardcode mat karo — env / Kaggle / Colab secrets se lo.
tok = os.environ.get("HF_TOKEN") or os.environ.get("HUGGING_FACE_HUB_TOKEN")
if not tok:
try:
from kaggle_secrets import UserSecretsClient
tok = UserSecretsClient().get_secret("HF_TOKEN")
except Exception:
pass
if not tok:
try:
from google.colab import userdata
tok = userdata.get("HF_TOKEN")
except Exception:
pass
return tok
HF_TOKEN = _get_hf_token()
# Llama 3 / Indic regex pattern: includes \p{M} so Devanagari vowel signs stay attached to consonants
INDIC_LLAMA3_PATTERN = (
r"(?i:'s|'t|'re|'ve|'m|'ll|'d)|"
r"[^\r\n\p{L}\p{N}]?[\p{L}\p{M}]+|"
r"\p{N}{1,3}|"
r" ?[^\s\p{L}\p{N}\p{M}]+[\r\n]*|"
r"\s*[\r\n]+|"
r"\s+(?!\S)|\s+"
)
SPECIAL_TOKENS = [
"",
"",
"",
"",
"", # v2 (2026-09-24): `` typo fixed
"<|hindi|>",
"<|english|>",
"<|hinglish|>",
"",
"",
"<|user|>",
"<|assistant|>",
"<|system|>",
]
BENCHMARK_SAMPLES = [
# Hinglish (Romanized Hindi)
"mai tumse bahut pyaar karta hu",
"bhai kal party me kya scene hai?",
"yaar ye phone ka network bahut slow hai",
"tumne khana khaya kya abhi tak?",
"<|user|> mujhe train ka status batao\n<|assistant|> Checking train schedule... aapki train time par hai.",
# Devanagari Hindi
"नमस्ते, आप कैसे हैं?",
"मुझे हिंदी में कहानी सुनाओ",
"भारतीय संविधान का अनुच्छेद 21 जीवन के अधिकार की रक्षा करता है।",
"क्षत्रिय ज्ञानी व्यक्ति त्रिशूल लेकर आया।",
"<|user|> भारत की राजधानी क्या है?\n<|assistant|> नई दिल्ली भारत की राजधानी है। नई दिल्ली।",
# English
"The quick brown fox jumps over the lazy dog.",
"Artificial intelligence is transforming real-world problem solving.",
"Can you explain quantum computing in simple terms?",
"DeepSeek-R1 utilizes reinforcement learning for reasoning verification.",
]
def build_cloud_streaming_iterator(repo_id: str, max_lines: int, token: str):
"""Stream lines from Hub. v2 mix (OPTIONAL rule): 30% Hindi, 35% Hinglish, 35% English (English-boosted; v1 was 45/35/20)."""
api = HfApi(token=token)
repo_files = api.list_repo_files(repo_id, repo_type="dataset")
hindi_files = [f for f in repo_files if (f.startswith("hindi/") or f.startswith("hindi_fixed/")) and f.endswith(".parquet")]
hinglish_files = [f for f in repo_files if f.startswith("hinglish/") and (f.endswith(".parquet") or f.endswith(".jsonl"))]
english_files = [f for f in repo_files if (f.startswith("distilled/") or f.startswith("english_fixed/")) and f.endswith(".parquet")]
print(f"[corpus] Discovered on Hub:")
print(f" - Hindi files: {len(hindi_files)}")
print(f" - Hinglish files: {len(hinglish_files)}")
print(f" - English files: {len(english_files)}")
target_hinglish = int(max_lines * 0.35)
target_hindi = int(max_lines * 0.30)
target_english = max_lines - target_hindi - target_hinglish
print(f"[targets] Hindi: {target_hindi:,} lines | Hinglish: {target_hinglish:,} lines | English: {target_english:,} lines")
def fetch_stream(file_list, target_count, category_name):
emitted = 0
for fpath in file_list:
if emitted >= target_count:
break
try:
ds = load_dataset(repo_id, data_files=fpath, split="train", streaming=True, token=token)
for row in ds:
text = (row.get("text", "") or "").strip()
if len(text) >= 15:
yield text
emitted += 1
if emitted >= target_count:
break
except Exception as exc:
continue
print(f"[stream] Finished streaming {emitted:,} lines for {category_name}")
def interleave_generator():
hi_gen = fetch_stream(hindi_files, target_hindi, "Hindi")
h_gen = fetch_stream(hinglish_files, target_hinglish, "Hinglish")
e_gen = fetch_stream(english_files, target_english, "English/Reasoning")
generators = {"hindi": hi_gen, "hinglish": h_gen, "english": e_gen}
pattern = ["hinglish"] * 7 + ["hindi"] * 6 + ["english"] * 7 # v2: 35/30/35 (v1 tha 5/3/2 = 50/30/20)
active = {"hindi": True, "hinglish": True, "english": True}
total_emitted = 0
while total_emitted < max_lines and any(active.values()):
progress = False
for cat in pattern:
if not active[cat]:
continue
try:
line = next(generators[cat])
yield line
total_emitted += 1
progress = True
if total_emitted % 50000 == 0:
print(f" [progress] Streamed {total_emitted:,} / {max_lines:,} training lines...")
if total_emitted >= max_lines:
return
except StopIteration:
active[cat] = False
if not progress:
break
return interleave_generator()
def run_evaluation(tok: Tokenizer):
"""Run comprehensive quality audit on the trained tokenizer."""
print("\n" + "=" * 70)
print("PRODUCTION TOKENIZER EVALUATION & QUALITY AUDIT")
print("=" * 70)
# 1. Special token isolation check
print("\n[Audit 1] Special Tokens Atomic Isolation Check:")
isolation_passed = True
for st in SPECIAL_TOKENS:
enc = tok.encode(st)
if len(enc.tokens) == 1 and enc.tokens[0] == st:
print(f" [PASS] {st:15} -> Token ID: {enc.ids[0]}")
else:
isolation_passed = False
print(f" [FAIL] {st:15} -> Split into {enc.tokens} (IDs: {enc.ids})")
if isolation_passed:
print(" -> All 13 special tokens successfully isolated as single atomic IDs.")
# 2. Multi-lingual fertility benchmark
print("\n[Audit 2] Multi-Lingual Fertility & Compression Benchmark:")
category_fertility = {"Hinglish": [], "Hindi": [], "English": []}
for sample in BENCHMARK_SAMPLES:
enc = tok.encode(sample)
words = sample.split()
ratio = len(enc.tokens) / max(len(words), 1)
if any(ord(c) >= 0x0900 and ord(c) <= 0x097F for c in sample):
category_fertility["Hindi"].append(ratio)
elif "mai" in sample or "bhai" in sample or "yaar" in sample or "train" in sample:
category_fertility["Hinglish"].append(ratio)
else:
category_fertility["English"].append(ratio)
print("\nFertility Evaluation Summary (Tokens per Word):")
for category, ratios in category_fertility.items():
if ratios:
avg_ratio = sum(ratios) / len(ratios)
target = 1.8 if category == "Hindi" else (1.5 if category == "Hinglish" else 1.3)
status = "EXCELLENT" if avg_ratio <= target else ("ACCEPTABLE" if avg_ratio <= target + 0.3 else "HIGH")
print(f" - {category:10}: {avg_ratio:.2f} tokens/word (Target: <= {target:.1f}) [{status}]")
# 3. Round-trip lossless decoding check
print("\n[Audit 3] Round-Trip Lossless Decoding Check:")
fidelity_passed = True
for sample in BENCHMARK_SAMPLES:
enc = tok.encode(sample)
decoded = tok.decode(enc.ids, skip_special_tokens=False)
if decoded.strip() != sample.strip():
fidelity_passed = False
print(f" [FAIL] Round-trip mismatch:\n Expected: {sample}\n Actual: {decoded}")
if fidelity_passed:
print(" [PASS] 100% Round-trip lossless fidelity verified across all test samples.")
print("=" * 70 + "\n")
return isolation_passed and fidelity_passed
def main():
start_time = time.time()
print("=" * 70)
print("ViuMini-MoE-242M: Production Tokenizer Training (Indic-Optimized)")
print(f"Target Vocabulary: {VOCAB_SIZE:,} | Training Samples: {TOTAL_TRAIN_LINES:,}")
print(f"Corpus Source: {HF_DATASET_REPO}")
print("=" * 70)
# Initialize Tokenizer Architecture with Indic-optimized Llama-3 Split Regex
tok = Tokenizer(BPE(unk_token=""))
tok.normalizer = NormSequence([NFC()])
tok.pre_tokenizer = Sequence([
Split(pattern=Regex(INDIC_LLAMA3_PATTERN), behavior="isolated"),
ByteLevel(add_prefix_space=False, use_regex=False),
])
tok.decoder = ByteLevelDecoder()
trainer = BpeTrainer(
vocab_size=VOCAB_SIZE,
min_frequency=2,
show_progress=True,
special_tokens=SPECIAL_TOKENS,
initial_alphabet=ByteLevel.alphabet(),
)
# Build streaming training iterator
print("[train] Preparing balanced multi-lingual streaming iterator...")
training_iterator = build_cloud_streaming_iterator(
repo_id=HF_DATASET_REPO,
max_lines=TOTAL_TRAIN_LINES,
token=HF_TOKEN,
)
# Train Byte-Level BPE
print(f"[train] Commencing Rust-accelerated BPE training on {TOTAL_TRAIN_LINES:,} samples...")
tok.train_from_iterator(training_iterator, trainer=trainer, length=TOTAL_TRAIN_LINES)
# Save trained tokenizer locally
tok.save(OUTPUT_TOKENIZER_PATH)
file_size_mb = os.path.getsize(OUTPUT_TOKENIZER_PATH) / (1024 * 1024)
print(f"[train] Tokenizer saved locally: {OUTPUT_TOKENIZER_PATH} ({file_size_mb:.2f} MB)")
# Execute Evaluation Suite
audit_success = run_evaluation(tok)
# Upload to Hugging Face Hub
if HF_TOKEN:
print(f"[hub] Uploading production tokenizer to {HF_DATASET_REPO}...")
api = HfApi(token=HF_TOKEN)
api.upload_file(
path_or_fileobj=OUTPUT_TOKENIZER_PATH,
path_in_repo="tokenizer/tokenizer.json",
repo_id=HF_DATASET_REPO,
repo_type="dataset",
)
print(f"[hub] Successfully uploaded tokenizer/tokenizer.json to {HF_DATASET_REPO}!")
elapsed = time.time() - start_time
print(f"[complete] All steps finished successfully in {elapsed / 60:.2f} minutes.")
if __name__ == "__main__":
main()