File size: 34,183 Bytes
dc7e099
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
# Ankahi (अनकही) — Backend, Core System & Testing Specification
## Model Deployment · Pipeline Conversion · Robustness Testing · Benchmarking

---

> **AGENT INSTRUCTION:** This document contains NO finished code. It contains precise, actionable instructions, resource pointers, search queries, and architectural decisions that you must execute step by step. For every section marked **[SEARCH REQUIRED]**, you must query the listed resources and documentation before proceeding — do not rely on memory or assumptions, as MediaPipe, LiteRT, and Unsloth APIs change frequently. For every benchmark, you must produce actual measured numbers — no fabricated figures. This document also defines the exact format for the results report that must accompany the Kaggle submission.

---

## PART 1: THE CRITICAL PATH — .litertlm CONVERSION

This is the single biggest blocker to a working demo. Without the on-device binary, the Flutter app has nothing to run. Do this before anything else.

---

### 1.1 Overview: What the conversion pipeline does

```
Unsloth fine-tuned Gemma 4 E4B
  (stage1 + stage2 adapter, merged)
         ↓
[bitsandbytes INT8 quantization]
  (merge_and_quantize.py)
         ↓
Hugging Face safetensors checkpoint
  (float32 or int8, standard format)
         ↓
[MediaPipe Model Maker conversion]
  (convert_to_litertlm.py)
         ↓
.task or .litertlm flatbuffer file
  (~2.3 GB for E4B INT8)
         ↓
Sideloaded to Android via adb push
  (or bundled in APK assets for small adapters)
         ↓
MediaPipe GenAI / LiteRT-LM runtime
  running on Android CPU/GPU/NPU
```

---

### 1.2 Environment Setup

**[SEARCH REQUIRED]** Before running anything, read these resources:
- Search: `"mediapipe model maker" "LLM inference" "gemma" site:ai.google.dev`
- URL to read: `https://ai.google.dev/edge/mediapipe/solutions/genai/llm_inference`
- URL to read: `https://ai.google.dev/edge/mediapipe/solutions/genai/llm_inference/android`
- Search: `"mediapipe-model-maker" pip install python version compatibility 2025 2026`
- Search: `"LiteRT" "LiteRT-LM" gemma conversion site:github.com/google`

**Why this matters:** `mediapipe-model-maker` has strict Python and CUDA version dependencies that change between releases. You must verify the current requirements before installing. Installing the wrong version wastes hours.

**Recommended environment (verify against current docs):**
```
Python:      3.10 or 3.11 (verify with mediapipe docs — NOT 3.12)
CUDA:        11.8 or 12.1 (check current compatibility matrix)
PyTorch:     The version compatible with your CUDA
mediapipe:   Latest stable (search: "mediapipe pypi latest version")
mediapipe-model-maker: Must match mediapipe version exactly

Recommended: Use a fresh conda environment
conda create -n ankahi_convert python=3.10
conda activate ankahi_convert
# Then follow exact installation from current mediapipe docs
```

**[SEARCH REQUIRED]** For the H100 server specifically:
- Search: `mediapipe-model-maker H100 installation cuSPARSELt compatibility`
- Cross-reference with the environment cascade issue documented in the Ankahi handover — the H100 server had pyannote/CUDA/cuSPARSELt conflicts. The conversion environment should be kept SEPARATE from the training environment.
- Run conversion in its own conda environment. Do not mix with the Unsloth training environment.

---

### 1.3 Step-by-Step Conversion Pipeline

**[SEARCH REQUIRED]** For each step below, search for the current API before running:

#### Step A: Verify the merged checkpoint

The `merge_and_quantize.py` script should have already produced a merged safetensors checkpoint. Verify:

```python
# Check the output directory — you need to confirm these files exist:
# - config.json
# - tokenizer.json / tokenizer_config.json / tokenizer.model
# - model-00001-of-XXXXX.safetensors (and remaining shards)
# - generation_config.json

# Verification check:
from transformers import AutoModelForCausalLM, AutoTokenizer
# Load the checkpoint to verify it's valid before conversion
# If this fails, the merge step needs to be rerun
```

**[SEARCH REQUIRED]** Search: `"Gemma 4" "safetensors" "merge lora" "unsloth" verification checklist`

#### Step B: INT8 Quantization verification

The handover doc specifies bitsandbytes INT8. Verify the quantization is correctly applied:

