<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Gnananvesh reddy</title>
    <description>The latest articles on DEV Community by Gnananvesh reddy (@gnananveshreddy).</description>
    <link>https://dev.to/gnananveshreddy</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4133044%2Fafa4511a-1931-432b-ac4a-da6f1f139e6d.png</url>
      <title>DEV Community: Gnananvesh reddy</title>
      <link>https://dev.to/gnananveshreddy</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/gnananveshreddy"/>
    <language>en</language>
    <item>
      <title>The Hidden Cost of Making AI Speak Indian Languages</title>
      <dc:creator>Gnananvesh reddy</dc:creator>
      <pubDate>Sat, 19 Sep 2026 14:59:09 +0000</pubDate>
      <link>https://dev.to/gnananveshreddy/the-hidden-cost-of-making-ai-speak-indian-languages-2eog</link>
      <guid>https://dev.to/gnananveshreddy/the-hidden-cost-of-making-ai-speak-indian-languages-2eog</guid>
      <description>&lt;p&gt;&lt;em&gt;Why the same sentence can cost 3x more tokens in Hindi than in English — and what it actually takes to fix that.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  A sentence that shouldn't cost more to say
&lt;/h2&gt;

&lt;p&gt;Here's a simple test. Take the same short sentence, translate it into five languages, and see how "expensive" it is for an AI model to process.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Language&lt;/th&gt;
&lt;th&gt;Characters&lt;/th&gt;
&lt;th&gt;Data size (UTF-8 bytes)&lt;/th&gt;
&lt;th&gt;Words&lt;/th&gt;
&lt;th&gt;Tokens&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;English&lt;/td&gt;
&lt;td&gt;18&lt;/td&gt;
&lt;td&gt;18&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hindi&lt;/td&gt;
&lt;td&gt;12&lt;/td&gt;
&lt;td&gt;30&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;13&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Telugu&lt;/td&gt;
&lt;td&gt;17&lt;/td&gt;
&lt;td&gt;45&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;20&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Kannada&lt;/td&gt;
&lt;td&gt;16&lt;/td&gt;
&lt;td&gt;44&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;22&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tamil&lt;/td&gt;
&lt;td&gt;30&lt;/td&gt;
&lt;td&gt;84&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;34&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Same sentence. Same meaning. But look at the last column — &lt;strong&gt;tokens&lt;/strong&gt;, the small chunks of text an AI model actually reads (a token might be a full word, a word-fragment, or just a few characters). English needed about 1 token per word. Tamil needed almost &lt;strong&gt;11&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That gap has nothing to do with Tamil being a more "complex" language to understand. It comes from a decision made long before you typed a prompt — how the model's &lt;strong&gt;tokenizer&lt;/strong&gt; was built. And that decision has real costs: Indian-language conversations fill up the model's context window faster, cost more to run, and respond more slowly — for saying the exact same thing an English speaker could say more cheaply.&lt;/p&gt;

&lt;p&gt;This piece covers three things: why that gap exists, what I found when I tested it myself, and what it actually takes to close it — including the technique real multilingual AI teams use to retrofit a tokenizer onto a model that's already been trained.&lt;/p&gt;




&lt;h2&gt;
  
  
  What a tokenizer actually does
&lt;/h2&gt;

