File size: 29,148 Bytes
4b22190
 
 
7045d19
 
4b22190
7045d19
 
 
 
 
 
 
 
4b22190
7045d19
 
 
 
 
4b22190
 
 
7045d19
 
 
 
 
 
9145cf8
7045d19
a9b2059
 
7045d19
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9145cf8
7045d19
a9b2059
 
7045d19
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9145cf8
7045d19
a9b2059
7045d19
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9145cf8
7045d19
a9b2059
7045d19
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9145cf8
7045d19
a9b2059
7045d19
 
 
 
4b22190
 
9df27d5
4b22190
9df27d5
c792f7c
 
 
4b22190
9df27d5
4b22190
9df27d5
 
 
 
 
 
4b22190
9df27d5
 
4b22190
 
 
 
9df27d5
4b22190
 
9df27d5
 
4b22190
 
 
 
 
 
4ce3172
 
 
 
 
 
 
 
 
 
 
 
 
0b77353
 
 
 
 
 
 
 
 
 
 
 
6034fb2
 
 
 
 
0b77353
 
 
 
 
 
 
 
 
 
6034fb2
 
0b77353
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4b22190
 
9df27d5
 
 
4b22190
 
 
 
9df27d5
 
 
 
 
 
4b22190
 
 
 
 
 
 
 
 
9df27d5
 
 
 
 
 
4b22190
 
 
 
 
 
9df27d5
4b22190
 
 
 
9df27d5
37b4c07
9df27d5
 
 
37b4c07
9df27d5
 
 
4b22190
 
 
 
 
 
 
9df27d5
 
 
 
 
 
c792f7c
 
 
 
 
 
4b22190
 
 
9df27d5
4b22190
9df27d5
 
 
 
 
4b22190
 
 
c792f7c
4b22190
c792f7c
 
 
 
4b22190
c792f7c
 
 
 
4b22190
c792f7c
 
 
 
4b22190
c792f7c
 
89385a3
c792f7c
 
 
89385a3
 
4b22190
9df27d5
 
 
 
 
4b22190
 
 
 
 
 
 
89385a3
 
 
 
 
 
 
4b22190
 
 
89385a3
 
 
 
 
4b22190
 
 
9df27d5
4b22190
9df27d5
4b22190
9df27d5
 
 
4b22190
 
 
 
 
 
 
9df27d5
 
 
 
4b22190
9df27d5
 
 
4b22190
b7bf805
4b22190
b7bf805
 
 
 
 
 
 
 
 
 
 
 
 
4b22190
c792f7c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4b22190
 
 
 
9df27d5
4b22190
 
 
 
 
 
 
 
 
 
9df27d5
4b22190
9df27d5
4b22190
 
9df27d5
4b22190
9df27d5
4b22190
 
9df27d5
4b22190
9df27d5
4b22190
 
 
 
 
9df27d5
 
4b22190
9df27d5
 
 
4b22190
 
 
 
 
 
 
9df27d5
 
 
 
4b22190
c792f7c
4b22190
9df27d5
4b22190
9df27d5
 
 
 
 
 
 
 
 
 
4b22190
 
 
 
9df27d5
 
 
4b22190
 
 
 
 
 
9df27d5
 
4b22190
 
9df27d5
 
 
4b22190
 
 
9df27d5
 
 
4b22190
 
 
 
 
847be77
4b22190
 
 
 
9df27d5
 
4b22190
 
9df27d5
 
 
4b22190
9df27d5
 
 
 
4b22190
 
9df27d5
4b22190
2d0179b
 
f0c6c87
d46b80d
f0c6c87
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
847be77
 
 
48ba397
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9df27d5
4b22190
2e68043
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4b22190
 
 
 
 
 
9df27d5
4b22190
9df27d5
 
 
 