```python
# Check quantization was applied:
# model.config should show quantization_config with load_in_8bit=True
# Run a quick forward pass to confirm no NaN outputs:
# inputs = tokenizer("WANT WATER COLD", return_tensors="pt")
# outputs = model.generate(**inputs, max_new_tokens=20)
# print(tokenizer.decode(outputs[0]))
# Expected: Hindi sentence, no garbage tokens, no infinite repetition
```

**Known issue from handover:** INT8 quantization causes repetition loops on short inputs. Confirm `repetition_penalty=1.2` is in `generation_config.json`. If not, add it before conversion — it must be baked into the model config for on-device inference.

#### Step C: Convert to LiteRT-LM format

**[SEARCH REQUIRED]** The exact API for this changes between MediaPipe releases. Before running `convert_to_litertlm.py`, search:
- `"mediapipe model maker" "llm" "gemma" "convert" "python" site:ai.google.dev 2025 OR 2026`
- `"LiteRT" "flatbuffer" ".task" gemma 4 conversion tutorial`
- Check: `https://github.com/google-ai-edge/mediapipe-samples` for the most recent LLM inference examples

The conversion call will look approximately like this (verify against current docs — do not run this verbatim):

```python
# APPROXIMATE — verify exact API from current mediapipe docs before running
import mediapipe as mp
# OR: from mediapipe.tasks.python.genai import converter as genai_converter

# Key parameters to understand and configure:
# - model_path: path to your merged safetensors checkpoint directory
# - output_path: where to write the .litertlm or .task file  
# - output_type: "TFLITE" or "LITERTLM" — check current options
# - quantization_type: "w8a8" (weights 8-bit, activations 8-bit) or "w4a8" — w8a8 matches your bitsandbytes INT8
# - backend: "CPU" or "GPU" — verify Android GPU support for your target devices
# - lora_rank: 8 (must match Stage 2 adapter rank)
```

**[SEARCH REQUIRED]** Critical constraint documented in handover: LoRA rank must be 4 or 8 for MediaPipe GenAI compatibility. This is already set. But verify the conversion tool's current LoRA rank support:
- Search: `"mediapipe" "lora" "rank 8" android "llm inference" compatibility 2025 OR 2026`

#### Step D: Adapter conversion (separate files)

The base model and persona adapters are separate files. The base model is the large .litertlm file. Each 30MB adapter must also be converted to a format MediaPipe can load at runtime.

**[SEARCH REQUIRED]**:
- Search: `mediapipe genai "lora adapter" android "load at runtime" ".task" OR ".bin" format`
- Search: `"mediapipe-model-maker" "lora" "convert adapter" python example`
- Search: `LiteRT-LM "hot-swappable" adapter loading android kotlin`

Expected output structure:
```
ankahi_bundle/
├── model/
│   ├── ankahi_base_e4b_int8.litertlm   (~2.3 GB)
│   └── symlinks → point to above (use cp -L when moving across filesystems!)
├── adapters/
│   ├── arjun_v1.ankahi                 (~30 MB, converted LoRA)
│   ├── ananya_v1.ankahi
│   ├── priya_v1.ankahi
│   ├── rohan_v1.ankahi
│   └── zara_v1.ankahi
└── voices/
    └── (AI4Bharat TTS voice clone files, one per persona)
```

#### Step E: Quick validation on-device

After conversion, validate before spending time on the Flutter integration:

```bash
# Use adb to push and test directly
adb push ankahi_base_e4b_int8.litertlm /sdcard/ankahi/model/
adb push arjun_v1.ankahi /sdcard/ankahi/adapters/

# [SEARCH REQUIRED] Search for:
# "mediapipe" "llm inference" "android" "command line test" OR "standalone test"
# There may be a MediaPipe demo APK you can sideload for quick validation
# before building the full Flutter app
```

**[SEARCH REQUIRED]**: 
- Search: `"mediapipe" "llm_inference" android demo app github`
- Search: `google-ai-edge mediapipe-samples llm inference android kotlin example`
- URL: `https://github.com/google-ai-edge/mediapipe-samples/tree/main/examples/llm_inference/android`

---

### 1.4 AI4Bharat svara-TTS Integration

**[SEARCH REQUIRED]** This is listed as "Next Step #3" in the handover but should be treated as highest priority after model conversion.

Resources to read:
- Search: `"AI4Bharat" "Indic TTS" OR "IndicTTS" OR "svara" python pip install 2025 2026`
- URL: `https://github.com/AI4Bharat/Indic-TTS` — check current state, branches, releases
- Search: `AI4Bharat TTS "voice cloning" python inference minimal example`
- Search: `AI4Bharat TTS android deployment OR "mobile" OR "on-device"`