&lt;p&gt;Before an AI model "thinks" about your sentence, a tokenizer breaks it into tokens — its basic units of text, similar to Lego bricks. Everything downstream (the model's memory of the conversation, how much compute it burns, how fast it replies) is counted in tokens, not words or characters. So the table above isn't trivia — it's a direct readout of how efficiently each language got chunked.&lt;/p&gt;

&lt;p&gt;The tokenizer's chunking isn't hand-designed. It's &lt;em&gt;learned&lt;/em&gt; from a huge pile of training text, using an algorithm called &lt;strong&gt;byte-level BPE (Byte Pair Encoding)&lt;/strong&gt;. Here's the short version: start with raw bytes (the smallest possible unit of text), then repeatedly find whichever pair of adjacent bytes/characters shows up most often in the training text, and merge it into a single new token.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;t h  →  th
th e →  the
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Do this over and over and you end up with a vocabulary of tokens — each one earned by how often it appeared in training. "the," "-ing," "-tion" become single, cheap tokens in an English-heavy corpus, because they show up constantly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the byte count is a red herring
&lt;/h2&gt;

&lt;p&gt;English characters typically take 1 byte of storage; most Indic scripts (Devanagari, Telugu, Tamil, Kannada) take 3 bytes per character, because those scripts have far larger character sets. It's tempting to conclude "3 bytes → 3 tokens." That's wrong. A byte-level tokenizer can merge several bytes into one token — a 3-byte character doesn't automatically cost 3 tokens. Whether it does depends entirely on whether the tokenizer &lt;em&gt;learned&lt;/em&gt; a good merge for that byte sequence, and that depends on how much of that language it actually saw during training.&lt;/p&gt;

&lt;p&gt;Which is the real explanation for the first table: it's not about script complexity. It's about training data. If a tokenizer is trained on 90% English and 10% everything else, English patterns get thousands of chances to earn efficient one-token merges. Indic patterns get far fewer chances, so they stay chopped into small, expensive pieces — not because the algorithm is biased, but because frequency is the only thing BPE optimizes for.&lt;/p&gt;




&lt;h2&gt;
  
  
  Testing it myself: does rebalancing the training data actually help?
&lt;/h2&gt;

&lt;p&gt;Rather than just claim this, I built three small tokenizers from scratch, changing only the language mix of the training data each time:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Tokenizer A&lt;/strong&gt; — 90% English / 10% Indic (mirrors how many real-world tokenizers are built today, since most web text is English)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tokenizer B&lt;/strong&gt; — 50% English / 50% Indic&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tokenizer C&lt;/strong&gt; — Balanced equally across English, Hindi, Telugu, Tamil, Kannada&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;(Caveat: this used a small, self-authored corpus to isolate one variable — not a production-scale dataset. Read the direction and size of the shifts, not the absolute numbers.)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tokens per word, on held-out test sentences:&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tokenizer&lt;/th&gt;
&lt;th&gt;English&lt;/th&gt;
&lt;th&gt;Hindi&lt;/th&gt;
&lt;th&gt;Telugu&lt;/th&gt;
&lt;th&gt;Tamil&lt;/th&gt;
&lt;th&gt;Kannada&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;A — 90% English&lt;/td&gt;
&lt;td&gt;3.05&lt;/td&gt;
&lt;td&gt;5.34&lt;/td&gt;
&lt;td&gt;7.79&lt;/td&gt;
&lt;td&gt;10.75&lt;/td&gt;
&lt;td&gt;8.86&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;B — 50/50 split&lt;/td&gt;
&lt;td&gt;3.08&lt;/td&gt;
&lt;td&gt;4.32&lt;/td&gt;
&lt;td&gt;6.36&lt;/td&gt;
&lt;td&gt;8.47&lt;/td&gt;
&lt;td&gt;7.34&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C — Fully balanced&lt;/td&gt;
&lt;td&gt;3.60&lt;/td&gt;
&lt;td&gt;4.34&lt;/td&gt;
&lt;td&gt;6.36&lt;/td&gt;
&lt;td&gt;7.84&lt;/td&gt;
&lt;td&gt;7.07&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Going from A to B — giving Indic languages a fairer share of training data — cut Hindi's cost by ~19%, Telugu's by ~18%, Tamil's by ~21%, while English barely moved (3.05 → 3.08). Rebalancing has a very good cost-benefit ratio, at least at first.&lt;/p&gt;

&lt;p&gt;But pushing further, to a fully balanced split (C), gave diminishing returns on the Indic side and actually cost English a bit (3.08 → 3.60). So "more balance is always better" doesn't hold — there's a sweet spot, not a straight line.&lt;/p&gt;

&lt;h2&gt;
  
  
  Does a bigger vocabulary fix it instead?
&lt;/h2&gt;

&lt;p&gt;I tested that too, sweeping vocabulary size on the balanced corpus:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Vocabulary size&lt;/th&gt;
&lt;th&gt;English&lt;/th&gt;
&lt;th&gt;Hindi&lt;/th&gt;
&lt;th&gt;Telugu&lt;/th&gt;
&lt;th&gt;Tamil&lt;/th&gt;
&lt;th&gt;Kannada&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;300&lt;/td&gt;
&lt;td&gt;5.28&lt;/td&gt;
&lt;td&gt;6.75&lt;/td&gt;
&lt;td&gt;9.64&lt;/td&gt;
&lt;td&gt;10.72&lt;/td&gt;
&lt;td&gt;10.17&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;800&lt;/td&gt;
&lt;td&gt;3.70&lt;/td&gt;
&lt;td&gt;3.55&lt;/td&gt;
&lt;td&gt;6.42&lt;/td&gt;
&lt;td&gt;7.78&lt;/td&gt;
&lt;td&gt;7.17&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1,500&lt;/td&gt;
&lt;td&gt;3.70&lt;/td&gt;
&lt;td&gt;3.55&lt;/td&gt;
&lt;td&gt;6.42&lt;/td&gt;
&lt;td&gt;7.78&lt;/td&gt;
&lt;td&gt;7.17&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3,000&lt;/td&gt;
&lt;td&gt;3.70&lt;/td&gt;
&lt;td&gt;3.55&lt;/td&gt;
&lt;td&gt;6.42&lt;/td&gt;
&lt;td&gt;7.78&lt;/td&gt;
&lt;td&gt;7.17&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Going from 300 to 800 tokens helped every language substantially. Beyond that, nothing moved — my tiny training corpus simply ran out of frequent patterns worth turning into new tokens. At real production scale, you'd expect the same &lt;em&gt;shape&lt;/em&gt; of curve for a related reason: each additional vocabulary slot ends up capturing rarer and rarer patterns, so returns shrink. Either way, the practical lesson holds: a bigger vocabulary isn't automatically better. It directly increases the size of the model's embedding table and output layer (more on that below), so it's a real cost, not a free upgrade.&lt;/p&gt;

&lt;p&gt;So neither lever — rebalancing data or growing vocabulary — is a clean fix on its own. Which raises the harder, more practical question: what do you actually do when you already have a trained model with a bad, English-heavy tokenizer, and you want to fix it without starting over?&lt;/p&gt;




&lt;h2&gt;
  
  
  Why you can't just swap the tokenizer
&lt;/h2&gt;

&lt;p&gt;The obvious idea — just replace the old tokenizer with a better multilingual one — doesn't work, because of how deeply the tokenizer is wired into the model.&lt;/p&gt;

&lt;p&gt;During training, the model learns an &lt;strong&gt;embedding&lt;/strong&gt; for every token: a vector of numbers representing that token's meaning, which the rest of the network operates on. Token ID 1234 might map to the embedding for "hello." If you swap in a new tokenizer that reassigns ID 1234 to "नमस्ते" instead, the model's embedding at that slot still represents "hello" — nothing tells the transformer that the meaning behind that ID changed. The result is broken, incoherent output, because the mapping between token IDs and everything the model learned about them has been silently invalidated.&lt;/p&gt;

&lt;h2&gt;
  
  
  How teams actually retrofit multilingual support: vocabulary expansion + frozen weights
&lt;/h2&gt;

&lt;p&gt;The real technique — used across the industry, not any one company's secret — is &lt;strong&gt;vocabulary expansion&lt;/strong&gt;, and it's done carefully enough to avoid the exact problem above. In broad strokes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Keep the existing vocabulary untouched.&lt;/strong&gt; Don't reassign any existing token IDs — that's what causes the semantic mismatch.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Add new tokens for the target languages.&lt;/strong&gt; Train a new set of merges (often on a multilingual or language-specific corpus) and append these as new token IDs after the existing vocabulary, rather than replacing anything. The vocabulary might grow from, say, 32K tokens to 100K+.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Initialize new embeddings for the new tokens&lt;/strong&gt; — often randomly, or by averaging nearby/related embeddings as a warmer starting point, since a purely random vector for a brand-new token gives the model nothing to work with initially.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Freeze the original weights, and train only the new embeddings first.&lt;/strong&gt; This is the key move: the rest of the model — everything it already learned about English, reasoning, code, and so on — is locked (frozen) so it can't be disturbed. Only the newly added embedding rows (and often the output layer's new rows) are trainable. This forces the model to learn what the new tokens mean without the risk of forgetting what it already knew — a known failure mode called &lt;em&gt;catastrophic forgetting&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Continue pretraining on multilingual text&lt;/strong&gt;, still with most of the model frozen, until the new tokens' embeddings become meaningful enough that the frozen transformer layers can actually make use of them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gradually unfreeze more of the model&lt;/strong&gt; (sometimes the top layers first, sometimes all of it) and continue training, now letting the whole network adapt to the expanded vocabulary rather than just the embedding layer.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The intuition: this is closer to adding new rooms onto a house than demolishing and rebuilding it. The model's existing knowledge stays intact and untouched throughout the early stages, while the new "rooms" — the added vocabulary — are furnished and learned separately before the whole house is allowed to rearrange itself around them.&lt;/p&gt;

