KATHE 2026 — English to Kashmiri (eng_Latn → kas_Arab)
Fine-tune of ai4bharat/indictrans2-en-indic-1B, 1.1B parameters. Scored
13.90 on the KATHE 2026 public leaderboard, whose metric is
sqrt(BLEU × chrF++).
Inference scripts, the full write-up, and the list of what did not work: https://github.com/maliktafheem/kathe-2026-en-kas
Usage
from transformers import AutoModelForSeq2SeqLM, AutoTokenizer
from IndicTransToolkit import IndicProcessor
import torch
MODEL = "maliktafheem/kathe-2026-en-kas-arab-1b"
tokenizer = AutoTokenizer.from_pretrained(MODEL, trust_remote_code=True)
model = AutoModelForSeq2SeqLM.from_pretrained(
MODEL, trust_remote_code=True, attn_implementation="eager", low_cpu_mem_usage=False
)
# Generation reads config.vocab_size, which here must be the target vocabulary.
model.config.vocab_size = model.config.decoder_vocab_size
model.eval()
processor = IndicProcessor(inference=True)
sentences = ["The sun rises in the east."]
batch = processor.preprocess_batch(sentences, src_lang="eng_Latn", tgt_lang="kas_Arab")
inputs = tokenizer(batch, padding="longest", truncation=True, return_tensors="pt")
with torch.inference_mode():
generated = model.generate(**inputs, num_beams=5, max_length=48, length_penalty=1.0)
with tokenizer.as_target_tokenizer():
decoded = tokenizer.batch_decode(generated, skip_special_tokens=True)
print(processor.postprocess_batch(decoded, lang="kas_Arab"))
transformers must stay on 4.51.x. Version 5 removed
tokenizer.as_target_tokenizer(), which this architecture needs to decode
output ids in target-vocabulary space. Install with:
pip install "transformers==4.51.3" IndicTransToolkit==1.1.1 torch sentencepiece
The model and tokenizer code are included in this repository, so nothing is
fetched from another repo at load time. trust_remote_code=True is still
required because the architecture is not built into transformers.
Decoding settings
| Setting | Value |
|---|---|
| Beams | 5 |
max_length | 48 |
| Length penalty | 1.0 |
Each was swept on 1,500 held-out rows and these values won.
How it was trained
The score comes almost entirely from one diagnosis.
IndicProcessor.preprocess_batch(..., is_target=True) deletes kasra (U+0650),
damma (U+064F) and fatha (U+064E) from Kashmiri targets, 100% of them. Indic NLP
inherits this from Urdu, where the marks are optional. In Kashmiri they are
phonemic, and the competition's own scorer preserves them.
26.4% of Kashmiri words carry at least one. A translator that is otherwise
perfect but omits only these marks scores 67.08 composite, so every model
trained through that preprocessing sits under a hard 0.67x ceiling. Ours did,
for nine training runs.
Training targets were normalized with KashmiriNormalizer instead, and the
training pool was rebuilt from the two consistently marked sources so that only
25.0% of targets were unmarked, against 21.8% for the references.
| Setting | Value |
|---|---|
| Data | 111,053 rows, BPCC and OPUS wikimedia |
| Optimizer | Adafactor |
| Learning rate | 3e-5, 200 warmup steps |
| Steps | 6,940, 4 epochs |
| Batch | 8 × 8 accumulation, effective 64 |
| Label smoothing | 0.1 |
| Precision | fp16 |
Preserving the diacritics was worth +4.06, taking 9.69 to 13.75.
These weights are the element-wise mean of two checkpoints, steps 6,500 and
6,940 of that run. The average beat both of its components, worth a further
+0.15. A four-way average was worse (13.66).
Limits
Diacritic accuracy is the main remaining gap. Of the words that match the
reference once marks are stripped, 85.4% carry exactly the right marks. Copying
the reference marks onto those words would raise the composite by about 1.21x.
The model was trained and evaluated on short teaching-register sentences, a median of 7 source words. Behaviour on long or technical prose is untested.
Licence and attribution
A derivative of ai4bharat/indictrans2-en-indic-1B; see that model card for its
licence and intended use. Training used English–Kashmiri pairs from BPCC and
OPUS wikimedia. No competition data is redistributed here.