**Key questions to answer from the search:**
1. Does AI4Bharat's current TTS support on-device Android inference, or does it require a server?
2. If server-required: Is there a small model variant suitable for on-device use?
3. What format does the voice cloning model accept? (wav file? sampling rate? duration?)
4. What languages are reliably supported right now?

**Fallback plan if AI4Bharat TTS cannot run on-device:**
- **Option A:** Run TTS on a lightweight server (FastAPI) that the device calls over local WiFi only (not cloud). This still works for the demo.
- **Option B:** Use a pre-synthesized voice library with the cloned voice (record 50–100 phoneme combinations, stitch on-device). Cruder, but zero-latency.
- **Option C:** Use Android's built-in TTS engine (`TextToSpeech`) as a fallback only — it won't sound like the parent, but it ensures the app works.

**[SEARCH REQUIRED]** For Option A (if needed):
- Search: `AI4Bharat TTS "FastAPI" OR "flask" serve REST API example`
- Search: `AI4Bharat TTS model size "hindi" inference latency`

---

## PART 2: TESTING STRATEGY & ROBUSTNESS

---

### 2.1 Testing Philosophy

The Ankahi system has three distinct testing domains:

```
Domain 1: ML Pipeline Tests (pytest)
  → Model output quality, adapter isolation, safety layer
  
Domain 2: Inference Pipeline Tests (device benchmarking)
  → Latency, memory, battery, hardware compatibility
  
Domain 3: Application Tests (Flutter)
  → Widget tests, integration tests, accessibility tests
```

The handover reports 36/36 unit tests passing. This section expands that into a full test strategy for Kaggle submission evidence.

---

### 2.2 ML Pipeline Tests (src/ankahi/eval/)

The existing test suite covers: BLEU-4 4-gram potential issue (fixed), BLEU-4 smoothing, chrF++ calculation, IndicSBERT heatmap generation. Expand it as follows:

#### Test Suite A: Output Quality Tests
```python
# File: tests/test_output_quality.py

# Test 1: Language accuracy per language
# For each of 5 supported languages, run 20 test inputs from test.jsonl
# Assert chrF++ score > threshold (set threshold based on Stage 1 training result)

# Test 2: Code-switching fidelity  
# Input: Hinglish pictogram sequences (e.g., "WANT + MOVIE + NIGHT + WITH + FRIENDS")
# Expected output: natural Hinglish ("Yaar, raat ko movie dekhni hai")
# Assert: output contains both Hindi and English words (simple heuristic check)

# Test 3: Persona isolation (the 5×5 heatmap test)
# For each of 5 adapters: run 10 persona-specific inputs
# Compute IndicSBERT similarity between:
#   - Arjun adapter output for Arjun-specific input
#   - Ananya adapter output for same input
# Assert: diagonal scores > 0.85, off-diagonal < 0.65
# This is the "no leakage" test — adapters must not sound like each other

# Test 4: Repetition loop detection
# Run 50 short inputs (1–3 pictograms)
# Assert: no output repeats any phrase more than 2 times
# Assert: all outputs are < 25 tokens (AAC sentences should be short)

# Test 5: chrF++ vs BLEU-4 comparison
# For morphologically rich languages (Hindi, Tamil, Bengali):
# Assert: chrF++ score > BLEU-4 score (validates the metric choice)

# Test 6: Safety layer completeness
# 50 self-harm trigger inputs (from the safety test set)
# Assert: 100% refusal rate (0 completions on forbidden content)
# 20 legitimate anger/pain inputs
# Assert: 100% completion rate (safety layer must NOT block these)
```

#### Test Suite B: Adapter Loading Tests
```python
# File: tests/test_adapter_switching.py

# Test 1: Cold load time
# Measure time to load each adapter from disk to GPU memory
# Assert: load time < 5 seconds per adapter on H100

# Test 2: Hot swap correctness  
# Load Arjun adapter → generate sentence
# Swap to Ananya adapter → generate same sentence
# Assert: sentences are different (adapter is actually being swapped)

# Test 3: Memory after swap
# After 5 consecutive adapter swaps:
# Assert: GPU memory usage returns to baseline (gc.collect + empty_cache working)

# Test 4: Rank constraint validation
# Programmatically verify each Stage 2 adapter has rank=8
# Assert: all adapters fail to load if rank > 8 (simulated)
```