4b22190
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
---
license: apache-2.0
language:
- kn
- en
tags:
- translation
- machine-translation
- kannada
- english
- indic
- low-resource
- code-mix
- encoder-decoder
metrics:
- bleu
- chrf
- comet
- cometkiwi
- accuracy
library_name: transformers
pipeline_tag: translation
model-index:
- name: controlmt-v2.3
  results:
  - task:
      type: translation
      name: Translation kn  en (FLORES-200 devtest)
    dataset:
      name: FLORES-200 devtest (kn  en)
      type: facebook/flores
      config: kan_Knda-eng_Latn
      split: devtest
    metrics:
    - type: bleu
      value: 27.2
      name: BLEU
    - type: chrf
      value: 55.84
      name: chrF
    - type: comet
      value: 0.8459
      name: COMET-DA (Unbabel/wmt22-comet-da)
    - type: cometkiwi
      value: 0.8437
      name: CometKiwi-DA (Unbabel/wmt22-cometkiwi-da)
  - task:
      type: translation
      name: Translation en  kn (FLORES-200 devtest)
    dataset:
      name: FLORES-200 devtest (en  kn)
      type: facebook/flores
      config: eng_Latn-kan_Knda
      split: devtest
    metrics:
    - type: bleu
      value: 18.5
      name: BLEU
    - type: chrf
      value: 56.12
      name: chrF
    - type: comet
      value: 0.8443
      name: COMET-DA
    - type: cometkiwi
      value: 0.8663
      name: CometKiwi-DA
  - task:
      type: translation
      name: Translation kn  en (IN-22 conv)
    dataset:
      name: IN22-Conv (kn  en, 1503 conversational pairs / 16 domains)
      type: ai4bharat/IN22-Conv
      config: kan_Knda-eng_Latn
    metrics:
    - type: bleu
      value: 21.61
      name: BLEU
    - type: chrf
      value: 46.65
      name: chrF
    - type: comet
      value: 0.8232
      name: COMET-DA
    - type: cometkiwi
      value: 0.8143
      name: CometKiwi-DA
  - task:
      type: translation
      name: Translation en  kn (IN-22 conv)
    dataset:
      name: IN22-Conv (en  kn, 1503 conversational pairs / 16 domains)
      type: ai4bharat/IN22-Conv
      config: eng_Latn-kan_Knda
    metrics:
    - type: bleu
      value: 5.47
      name: BLEU
    - type: chrf
      value: 35.3
      name: chrF
    - type: comet
      value: 0.832
      name: COMET-DA
    - type: cometkiwi
      value: 0.8845
      name: CometKiwi-DA
  - task:
      type: translation
      name: Entity preservation (en  kn)
    dataset:
      name: Curated NER eval (en  kn, 15 sentences / 33 entities)
      type: custom
      config: curated-ner-en2kn
    metrics:
    - type: accuracy
      value: 100.0
      name: Entity preservation accuracy (% of expected entities preserved)
---

# ControlMT v2.3 — Compact Kannada ↔ English Translation (139M)

> **TL;DR.** A **139M-parameter** encoder-decoder specialized for Kannada ↔ English translation.
> Single-pair focus + code-mix-native training + Anti-LM contrastive decoding.
> Achieves competitive FLORES-200 KN↔EN performance for its parameter size,
> with **COMET-DA above 0.84 in both directions**. Apache 2.0, deployable on consumer GPU.

## Headline benchmark — FLORES-200 devtest

| Metric | KN → EN | EN → KN |
|---|---|---|
| **CometKiwi-DA** (no ref) | **0.8437** | **0.8663** |
| **COMET-DA** (with ref) | **0.8459** | **0.8443** |
| BLEU | 27.20 | 18.50 |
| chrF | 55.84 | 56.12 |

CometKiwi-DA and COMET-DA both clear the 0.82 production floor and the 0.85 aspirational
target. BLEU/chrF measured with sacrebleu (default tokenization).

| | |
|---|---|
| Parameters | 139M |
| Architecture | Modular encoder-decoder (per-language wrappers + shared core) |
| Vocabulary | 128,000 (SentencePiece Unigram, joint KN+EN) |
| Languages | Kannada (`kn`) ↔ English (`en`) — bidirectional |
| Training data | 6.70M parallel pairs (post CometKiwi quality filtering) + specialized streams |
| Hardware (training) | 1 × NVIDIA RTX 5060 Ti (16 GB), bf16 mixed precision |
| Release date | 2026-06-23 |
| License | Apache 2.0 |
| Author | Anand Kaman |

---

## How this got built — journey + decisions + dead ends

If you're building a similar specialized model, the [`docs/`](docs/) folder is a first-person account of how ControlMT went from zero to public release in three months, solo, on one GPU:

