Design a Sarvam-Style Multilingual AI Platform
Building India's AI backbone: NLP, ASR, TTS, translation, and OCR across 22+ Indic languages at planetary scale
Table of Contents
- Introduction: Why Multilingual AI Matters
- The Multilingual AI Landscape (India Focus)
- Functional and Non-Functional Requirements
- Capacity Estimation and Back-of-Envelope
- Data Model and Storage Schema
- High-Level Architecture
- API Design
- Indic Language NLP Pipeline
- Speech-to-Text (ASR) for Indian Languages
- Text-to-Speech (TTS)
- Machine Translation Engine
- Sentiment Analysis and Toxicity Detection
- OCR for Indian Scripts
- Dataset Curation and Annotation
- Model Training Pipeline
- Low-Resource Language Handling
- Code-Switching and Hinglish Support
- Government and BIS Compliance
- API Gateway and Developer Ecosystem
- Real-Time Inference
- Edge Deployment
- Monitoring and Observability
- Cost Estimation
- Testing Strategy
- Interview Q and A
1. Introduction: Why Multilingual AI Matters
India is home to 22 scheduled languages, over 19,500 dialects, and approximately 1.4 billion people. Despite English proficiency growing in urban centres, the vast majority of the Indian population, roughly 900 million speakers, interacts with technology primarily in languages other than English. The next wave of internet users, expected to add 400 to 500 million people by 2030, will overwhelmingly speak Hindi, Bengali, Telugu, Marathi, Tamil, Kannada, Malayalam, Gujarati, Odia, Punjabi, Assamese, and dozens of other regional tongues. Building AI systems that can understand, process, and generate content in these languages is not merely a product feature; it is a civilisational necessity.
Sarvam AI, founded in 2023, emerged as India's first homegrown full-stack multilingual AI platform. Unlike generic global AI models that treat Indian languages as afterthoughts, typically supporting Hindi alone among 22 scheduled languages, Sarvam was architected from the ground up to deliver speech-to-text, text-to-speech, machine translation, text understanding, OCR, and content generation across all 22 scheduled languages of India, plus several regional dialects and code-mixed variants such as Hinglish (Hindi-English) and Tanglish (Tamil-English). The platform leverages indigenous training data, culturally aware annotation pipelines, and specialised model architectures to deliver accuracy that monolingual English models simply cannot match when applied to Indian language tasks.
In this comprehensive guide, we walk through the complete system design of a Sarvam-style multilingual AI platform. We cover every architectural layer: from capacity estimation and data modelling through to model training pipelines, real-time inference serving, edge deployment, government compliance, API gateway design, and cost estimation. Each section includes C# implementation code, database schemas, Mermaid diagrams, and tables to provide a production-grade reference architecture. Whether you are building a competing platform, integrating Indic language capabilities into an existing product, or preparing for a senior system design interview, this guide provides the depth and breadth you need.
The design challenge is immense. You must build a system that simultaneously serves ASR requests for spoken Tamil, translates between Marathi and English, performs OCR on handwritten Devanagari text, detects toxicity in mixed Hindi-English social media posts, and generates natural-sounding Telugu speech, all within latency budgets of 200 to 500 milliseconds and at a cost structure viable for India's price-sensitive market. This is fundamentally different from designing a general-purpose LLM API, because Indian languages present unique challenges in tokenisation, script rendering, phonetic mapping, code-switching, and limited high-quality training data.
Consider the scale: India generates approximately 2.5 exabytes of data per day across digital channels. Over 700 million smartphones in the country produce voice messages in dozens of languages. WhatsApp alone handles 20 billion messages per day in India, a large fraction of which are voice notes in Hindi, Bengali, Tamil, Telugu, and other languages. Government digitisation programmes like Digital India are generating massive volumes of scanned documents in Indic scripts that require OCR. Educational technology platforms need TTS and translation to make content accessible in local languages. Healthcare chatbots must understand patient queries in their mother tongue. Every one of these use cases represents millions of API calls per day on a platform like this.
2. The Multilingual AI Landscape (India Focus)
The global NLP landscape has been dominated by English-centric models. GPT-4, PaLM-2, Claude, and Llama were trained predominantly on English data, with other languages represented only fractionally. For Indian languages, this means that even state-of-the-art models exhibit significantly degraded performance. BLEU scores for Hindi-English translation from generic models hover around 28 to 32, while specialised Indic models achieve 42 to 48 on the same benchmarks. For lower-resource languages like Assamese, Manipuri, or Konkani, the gap is even more dramatic: generic models may produce near-unusable output, while purpose-built models achieve functional accuracy.
Key Players in the Indian Multilingual AI Space
| Organisation | Focus Area | Languages Supported | Key Models |
|---|---|---|---|
| Sarvam AI | Full-stack Indic AI platform | 22 scheduled + dialects | Sarvam-2B, Saaras (ASR) |
| AI4Bharat (IIT Madras) | Open-source Indic NLP | 22+ languages | IndicBERT, IndicTrans, Navarasa |
| Krutrim (Ola) | Multilingual LLM | 10+ Indian languages | Krutrim-7B |
| Google India | Indic language tools | 13+ languages | MUVR, Google Translate Indic |
| Microsoft (Bhashini) | Government translation | 22 scheduled languages | IndicTrans v2 |
| CoRover.ai | Multilingual chatbots | 12+ languages | Bhashini-powered bots |
The Script Challenge
India uses 13 major scripts: Devanagari (Hindi, Marathi, Sanskrit, Nepali), Bengali-Assamese (Bengali, Assamese), Tamil, Telugu, Kannada, Malayalam, Gujarati, Gurmukhi (Punjabi), Odia, and Latin (for English, Konkani, and Manipuri in Roman script). Each script has unique rendering complexities including conjunct consonants in Devanagari, vowel marks (matras) in Bengali, ligatures in Tamil, and complex stacking in Malayalam. A tokeniser trained on English text will fragment Indic text into suboptimal tokens, increasing sequence lengths by 3 to 5x and degrading model performance. The platform must implement script-aware tokenisation that respects Unicode boundaries, vowel-consonant combinations, and Unicode Normalization Form C (NFC) for consistent representation.
The Audio Landscape
Indian language speech presents acoustic challenges that English ASR systems are not designed to handle. Indian languages are primarily syllable-timed rather than stress-timed (as English is), resulting in more uniform syllable durations. Speakers frequently code-switch between languages mid-sentence, producing utterances like "Main project ka deadline kal hai, can you help?" (a mix of Hindi and English). Background noise profiles differ: street noise, temple bells, vehicle horns, and multi-speaker environments in joint family settings create unique acoustic challenges. Accent variation within a single language is enormous: Hindi spoken in Lucknow differs substantially from Hindi spoken in Mumbai or Patna. A robust platform must handle all of these variations gracefully.
3. Functional and Non-Functional Requirements
Functional Requirements
| # | Requirement | Priority | Details |
|---|---|---|---|
| F1 | Speech-to-Text (ASR) | Must | Transcribe audio in 22 scheduled languages with Word Error Rate below 12% |
| F2 | Text-to-Speech (TTS) | Must | Generate natural speech from text in 22 scheduled languages |
| F3 | Machine Translation | Must | Translate between any pair of 22 scheduled languages plus English |
| F4 | Text Understanding | Must | Sentiment analysis, NER, summarisation, classification in Indic languages |
| F5 | OCR | Must | Extract text from images and scanned documents in all Indic scripts |
| F6 | Toxicity Detection | Should | Detect hate speech, abusive content, and misinformation in Indic languages |
| F7 | Code-Switching Support | Should | Handle Hinglish, Tanglish, and other mixed-language inputs |
| F8 | Streaming ASR | Should | Real-time transcription with partial results for live audio streams |
| F9 | Batch Processing | Should | Async processing for large files and bulk operations |
| F10 | Developer SDK | Should | REST API, Python SDK, JavaScript SDK, and mobile SDKs |
| F11 | Voice Cloning | Nice | Custom voice synthesis from a few minutes of reference audio |
| F12 | Content Generation | Nice | Generate text content in Indic languages using LLM |
Non-Functional Requirements
| Requirement | Target | Rationale |
|---|---|---|
| Language Coverage | 22 scheduled + dialects | Constitutional mandate and market necessity |
| ASR Latency | Below 300ms for short utterances | Real-time conversational UX |
| TTS Latency | Below 500ms time-to-first-byte | Interactive voice response systems |
| Translation Latency | Below 200ms for 100-word text | Real-time chat and document translation |
| OCR Accuracy | Above 95% character accuracy for printed text | Government document processing |
| Availability | 99.95% | Government and enterprise SLA |
| Throughput | 10,000 requests/second aggregate | Scale for 100M+ daily active users |
| Cost per 1M characters | Below 2 INR | India price sensitivity requirement |
| Data Residency | India-only | Data Protection Bill compliance |
4. Capacity Estimation and Back-of-Envelope
Daily Volume Estimates
| Metric | Calculation | Result |
|---|---|---|
| Daily ASR requests | 500M voice messages x 20% processed via API | 100M requests/day |
| Daily TTS requests | 200M e-learning + IVR + accessibility sessions | 200M requests/day |
| Daily Translation requests | 500M messages x 10% cross-language | 50M requests/day |
| Daily OCR requests | 50M document scans + 20M images | 70M requests/day |
| Daily NLP requests | 1B social media x 5% moderation | 50M requests/day |
| Total daily requests | Sum of all services | Approx 470M requests/day |
| Average QPS | 470M / 86,400 | Approx 5,440 QPS |
| Peak QPS (3x) | 5,440 x 3 | Approx 16,320 QPS |
Storage Estimates
| Data Type | Size per Unit | Daily Volume | Daily Storage |
|---|---|---|---|
| Audio inputs (ASR) | 30 seconds = 480 KB (16-bit PCM) | 100M files | Approx 48 TB/day |
| Audio outputs (TTS) | 10 seconds = 160 KB | 200M files | Approx 32 TB/day |
| OCR images | 2 MB average | 70M images | Approx 140 TB/day |
| Text metadata | 500 bytes per request | 470M requests | Approx 235 GB/day |
| Model artifacts | Static | N/A | Approx 2 TB total |
| Training data | Static plus growing | N/A | Approx 50 TB total |
GPU Compute Estimates
| Model | GPU Type | Batch Size | Latency | GPU Hours/Day | |
|---|---|---|---|---|---|
| ASR (Whisper-large-v3 fine-tuned) | A100 80GB | 32 | 150ms per utterance | Approx 4,200 | |
| TTS (VITS2 fine-tuned) | A100 80GB | 16 | 200ms per utterance | Approx 5,500 | |
| Translation (NLLB-200 fine-tuned) | A100 80GB | 64 | 80ms per sentence | Approx 1,100 | |
| OCR (Donut fine-tuned) | A100 80GB | 8 | 350ms per page | Approx 3,400 | |
| Text Understanding (IndicBERT) | A100 80GB | 128 | 30ms per request | Approx 420 | |
| Toxicity Detection | A100 80GB | 256 | 15ms per request | Approx 210 | |
| Total GPU fleet | Approximately 600 to 800 A100 equivalents | Approx 14,830 | |||
Bandwidth Estimates
Incoming audio traffic at 100M ASR requests of 30 seconds each equals roughly 48 TB per day, or approximately 4.4 Gbps sustained. Outgoing audio from TTS adds another 2.9 Gbps. Text-based APIs (translation, NLP, toxicity) add approximately 500 Mbps. Total bandwidth requirement is approximately 8 to 10 Gbps sustained, peaking at 25 to 30 Gbps during peak hours. This requires multiple 10 Gbps links and geographic distribution across at least two Indian data centre regions (Mumbai and Chennai, or Mumbai and Hyderabad) for low-latency access from all parts of India.
5. Data Model and Storage Schema
Entity Relationship
PostgreSQL Schema
SQL
CREATE TABLE languages (
code VARCHAR(10) PRIMARY KEY,
name VARCHAR(100) NOT NULL,
native_name VARCHAR(100) NOT NULL,
script VARCHAR(50) NOT NULL,
is_scheduled BOOLEAN DEFAULT true,
resource_level FLOAT DEFAULT 0.5,
bcp47_tag VARCHAR(20) NOT NULL,
created_at TIMESTAMP DEFAULT NOW()
);
CREATE TABLE models (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
name VARCHAR(200) NOT NULL,
model_type VARCHAR(20) NOT NULL,
version VARCHAR(50) NOT NULL,
supported_languages JSONB DEFAULT '[]',
model_path TEXT NOT NULL,
config JSONB DEFAULT '{}',
accuracy_score FLOAT,
is_active BOOLEAN DEFAULT true,
deployed_at TIMESTAMP DEFAULT NOW(),
created_at TIMESTAMP DEFAULT NOW(),
UNIQUE(name, version)
);
CREATE TABLE inference_requests (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
service_type VARCHAR(20) NOT NULL,
source_language VARCHAR(10) REFERENCES languages(code),
target_language VARCHAR(10) REFERENCES languages(code),
model_id UUID REFERENCES models(id),
user_id BIGINT REFERENCES users(id),
status VARCHAR(20) DEFAULT 'pending',
input_size_bytes BIGINT,
output_size_bytes BIGINT,
latency_ms FLOAT,
request_metadata JSONB DEFAULT '{}',
created_at TIMESTAMP DEFAULT NOW(),
completed_at TIMESTAMP
);
CREATE TABLE training_datasets (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
name VARCHAR(200) NOT NULL,
language_code VARCHAR(10) REFERENCES languages(code),
domain VARCHAR(100),
sample_count BIGINT DEFAULT 0,
total_hours FLOAT DEFAULT 0,
quality_score FLOAT,
storage_path TEXT NOT NULL,
license_type VARCHAR(100),
created_at TIMESTAMP DEFAULT NOW()
);
CREATE TABLE audio_files (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
storage_path TEXT NOT NULL,
language_code VARCHAR(10) REFERENCES languages(code),
sample_rate INTEGER DEFAULT 16000,
bit_depth INTEGER DEFAULT 16,
channels INTEGER DEFAULT 1,
duration_ms INTEGER,
format VARCHAR(20) DEFAULT 'wav',
transcription TEXT,
speaker_id VARCHAR(100),
quality_score FLOAT,
created_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX idx_inference_requests_user ON inference_requests(user_id, created_at DESC);
CREATE INDEX idx_inference_requests_status ON inference_requests(status, created_at DESC);
CREATE INDEX idx_inference_requests_language ON inference_requests(source_language, target_language);
CREATE INDEX idx_audio_files_language ON audio_files(language_code, created_at DESC);
CREATE INDEX idx_models_active ON models(model_type, is_active) WHERE is_active = true;
Redis Cache Schema
C#
public class IndicCacheService
{
private readonly IConnectionMultiplexer _redis;
private const string MODEL_CACHE_PREFIX = "model:active:";
private const string LANGUAGE_CACHE_PREFIX = "lang:meta:";
private const string TRANSLATION_CACHE_PREFIX = "mt:cache:";
private const int DEFAULT_TTL_HOURS = 24;
public async Task<CachedTranslationResult?> GetCachedTranslationAsync(
string sourceLang, string targetLang, string contentHash)
{
var key = $"{TRANSLATION_CACHE_PREFIX}{sourceLang}:{targetLang}:{contentHash}";
var db = _redis.GetDatabase();
var cached = await db.StringGetAsync(key);
return cached.HasValue
? JsonSerializer.Deserialize<CachedTranslationResult>(cached)
: null;
}
public async Task CacheTranslationAsync(
string sourceLang, string targetLang, string contentHash,
CachedTranslationResult result, TimeSpan? ttl = null)
{
var key = $"{TRANSLATION_CACHE_PREFIX}{sourceLang}:{targetLang}:{contentHash}";
var db = _redis.GetDatabase();
var serialized = JsonSerializer.Serialize(result);
await db.StringSetAsync(key, serialized, ttl ?? TimeSpan.FromHours(DEFAULT_TTL_HOURS));
}
public async Task<ModelConfig?> GetActiveModelAsync(string modelType, string language)
{
var key = $"{MODEL_CACHE_PREFIX}{modelType}:{language}";
var db = _redis.GetDatabase();
var cached = await db.HashGetAllAsync(key);
return cached.Length > 0 ? MapToModelConfig(cached) : null;
}
}
6. High-Level Architecture
Architecture Principles
- Language-Aware Routing: Every request carries a language code. The API gateway routes to language-specific model instances to maximise cache hits and reduce cold-start latency.
- GPU Pool Isolation: Each model type (ASR, TTS, MT, OCR) runs in its own GPU resource pool to prevent noisy-neighbour problems. High-priority ASR models are never starved by batch OCR jobs.
- Graceful Degradation: If a specific language model is unavailable, the system falls back to a generic multilingual model (with reduced accuracy) rather than failing the request entirely.
- Edge Caching: Frequent translations and TTS outputs are cached at edge nodes in Mumbai, Delhi, Chennai, and Hyderabad to serve requests within 50ms for cache hits.
- India-First Data Residency: All data is stored and processed exclusively within Indian data centres. No audio or text data leaves Indian borders at any point in the pipeline.
Service Breakdown
| Service | Responsibility | Language | GPU Type | Instances |
|---|---|---|---|---|
| ASR Service | Audio transcription | C# and Python gRPC | A100 | 200 |
| TTS Service | Speech synthesis | C# and Python gRPC | A100 | 250 |
| Translation Service | Text translation | C# and Python gRPC | A100 | 80 |
| OCR Service | Document image OCR | C# and Python gRPC | A100 | 120 |
| NLP Service | Sentiment, NER, summarisation | C# and Python gRPC | T4 | 60 |
| Toxicity Service | Content moderation | C# and Python gRPC | T4 | 30 |
7. API Design
Speech-to-Text API
HTTP
POST /v1/asr/transcribe HTTP/1.1
Host: api.sarvam-platform.in
Authorization: Bearer sk-xxxxxxxxxxxx
Content-Type: multipart/form-data
Form Fields:
language: hi
model: saaras-v2
enable_timestamps: true
enable_punctuation: true
audio: [binary WAV/OGG/MP3 data]
Response 200:
{
"request_id": "req_abc123def456",
"language": "hi",
"results": [
{
"transcript": "Namaste, aaj ka mausam bahut achha hai.",
"confidence": 0.96,
"words": [
{"word": "Namaste", "start_ms": 0, "end_ms": 620, "confidence": 0.98},
{"word": "aaj", "start_ms": 780, "end_ms": 940, "confidence": 0.97},
{"word": "ka", "start_ms": 960, "end_ms": 1050, "confidence": 0.99},
{"word": "mausam", "start_ms": 1100, "end_ms": 1480, "confidence": 0.95},
{"word": "bahut", "start_ms": 1520, "end_ms": 1800, "confidence": 0.97},
{"word": "achha", "start_ms": 1840, "end_ms": 2200, "confidence": 0.94}
],
"duration_ms": 2800
}
],
"model_version": "saaras-v2.1"
}
Machine Translation API
HTTP
POST /v1/translate HTTP/1.1
Host: api.sarvam-platform.in
Authorization: Bearer sk-xxxxxxxxxxxx
Content-Type: application/json
{
"input": [
{"text": "Bharat ek mahan desh hai jahan vividhta mein ekta ka sandesh diya jata hai."}
],
"source_language": "hi",
"target_language": "en",
"mode": "formal",
"model": "indictranslate-v3"
}
Response 200:
{
"request_id": "req_xyz789",
"translations": [
{
"translated_text": "India is a great country where the message of unity in diversity is conveyed.",
"confidence": 0.91,
"source_language": "hi",
"target_language": "en"
}
],
"model_version": "indictranslate-v3.2"
}
Text-to-Speech API
HTTP
POST /v1/tts/synthesize HTTP/1.1
Host: api.sarvam-platform.in
Authorization: Bearer sk-xxxxxxxxxxxx
Content-Type: application/json
{
"input": "Namaste, aapka swagat hai. Aaj ka mausam bahut achha hai.",
"language": "hi",
"voice_id": "FEMALE_1",
"speed": 1.0,
"output_format": "wav",
"sample_rate": 22050
}
Response 200:
{
"request_id": "req_aud123",
"audio_url": "https://storage.sarvam-platform.in/tts-output/req_aud123.wav",
"duration_ms": 4200,
"language": "hi",
"expires_at": "2026-06-29T10:00:00Z"
}
Streaming ASR API (WebSocket)
C#
public class StreamingAsrController : ControllerBase
{
[HttpPost("/v1/asr/stream/start")]
public async Task<ActionResult> StartStream([FromBody] StreamConfig config)
{
var sessionId = Guid.NewGuid().ToString();
var channel = await _asrService.OpenStreamAsync(new StreamRequest
{
SessionId = sessionId,
Language = config.Language,
Model = config.Model,
EnableInterimResults = true,
SampleRate = config.SampleRate ?? 16000
});
return Ok(new { session_id = sessionId, ws_url = $"/v1/asr/stream/{sessionId}" });
}
[HttpPost("/v1/asr/stream/{sessionId}/chunk")]
public async Task StreamChunk(string sessionId, [FromBody] AudioChunk chunk)
{
var intermediate = await _asrService.ProcessChunkAsync(sessionId, chunk.AudioData);
if (intermediate.HasPartialResult)
{
await WebSocketHub.SendAsync(sessionId, new
{
type = "interim",
transcript = intermediate.PartialTranscript,
is_final = false
});
}
}
[HttpPost("/v1/asr/stream/{sessionId}/end")]
public async Task<ActionResult> EndStream(string sessionId)
{
var final = await _asrService.EndStreamAsync(sessionId);
return Ok(new { transcript = final.Transcript, confidence = final.Confidence });
}
}
8. Indic Language NLP Pipeline
The NLP pipeline is the intelligence layer that powers text understanding across all Indic languages. Unlike English NLP pipelines that can leverage mature tools like spaCy and Hugging Face Transformers out-of-the-box, Indic language NLP requires custom components for tokenization, sentence segmentation, part-of-speech tagging, named entity recognition, and dependency parsing. The pipeline must handle Unicode complexity, multi-script input, code-mixed text, and varying levels of linguistic resource availability across India's 22 scheduled languages.
Pipeline Architecture
Script-Aware Tokenizer
C#
public class IndicScriptTokenizer
{
private readonly Dictionary<string, ScriptConfig> _scriptConfigs;
public IndicScriptTokenizer()
{
_scriptConfigs = new Dictionary<string, ScriptConfig>
{
["devanagari"] = new ScriptConfig
{
UnicodeStart = 0x0900, UnicodeEnd = 0x097F,
ConjunctHandling = ConjunctStrategy.SplitByAkshara,
MatraJoining = true
},
["bengali"] = new ScriptConfig
{
UnicodeStart = 0x0980, UnicodeEnd = 0x09FF,
ConjunctHandling = ConjunctStrategy.Preserve,
MatraJoining = true
},
["tamil"] = new ScriptConfig
{
UnicodeStart = 0x0B80, UnicodeEnd = 0x0BFF,
ConjunctHandling = ConjunctStrategy.Preserve,
MatraJoining = true
},
["telugu"] = new ScriptConfig
{
UnicodeStart = 0x0C00, UnicodeEnd = 0x0C7F,
ConjunctHandling = ConjunctStrategy.Preserve,
MatraJoining = true
},
["kannada"] = new ScriptConfig
{
UnicodeStart = 0x0C80, UnicodeEnd = 0x0CFF,
ConjunctHandling = ConjunctStrategy.Preserve,
MatraJoining = true
},
["malayalam"] = new ScriptConfig
{
UnicodeStart = 0x0D00, UnicodeEnd = 0x0D7F,
ConjunctHandling = ConjunctStrategy.LigatureAware,
MatraJoining = true
}
};
}
public List<string> Tokenize(string text, string scriptHint = "auto")
{
var script = scriptHint == "auto" ? DetectScript(text) : scriptHint;
var config = _scriptConfigs.GetValueOrDefault(script);
var tokens = new List<string>();
var currentToken = new StringBuilder();
foreach (var rune in text.EnumerateRunes())
{
if (IsWhitespace(rune))
{
if (currentToken.Length > 0)
{
tokens.Add(currentToken.ToString());
currentToken.Clear();
}
continue;
}
if (config != null && IsInScriptRange(rune, config) && IsMatra(rune) && currentToken.Length > 0)
{
currentToken.Append(rune.ToString());
}
else
{
if (currentToken.Length > 0)
{
tokens.Add(currentToken.ToString());
currentToken.Clear();
}
currentToken.Append(rune.ToString());
}
}
if (currentToken.Length > 0) tokens.Add(currentToken.ToString());
return tokens;
}
}
Named Entity Recognition
NER in Indian languages faces unique challenges. Person names vary enormously across languages, location names may use local scripts or transliterated forms, and organisation names often appear in English even within otherwise Indic-language text. The platform uses a multi-granularity NER approach: a character-level CNN for robust handling of unknown words and morphological variation, combined with a word-level BiLSTM-CRF for sequence labelling. The model is trained on datasets from multiple NER shared tasks (IIIT-H datasets, IIT Bombay NER corpora) and supplemented with automatically labelled data from Wikipedia infoboxes and government gazettes in all 22 scheduled languages.
9. Speech-to-Text (ASR) for Indian Languages
Speech-to-Text is the most requested capability on the platform, driven by India's voice-first internet usage pattern. WhatsApp voice notes, IVR systems, dictation tools, and voice search all require accurate transcription across Indian languages. The platform's ASR engine, codenamed Saaras, is a fine-tuned variant of OpenAI's Whisper architecture, trained on over 100,000 hours of Indian language speech data curated from government proceedings (Sansad TV), audiobooks (Sahitya Akademi), radio broadcasts (All India Radio), YouTube videos, and crowdsourced data collected through the IndicVoices project.
ASR Architecture
ASR Service Implementation
C#
public class AsrInferenceService : IAsrService
{
private readonly IModelRegistry _modelRegistry;
private readonly IAudioPreprocessor _preprocessor;
private readonly IGrpcClient<WhisperService.WhisperServiceClient> _whisperClient;
private readonly ICacheService _cache;
public async Task<AsrResult> TranscribeAsync(AsrRequest request)
{
var cacheKey = ComputeAudioHash(request.AudioData, request.Language);
var cached = await _cache.GetAsync<AsrResult>($"asr:{cacheKey}");
if (cached != null) return cached;
var model = await _modelRegistry.GetActiveModelAsync("asr", request.Language)
?? throw new ModelNotFoundException($"No ASR model for: {request.Language}");
var processedAudio = await _preprocessor.PreprocessAsync(request.AudioData, new AudioConfig
{
TargetSampleRate = 16000, TargetBitDepth = 16,
NormalizeVolume = true, RemoveNoise = request.EnableDenoising, TrimSilence = true
});
var spectrogram = AudioFeatureExtractor.ExtractMelSpectrogram(processedAudio, new MelConfig
{
SampleRate = 16000, NFFT = 400, HopLength = 160, NMelBins = 80
});
var grpcRequest = new TranscribeRequest
{
ModelId = model.Id.ToString(),
SpectrogramData = { spectrogram.Flatten() },
Language = request.Language,
EnableTimestamps = request.EnableTimestamps,
BeamSize = request.BeamSize ?? 5
};
var response = await _whisperClient.TranscribeAsync(grpcRequest);
var result = new AsrResult
{
RequestId = request.RequestId,
Transcript = response.Text,
Language = response.DetectedLanguage,
Confidence = response.AverageConfidence,
Duration = TimeSpan.FromMilliseconds(response.AudioDurationMs),
WordTimings = response.WordTimings.Select(wt => new WordTiming
{
Word = wt.Word,
Start = TimeSpan.FromMilliseconds(wt.StartMs),
End = TimeSpan.FromMilliseconds(wt.EndMs),
Confidence = wt.Confidence
}).ToList()
};
await _cache.SetAsync($"asr:{cacheKey}", result, TimeSpan.FromHours(1));
return result;
}
}
Training Data for Indian ASR
| Language | Hours | Source | WER Target |
|---|---|---|---|
| Hindi | 15,000 | Sansad TV, AIR, YouTube | Below 8% |
| Bengali | 8,000 | Bangla YouTube, Radio | Below 10% |
| Tamil | 10,000 | Sun TV, speeches | Below 9% |
| Telugu | 9,000 | TV debates, audiobooks | Below 10% |
| Marathi | 6,000 | Lokmat, Zee24Tas | Below 11% |
| Kannada | 5,000 | Public Radio, podcasts | Below 12% |
| Malayalam | 5,500 | Manorama, TV channels | Below 11% |
| Gujarati | 4,000 | Guj Samachar, radio | Below 12% |
| Odia | 3,000 | OTV, radio | Below 14% |
| Punjabi | 4,500 | PTC News, music | Below 12% |
| Assamese | 2,000 | Doordarshan, radio | Below 15% |
| Others (11) | 2,000 each | Mixed sources | Below 15% |
10. Text-to-Speech (TTS)
The TTS engine converts text in any of the 22 scheduled Indian languages into natural, intelligible speech. The platform supports multiple voice personas per language (typically 4 to 6 male and 4 to 6 female voices), each trained on a single professional voice artist to ensure consistency and naturalness. The TTS system uses a VITS2-based architecture with language-specific acoustic models and a shared multi-lingual HiFi-GAN vocoder for waveform generation. Prosody modelling is critical for Indian languages, where tonal patterns carry semantic meaning: a rising intonation at the end of a Hindi sentence turns a statement into a question, while tonal variations in Tamil can change word meaning entirely.
TTS Pipeline Architecture
TTS Text Normalization
C#
public class IndicTextNormalizer
{
public async Task<string> NormalizeAsync(string text, string language)
{
var normalized = text.Normalize(NormalizationForm.FormC);
normalized = ExpandNumbers(normalized, language);
normalized = ExpandAbbreviations(normalized, language);
normalized = NormalizeDateTime(normalized, language);
normalized = NormalizeCurrency(normalized, language);
normalized = NormalizePunctuation(normalized);
return normalized;
}
private string ExpandNumbers(string text, string language)
{
var numberPattern = @"\b\d+(?:\.\d+)?\b";
return Regex.Replace(text, numberPattern, match =>
{
var number = double.Parse(match.Value);
return language switch
{
"hi" => ExpandHindiNumber(number),
"bn" => ExpandBengaliNumber(number),
"ta" => ExpandTamilNumber(number),
"te" => ExpandTeluguNumber(number),
_ => ExpandGenericIndicNumber(number, language)
};
});
}
private string ExpandHindiNumber(double number)
{
if (number >= 10000000)
return $"{ExpandHindiNumber(number / 10000000)} crore";
if (number >= 100000)
return $"{ExpandHindiNumber(number / 100000)} lakh";
if (number >= 1000)
return $"{ExpandHindiNumber(number / 1000)} hazaar";
var ones = new[] { "", "ek", "do", "teen", "chaar", "paanch",
"chah", "saat", "aath", "nau", "das" };
if (number < ones.Length) return ones[(int)number];
return number.ToString();
}
}
Supported Voices
| Language | Female Voices | Male Voices | Total |
|---|---|---|---|
| Hindi | 6 | 5 | 11 |
| Bengali | 4 | 4 | 8 |
| Tamil | 4 | 4 | 8 |
| Telugu | 4 | 3 | 7 |
| Marathi | 3 | 3 | 6 |
| Kannada | 3 | 3 | 6 |
| Malayalam | 3 | 3 | 6 |
| Gujarati | 3 | 3 | 6 |
| Punjabi | 3 | 3 | 6 |
| Odia | 2 | 2 | 4 |
| Others (12) | 2 each | 2 each | 48 |
11. Machine Translation Engine
The machine translation engine supports all 462 possible language pairs among India's 22 scheduled languages, plus 22 additional pairs with English. The system uses a fine-tuned variant of Meta's NLLB-200 (No Language Left Behind) architecture, supplemented with domain-specific adapters for government, legal, medical, and technical text. Translation quality is benchmarked using BLEU, COMET, and human evaluation on standard test sets, with quality targets of 40+ BLEU for high-resource pairs (Hindi-English, Bengali-English) and 25+ BLEU for low-resource pairs (Manipuri-Konkani).
Translation Service Implementation
C#
public class TranslationService : ITranslationService
{
private readonly IModelRegistry _models;
private readonly ICacheService _cache;
public async Task<TranslationResult> TranslateAsync(TranslationRequest request)
{
if (request.SourceLanguage == request.TargetLanguage)
return TranslationResult.Identity(request.Input);
var cacheHash = ComputeContentHash(request.Input, request.Mode);
var cacheKey = $"mt:{request.SourceLanguage}:{request.TargetLanguage}:{cacheHash}";
var cached = await _cache.GetAsync<TranslationResult>(cacheKey);
if (cached != null) return cached;
var model = await _models.GetActiveModelAsync("mt",
$"{request.SourceLanguage}-{request.TargetLanguage}")
?? await _models.GetActiveModelAsync("mt", "multilingual");
var inferenceRequest = new TranslationInferenceRequest
{
ModelId = model.Id,
SourceTexts = request.Input.Split('\n')
.Where(line => !string.IsNullOrWhiteSpace(line)).ToArray(),
SourceLanguage = Bcp47ToModelLang(request.SourceLanguage),
TargetLanguage = Bcp47ToModelLang(request.TargetLanguage),
MaxNewTokens = 512, BeamSize = 5
};
var rawResult = await CallInferenceEndpoint<RawTranslationResponse>(
"/translate", inferenceRequest);
var result = new TranslationResult
{
RequestId = request.RequestId,
Translations = rawResult.TranslatedTexts.Select((text, idx) =>
new TranslatedSegment
{
SourceText = inferenceRequest.SourceTexts[idx],
TranslatedText = text,
Confidence = rawResult.Scores?[idx] ?? 0.0f
}).ToList(),
SourceLanguage = request.SourceLanguage,
TargetLanguage = request.TargetLanguage
};
await _cache.SetAsync(cacheKey, result, TimeSpan.FromHours(6));
return result;
}
private string Bcp47ToModelLang(string bcp47) => bcp47 switch
{
"hi" => "hin_Deva", "bn" => "ben_Beng", "ta" => "tam_Taml",
"te" => "tel_Telu", "mr" => "mr_Deva", "kn" => "kan_Knda",
"ml" => "mal_Mlym", "gu" => "guj_Gujr", "pa" => "pan_Guru",
"or" => "ory_Orya", "as" => "asm_Beng", "en" => "eng_Latn",
_ => bcp47
};
}
Translation Quality Benchmarks
| Language Pair | BLEU | COMET | Human Rating (1-5) |
|---|---|---|---|
| Hindi to English | 44.2 | 0.87 | 4.3 |
| English to Hindi | 41.8 | 0.85 | 4.2 |
| Bengali to English | 39.5 | 0.83 | 4.1 |
| Tamil to English | 37.1 | 0.81 | 4.0 |
| Hindi to Bengali | 32.6 | 0.78 | 3.8 |
| Tamil to Telugu | 28.4 | 0.73 | 3.5 |
| Assamese to English | 28.8 | 0.72 | 3.4 |
| Manipuri to Hindi | 22.1 | 0.65 | 3.1 |
| Konkani to English | 24.5 | 0.68 | 3.2 |
12. Sentiment Analysis and Toxicity Detection
Sentiment analysis and toxicity detection are critical for social media monitoring, customer feedback analysis, and content moderation in India. The challenge is enormous: toxic content in Indian languages often uses creative transliteration, euphemisms, and culturally specific slang that automated systems struggle to detect. The platform's toxicity detection system operates in real-time, processing social media feeds and flagging content with less than 50ms latency.
Toxicity Detection Performance
| Language | F1 Score | Precision | Recall | Latency P99 |
|---|---|---|---|---|
| Hindi | 0.94 | 0.96 | 0.92 | 12ms |
| Bengali | 0.91 | 0.93 | 0.89 | 14ms |
| Tamil | 0.90 | 0.92 | 0.88 | 15ms |
| Hinglish | 0.88 | 0.90 | 0.86 | 18ms |
| Telugu | 0.89 | 0.91 | 0.87 | 14ms |
| Marathi | 0.87 | 0.89 | 0.85 | 15ms |
13. OCR for Indian Scripts
OCR for Indian scripts is substantially more challenging than OCR for Latin text. Indic scripts have complex character shapes, extensive use of conjunct characters (combined consonants), vowel marks that attach above and below the base line, and inconsistent spacing between characters. Handwritten Indic script OCR is even harder due to personal variation in stroke formation. The platform supports OCR across all 13 major Indic scripts used for the 22 scheduled languages, handling both printed and handwritten text. The system processes approximately 70 million document pages per day, including government forms, educational certificates, land records, and medical prescriptions.
OCR Service Implementation
C#
public class IndicOcrService : IOcrService
{
private readonly IModelRegistry _modelRegistry;
private readonly IImagePreprocessor _preprocessor;
private readonly ILayoutAnalyzer _layoutAnalyzer;
public async Task<OcrResult> ExtractTextAsync(OcrRequest request)
{
var preprocessed = await _preprocessor.PreprocessAsync(request.ImageData, new PreprocessConfig
{
Deskew = true, Binarize = true, Denoise = true,
UpscaleFactor = 2.0f, TargetDPI = 300
});
var detectedScript = await DetectScriptAsync(preprocessed);
var detectedLanguage = await DetectLanguageAsync(preprocessed, detectedScript);
var model = await _modelRegistry.GetActiveModelAsync("ocr", detectedLanguage)
?? throw new ModelNotFoundException($"No OCR model for: {detectedLanguage}");
var layoutBlocks = await _layoutAnalyzer.AnalyzeAsync(preprocessed);
var results = new List<OcrBlock>();
foreach (var block in layoutBlocks.OrderBy(b => b.Y).ThenBy(b => b.X))
{
var croppedImage = CropImage(preprocessed, block.BoundingBox);
var ocrText = await RecognizeTextAsync(croppedImage, model, detectedLanguage);
results.Add(new OcrBlock
{
Text = ocrText.Text,
Confidence = ocrText.Confidence,
BlockType = block.Type,
BoundingBox = block.BoundingBox
});
}
return new OcrResult
{
RequestId = request.RequestId,
DetectedScript = detectedScript,
DetectedLanguage = detectedLanguage,
FullText = string.Join("\n", results.Select(r => r.Text)),
Blocks = results
};
}
}
OCR Performance by Script
| Script | Languages | Printed CER | Handwritten CER |
|---|---|---|---|
| Devanagari | Hindi, Marathi, Nepali, Sanskrit | 1.8% | 8.5% |
| Bengali-Assamese | Bengali, Assamese | 2.1% | 9.2% |
| Tamil | Tamil | 2.5% | 10.1% |
| Telugu | Telugu | 2.3% | 9.8% |
| Kannada | Kannada | 2.4% | 10.5% |
| Malayalam | Malayalam | 3.1% | 12.3% |
| Gujarati | Gujarati | 2.0% | 8.9% |
| Gurmukhi | Punjabi | 2.2% | 9.5% |
| Odia | Odia | 3.5% | 13.8% |
14. Dataset Curation and Annotation
The quality of a multilingual AI platform is fundamentally determined by the quality of its training data. Unlike English, where massive corpora exist on the web, Indian language data is fragmented across scripts, domains, and quality levels. The platform's data curation team works with 500+ annotators across India, covering all 22 scheduled languages, to build high-quality training datasets. Annotation guidelines are language-specific, accounting for dialectal variation, formality levels, and regional vocabulary differences. For example, Hindi has at least 25 major dialects (Bhojpuri, Maithili, Awadhi, Braj, and more), and a training dataset must represent this diversity to build robust models.
Annotation Orchestration
C#
public class AnnotationOrchestrator
{
private readonly ITaskQueue _taskQueue;
private readonly IAnnotatorPool _annotatorPool;
public async Task<Guid> CreateAnnotationBatchAsync(DatasetConfig config)
{
var annotators = await _annotatorPool.SelectAnnotatorsAsync(
language: config.Language,
taskType: config.TaskType,
minExperience: config.MinExperienceLevel,
count: config.ReviewsPerSample
);
var samples = await LoadUnannotatedDataAsync(config);
var batchId = Guid.NewGuid();
foreach (var sample in samples)
{
var task = new AnnotationTask
{
TaskId = Guid.NewGuid(),
TaskType = config.TaskType,
Language = config.Language,
SourceData = sample.Content,
Labels = config.LabelSchema,
RequiredAnnotations = config.ReviewsPerSample,
Annotators = annotators.Select(a => new AssignedAnnotator
{
AnnotatorId = a.Id,
AssignedAt = DateTime.UtcNow,
Deadline = DateTime.UtcNow.AddHours(config.DeadlineHours)
}).ToList()
};
await _taskQueue.EnqueueAsync(task);
}
return batchId;
}
public async Task<InterAnnotatorAgreement> ComputeAgreementAsync(Guid batchId)
{
var completedTasks = await GetCompletedTasksAsync(batchId);
var groupedBySample = completedTasks.GroupBy(t => t.SourceData);
var agreement = new InterAnnotatorAgreement();
foreach (var group in groupedBySample)
{
var annotations = group.Select(t => t.Annotation).ToList();
var kappa = ComputeFleissKappa(annotations);
agreement.Scores.Add(new SampleAgreement
{
SampleId = group.Key, Kappa = kappa, Annotations = annotations.Count
});
}
agreement.OverallKappa = agreement.Scores.Average(s => s.Kappa);
return agreement;
}
}
Dataset Sizes by Language
| Language | ASR (Hours) | Translation (Pairs) | NER (Sentences) | Toxicity (Samples) |
|---|---|---|---|---|
| Hindi | 15,000 | 2.5M | 120K | 500K |
| Bengali | 8,000 | 1.2M | 60K | 300K |
| Tamil | 10,000 | 1.5M | 80K | 350K |
| Telugu | 9,000 | 1.3M | 70K | 320K |
| Marathi | 6,000 | 800K | 50K | 250K |
| Kannada | 5,000 | 700K | 45K | 220K |
| Malayalam | 5,500 | 750K | 42K | 230K |
| Gujarati | 4,000 | 600K | 35K | 200K |
| Punjabi | 4,500 | 650K | 38K | 210K |
| Odia | 3,000 | 400K | 25K | 150K |
| Assamese | 2,000 | 300K | 20K | 120K |
| Others (11) | 2,000 each | 250K each | 18K each | 100K each |
Annotation Quality Control
Quality control is enforced through multiple mechanisms: inter-annotator agreement (Cohen's kappa above 0.7 required), golden set validation (hidden correct answers embedded in annotation tasks), anomaly detection (flagging annotators whose agreement drops below 0.6), and periodic calibration sessions where annotators discuss edge cases. For ASR transcription, a two-pass system is used: the first pass generates automatic transcription using the current ASR model, and human annotators correct errors. This is 5x more efficient than transcribing from scratch. For toxicity annotation, a separate team of trained reviewers with psychology backgrounds handles the most ambiguous cases, as cultural context significantly affects toxicity perception across Indian languages.
15. Model Training Pipeline
The training pipeline orchestrates the end-to-end lifecycle of model development: from raw data ingestion through preprocessing, training, evaluation, and deployment. The pipeline is built on Kubernetes with custom operators for ML workloads, using Ray for distributed training and MLflow for experiment tracking. Training runs are reproducible: every model version is tied to a specific data snapshot, hyperparameter configuration, and code commit. The platform trains on a cluster of 512 NVIDIA A100 GPUs distributed across two Indian data centre regions.
Training Pipeline Architecture
Distributed Training Configuration
C#
public class TrainingJobManager
{
private readonly IKubernetesClient _k8s;
private readonly IModelRegistry _registry;
public async Task<TrainingJob> LaunchTrainingAsync(TrainingConfig config)
{
var job = new TrainingJob
{
Id = Guid.NewGuid(),
ModelType = config.ModelType,
Language = config.Language,
DatasetVersion = config.DatasetVersion,
Hyperparameters = config.Hyperparameters,
Status = TrainingStatus.Queued,
CreatedAt = DateTime.UtcNow
};
var k8sJob = BuildKubernetesJob(job, config);
await _k8s.CreateNamespacedJobAsync(k8sJob, "training-namespace");
return job;
}
private KubernetesJob BuildKubernetesJob(TrainingJob job, TrainingConfig config)
{
return new KubernetesJob
{
Metadata = new ObjectMeta
{
Name = $"train-{job.ModelType}-{job.Language}-{job.Id:N8}"
},
Spec = new JobSpec
{
Parallelism = config.GPUCount,
Template = new PodTemplateSpec
{
Spec = new PodSpec
{
Containers = new[]
{
new Container
{
Name = "trainer",
Image = $"registry.sarvam.in/trainer:{config.ImageTag}",
Resources = new ResourceRequirements
{
Limits = new Dictionary<string, ResourceQuantity>
{
["nvidia.com/gpu"] = new ResourceQuantity($"{config.GPUsPerReplica}"),
["memory"] = new ResourceQuantity($"{config.MemoryGB}Gi")
}
},
Env = new[]
{
new EnvVar("WANDB_PROJECT", "sarvam-training"),
new EnvVar("WANDB_RUN_NAME", job.Id.ToString())
}
}
},
NodeSelector = new Dictionary<string, string>
{
["gpu-pool"] = "a100-80gb"
}
}
}
}
};
}
}
Training Resource Allocation
| Model | GPU Count | Training Time | Data Size | Compute (GPU-hours) |
|---|---|---|---|---|
| Saaras ASR (Hindi) | 64 | 72 hours | 15K hours audio | 4,608 |
| Saaras ASR (All 22) | 256 | 168 hours | 85K hours audio | 43,008 |
| TTS Model (Per language) | 32 | 96 hours | 50 hours audio per voice | 3,072 |
| IndicTranslate (Fine-tune) | 128 | 48 hours | 5M sentence pairs | 6,144 |
| IndicBERT (Pre-train) | 256 | 336 hours | 50B tokens | 86,016 |
| OCR Donut (Per script) | 16 | 48 hours | 2M pages | 768 |
| Toxicity Classifier | 8 | 24 hours | 2M samples | 192 |
16. Low-Resource Language Handling
Of India's 22 scheduled languages, at least 8 are considered low-resource in the AI context: Assamese, Manipuri, Konkani, Sindhi, Dogri, Maithili, Bodo, and Santhali. These languages have limited digital text corpora, minimal parallel translation data, and very few speech datasets. The platform employs several strategies to handle low-resource languages effectively: transfer learning from related high-resource languages, multilingual pre-training with language-family-aware sampling, data augmentation through back-translation, and active learning to prioritise the most impactful data collection efforts.
Transfer Learning Strategy
C#
public class LowResourceTransferLearner
{
private readonly Dictionary<string, LanguageFamily> _languageFamilies = new()
{
["as"] = LanguageFamily.IndoAryan,
["bn"] = LanguageFamily.IndoAryan,
["hi"] = LanguageFamily.IndoAryan,
["mr"] = LanguageFamily.IndoAryan,
["ta"] = LanguageFamily.Dravidian,
["te"] = LanguageFamily.Dravidian,
["kn"] = LanguageFamily.Dravidian,
["ml"] = LanguageFamily.Dravidian,
["mni"] = LanguageFamily.TibetoBurman,
["sat"] = LanguageFamily.Austroasiatic,
["brx"] = LanguageFamily.SinoTibetan
};
public async Task<TransferConfig> PlanTransferAsync(
string targetLanguage, string taskType)
{
var family = _languageFamilies[targetLanguage];
var donorLanguages = _languageFamilies
.Where(kvp => kvp.Value == family && kvp.Key != targetLanguage)
.Select(kvp => kvp.Key).ToList();
var rankedDonors = await RankDonorsBySimilarityAsync(
targetLanguage, donorLanguages, taskType);
return new TransferConfig
{
TargetLanguage = targetLanguage,
DonorLanguages = rankedDonors.Take(3).ToList(),
Strategy = DetermineStrategy(targetLanguage),
FreezeLayers = new[] { "encoder.layers.0", "encoder.layers.1" },
LearningRateScale = 0.3f,
MaxEpochs = 50
};
}
private TransferStrategy DetermineStrategy(string language)
{
var resourceLevel = EstimateResourceLevel(language);
return resourceLevel switch
{
ResourceLevel.UltraLow => TransferStrategy.ZeroShotFromRelated,
ResourceLevel.Low => TransferStrategy.FineTuneWithAugmentation,
ResourceLevel.Medium => TransferStrategy.FineTuneOnly,
_ => TransferStrategy.DirectTraining
};
}
}
Data Augmentation Techniques
- Back-Translation: Translate existing English text into the target language using a general MT model, then use the translated text as additional training data. This is particularly effective for translation models where English monolingual data is abundant but Indic parallel data is scarce.
- Cross-Lingual Transfer: Use multilingual pre-trained models (mBERT, XLM-R, IndicBERT) as initialisation points and fine-tune on small target-language datasets. Even 500 labelled examples can produce useful models when starting from a strong multilingual checkpoint.
- Synthetic Speech Generation: For ASR, generate synthetic training audio by using the TTS model to voice text data in the target language. While not as natural as real speech, this can bootstrap a functional ASR model before real speech data is collected.
- Script Transfer: For related languages sharing the same script family (e.g., Bengali-Assamese), train a character-level model on the high-resource language and transfer it directly to the low-resource language with minimal fine-tuning.
- Paraphrase Generation: Use large language models to generate paraphrases of existing training data in the target language, expanding the effective training set size by 3 to 5x.
Low-Resource Language Priority Matrix
| Language | Speakers (Millions) | Resource Level | Priority Strategy | Timeline |
|---|---|---|---|---|
| Maithili | 50 | Ultra-Low | Transfer from Hindi/Bengali | Q1 2027 |
| Santhali | 7.4 | Ultra-Low | Transfer from Bengali + crowdsourcing | Q2 2027 |
| Konkani | 2.5 | Ultra-Low | Transfer from Marathi + Hindi | Q3 2027 |
| Dogri | 3.2 | Ultra-Low | Transfer from Hindi/Punjabi | Q2 2027 |
| Manipuri | 1.8 | Low | Transfer from Bengali + dedicated collection | Q1 2027 |
| Bodo | 1.5 | Ultra-Low | Transfer from Assamese | Q3 2027 |
| Assamese | 15 | Low | Dedicated collection + Bengali transfer | Q4 2026 |
| Sindhi | 25 | Low | Transfer from Hindi/Urdu | Q1 2027 |
17. Code-Switching and Hinglish Support
Code-switching, the practice of alternating between two or more languages within a single conversation or sentence, is a defining characteristic of multilingual speech in India. Studies estimate that over 60% of urban Indian internet users regularly mix languages, with Hindi-English (Hinglish) being the most common combination. A typical Hinglish message might read: "Project ki deadline kal hai, can you please extend it by a week? Bahut busy tha last few days." The platform must understand, process, and generate such code-mixed text naturally.
Code-Switching Detection
C#
public class CodeSwitchingDetector
{
private readonly LanguageIdentificationService _lidService;
public async Task<CodeSwitchAnalysis> AnalyzeAsync(string text)
{
var tokens = text.Split(' ', StringSplitOptions.RemoveEmptyEntries);
var tokenLabels = new List<TokenLanguageLabel>();
foreach (var token in tokens)
{
var prediction = await _lidService.IdentifyTokenLanguageAsync(token);
tokenLabels.Add(new TokenLanguageLabel
{
Token = token,
PrimaryLanguage = prediction.Language,
Confidence = prediction.Confidence,
IsAmbiguous = prediction.Confidence < 0.7f
});
}
var detectedLanguages = tokenLabels
.Where(t => t.Confidence > 0.5f)
.GroupBy(t => t.PrimaryLanguage)
.Select(g => new DetectedLanguageSegment
{
Language = g.Key,
TokenCount = g.Count(),
Ratio = (float)g.Count() / tokens.Length
})
.OrderByDescending(d => d.Ratio).ToList();
var isCodeMixed = detectedLanguages.Count > 1 &&
detectedLanguages[1].Ratio > 0.1f;
return new CodeSwitchAnalysis
{
IsCodeMixed = isCodeMixed,
DetectedLanguages = detectedLanguages,
DominantLanguage = detectedLanguages.FirstOrDefault()?.Language,
TokenLabels = tokenLabels
};
}
}
Hinglish ASR Approach
Traditional ASR systems are trained on monolingual data and fail catastrophically on code-mixed speech. When a speaker says "Mujhe meeting ka agenda chahiye" (Hindi with the English words "meeting" and "agenda"), a Hindi-only ASR might misrecognise the English words, while an English-only ASR would fail on the Hindi portions. The platform addresses this with a multi-encoder ASR architecture: a shared acoustic encoder processes the audio, while two language-specific decoders compete to decode each segment. A language model gate decides which decoder to use at each time step, enabling seamless transitions between languages within a single utterance. This approach achieves 12% WER on Hinglish speech, compared to 35%+ WER from monolingual models.
Code-Mixed Text Normalization
Code-mixed text presents unique normalization challenges. Users may write Hinglish in multiple ways: pure Roman script, Devanagari, or mixed. The normalization pipeline must handle all variants by detecting the script at the token level and routing to the appropriate language model for processing. Transliteration between scripts is performed using a sequence-to-sequence model trained on parallel Devanagari-Roman text pairs, which handles the many-to-one mapping problem where multiple Devanagari characters map to a single Roman transliteration.
18. Government and BIS Compliance
Operating a multilingual AI platform in India requires compliance with multiple regulatory frameworks. The Digital Personal Data Protection Act (DPDPA) 2023 governs data processing and storage. The Information Technology Act 2000 (amended 2008) sets requirements for electronic records. The Bureau of Indian Standards (BIS) has published IS 17100:2018 for translation quality, and the National Platform for Language Technology (Bhashini) mandates interoperability standards for government language services. The Reserve Bank of India requires that financial data in Indian languages be processed and stored within Indian borders.
Compliance Requirements Matrix
| Regulation | Requirement | Implementation | Status |
|---|---|---|---|
| DPDPA 2023 | Consent for data processing | Explicit opt-in consent with purpose limitation | Compliant |
| DPDPA 2023 | Data localisation | All data processed in Indian data centres | Compliant |
| IT Act 2000 | Electronic record integrity | SHA-256 hashing and tamper-proof audit logs | Compliant |
| BIS IS 17100 | Translation quality standards | BLEU above 35 and human evaluation quarterly | Compliant |
| RBI Guidelines | Financial data localisation | Isolated processing zone for financial text | Compliant |
| Bhashini | API interoperability | REST and gRPC interfaces per Bhashini spec | In Progress |
| Accessibility Act | Screen reader compatibility | ARIA labels, semantic HTML, alt text | Compliant |
Compliance Engine
C#
public class ComplianceEngine
{
private readonly IDataClassificationService _classification;
private readonly IAuditLogger _auditLogger;
private readonly IEncryptionService _encryption;
private readonly IConsentManager _consentManager;
public async Task<ProcessingResult> ProcessWithComplianceAsync(
ProcessingRequest request, UserContext user)
{
var residencyCheck = await ValidateDataResidencyAsync(request);
if (!residencyCheck.IsCompliant)
throw new DataResidencyViolationException(residencyCheck.Reason);
var consentStatus = await _consentManager.VerifyConsentAsync(
user.UserId, request.ProcessingPurpose);
if (!consentStatus.HasValidConsent)
throw new ConsentRequiredException(consentStatus.MissingPurposes);
var classification = await _classification.ClassifyAsync(request.InputData);
if (classification.SensitivityLevel == DataSensitivity.Critical)
{
request.InputData = await _encryption.EncryptAtRestAsync(
request.InputData, EncryptionStandard.AES256);
}
var result = await ProcessRequestAsync(request);
await _auditLogger.LogAsync(new AuditEntry
{
UserId = user.UserId,
ServiceType = request.ServiceType,
Language = request.Language,
DataClassification = classification,
ProcessingRegion = "ap-south-1",
Timestamp = DateTimeOffset.UtcNow
});
return result;
}
}
19. API Gateway and Developer Ecosystem
The API gateway is the single entry point for all developer traffic. It handles authentication, rate limiting, request routing, protocol translation (REST to gRPC for backend services), response caching, and usage metering. The gateway is built on Apache APISIX, deployed as a cluster of 12 instances behind a load balancer. It processes approximately 10,000 requests per second at peak, with P99 latency of 8ms for cache hits and 25ms for cache misses.
Rate Limiting Implementation
C#
public class ApiGatewayMiddleware
{
private readonly IRateLimiter _rateLimiter;
private readonly IApiKeyValidator _apiKeyValidator;
public async Task<HttpContext> ProcessRequestAsync(HttpContext context)
{
var apiKey = ExtractApiKey(context.Request);
if (string.IsNullOrEmpty(apiKey))
{
context.Response.StatusCode = 401;
await context.Response.WriteAsJsonAsync(new ErrorResponse
{
Error = "missing_api_key",
Message = "Authorization header with Bearer token required"
});
return context;
}
var keyInfo = await _apiKeyValidator.ValidateAsync(apiKey);
if (keyInfo == null)
{
context.Response.StatusCode = 401;
return context;
}
var rateLimitResult = await _rateLimiter.CheckAsync(
keyInfo.KeyId, keyInfo.PlanTier, context.Request.Path);
if (!rateLimitResult.IsAllowed)
{
context.Response.StatusCode = 429;
context.Response.Headers["Retry-After"] =
rateLimitResult.RetryAfterSeconds.ToString();
return context;
}
context.Items["ApiKeyInfo"] = keyInfo;
return context;
}
}
Developer Plan Tiers
| Plan | Price | Rate Limit | Monthly Quota | Features |
|---|---|---|---|---|
| Free | 0 INR | 60 req/min | 100K characters | All APIs, community support |
| Starter | 999 INR/month | 300 req/min | 10M characters | All APIs, email support |
| Professional | 4,999 INR/month | 1,000 req/min | 100M characters | All APIs, streaming ASR, priority queue |
| Enterprise | Custom | Custom | Unlimited | SLA, dedicated support, custom models |
| Government | Subsidised | 5,000 req/min | 500M characters | Bhashini-compliant, audit logs |
SDK Usage Example
C#
// .NET SDK Usage
var client = new SarvamClient("sk-your-api-key");
// Translate Hindi to English
var translation = await client.TranslateAsync(new TranslateRequest
{
Input = "Bharat vividhta mein ekta ka desh hai.",
SourceLanguage = "hi",
TargetLanguage = "en"
});
Console.WriteLine(translation.Result);
// Transcribe audio
var audioBytes = await File.ReadAllBytesAsync("hindi_speech.wav");
var transcription = await client.TranscribeAsync(new TranscribeRequest
{
Audio = audioBytes,
Language = "hi"
});
Console.WriteLine(transcription.Result);
// Text to speech
var audio = await client.SynthesizeAsync(new SynthesizeRequest
{
Text = "Namaste, aapka swagat hai.",
Language = "hi",
Voice = "female_1"
});
await File.WriteAllBytesAsync("output.wav", audio.AudioData);
20. Real-Time Inference
Real-time inference is the core of the platform's value proposition. Users expect sub-second responses for ASR, TTS, and translation. The inference stack is optimised for latency at every layer: model quantisation (INT8 for deployment), continuous batching (processing multiple requests simultaneously on a single GPU), speculative decoding (using a smaller draft model to predict tokens that the larger model verifies), and pre-computed attention caches for autoregressive models. The system uses NVIDIA Triton Inference Server as the model serving backend, with custom request scheduling that prioritises real-time requests over batch jobs.
Inference Optimisation Pipeline
C#
public class InferenceOptimizer
{
public async Task<OptimizedModel> OptimizeModelAsync(
ModelArtifact artifact, OptimizationConfig config)
{
var optimized = new OptimizedModel
{
OriginalModelId = artifact.Id,
OptimizationSteps = new List<string>()
};
if (config.EnableGraphOptimization)
{
artifact = await ApplyGraphOptimizationAsync(artifact);
optimized.OptimizationSteps.Add("graph_optimization");
}
if (config.QuantizationTarget != Quantization.None)
{
artifact = config.QuantizationTarget switch
{
Quantization.INT8 => await QuantizeINT8Async(artifact),
Quantization.FP16 => await QuantizeFP16Async(artifact),
Quantization.BF16 => await QuantizeBF16Async(artifact),
_ => artifact
};
optimized.OptimizationSteps.Add($"quantization_{config.QuantizationTarget}");
}
if (config.EnableTensorRT)
{
artifact = await CompileTensorRTAsync(artifact, new TensorRTConfig
{
Precision = config.QuantizationTarget == Quantization.INT8
? TensorRTPrecision.INT8 : TensorRTPrecision.FP16,
MaxBatchSize = config.MaxBatchSize
});
optimized.OptimizationSteps.Add("tensorrt_compilation");
}
optimized.OptimizedArtifact = artifact;
optimized.EstimatedSpeedup = await BenchmarkSpeedupAsync(artifact, optimized);
return optimized;
}
}
Latency Breakdown
| Stage | ASR | TTS | Translation | OCR |
|---|---|---|---|---|
| Network and Deserialization | 5ms | 5ms | 5ms | 5ms |
| Pre-processing | 15ms | 10ms | 5ms | 30ms |
| Model Inference | 120ms | 180ms | 60ms | 300ms |
| Post-processing | 10ms | 20ms | 5ms | 15ms |
| Serialization and Response | 5ms | 5ms | 5ms | 5ms |
| Total P99 | 155ms | 220ms | 80ms | 355ms |
21. Edge Deployment
Edge deployment brings AI inference closer to users, reducing latency and bandwidth costs. For India, where internet connectivity varies dramatically between urban 5G and rural 2G/3G networks, edge deployment is not a luxury but a necessity. The platform deploys lightweight models on edge nodes at ISP points of presence (PoPs) in 50 cities across India, and on-device models for mobile SDKs in select use cases. Edge models are quantised to INT4/INT8 precision, pruned to 30% of the cloud model size, and use knowledge distillation from the full cloud models to maintain acceptable accuracy.
Edge Model Deployment Strategy
| Service | Cloud Model Size | Edge Model Size | Quantization | Accuracy Retention |
|---|---|---|---|---|
| ASR (Hindi) | 1.5 GB | 180 MB | INT8 + Pruning | 92% |
| TTS (Hindi) | 800 MB | 120 MB | INT8 + Quant | 88% |
| Translation (Hindi-English) | 2.1 GB | 250 MB | INT8 + Distillation | 90% |
| Toxicity Detection | 500 MB | 80 MB | INT4 | 85% |
| Sentiment Analysis | 400 MB | 60 MB | INT4 | 87% |
| OCR (Devanagari) | 1.2 GB | 200 MB | INT8 + Pruning | 86% |
On-Device SDK Architecture
C#
public class EdgeInferenceEngine
{
private readonly IModelDownloader _downloader;
private readonly Dictionary<string, OnDeviceModel> _loadedModels = new();
public async Task InitializeAsync(string[] requiredServices, string language)
{
foreach (var service in requiredServices)
{
var modelId = await _registry.GetEdgeModelIdAsync(service, language);
if (modelId == null) continue;
var modelPath = await _downloader.DownloadIfMissingAsync(modelId);
var model = await LoadOnDeviceModelAsync(modelPath, service);
_loadedModels[$"{service}:{language}"] = model;
}
}
public async Task<InferenceResponse> InferAsync(string service, string language, byte[] input)
{
var key = $"{service}:{language}";
if (!_loadedModels.TryGetValue(key, out var model))
throw new EdgeModelNotAvailableException($"Edge model for {service}/{language} not loaded");
var startTime = Stopwatch.GetTimestamp();
var result = await model.RunAsync(input);
var latency = Stopwatch.GetElapsedTime(startTime);
await _metricsCollector.RecordEdgeInferenceAsync(service, language, latency);
return result;
}
}
22. Monitoring and Observability
Monitoring a multilingual AI platform requires tracking model-specific metrics (accuracy, latency, throughput), infrastructure metrics (GPU utilisation, memory, network), business metrics (API usage by language, revenue per service), and quality metrics (WER, BLEU, CER) in near-real-time. The platform uses a three-pillar observability stack: Prometheus for metrics, Grafana for dashboards, Jaeger for distributed tracing, and the ELK stack for log aggregation. Custom exporters translate ML-specific metrics (model drift, accuracy degradation, distribution shift) into Prometheus format for unified monitoring.
Key Monitoring Metrics
| Metric Category | Metric | Alert Threshold | Dashboard |
|---|---|---|---|
| ASR Quality | Word Error Rate (rolling 1h) | Above 15% for any language | ML Quality |
| TTS Quality | MOS (Mean Opinion Score) | Below 3.5 for any voice | ML Quality |
| Translation | BLEU score (rolling 1h) | Below 30 for any pair | ML Quality |
| OCR | Character Error Rate | Above 5% for any script | ML Quality |
| Latency | P99 latency per service | Above 2x baseline | Infrastructure |
| Throughput | Requests per second | Below 50% of capacity | Infrastructure |
| GPU | Utilisation percentage | Above 95% sustained | Infrastructure |
| Error Rate | 5xx error rate | Above 0.1% | Reliability |
| Availability | Service uptime | Below 99.95% | Reliability |
| Cost | Cost per 1M characters | Above 2.5 INR | Business |
| Usage | Daily active API keys | Below 80% of forecast | Business |
| Drift | Input distribution shift | KL divergence above 0.1 | ML Quality |
Model Drift Detection
C#
public class ModelDriftDetector
{
private readonly IMetricsCollector _metrics;
private readonly IReferenceDistributionStore _referenceStore;
public async Task<DriftReport> CheckDriftAsync(string modelId, string language)
{
var currentSamples = await _metrics.GetRecentInferenceInputsAsync(
modelId, language, TimeSpan.FromHours(1), sampleCount: 1000);
var referenceDist = await _referenceStore.GetDistributionAsync(modelId, language);
var klDivergence = ComputeKLDivergence(currentSamples, referenceDist);
var psiMetric = ComputePopulationStabilityIndex(currentSamples, referenceDist);
var report = new DriftReport
{
ModelId = modelId, Language = language,
KLDivergence = klDivergence, PSI = psiMetric,
IsDrifting = klDivergence > 0.1 || psiMetric > 0.2,
SampleCount = currentSamples.Count,
CheckedAt = DateTimeOffset.UtcNow
};
if (report.IsDrifting)
{
await TriggerDriftAlertAsync(report);
await ScheduleRetrainingAsync(modelId, language);
}
return report;
}
}
23. Cost Estimation
Running a full-stack multilingual AI platform at scale in India requires significant infrastructure investment, but the cost structure must be viable for India's price-sensitive market. The platform targets a blended cost of less than 2 INR per 1 million characters processed across all services. This section provides a detailed breakdown of infrastructure costs, optimisation strategies, and unit economics.
Monthly Infrastructure Costs
| Component | Specification | Quantity | Monthly Cost (INR) |
|---|---|---|---|
| GPU Cluster (A100 80GB) | Hyperscale instances | 800 GPUs | 4,80,00,000 |
| GPU Cluster (T4) | Inference instances | 200 GPUs | 20,00,000 |
| CPU Compute (K8s) | c5.4xlarge equivalents | 500 instances | 1,50,00,000 |
| PostgreSQL (RDS) | db.r6g.4xlarge Multi-AZ | 3 instances | 12,00,000 |
| Redis Cluster | r6g.2xlarge | 6 nodes | 8,40,000 |
| TimescaleDB | db.r6g.2xlarge | 2 instances | 5,60,000 |
| S3 Object Storage | 500 TB hot, 2 PB cold | Global | 25,00,000 |
| Network Bandwidth | 10 Gbps sustained | Mumbai + Chennai | 15,00,000 |
| CDN and Edge | CloudFront-like | 50 edge nodes | 8,00,000 |
| Monitoring Stack | Prometheus + Grafana + ELK | Dedicated cluster | 4,00,000 |
| ML Platform | Ray + MLflow | Training cluster | 10,00,000 |
| Engineering Team (100) | ML engineers, SRE, data | Average 30 LPA | 2,50,00,000 |
| Annotator Team (500) | Part-time, all languages | Average 3 LPA | 1,25,00,000 |
| Total Monthly | 11,13,00,000 | ||
Unit Economics
| Metric | Value | Notes |
|---|---|---|
| Total monthly cost | 111.3M INR | Approx 1.3M USD |
| Total characters processed per month | 50 billion | All services combined |
| Cost per 1M characters | 2.23 INR | Blended across all services |
| Target selling price per 1M chars | 5.00 INR | Government pricing |
| Gross margin | 55.4% | At government pricing tier |
| Break-even monthly characters | 25 billion | At 5 INR per 1M chars |
| Projected monthly revenue (Year 2) | 200M INR | 50 enterprise customers |
| Projected monthly profit (Year 2) | 88.7M INR | At 55% gross margin |
24. Testing Strategy
Testing a multilingual AI platform requires a multi-dimensional approach that goes far beyond traditional software testing. Each model must be tested for accuracy across all supported languages, each API endpoint must be load-tested for realistic traffic patterns, and the system as a whole must be tested for failure scenarios (model unavailability, GPU failures, network partitions). The testing strategy spans five levels: unit tests for individual components, integration tests for service interactions, model evaluation tests for ML accuracy, load tests for performance, and chaos tests for resilience.
Model Evaluation Framework
C#
public class ModelEvaluationSuite
{
private readonly IModelRegistry _registry;
private readonly IEvaluationMetrics _metrics;
public async Task<EvaluationReport> EvaluateModelAsync(
string modelId, string language, EvaluationDataset dataset)
{
var model = await _registry.GetModelAsync(modelId);
var results = new List<EvaluationResult>();
foreach (var sample in dataset.Samples)
{
var prediction = await model.PredictAsync(sample.Input);
var metric = sample.TaskType switch
{
"asr" => ComputeWER(sample.Expected, prediction),
"translation" => ComputeBLEU(sample.Expected, prediction),
"ocr" => ComputeCER(sample.Expected, prediction),
"sentiment" => ComputeAccuracy(sample.Expected, prediction),
"toxicity" => ComputeF1Score(sample.Expected, prediction),
_ => throw new NotSupportedException(sample.TaskType)
};
results.Add(new EvaluationResult
{
SampleId = sample.Id, Metric = metric, Latency = prediction.Latency
});
}
return new EvaluationReport
{
ModelId = modelId, Language = language,
AverageMetric = results.Average(r => r.Metric),
P95Latency = Percentile(results.Select(r => r.Latency).ToList(), 95),
TotalSamples = results.Count,
PassedThresholds = CheckThresholds(results, model.TaskType),
EvaluatedAt = DateTimeOffset.UtcNow
};
}
}
Test Coverage Matrix
| Test Type | Coverage Target | Tools | Frequency |
|---|---|---|---|
| Unit Tests | 90% code coverage | xUnit, Moq | Every commit |
| Integration Tests | All API endpoints | Testcontainers, gRPC Test | Nightly |
| Model Accuracy Tests | All 22 languages per model | Custom eval framework | Weekly and pre-deploy |
| Load Tests | 3x peak traffic | k6, Grafana Cloud | Weekly |
| Chaos Tests | Critical failure paths | Chaos Monkey, Litmus | Bi-weekly |
| Security Tests | OWASP Top 10 | SonarQube, Snyk | Every PR |
| E2E Tests | All service combinations | Playwright, custom SDK | Nightly |
| Regression Tests | Accuracy regression detection | Golden test sets | Pre-deploy |
25. Interview Q and A
Q1: How would you handle a sudden spike in ASR requests for a specific language during a live event?
Answer: The system uses a multi-layered approach to handle traffic spikes. First, the API gateway implements token bucket rate limiting that allows temporary bursts up to 3x normal traffic. Second, the ASR service uses Kubernetes HPA (Horizontal Pod Autoscaler) with custom GPU-based metrics to scale from 50 to 200 instances within 90 seconds. Third, if GPU capacity is exhausted, the system falls back to a quantised INT8 model running on CPU instances, which provides 30% of GPU throughput but at 5x the latency. Fourth, requests are queued in Apache Kafka with a maximum wait time of 5 seconds, after which users receive a friendly high-demand message. The entire failover chain completes within 2 seconds of the spike detection.
Q2: How do you ensure consistent translation quality across all 462 language pairs?
Answer: We use a tiered quality management approach. High-resource pairs (Hindi-English, Bengali-English) use dedicated fine-tuned models with 40+ BLEU. Medium-resource pairs use the multilingual NLLB model with domain adapters. Low-resource pairs use the multilingual model with transfer learning from related languages. Quality is monitored continuously through automated BLEU scoring on a held-out test set, with human evaluation on a weekly sample. When quality drops below threshold for any pair, the system automatically routes traffic to a higher-quality fallback pair (for example, Manipuri-Hindi instead of Manipuri-English). The Bhashini compliance layer ensures government-mandated minimum quality for all 22 scheduled language pairs.
Q3: Design the data pipeline for collecting and curating ASR training data at scale.
Answer: The pipeline has four stages: Collection, Processing, Annotation, and Validation. Collection sources include government proceedings (Sansad TV live streams captured via RTMP), public radio (All India Radio archives), YouTube Creative Commons content (filtered by language and quality), and a crowdsourcing mobile app that pays users to record sentences in their native language. Processing includes audio quality filtering (SNR above 15dB, no clipping), speaker diarization, language verification, and deduplication. Annotation uses a two-pass approach: first-pass automatic transcription with the current ASR model, second-pass human correction by language-specific annotators. Validation includes inter-annotator agreement checks, golden sample verification, and automatic WER measurement. The entire pipeline processes approximately 10,000 hours of audio per month across all 22 languages.
Q4: How would you design the system to handle OCR for a multi-page document in mixed Devanagari and English?
Answer: Multi-page, multi-script OCR requires a cascading pipeline. First, page-level script detection determines which scripts are present on each page. Second, layout analysis identifies text blocks, headings, tables, and images using a Donut-based model. Third, each text block is routed to the appropriate script-specific OCR model. Fourth, a post-processing language model (IndicBERT) resolves ambiguities and corrects common OCR errors. Fifth, the structured output merges blocks back into a coherent document with page numbers, block boundaries, and confidence scores. The system handles code-mixed pages by running both script models on each block and selecting the one with higher confidence.
Q5: Explain the trade-offs between on-device and cloud inference for Indian language ASR.
Answer: Cloud inference provides highest accuracy (8% WER) but requires network connectivity and adds 100-200ms latency. On-device inference works offline with 50ms latency but at reduced accuracy (15% WER) due to model compression. The trade-off depends on use case: IVR systems always use cloud (guaranteed connectivity), messaging apps use on-device with cloud fallback (optimise for latency), and educational apps use cloud (optimise for accuracy). Storage constraints on mobile devices limit the number of languages that can be stored on-device to 3-5 per device. A hybrid approach where on-device handles the first pass and cloud refines the result provides both low latency and high accuracy. Battery impact is also significant: on-device inference on a modern smartphone consumes approximately 2% battery per hour of continuous ASR, compared to 5% for cloud-based (due to network radio usage).
Q6: How do you handle model versioning and zero-downtime deployments for 22+ language models?
Answer: Each language model has its own independent versioning and deployment lifecycle. The Model Registry tracks version, accuracy metrics, deployment status, and traffic allocation per language. Deployments use a canary strategy: new model version receives 5% of traffic for 2 hours while accuracy metrics are monitored in real-time. If metrics stay within 2% of the baseline, traffic is gradually increased to 100% over 6 hours. If metrics degrade, traffic is automatically rolled back within 30 seconds. Blue-green deployment is used for major version upgrades where the old model runs in parallel until the new model is fully validated. The key insight is that different languages can be at different model versions simultaneously.
Q7: Design the caching strategy for the translation service.
Answer: Translation caching operates at three levels. L1 (Redis, 10ms): Exact-match cache keyed by source language, target language, content hash, and formality mode. TTL of 6 hours for news content, 24 hours for static content. Hit rate approximately 25%. L2 (Edge, 25ms): Cache at CDN edge nodes for the top 100 most frequent translation pairs. Hit rate approximately 15%. L3 (In-process, 1ms): LRU cache in each service instance for the 1,000 most recent requests. Hit rate approximately 5%. Combined cache hit rate is approximately 45%, meaning 55% of requests reach the model. Cache invalidation uses TTL-based expiry rather than active invalidation. For high-volume API customers, a dedicated cache partition prevents cache pollution from one customers traffic patterns affecting another's hit rate.
Q8: How do you monitor and respond to model quality degradation in production?
Answer: We use a three-tier monitoring approach. Tier 1 (Automatic): Real-time comparison of model outputs against a reference distribution using KL divergence and Population Stability Index. If the PSI exceeds 0.2 for any language, an automatic alert is triggered. Tier 2 (Scheduled): Weekly evaluation against golden test sets for all 22 languages. If accuracy drops below the threshold, a retraining job is automatically queued. Tier 3 (Human): Monthly qualitative review where native speakers evaluate a random sample of 100 outputs per language for each service. This catches subtle quality issues that automated metrics miss. The system also monitors input distribution: if the proportion of code-mixed inputs increases, the system automatically increases the weight of code-mixed data in the inference routing.
Q9: What are the key challenges in deploying AI models for Indian languages compared to English?
Answer: The challenges span five dimensions: (1) Data scarcity: English has trillions of tokens of web text; Hindi has billions, and Odia has millions. (2) Script complexity: 13 scripts with conjunct characters, vowel marks, and varying Unicode representations. (3) Morphological richness: Tamil and Malayalam are agglutinative, meaning a single word can encode what English expresses in a full sentence, requiring different tokenisation strategies. (4) Code-switching: 60% of urban Indian users mix languages, requiring models that handle intra-sentential language switching. (5) Dialect variation: Hindi alone has 25+ major dialects with different vocabulary, pronunciation, and grammar. The design must accommodate all these variations through language-specific model components, script-aware preprocessing, and culturally informed evaluation criteria.
Q10: How would you design the system to comply with the DPDPA 2023 data protection requirements?
Answer: DPDPA compliance requires five key mechanisms. (1) Consent Management: Every user must provide explicit, informed consent for each processing purpose with granular opt-in controls. Consent records are stored in an immutable audit log. (2) Purpose Limitation: Data collected for ASR cannot be repurposed for model training without separate consent. (3) Data Minimisation: Audio files are retained for only 72 hours after processing unless the user explicitly requests longer retention. Transcriptions are retained for 30 days. (4) Right to Erasure: Users can request deletion of all their data through an API endpoint, which triggers a cascade deletion across all storage systems within 72 hours. (5) Data Localisation: All processing and storage occurs within Indian data centres, with no data transfers to servers outside India. The compliance engine intercepts every API request and enforces these rules before any processing occurs.