#### Test Suite C: Audio Tower Tests
```python
# File: tests/test_audio_tower.py

# Test 1: Dysarthric speech disambiguation
# Scenario: pictogram input says "DOG", audio signal suggests "DRINK" (fricative sounds)
# Assert: output sentence is drink-related, not dog-related
# Use pre-recorded test audio clips from the TORGO corpus augmentation

# Test 2: No audio input baseline
# Assert: system works correctly with audio input disabled
# The audio tower is an enhancement, not a requirement

# Test 3: Ambient noise robustness
# Inject synthetic noise (café noise, TV audio) into audio input
# Assert: output quality does not degrade by more than 10% chrF++ vs clean audio
```

---

### 2.3 Device Benchmarking Tests

This is the most important section for the Kaggle submission. You need real numbers.

#### Hardware Setup
**[SEARCH REQUIRED]** Before benchmarking:
- Search: `"MediaPipe" "LLM inference" Android benchmark "prefill speed" "decode speed" measurement`
- Search: `LiteRT android profiling tool GPU CPU NPU benchmark script`
- URL: `https://ai.google.dev/edge/mediapipe/solutions/genai/llm_inference#performance_benchmarks`

**Target devices for benchmarking (use what you have, document what you used):**
```
Tier 1 (target market): Any device with Snapdragon 680 or similar (e.g., Realme Narzo 50, ~₹12,000)
Tier 2 (mid-range):     Any device with Snapdragon 778G or similar (e.g., Poco X5 Pro, ~₹25,000)
Tier 3 (development):   Any available Android tablet/phone you have access to
Note: Document the exact device model, Android version, and RAM in results.
```

**If no physical device is available:**
- Use Android emulator with GPU acceleration (note this in results as "emulated, not representative")
- Or use MediaPipe's published benchmarks and cite them as reference

#### Benchmark Test Suite D: Latency
```python
# File: benchmarks/latency_benchmark.py

# Metric 1: Time to First Token (TTFT)
# = Time from input submission to first output token
# Measure across 3 input lengths: 1 tile (short), 3 tiles (medium), 6 tiles (long)
# Run 20 trials each, report mean ± std

# Metric 2: Total generation time
# = Time from input to complete sentence output
# Target: < 200ms (from handover spec)
# If > 200ms: document and explain (model size, quantization level)

# Metric 3: TTS synthesis time
# = Time from text ready to audio playing
# Measured separately from inference
# Target: < 300ms

# Metric 4: End-to-end latency
# = Tap "Speak" → audio begins playing
# Target: < 500ms total (inference + TTS)
```

#### Benchmark Test Suite E: Memory & Battery
```python
# File: benchmarks/resource_benchmark.py

# Metric 1: RAM usage during inference
# Measure with adb shell dumpsys meminfo package.name
# Record: base app RAM, + model loaded RAM, + during inference peak RAM
# Assert: total does not exceed 4GB (leaves headroom for Android OS on 6GB devices)

# Metric 2: Battery consumption
# Run continuous inference for 30 minutes (simulating active communication session)
# Measure battery % delta
# Target: < 5% per hour
# Tool: adb shell dumpsys battery OR Android Battery Historian

# Metric 3: Thermal performance
# Monitor device temperature during 30-minute sustained use
# Note: thermal throttling will increase latency — document the curve
# adb shell cat /sys/class/thermal/thermal_zone*/temp

# Metric 4: Cold start time  
# Time from app icon tap to communication screen ready (model loaded)
# Target: < 5 seconds (model should stay resident after first load)
```

#### Benchmark Test Suite F: Hardware Compatibility
```python
# File: benchmarks/compatibility_check.py

# Check which inference backends are available on the device:
# - CPU (always available)
# - GPU (via MediaPipe GPU delegate)
# - NPU/DSP (via NNAPI delegate)

# [SEARCH REQUIRED]: 
# Search: mediapipe genai "gpu delegate" OR "nnapi delegate" android compatibility
# Search: LiteRT android "backend fallback" cpu gpu npu strategy

# Test each backend:
# 1. Run 10 inference trials on each available backend
# 2. Record latency and memory for each
# 3. Report which backend is recommended for the target device class
```

---

### 2.4 Flutter Application Tests

#### Widget Tests
```dart
// test/widget_test.dart

// Test 1: PictogramTile renders correctly
// - Check tile displays Hindi label
// - Check tile displays English label  
// - Check tile is accessible (Semantics widget present with correct label)
// - Check tile responds to tap

// Test 2: PhraseBar state management
// - Start empty → assert SPEAK button is disabled
// - Add 1 tile → assert SPEAK button is enabled
// - Clear → assert returns to empty state

// Test 3: Result card appearance
// - Mock inference result
// - Assert Hindi text is displayed
// - Assert "Play again" button is present
// - Assert "Save to history" button is present

// Test 4: Category tab switching  
// - Tap second category tab
// - Assert grid content changes
// - Assert animation completes without error
```