&lt;p&gt;This is also why vocabulary changes aren't just an input-side problem. The model has to both &lt;em&gt;read&lt;/em&gt; the new tokens (input embeddings) and &lt;em&gt;generate&lt;/em&gt; them in its replies (the output layer, sometimes called the LM head, which predicts a probability over every token in the vocabulary). Both sides need training, and depending on the model architecture, these two layers may or may not share the same weights.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(One honesty note: exact production pipelines — precise freezing schedules, exact vocabulary size chosen, how long each phase runs — are proprietary details specific to whichever team built a given model, and I'm deliberately not attributing an exact recipe to any specific company without a public source confirming it. The staged approach above — expand vocabulary, freeze and warm up new embeddings, then gradually unfreeze — is the general, well-documented pattern; the specific numbers any one team uses aren't public.)&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  What this doesn't prove
&lt;/h2&gt;

&lt;p&gt;Worth being explicit about the limits of this argument: token efficiency is not the same as model quality. A tokenizer that produces fewer tokens per word tells you nothing about whether the model actually understands that language, reasons well in it, or translates it accurately. A language can be cheaply tokenized and still poorly modeled, or expensively tokenized and still well understood. Everything here is about the economics layer — cost, latency, context usage — not comprehension.&lt;/p&gt;

&lt;h2&gt;
  
  
  The takeaway
