Views
No views yet
naklitechie/indictrans2-en-indic-dist-200M
(itself a verbatim mirror of ai4bharat/indictrans2-en-indic-dist-200M,
AI4Bharat's distilled 200M en→indic model).naklitechie/indictrans2-en-indic-dist-200M on greedy decoding.| Test | Pass rate |
|---|---|
| 528 fixtures × greedy decode, token-exact match vs PyTorch | 528/528 (100%) |
| 528 fixtures × greedy decode, text-exact match vs PyTorch | 528/528 (100%) |
num_beams=1, do_sample=False, max_new_tokens=128.fp32 ONNX bundle → encoder.run + decoder.run loop (onnxruntime CPU) → output token IDs
‖ exact-match
PyTorch original → model.generate(num_beams=1) → output token IDsscripts/04_parity_test.py
in the source repo. Full report: parity_report.json in this repo.See the int8-quantized variant atnaklitechie/indictrans2-en-indic-dist-200M-ONNX-int8for a 4× smaller bundle (~360 MB) at the cost of ~20% sentences drifting in word choice. Use this fp32 repo for any production / research use.
| File | Purpose | Size |
|---|---|---|
encoder_model.onnx + .data | encoder graph (fp32, weights externalised) | 280 MB |
decoder_model.onnx + .data | decoder first-step (no past KV in, full KV out) | 530 MB |
decoder_with_past_model.onnx + .data | decoder steps 2..N (past KV in/out) | 495 MB |
tokenizer_src.json | encoder-side fast tokenizer (BPE + lang-tag AddedTokens + NFKC) | 3.2 MB |
tokenizer_tgt.json | decoder-side fast tokenizer | 17 MB |
tokenizer_meta.json | dict-size cutoffs for the extended-vocab → <unk> remap | <1 KB |
config.json, generation_config.json | model config | — |
dict.SRC.json, dict.TGT.json | raw vocabs (~3.7 MB combined) | — |
model.SRC, model.TGT | raw SPM models for slow-tokenizer fallback | ~3.8 MB |
tokenization_indictrans.py + tokenizer_config.json + special_tokens_map.json | HF AutoTokenizer.from_pretrained compat | — |
1import json, numpy as np, onnxruntime as ort
2from tokenizers import Tokenizer
3from huggingface_hub import snapshot_download
4
5snap = snapshot_download(repo_id="naklitechie/indictrans2-en-indic-dist-200M-ONNX")
6
7src = Tokenizer.from_file(f"{snap}/tokenizer_src.json")
8tgt = Tokenizer.from_file(f"{snap}/tokenizer_tgt.json")
9meta = json.load(open(f"{snap}/tokenizer_meta.json"))
10
11enc = ort.InferenceSession(f"{snap}/encoder_model.onnx")
12dec = ort.InferenceSession(f"{snap}/decoder_model.onnx")
13decp = ort.InferenceSession(f"{snap}/decoder_with_past_model.onnx")
14
15# Tokenize "Who will win the election?" en→hi
16text = f"eng_Latn hin_Deva Who will win the election?"
17e = src.encode(text)
18input_ids = np.array([[i if i < meta["src_dict_size"] else meta["unk_id"] for i in e.ids]], dtype=np.int64)
19attn_mask = np.array([e.attention_mask], dtype=np.int64)
20
21# Encoder
22enc_h = enc.run(["last_hidden_state"], {"input_ids": input_ids, "attention_mask": attn_mask})[0]
23
24# Greedy decode (see scripts/04_parity_test.py in the source repo for the full loop)
25# ...04_parity_test.py.tokenizer_src.json has 33,888
tokens (32,322 canonical + 1,566 SPM-only chars BPE needs as merge halves).
Any output ID >= tokenizer_meta.src_dict_size (= 32322) must be replaced
with the <unk> ID (3) before feeding to ONNX — the model's encoder
embedding only goes up to 32,322. Same applies to tokenizer_tgt.json
with tgt_dict_size = 122,672. The slow HF tokenizer does this implicitly
via encoder.get(token, unk_id).IndicProcessor.postprocess_batch handles the
script conversion. A JS port lives in the source repo at
browser-prep/js/indic_processor.js.01_export_onnx_manual.py → 02_build_tokenizer.py →
03_capture_truth.py → 04_parity_test.py pipeline at
prashnam/prashnam-voice
(browser-prep/scripts/).LICENSE and NOTICE.md.