#### Integration Tests
```dart
// integration_test/communication_flow_test.dart
// [SEARCH REQUIRED]: Search: flutter integration_test mediapipe method channel mock

// Test 1: Full communication flow (with mocked inference)
// Mock InferenceService to return "मुझे पानी चाहिए" for any input
// 1. Tap three pictogram tiles
// 2. Assert tiles appear in phrase bar
// 3. Tap SPEAK button
// 4. Assert result card appears with correct text
// 5. Assert TTS is called (mock TTS service)

// Test 2: Persona switching
// 1. Start with Arjun persona active
// 2. Navigate to Personas screen
// 3. Tap "Set Active" on Ananya
// 4. Assert adapter switch is triggered
// 5. Navigate back to communication screen
// 6. Assert persona indicator shows Ananya

// Test 3: Offline resilience
// Disable network (can be done in integration test setup)
// Assert: app works identically — no network errors, no degraded functionality
```

#### Accessibility Tests
```dart
// test/accessibility_test.dart

// Test 1: All tiles meet contrast requirements
// Programmatically check color contrast ratio for each category color + text
// Assert: all ratios >= 4.5:1

// Test 2: Touch target sizes
// Assert: all interactive widgets have minimum 72×72 logical pixels

// Test 3: TalkBack labels present
// Assert: every PictogramTile has non-empty Semantics.label
// Assert: SPEAK button has Semantics with state description

// Test 4: Animation disable respect
// Simulate AccessibilityFeatures.disableAnimations = true
// Assert: no AnimationController is started when flag is set
```

---

## PART 3: RESULTS REPORT FORMAT

---

### 3.1 The Results Document Structure

This section defines the exact format for the benchmarking results document that will accompany the Kaggle submission. This document should be a single, well-formatted Markdown file named `RESULTS.md` in the repository root, AND should be mirrored as a well-designed section of the Kaggle notebook.

**The document must contain:**

---

### Template: RESULTS.md

```markdown
# Ankahi — System Evaluation Results
**Version:** 1.0.0  
**Date:** [Run date]  
**Hardware (training):** NVIDIA H100 (40GB VRAM)  
**Hardware (inference benchmark):** [Device model, Android version, RAM]  

---

## Section 1: Training Metrics

### Stage 1: Base AAC SFT
| Metric | Value |
|--------|-------|
| Final training loss | 0.6028 |
| Training pairs | 16,500 |
| Languages | Hindi, Punjabi, Tamil, Bengali, Hinglish |
| LoRA rank | 16 |
| Training time | [X hours on H100] |
| Tokens packed (MemoryPackCollator) | 2048-token blocks |
| Training speedup (vs. non-packed) | ~3× |

### Stage 2: Persona Adapters
| Adapter | Language | Rank | Size (MB) | Vocab coverage |
|---------|----------|------|-----------|----------------|
| Arjun | Hindi+Punjabi | 8 | [X] | [N] items |
| Ananya | Tamil+English | 8 | [X] | [N] items |
| Priya | Bengali+Hindi | 8 | [X] | [N] items |
| Rohan | Hindi+Marathi+English | 8 | [X] | [N] items |
| Zara | Urdu+Hindi+Telugu | 8 | [X] | [N] items |

---

## Section 2: Language Quality Evaluation

### BLEU-4 by Language (Stage 1 outputs)
[INSERT BAR CHART: horizontal bars, one per language, showing BLEU-4 score 0.0–1.0]

| Language | BLEU-4 | chrF++ |
|----------|--------|--------|
| Hindi | [X] | [X] |
| Punjabi | [X] | [X] |
| Tamil | [X] | [X] |
| Bengali | [X] | [X] |
| Hinglish | [X] | [X] |
| **Average** | **[X]** | **[X]** |

**Note:** chrF++ is the primary metric — it is better suited to morphologically rich Indian languages than BLEU-4. BLEU-4 is included for comparison.

### BLEU-4 vs. Zero-Shot GPT-4 Baseline
[INSERT GROUPED BAR CHART: Ankahi vs GPT-4 zero-shot on same test set, per language]

Context: GPT-4 zero-shot with a "translate this pictogram sequence to natural Hindi" prompt was used as a baseline. Ankahi's fine-tuned system should outperform it on code-switched and persona-specific outputs where GPT-4 has no grounding.

---

## Section 3: Adapter Isolation (No-Leakage Verification)

### IndicSBERT Cross-Adapter Similarity Heatmap
[INSERT 5×5 HEATMAP: rows = query adapter, cols = reference adapter]
[Color scale: low similarity = white/cream, high similarity = forest green]
[Diagonal = 1.0 (perfect self-similarity)]

```
          Arjun  Ananya  Priya  Rohan  Zara
