Model card: AnuLM-Base-400M (ckpt_multi36k.pt)

The three-language base model: pretrained from scratch on Hindi, English and Python with the multi32k tokenizer, 36,000 steps at batch 8 × 512 (about 150M tokens), on one consumer GPU. It is the checkpoint the translation and question-answering models were fine-tuned from, and the one to continue Hindi or English prose with. Full log: docs/RESULTS.md §22; the Hindi-only ladder that led to it is §1–21.

Licence: CC BY-SA 4.0. Hindi Wikipedia and Wikisource are CC BY-SA; C4 is ODC-BY; the Python slice is codeparrot-clean, de-duplicated GitHub Python with mixed licences. Not affiliated with Sarvam AI, AI4Bharat, BharatGen or the Government of India.

What it does

Continues text in the register it was given. A Hindi title followed by a blank line yields a Wikipedia- or Wikisource-style article; a narrative phrase yields narrative; a Python signature yields code. Val loss 4.441 at step 36,000 on the mixed held-out split. Everything factual in its output is invented; treat names, dates and numbers as fiction.

Data

part source licence
Hindi Hindi Wikipedia + Wikisource dumps (fetch_hindi.py, filter_prose.py) CC BY-SA
English C4 (allenai), a small slice (fetch_web.py) ODC-BY
Python codeparrot-clean (fetch_code.py) mixed, GitHub

Corpus and tokenizer build: experiments/build_multi.sh; training: experiments/run_multi.sh. Both re-fetch everything from public sources; no data is redistributed.

Architecture

The configuration the ablations in docs/RESULTS.md §12 and §16 converged on: 20 layers, hidden 1,024, GQA with 16 query / 4 key-value heads and QK-norm, RoPE θ = 1,000,000, sliding window 256 on layers 0–9, a dense SwiGLU MLP on layer 0 and 24 routed experts of 192 with top-4 routing on layers 1–19, aux-loss-free bias balancing (bias_update_rate 3e-3), no shared expert, context 512, 32,768-entry vocabulary, untied embeddings. 397.7M parameters, 173.5M active per token. An independent re-implementation of the Sarvam 30B design; docs/ARCHITECTURE.md §10 says which of Sarvam's choices held up at this scale.

Use

python sample.py --ckpt <this folder> --prompt "हिन्दी साहित्य

"
python serve.py  --ckpt <this folder>        # continue-the-text page

To fine-tune it, finetune.py --ckpt <this folder> --qa pairs.jsonl takes question/answer JSONL; docs/DEVELOPING.md describes the format.

How to load

With transformers

The modelling code travels with the weights, so trust_remote_code=True is required and there is nothing to clone:

from transformers import AutoModelForCausalLM, AutoTokenizer

model = AutoModelForCausalLM.from_pretrained("toonist/AnuLM-Base-400M", trust_remote_code=True)
tok = AutoTokenizer.from_pretrained("toonist/AnuLM-Base-400M")

ids = tok("\u092d\u093e\u0930\u0924 \u0915\u0940 \u0930\u093e\u091c\u0927\u093e\u0928\u0940", return_tensors="pt")
print(tok.decode(model.generate(**ids, max_new_tokens=60, do_sample=False)[0]))

Greedy output is identical to the AnuLM repository's own generate, cached or not, and the tokenizer here agrees with bpe.py token for token; both are pinned by tests in that repository.

Load it in float32 — which the config now asks for, so the line above is enough. Do not force dtype=torch.bfloat16: this is a mixture-of-experts model whose router keeps a per-expert bias, and rounding that bias to 16 bits changes which experts fire. The output does not get slightly worse, it collapses into repeated tokens. The big tensors are stored in bfloat16 and upcast on load; the router bias and the norms are stored in float32 for this reason. For speed, use torch.autocast over float32 weights, which is how every number in this card was measured. The model loads the code from this repo at trust_remote_code=True; pin a revision if you want that fixed.

Batches must be unpadded (one sequence at a time), and beam search is not supported.

With the AnuLM repository

Every script there takes this folder wherever it takes a .pt:

hf download toonist/AnuLM-Base-400M --local-dir AnuLM-Base-400M
python serve.py  --ckpt AnuLM-Base-400M          # web page at http://127.0.0.1:8000
python sample.py --ckpt AnuLM-Base-400M --prompt "\u092d\u093e\u0930\u0924 \u0915\u0940 \u0930\u093e\u091c\u0927\u093e\u0928\u0940"
from model import load_checkpoint, AnuLM
ck = load_checkpoint("AnuLM-Base-400M")
m = AnuLM(ck["cfg"]).eval(); m.load_state_dict(ck["model"])

Files: model.safetensors (397.7M parameters), tokenizer.multi32k.json for bpe.BPE.load, and tokenizer.json in the tokenizers format for AutoTokenizer.

Downloads last month
430
Safetensors
Model size
0.4B params
Tensor type
F32
·
BF16
·
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Model tree for toonist/AnuLM-Base-400M

Finetunes
3 models