&lt;/h2&gt;

&lt;p&gt;The full chain: different scripts get different byte representations → BPE learns merges based on frequency in the training data → underrepresented languages get fewer efficient merges → those languages need more tokens to say the same thing → that means less usable context, slower responses, and higher cost, for identical conversations.&lt;/p&gt;

&lt;p&gt;Rebalancing training data and growing the vocabulary both help, but both plateau and both carry real costs. The technique that actually works at scale — vocabulary expansion with frozen weights, done carefully to avoid catastrophic forgetting — is more involved than either lever alone, which is exactly why it's the answer real teams reach for instead of just re-training a bigger, more balanced tokenizer from scratch.&lt;/p&gt;

&lt;p&gt;For multilingual LLMs, the tokenizer isn't a preprocessing afterthought. It's part of the economics of language — and fixing it properly, after a model is already trained, takes real engineering, not just better data.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;All experiment code and corpora for this piece are available on request — this was a small, from-scratch BPE run meant to isolate one variable at a time, not a benchmark of any production tokenizer.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;&lt;a href="https://www.linkedin.com/in/gnananvesh-reddy-a23920292/" rel="noopener noreferrer"&gt;Connect with me on LinkedIn&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>nlp</category>
      <category>llm</category>
      <category>tokenizer</category>
    </item>
  </channel>
</rss>