Arjun   [ 1.00   X.XX    X.XX   X.XX  X.XX ]
Ananya  [ X.XX   1.00    X.XX   X.XX  X.XX ]
Priya   [ X.XX   X.XX    1.00   X.XX  X.XX ]
Rohan   [ X.XX   X.XX    X.XX   1.00  X.XX ]
Zara    [ X.XX   X.XX    X.XX   X.XX  1.00 ]
```

**Interpretation:** Off-diagonal values should be < 0.65. Values above this threshold would indicate persona "bleed" — one adapter sounding too much like another. A well-isolated adapter system protects each child's communication identity.

---

## Section 4: Safety Layer Verification

| Test Category | Inputs Tested | Refusals | Refusal Rate |
|---------------|---------------|----------|--------------|
| Self-harm triggers | 50 | [X] | [X]% |
| Inappropriate content | 50 | [X] | [X]% |
| Legitimate anger | 20 | 0 (correct) | 0% |
| Pain expression | 20 | 0 (correct) | 0% |
| Frustration | 20 | 0 (correct) | 0% |

**Target:** 100% refusal on harmful content, 0% refusal on legitimate emotional expression.

---

## Section 5: On-Device Inference Benchmarks

### Test Device
| Property | Value |
|----------|-------|
| Device | [Model name] |
| Processor | [SoC model] |
| RAM | [X] GB |
| Android version | [X] |
| Backend used | [CPU / GPU / NPU] |
| Backend selection rationale | [Why this backend was chosen] |

### Latency Breakdown
[INSERT BAR CHART: Stacked horizontal bars showing time components]

| Component | Mean (ms) | Std Dev (ms) | P95 (ms) |
|-----------|-----------|--------------|----------|
| Pictogram → tokens | [X] | [X] | [X] |
| LLM prefill (TTFT) | [X] | [X] | [X] |
| LLM decode (full sentence) | [X] | [X] | [X] |
| Adapter swap overhead | [X] | [X] | [X] |
| TTS synthesis | [X] | [X] | [X] |
| **End-to-end (tap → audio)** | **[X]** | **[X]** | **[X]** |

Target: end-to-end < 500ms.

[INSERT LINE CHART: Latency over 100 consecutive inferences — shows warmup curve and steady state]

### Latency by Input Length
[INSERT LINE CHART: x-axis = number of pictograms selected (1–8), y-axis = inference time ms]

Expected: roughly linear scaling. Deviations should be noted and explained.

---

## Section 6: Memory & Battery

### Memory Profile
[INSERT ANNOTATED SCREENSHOT or BAR CHART of memory usage at key states]

| State | RSS Memory (MB) |
|-------|----------------|
| App launched, no model | [X] |
| Base model loaded | [X] |
| Base model + Arjun adapter | [X] |
| During active inference | [X] (peak) |
| After inference, idle | [X] |

### Battery Consumption
| Session duration | Battery consumed | Implied drain/hour |
|-----------------|------------------|--------------------|
| 10 minutes active | [X]% | [X]% / hour |
| 30 minutes active | [X]% | [X]% / hour |

Target: < 5% per hour sustained.

### Thermal Behavior
[INSERT LINE CHART: Device temperature (°C) over 30-minute sustained use session]
Note: At what temperature does thermal throttling begin? What is the latency impact?

---

## Section 7: Unit Test Coverage

| Test Suite | Tests | Passed | Failed | Coverage |
|------------|-------|--------|--------|----------|
| Output quality | [X] | [X] | [X] | [X]% |
| Adapter switching | [X] | [X] | [X] | [X]% |
| Audio tower | [X] | [X] | [X] | [X]% |
| Safety layer | [X] | [X] | [X] | [X]% |
| Flutter widget tests | [X] | [X] | [X] | [X]% |
| Flutter integration tests | [X] | [X] | [X] | [X]% |
| **Total** | **[X]** | **[X]** | **[X]** | **[X]%** |

Previously confirmed: 36/36 passing in the original test suite. All new tests must achieve ≥ 95% pass rate.

---

## Section 8: Comparison vs. Commercial AAC Baseline

[INSERT RADAR CHART: 6 axes, comparing "Commercial AAC (best available)" vs "Ankahi"]

Axes:
1. Hindi / North Indian language support (0–5 scale)
2. South Indian language support (0–5)  
3. Code-switching / Hinglish support (0–5)
4. Offline capability (0–5)
5. Dysarthric speech tolerance (0–5)
6. Affordability under ₹20,000 (0–5)

Expected result: Ankahi fills or approaches the full radar on all 6 axes. Commercial AAC (designed for English-speaking markets) scores poorly on axes 1–4 and 6.

---

## Section 9: Open Research Artifacts

| Artifact | Location | Description |
|----------|----------|-------------|
| Training dataset | HuggingFace: ankahi/Ankahi-AAC-SFT | 16,500 code-switched AAC pairs |
| Base model weights | HuggingFace: ankahi/ankahi-gemma4-e4b-stage1 | Stage 1 fine-tuned Gemma 4 E4B |
| Persona adapters | HuggingFace: ankahi/ankahi-personas | 5 Rank-8 LoRA adapters |
| Eval benchmark | GitHub: ankahi/ankahi/benchmarks/ | chrF++, BLEU-4, IndicSBERT evaluation code |
| Source code | GitHub: [repo link] | Apache 2.0 |

---

## Appendix A: Chart Generation Code

All charts in this document were generated with the code in `benchmarks/generate_charts.py`. To reproduce:

```bash
pip install matplotlib seaborn pandas numpy
python benchmarks/generate_charts.py --results benchmarks/results.json --output charts/
```

Input format for results.json:
```json
{
  "bleu4": { "hindi": X.XX, "punjabi": X.XX, "tamil": X.XX, "bengali": X.XX, "hinglish": X.XX },
  "chrf": { "hindi": X.XX, ... },
  "adapter_similarity": [[1.0, X.XX, ...], [X.XX, 1.0, ...], ...],
  "latency_ms": { "prefill_mean": X, "prefill_std": X, "decode_mean": X, ... },
  "memory_mb": { "idle": X, "model_loaded": X, "peak_inference": X },
  "battery_pct_per_hour": X.X,
  "safety": { "harmful_refusal_rate": 1.0, "legitimate_expression_rate": 1.0 }
}
```
```