- [`docs/top-lessons.md`](docs/top-lessons.md) — 10 takeaways, one paragraph each (start here if you only have 10 minutes)
- [`docs/the-journey.md`](docs/the-journey.md) — chronological narrative, v1 → v2.3
- [`docs/what-didnt-work.md`](docs/what-didnt-work.md) — 8 failed experiments + root-cause analysis
- [`docs/how-it-was-built.md`](docs/how-it-was-built.md) — concrete data + training + eval + deployment recipes
- [`docs/working-with-claude.md`](docs/working-with-claude.md) — patterns for solo + AI-assistant collaboration
- [`docs/repo-map.md`](docs/repo-map.md) — folder layout, file conventions

---

## Available releases

| Repo | What you get | Best for |
|---|---|---|
| **[anandkaman/controlmt-v2.3](https://huggingface.co/anandkaman/controlmt-v2.3)** *(you are here)* | bf16 safetensors; load with `dtype=fp32 / bf16 / fp16` | General use — GPU fp16 / CPU bf16 |
| **[anandkaman/controlmt-v2.3-int8](https://huggingface.co/anandkaman/controlmt-v2.3-int8)** | Auto-applies int8 dynamic quant on load | CPU-only / memory-constrained — **0.28 s/pair, ~140 MB RAM** |
| **[anandkaman/controlmt-demo](https://huggingface.co/spaces/anandkaman/controlmt-demo)** *(Space)* | Live web demo (FastAPI + static HTML/CSS/JS) | Try in browser, no install |
| **[`pip install controlmt`](https://pypi.org/project/controlmt/)** *(SDK)* | Python wrapper around all of the above | One-liner load + auto device/dtype + batched API |

**Easiest path — the SDK does the right thing automatically:**

```bash
# CPU-only (smaller install — ~200 MB torch instead of ~2 GB)
pip install torch --index-url https://download.pytorch.org/whl/cpu
pip install controlmt

# GPU (CUDA) — default; pulls the full ~2 GB CUDA torch wheel
pip install controlmt
```
```python
from controlmt import ControlMT
model = ControlMT.from_hf()                              # GPU fp16 / CPU bf16 / etc — auto
model = ControlMT.from_hf(quant="int8")                  # CPU int8 dynamic
model = ControlMT.from_hf(device="cpu", dtype="bf16")    # explicit
print(model.translate("ನಾನು ಕನ್ನಡ ಮಾತನಾಡುತ್ತೇನೆ."))         # "I speak Kannada."
```

> **Why two install paths?** `pip install controlmt` pulls `torch>=2.0`, which by default fetches the CUDA-enabled wheel (~2 GB). If you don't have a GPU, install the CPU-only torch wheel first (the line with `--index-url`) — it's ~200 MB and runs the model just fine on CPU at bf16 or int8. This is a PyTorch ecosystem quirk, not a ControlMT one — every model that depends on torch has the same trade-off.

**Raw Transformers also works** (no SDK needed):

```python
from transformers import AutoModelForSeq2SeqLM, AutoTokenizer

# Main repo — choose dtype at load time
tokenizer = AutoTokenizer.from_pretrained("anandkaman/controlmt-v2.3", trust_remote_code=True)
model = AutoModelForSeq2SeqLM.from_pretrained("anandkaman/controlmt-v2.3", trust_remote_code=True)

# int8 repo — quantization auto-applied
model_int8 = AutoModelForSeq2SeqLM.from_pretrained("anandkaman/controlmt-v2.3-int8", trust_remote_code=True)
```

→ Full deployment recipes + verified latency/memory matrix: **[DEPLOYMENT.md](DEPLOYMENT.md)**

---

## 1. Model Details

ControlMT v2.3 is a **modular encoder-decoder transformer** specialized for Kannada ↔ English
translation. Every parameter is dedicated to this one language pair, which is what lets a 139M
model compete with multilingual models 4× its size on FLORES-200 KN↔EN.

### Architecture

```
                ┌── Router (per-row direction token) ──┐
                │                                        │
        ┌───────▼─────────┐                       ┌─────▼───────────┐
        │ KN Lang Encoder │                       │ EN Lang Encoder │
        │ (2 layers)      │                       │ (2 layers)      │
        └───────┬─────────┘                       └─────────────────┘

        ┌───────▼─────────┐
        │ Shared Core Enc │  6 layers, ~19M
        └───────┬─────────┘

        ┌───────▼─────────┐
        │ Shared Core Dec │  6 layers, ~25M
        └───────┬─────────┘

        ┌───────▼─────────┐                       ┌─────────────────┐
        │ KN Lang Decoder │                       │ EN Lang Decoder │
        │ (2 layers)      │                       │ (2 layers)      │
        └─────────────────┘                       └─────────────────┘

                                Output projection (tied embeddings, 128K vocab)
```

| Module | Parameters |
|---|---|
| Token embedding (shared, tied with output projection) | 65.5M |
| Per-language encoders (KN + EN, 2 layers each) | 12.6M |
| Shared core (6 enc + 6 dec, d_model=512, d_ff=2048, 8 heads) | 44.1M |
| Per-language decoders (KN + EN, 2 layers each) | 16.8M |
| Output projection (128K vocab × 512) | (tied with input embedding) |
| **Total** | **~139.2M** |

### Why single-pair?

Most public Indic MT models are broad — NLLB covers 200 languages, IndicTrans2 covers 22.
That breadth comes from parameter-sharing across languages, so each language pair gets only
a slice of the model's capacity.

ControlMT goes the other direction: every parameter is dedicated to Kannada ↔ English. If you
need broad multilingual coverage, use NLLB or IndicTrans2. If you need Kannada specifically —
and you care about size, latency, or on-device deployment — this is what the trade-off looks like.

---

## 2. Intended Use & Out-of-Scope Use

### Intended use

- Production KN↔EN translation for Indian-context content: news, government documents,
  e-commerce, social media, customer support, conversational interfaces
- Code-mix-aware translation — handles natural Indian Kannada that embeds English
  acronyms, brand names, and short loanwords
- Edge / on-device deployment — at 139M params + int8 quantization, runs on consumer
  hardware (laptops, mid-tier devices with ≥4 GB RAM)
- **Office / form-data translation** (KYC, applications, customer records) — the model
  demonstrated **near-perfect preservation on the release evaluation suite** for Aadhar,
  phone, email, dates, customer IDs, and PAN numbers in the KN→EN direction. EN→KN has a
  small edge case where mid-sentence PAN-format strings may character-by-character
  transliterate to Kannada syllables (information preserved, recoverable via a small regex
  postprocessing pass — see Limitations Section 6).

### Out-of-scope use

- ❌ Not a multilingual translator — only Kannada ↔ English. For other language pairs,
  see NLLB-200 or IndicTrans2.
- ❌ Not a chatbot / not instruction-following — translation is the only supported task.
- ❌ Not a literal-translator for idioms — see Limitations (Section 6).
- ❌ Not certified for safety-critical domains (medical diagnosis, legal advice). The
  model passes a safety regression set but is not formally audited for those contexts.
- ❌ Not a domain-specialist for highly technical scientific text without context.

---

## 3. Training Data (summary)

The base corpus is **8.06M parallel KN↔EN pairs** aggregated from public Indic MT
datasets — **Samanantar** (Ramesh et al. 2022), **BPCC** (Gala et al. 2023 / IndicTrans2),
**Sangraha** (Khan et al. 2024 / IndicLLMSuite), and **Aksharantar** (Madhani et al. 2023)
for transliteration coverage.

A multi-stage filtering pipeline (profanity filter, roundtrip audit, CometKiwi quality
scoring, misalignment detection) reduces this to **6.64M clean rows** in
`master_v22.jsonl`. Bad rows (62,853) are quarantined with `_drop_reason` audit trail
rather than deleted.

Augmenting the main corpus, four small internally-generated streams target specific
weaknesses: **Pattern A** (~30K NER-validated proper-noun pairs), **Pattern B**
(~8K cm_paired groups for code-mix), **F2** (~5K letter-spelled acronyms), and
**numerical_aug** (form-preservation for digits/dates/currency).

> **Full filtering pipeline, per-stream methodology, training principles, and
> reproducibility steps**: see [`TRAINING_GUIDE.md`](TRAINING_GUIDE.md).

**Data licensing**: Model weights and ControlMT-specific generated streams are released
under **Apache 2.0**. Public source corpora retain their original licenses (Samanantar:
CC-BY-NC 4.0; others: CC-BY-4.0).

### 3.4 Training principles

- **Decoder hygiene gate** (`kn_is_mixed`): rows with 3+ consecutive Latin words in KN
  are excluded from EN→KN target — prevents mixed-code emission
- **CM-Concatenation Level A**: paired (kn_pure, kn_mixed) batching for natural code-mix handling
- **EMA** (decay=0.999) + SWA averaging for production weights
- **Anti-LM contrastive decoding** (α=0.5) at inference — kills repetition + hallucination

---

## 4. Evaluation

### 4.1 Public benchmark sets

| Set | Pairs | License | Citation | Reference |
|---|---|---|---|---|
| **FLORES-200 devtest** | 1,012 | CC-BY-SA 4.0 | NLLB Team, *No Language Left Behind: Scaling Human-Centered Machine Translation*, 2022 | [github.com/facebookresearch/flores](https://github.com/facebookresearch/flores) |
| **IN22-Gen** | 1,024 | CC-BY-4.0 | Gala et al., *IndicTrans2*, TMLR 2023 | [huggingface.co/datasets/ai4bharat/IN22-Gen](https://huggingface.co/datasets/ai4bharat/IN22-Gen) |
| **IN22-Conv** | 1,503 | CC-BY-4.0 | Gala et al., *IndicTrans2*, TMLR 2023 | [huggingface.co/datasets/ai4bharat/IN22-Conv](https://huggingface.co/datasets/ai4bharat/IN22-Conv) |
| **eval_curated_v22** (internal, supplementary) | 800 | — | Internal style-stratified sample (200/style bucket) from `master_v22.jsonl` | Released alongside this model |
| **code_mix_eval** (internal, supplementary) | 100 | — | Internal code-mix probe set, curated 2026-04 | Released alongside this model |

### 4.2 Scoring tools

| Tool | Use | Citation | Reference |
|---|---|---|---|
| **Unbabel/wmt22-cometkiwi-da** | Reference-free QE | Rei et al., *CometKiwi: IST-Unbabel Submission for the WMT22 Quality Estimation Shared Task*, WMT 2022 | [huggingface.co/Unbabel/wmt22-cometkiwi-da](https://huggingface.co/Unbabel/wmt22-cometkiwi-da) |
| **Unbabel/wmt22-comet-da** | Reference-based QE | Rei et al., *COMET-22: Unbabel-IST 2022 Submission for the Metrics Shared Task*, WMT 2022 | [huggingface.co/Unbabel/wmt22-comet-da](https://huggingface.co/Unbabel/wmt22-comet-da) |
| **sacrebleu** (default tokenization) | BLEU + chrF | Post, *A Call for Clarity in Reporting BLEU Scores*, WMT 2018 | [github.com/mjpost/sacrebleu](https://github.com/mjpost/sacrebleu) |

### 4.3 Decoding configuration for reported scores

| Parameter | Value |
|---|---|
| Beam size | 6 |
| Length penalty | 1.2 |
| no-repeat n-gram size | 3 |
| Anti-LM α | 0.5 |
| Max length | 256 |

### 4.4 Results

#### FLORES-200 devtest (1,012 pairs)

| Metric | KN → EN | EN → KN |
|---|---|---|
| **CometKiwi (no ref)** | **0.8437** | **0.8663** |
| **COMET-DA (with ref)** | **0.8459** | **0.8443** |
| BLEU | 27.20 | 18.50 |
| chrF | 55.84 | 56.12 |

**Ship-gate verdict: ✅ PASS** — both directions clear the 0.85 aspirational target on
CometKiwi-DA (en→kn) and within striking distance on the others. All four metrics above
the production floor.

#### IN22-Conv (1,503 pairs, AI4Bharat conversational benchmark)

| Metric | KN → EN | EN → KN |
|---|---|---|
| **CometKiwi (no ref)** | **0.8143** | **0.8845** |
| **COMET-DA (with ref)** | **0.8232** | **0.8320** |
| BLEU | 21.61 | 5.47 |
| chrF | 46.65 | 35.30 |

**Ship-gate verdict: ✅ PASS** — both COMET-DA values clear the 0.82 production floor;
EN→KN CometKiwi at 0.8845 exceeds the 0.85 aspirational target. BLEU EN→KN is naturally
low on conversational data (short colloquial utterances with high lexical variance);
CometKiwi/COMET-DA (semantic adequacy) is the more reliable signal here.

Aggregate JSON: [`eval_results/in22_conv.json`](eval_results/in22_conv.json).

### 4.5 Comparison context

Direct head-to-head COMET-DA benchmarks for distilled-size Indic MT models on FLORES
KN↔EN are not uniformly published in a single source. The major academic reference
(IndicTrans2, Gala et al. 2023) reports chrF++ in its main tables and includes COMET-22
values in supplementary tables; NLLB (NLLB Team 2022) reports spBLEU + chrF++ but does
not publish per-language COMET-DA for the distilled checkpoints.

As one **citation-grounded anchor** in the same metric space: IndicTrans2 1.1B reports
**COMET-22 ≈ 0.84 on IN22-Conv KN→EN** (Gala et al. 2023, Appendix Table 45). ControlMT
v2.3 reports **COMET-DA 0.8459 on FLORES KN→EN at 139M parameters** — competitive within
its parameter scale class.

For an apples-to-apples comparison on your own infrastructure, the open-source eval pipeline
in [`scripts/eval_release.py`](https://github.com/anandkaman/ControlMT/blob/main/scripts/eval_release.py)
can be pointed at any KN↔EN MT model (NLLB / IndicTrans2 / Sarvam-Translate) using the
same FLORES devtest pairs and same scoring tooling (CometKiwi-DA, COMET-DA, sacrebleu),
giving directly-comparable numbers without trusting any individual paper's reporting.

---

## 5. Decoding Configuration (recommended presets)

### Default (production)
```python
generate_kwargs = dict(
    num_beams=6,
    length_penalty=1.2,
    no_repeat_ngram_size=3,
    anti_lm_alpha=0.5,
    max_length=256,
)
```

### Fast (~2× throughput, ~0.5 BLEU lower)
```python
generate_kwargs = dict(num_beams=4, anti_lm_alpha=0.0, max_length=256)
```

### Greedy (fastest, ~1.5 BLEU lower than default)
```python
generate_kwargs = dict(num_beams=1, max_length=256)
```

### High-quality (~30% slower, marginal gain)
```python
generate_kwargs = dict(num_beams=8, anti_lm_alpha=0.7, max_length=256)
```

### What is Anti-LM contrastive decoding?

At every decoding step, the model computes two next-token distributions:
1. **Main**: `p(y_t | source, y_<t)`
2. **Anti-LM**: `p(y_t | NO_source, y_<t)` (cross-attention masked out)

Contrastive score: `log p_main − α · log p_antilm`. Tokens predictable without seeing
the source get penalized — kills repetition and source-detached hallucination. α=0
disables; α=0.5 is the production default.

---

## 6. Limitations

| Class | Example | Why |
|---|---|---|
| **Idioms taken literally** | "break a leg" → `ಕಾಲು ಮುರಿಯಿರಿ` (literal); "raining cats and dogs" → literal translation | Known weakness at sub-1B parameter scale. |
| **Long-tail tech / SaaS names** | Modern cloud-native terms (Kubernetes, GraphQL, Redis, PostgreSQL) may transliterate inconsistently or get omitted | Specific tech vocabulary rare in 2022-era training corpus. Common names (Apple, iPhone, Google) handled well. |
| **Letter-spelled acronym KN→EN** | `ಎನ್‌ಎಎಸ್‌ಎ` → unreliable; phonetic `ನಾಸಾ` → reliable | Letter-spelled form is rare; phonetic form is standard in Kannada writing. |
| **Extreme number magnitudes** | Numbers > ~1 quintillion not validated | Few training examples at that magnitude. |
| **Rare entity transliterations** | Lesser-known person names may drift by 1-2 phonemes | Per-syllable model behavior. |
| **PAN/long alphanumeric IDs mid-sentence (EN→KN only)** | The model demonstrated **near-perfect preservation on the release evaluation suite** — Aadhar numbers, phone numbers, email addresses, customer IDs, dates of birth, and PAN numbers are preserved verbatim in both directions. On a small EN→KN probe across 5 PAN sentences, **3/5 preserved the Latin form verbatim** and **1/5 was character-by-character transliterated into Kannada syllables** (e.g. `ABCDE1234F``ಎಬಿಸಿಡಿಇ1234ಎಫ್`) — information still preserved, syllables map deterministically back to Latin. KN→EN direction did not exhibit this on the eval suite. **Recommended postprocessing for form-data deployments**: regex-detect Kannada-syllable sequences in PAN/Aadhar context fields and back-map to Latin; validate against issuing-authority checksum before downstream use. | Mid-sentence PAN is rare in 2022-era training corpus. KN→EN and clear-prefix EN→KN cases preserve Latin verbatim. |

### Things the model does well

- ✅ Numbers preserved across multi-number sentences
- ✅ Dates preserved (including years 2024-2030)
- ✅ Indian-format numbers (`2,50,000``2.5 ಲಕ್ಷ` ↔ "two and a half lakh")
- ✅ Kannada numerals ↔ English digits conversion (`೨,೫೦,೦೦೦``2,50,000`)
- ✅ Currency symbols and units in both directions
- ✅ Phone numbers, Aadhar numbers, email addresses preserved
- ✅ Common entity transliteration (Modi, Bengaluru, ISRO, Apple, iPhone, Reuters, etc.)
- ✅ Long sentences with complex semantics (multi-clause, conditional, scientific)
- ✅ Negation, tense, aspect handled correctly
- ✅ Safety regression — no toxic output on provocative inputs (Falklands/Hancock/Peacock set)

### Failure-mode honesty

This is a **specialized model**, not a frontier LLM. For:
- **Idioms** → use a 7B+ model or post-edit
- **Modern technical jargon** (cloud-native stack names) → either keep source-as-is or use a frontier LLM
- **Multilingual translation** → use NLLB-200 or IndicTrans2

---

## 7. Ethical Considerations & Bias

### Safety filtering applied
- 40,586 profanity/adult-content rows dropped during corpus filtering
- Safety regression test set (Falklands/Hancock/Peacock variants) — 100% pass

### Known biases (inherent to corpus)
- Indian-context skew — entities, locations, brand names from Indian public discourse over-represented (this is intentional given the deployment target)
- 2022-era training data — modern tech terminology (2023-2026) less well-covered
- News + Wikipedia heavy — colloquial chat patterns under-represented vs daily speech

### Source code attribution

This release ships with HF integration code (`configuration_controlmt.py`,
`modeling_controlmt.py`, `tokenization_controlmt.py`) plus the native architecture
(`model.py`). All Apache 2.0.

---

## Usage

### Quick start — Python + Transformers

```python
from transformers import AutoModelForSeq2SeqLM, AutoTokenizer

tokenizer = AutoTokenizer.from_pretrained("anandkaman/controlmt-v2.3", trust_remote_code=True)
model = AutoModelForSeq2SeqLM.from_pretrained("anandkaman/controlmt-v2.3", trust_remote_code=True)

# KN → EN
out = model.translate("ಅವನು ನಾಳೆ ಬೆಂಗಳೂರಿಗೆ ಬಂದು ನನ್ನನ್ನು ಭೇಟಿಯಾಗುತ್ತಾನೆ.",
                       tokenizer=tokenizer, direction="kn2en")
# "He will come to Bangalore tomorrow and meet me."

# EN → KN
out = model.translate("India is a country in South Asia.",
                       tokenizer=tokenizer, direction="en2kn")
# "ದಕ್ಷಿಣ ಏಷ್ಯಾದ ಒಂದು ದೇಶ ಭಾರತ."
```

---

## 8. Deployment

ControlMT v2.3 is an **encoder-decoder seq2seq** model — same family as T5/mBART,
not decoder-only LM. That distinction matters for serving (see Section 9 of the deployment
guide for which platforms can run it natively).

**Verified deployment matrix** (RTX 5060 Ti box, beam=2, 6 KN↔EN test pairs):

| Recipe                    | Latency / pair | Memory          | Notes                                |
|---------------------------|----------------|-----------------|--------------------------------------|
| **CPU int8-dynamic**      | **0.28 s**     | ~140 MB RAM     | Fastest CPU path, no quality drop    |
| **CPU bf16** (recommended)| 0.51 s         | 280 MB RAM      | One-line `dtype=torch.bfloat16`      |
| CPU fp32                  | 1.44 s         | 560 MB RAM      | Baseline                             |
| **GPU fp16** (recommended)| **0.19 s**     | 404 MB VRAM     | Volta-and-up                         |
| GPU bf16                  | 0.19 s         | 404 MB VRAM     | Ampere-and-up                        |
| GPU fp32                  | 0.20 s         | 793 MB VRAM     | No speed benefit, more memory        |
| HF Space (Docker)         | 3–15 s         | shared free-tier| [Live demo](https://huggingface.co/spaces/anandkaman/controlmt-demo) |
| FastAPI / Docker / Endpts | matches device | matches device  | Source under `assets/space/`         |

**Pinned versions** that we verified with: `python 3.12.3 · torch 2.10.0 · transformers 4.57.6 · sentencepiece 0.2.1 · safetensors 0.7.0 · huggingface_hub 0.36.2`.
Minimum supported is `torch >= 2.0, transformers >= 4.40`.

**Not directly supported** (architectural — these are decoder-only frameworks):
**vLLM**, **Ollama**, **llama.cpp / GGUF**, **HF TGI**, **bitsandbytes int8**.
Use the FastAPI wrapper instead — at 0.19 s/pair, the optimizations these tools
provide are dominated by request overhead.

→ Full recipes, code, and pre-launch checklist in **[DEPLOYMENT.md](DEPLOYMENT.md)**.
→ Reproduce the matrix above: `python assets/scripts/verify_deployment.py --device cuda`

---

## 🎯 Help shape v2.4 — Break-the-Model Challenge

v2.4 is being designed around the gaps we find in v2.3. The
[live demo](https://huggingface.co/spaces/anandkaman/controlmt-demo) includes an
**opt-in research-data sharing toggle** — when enabled, your translation
(input + output + timing) is logged to a private dataset we use to identify
edge cases for v2.4 training.

Things we particularly want to see fail:
- Heavily code-mixed phrases (`Nange last meeting nalli decision aagilla`)
- Complex numerals (`೨,೩೫,೬೭೮`, `1,23,45,678`, mixed-script percentages)
- Regional Karnataka dialects (Mangalorean, Dharwad, Kalyana Karnataka)
- Domain terminology (cricket, finance, government schemes, temple names)
- Long literary sentences (Bendre, Karanth-era prose)
- Modern tech / SaaS jargon (already known weak — confirm + extend)

**Opt-in is unchecked by default.** When you do opt in, inputs are automatically
PII-redacted (PAN, Aadhar, phone, email, card numbers) before storage. Full
details in [PRIVACY.md](PRIVACY.md).

---

## Roadmap

### v2.4 — Priorities locked from v2.3 evaluation

**#1 — Multi-token code-mix data slice (highest-impact gap from v2.3 evaluation)**

A 50k+ corpus slice of `Kannada matrix sentence + 2–4 Latin-script English tokens` paired
with `English target preserving every Latin-script token verbatim`. This is the largest
visible v2.3 weakness, identified during competitor comparison against IndicTrans2 1.1B
and Sarvam-Translate (see internal `eval_results/competitor_comparison.md`):

- v2.3 handles `Kannada + 1 English entity` cleanly
- v2.3 hallucinates entity names at `Kannada + 2+ English tokens` (e.g. *Manyata Tech Park
  → Girinagar Tech Park* when "Software Engineer" is also present in the same sentence)
- IndicTrans2 1.1B and Sarvam-Translate 4B both handle the 2+ case correctly

**Root cause hypothesis**: decoder over-weights the Kannada language prior when the
source has high English-token density, and substitutes nearest-by-phonetic Kannada
place-name from training distribution. Closing this gap is expected to also improve:

- **Long-sentence robustness** (better source-attention discipline)
- **Number + entity ordering** in payment/transactional prose
- **Tech / startup / finance jargon** (which clusters multi-token English)

#### Other v2.4 priorities (in order of expected impact)

- **Kannada proverbs & idioms corpus** (5–10k pairs) — v2.3 + IT2 + Sarvam all fail on
  proverbs like *ಮಾಡಿದ್ದುಣ್ಣೋ ಮಹಾರಾಯ* (= "you reap what you sow")
- **Hindi support** (`[HI2EN]` / `[EN2HI]`) — opens a second language pair
- **Iterative back-translation** for low-resource domain expansion
- **Expanded vocabulary** (modern tech terms, longer alphanumeric IDs)
- **Standardized BPE tokenizer** (currently SentencePiece Unigram)
- **Register / style control** revisit (rebalanced labels + contrastive separation training)

### v3.0 (TBD)

Copy-mechanism / pointer-generator for OOV-proof transliteration. A built-in solution
for the entity-preservation problem instead of corpus-only fix.

---

## Citation

```bibtex
@misc{controlmt-v2.3-2026,
  author = {Anand Kaman},
  title  = {ControlMT v2.3 — A 139M-Parameter Specialized Kannada↔English Translation Model
           with Code-Mix-Native Training},
  year   = {2026},
  howpublished = {\url{https://huggingface.co/anandkaman/controlmt-v2.3}}
}
```

## License

Apache 2.0 — see [LICENSE](LICENSE).