Views
No views yet
mgpt2) that achieves 54% better compression than
tiktoken-gpt2 and 38% better than tiktoken-cl100k on the same corpus.1import sys, torch
2import torch.nn.functional as F
3from huggingface_hub import snapshot_download
4
5local = snapshot_download("ace-1/mgpt2-pretrain")
6sys.path.insert(0, local)
7from model import GPT
8from tokenizer.regex_tokenizer import RegexTokenizer
9
10# Load model
11ckpt = torch.load(f"{local}/pytorch_model.pt", weights_only=False, map_location="cpu")
12model = GPT(ckpt["config"])
13model.load_state_dict(ckpt["model"])
14model.eval()
15
16# Load tokenizer
17enc = RegexTokenizer()
18enc.load(f"{local}/tokenizer/artifacts/mgpt2.model")
19
20# Generate
21prompt = "ಕರ್ನಾಟಕದ ರಾಜಧಾನಿ" # "Capital of Karnataka"
22ids = enc.encode(prompt)
23x = torch.tensor(ids, dtype=torch.long).unsqueeze(0)
24with torch.no_grad():
25 for _ in range(80):
26 logits, _ = model(x[:, -1024:])
27 probs = F.softmax(logits[:, -1, :] / 0.8, dim=-1)
28 next_id = torch.multinomial(probs, num_samples=1)
29 if next_id.item() == 50256: break
30 x = torch.cat([x, next_id], dim=1)
31print(enc.decode(x[0].tolist()))| Property | Value |
|---|---|
| Architecture | GPT-2 (12 layers / 12 heads / 768d) |
| Parameters | ~124M |
| Vocabulary | 50,257 (mgpt2 BPE) + padded to 50,304 |
| Context length | 1,024 tokens |
| Training stage | Pretrained |
| Git commit | 8aa064aaf1da |
| Parameter | Value |
|---|---|
seed | 1337 |
block_size | 1024 |
total_batch_size | 524288 |
micro_batch_size | 64 |
max_steps | 27538 |
warmup_steps | 715 |
max_lr | 0.003 |
min_lr_ratio | 0.1 |
weight_decay | 0.1 |
eval_interval | 250 |
| Metric | Value | Notes |
|---|---|---|
| Val loss | 2.5003 | Cross-entropy on held-out corpus |
| HellaSwag acc | 0.2869 | 10,042 examples, own tokenizer |
| BPB overall | 0.809 | bits-per-byte, normalised for tokenizer density |
| BPB vs baseline | −0.071 | mgpt2 better on every language bucket |
Raw perplexity (12.4) is higher than the GPT-2-tokenized baseline (3.6) — this comparison is invalid across tokenizers. Bits-per-byte (BPB) is the fair metric and reverses the result: mgpt2 wins on every bucket. HellaSwag z=1.59 (directional, not significant at 95% CI); BPB is the primary metric.
| Split | Source | Weight |
|---|---|---|
| English | FineWeb | 55% |
| Hindi (Devanagari) | AI4Bharat Sangraha verified/hin | 18% |
| Hindi (Latin translit) | AI4Bharat Sangraha synthetic/hin_Latn | 7% |
| Kannada (script) | AI4Bharat Sangraha verified/kan | 13% |
| Kannada (Latin translit) | AI4Bharat Sangraha synthetic/kan_Latn | 7% |
mgpt2), trained on the same corpus mixture.
Same vocabulary size as tiktoken-gpt2 (50,257 tokens), but with Indic-aware merge priorities:| Bucket | tiktoken-gpt2 | mgpt2 | Δ |
|---|---|---|---|
| Overall | 480 tok/kB | 223 tok/kB | −54% |
| Devanagari | 592 tok/kB | 215 tok/kB | −64% |
| Kannada | 981 tok/kB | 213 tok/kB | −78% |
| Latin | 257 tok/kB | 230 tok/kB | −10% |
1@misc{mgpt2,
2 title = {mgpt2: Multilingual GPT-2 with custom Indic tokenizer},
3 year = {2026},
4 note = {Pretrain → SFT → DPO pipeline for English/Hindi/Kannada},
5 url = {https://huggingface.co/ace-1/mgpt2-pretrain}
6}