---

### 3.2 Chart Generation Scripts

**[SEARCH REQUIRED]** For the benchmark visualization:
- Search: `seaborn heatmap "IndicSBERT" similarity matrix annotation python`
- Search: `matplotlib radar chart python "fill" multiple series comparison`

Implement the following in `benchmarks/generate_charts.py`:

**Chart 1: BLEU-4 by Language (horizontal bar chart)**
```python
# Use matplotlib, horizontal bars
# Colors: forest green (#2D6A4F) for Ankahi, gray for baseline
# Sort bars by score (highest at top)
# Add data labels on bars
# Save as: charts/bleu4_by_language.png (300 DPI)
```

**Chart 2: IndicSBERT Heatmap (5×5)**
```python
# Use seaborn.heatmap
# Color: white → forest green (#2D6A4F), range 0.0–1.0
# Annotate cells with 2-decimal values
# Title: "Cross-Adapter Similarity (IndicSBERT)"
# A clean diagonal of 1.00 and low off-diagonal proves no leakage
# Save as: charts/adapter_heatmap.png (300 DPI)
```

**Chart 3: Latency Breakdown (stacked horizontal bar)**
```python
# One bar per latency component
# Stacked to show total
# Colors: one per component (from Ankahi color palette)
# Target line at 500ms (red dashed vertical line)
# Save as: charts/latency_breakdown.png (300 DPI)
```

**Chart 4: Training Loss Curve**
```python
# Line chart, loss vs. training step
# Smooth curve (rolling average window=50)
# Forest green line on white background
# Annotate the final loss value
# Save as: charts/training_loss_curve.png (300 DPI)
```

**Chart 5: Radar (Capability Comparison)**
```python
# Use matplotlib polar plot
# Two filled areas: Ankahi (forest green, 40% alpha) vs Commercial AAC (gray, 30% alpha)
# 6 axes as specified above
# Legend outside the radar
# Save as: charts/capability_radar.png (300 DPI)
```

**Chart 6: Latency over time (line chart for 100 inferences)**
```python
# x: inference number (1–100)
# y: latency in ms
# Show individual points (small dots) + rolling average line
# Annotate: "warmup period" (first 5 inferences), "steady state" (rest)
# Save as: charts/latency_over_time.png (300 DPI)
```

**Chart 7: Cost Comparison (horizontal bar chart)**
```python
# y-axis: device/solution names
# x-axis: cost in INR (₹)
# Bars (low to high): Ankahi, Low-cost imported AAC, Mid-range AAC, Tobii Dynavox
# Add annotation: "ADIP scheme benefit: ₹6,000" as a vertical reference line
# Use log scale for x-axis (range is too wide for linear)
# Save as: charts/cost_comparison.png (300 DPI)
```

---

## PART 4: KAGGLE SUBMISSION CHECKLIST

Use this checklist before the May 18 deadline:

```
PRE-SUBMISSION
□ .litertlm binary produced and validated on at least one Android device
□ At least one persona adapter converted and loading successfully
□ AI4Bharat TTS integrated (or fallback TTS confirmed working)
□ Flutter app builds successfully in release mode
□ APK sideloads and runs on a physical device without crash
□ All unit tests passing (target: 36+ tests, ≥ 95% pass rate)
□ Benchmarks run and results.json populated with real numbers
□ All 7 charts generated from real data (no placeholder numbers)
□ RESULTS.md complete with all tables and chart embeds

GITHUB REPO
□ Repository is PUBLIC
□ README.md leads with: problem statement → solution → demo link → how to run
□ "Built with Unsloth" badge prominent in README (Unsloth special mention)
□ "Gemma 4 E4B" model badge prominent
□ Apache 2.0 LICENSE file present
□ requirements.txt or pyproject.toml present
□ Installation steps tested on a clean environment
□ Demo video linked in README

KAGGLE NOTEBOOK
□ Notebook runs without errors (test with "Run All")
□ All output cells have saved outputs (don't require actual H100 to view)
□ All charts render in notebook output
□ Section headers clearly label each training stage
□ Unsloth integration is highlighted and explained
□ A "Why Gemma 4?" section explicitly mentions E4B multimodal features used
□ RESULTS.md is linked from the notebook

VIDEO
□ Video is ≤ 5 minutes
□ Opens with problem statement (the 2.5 million CP children figure)
□ Shows a real Android tablet (not a laptop screen)
□ Shows a child (or hand) tapping pictogram tiles
□ Shows the Hindi sentence appearing
□ Shows audio playing (parent's voice)
□ Closes with the GitHub link and "free, offline, open-source" statement

FINAL SUBMISSION
□ Kaggle submission form completed
□ Track selected: Digital Equity (primary)
□ "Uses Unsloth" checkbox marked (if present in submission form)
□ GitHub link submitted
□ Video link (YouTube unlisted or Google Drive) submitted
□ Team members added to submission (if applicable)
```

---

## PART 5: RESOURCES MASTER LIST

**[SEARCH REQUIRED before starting any section]**

All resources below should be re-verified for current status — URLs and APIs may have changed.

### MediaPipe / LiteRT
- Main docs: `https://ai.google.dev/edge/mediapipe`
- LLM inference guide: `https://ai.google.dev/edge/mediapipe/solutions/genai/llm_inference`
- Android LLM guide: `https://ai.google.dev/edge/mediapipe/solutions/genai/llm_inference/android`
- Samples (search): `site:github.com/google-ai-edge mediapipe-samples llm_inference`
- PyPI: `mediapipe`, `mediapipe-model-maker` — always check latest version before installing

### Unsloth
- Main: `https://github.com/unslothai/unsloth`
- Docs: `https://docs.unsloth.ai`
- Gemma 4 specific: Search `"unsloth" "Gemma 4" fine-tuning notebook 2026`

### AI4Bharat TTS
- GitHub: Search `AI4Bharat Indic-TTS github`
- HuggingFace: Search `AI4Bharat TTS huggingface model`
- Demo: Search `AI4Bharat TTS voice cloning demo`

### IndicSBERT (for eval)
- Search: `"IndicSBERT" OR "Indic SBERT" huggingface sentence similarity`
- Likely: `sentence-transformers` library + an IndicNLP model

### Flutter + MediaPipe Integration
- Search: `flutter mediapipe genai "method channel" llm inference kotlin dart`
- Search: `flutter ffi mediapipe native library android`

### TORGO / UA-Speech (audio training data)
- TORGO: Search `"TORGO database" download dysarthric speech corpus`
- UA-Speech: Search `"UA-Speech" database download dysarthric`

### chrF++ implementation
- Search: `"sacrebleu" python "chrf" "chrf++" implementation`
- Library: `pip install sacrebleu` → `sacrebleu.corpus_chrf()`

---

*End of Backend & System Specification.*
*All three documents together constitute the complete Ankahi technical brief for the Kaggle Gemma 4 Good Hackathon submission.*