We translate everything from corporate explainers to casual vlogs, short dramas, and ads. The hard part is usually not getting a model to produce Tamil, Arabic, or Cantonese. It can already do that. The hard part is getting the version people would actually use in the situation you are dubbing.

Ask for Saudi Arabic and you will often get Modern Standard Arabic. Ask for Hong Kong Chinese and you may get Mandarin written in Traditional characters. Ask for Tamil and you can get perfectly grammatical Tamil with Hindi-shaped syntax and a few English words dropped in wherever the model hesitates.
None of that looks broken. That is what makes it hard.
The output is fluent. It is on topic. A general-purpose quality check will probably pass it. But a native speaker will hear that something is off: too formal, too bookish, too close to another language, or simply unlike anything a person would say aloud.
This is where localization starts. Not by teaching the model a language, but by keeping it from falling back to the version of that language it saw most often during training.
In an earlier post, I wrote about temporal alignment: fitting a translated voice track back into the timing of the original edit. There, the words already existed. The job was to make them fit.
The prompt is not a document
People often describe prompt engineering as editing one long instruction until the output improves. That is not how our translation prompts work.
We build them per request from smaller guidance blocks. Some are always included. Others depend on the job:
- Is this narration, dialogue, an ad, or a vlog?
- Does the source contain hesitations or interruptions worth preserving?
- Does the target language require grammatical gender?
- Do we know a recurring failure mode for this language pair?
- Are speaker labels available?
Two requests can start from the same English sentence and receive different prompts.
The assembly logic is not the interesting part. The interesting part is why those blocks differ.
Tamil and Marathi are both Indian languages, but they do not need the same warning. Saudi Arabic and Emirati Arabic are related, but the spoken forms you want are not interchangeable. “Hong Kong Chinese” is not just “Chinese with Traditional characters.”
The useful rules are not broad cultural labels. They are notes about how a particular model tends to go wrong for a particular target.
Don’t choose the tone. Stop it from wandering.
One of our always-on blocks deals with register. What it does not say is “be formal” or “be casual.”
That is deliberate.
A model generally understands that a legal notice, a product ad, and a casual vlog should not sound the same. The bigger problem is consistency over time. It starts in roughly the right place, then drifts.
A conversational line becomes slightly formal. A government term is translated carefully once, then casually two segments later. A character who sounded relaxed at the beginning suddenly starts speaking like a brochure.
Each choice can look reasonable in isolation. Put them together and the track sounds as if several translators worked on it without talking to one another.
So the instruction is not “use a formal register.” It is closer to this:
Match the source’s level of formality. Keep it stable. Do not mix casual wording with institutional terminology unless the source does too.
The same idea shows up elsewhere. We do not tell the model to “use simple words.” We tell it not to reach for a bookish synonym when a normal spoken word would do. We do not prescribe one treatment for abbreviations either. We tell it to choose a treatment and stick to it.
That matters in dubbing. If NPS remains NPS in one segment, becomes a transliteration in the next, and expands into a full program name later, every individual decision may be defensible. The result is still a mess.
There is also a timing cost. Turning a three-letter abbreviation into six spoken words can break a line that already has a fixed duration.
The pattern here is simple: the problem is often not one bad decision. It is a sequence of locally reasonable decisions that do not belong together.
A rule needs a destination
There is an obvious objection to negative instructions: if you tell someone not to think about a pink elephant, you have just made them think about one.
The same concern comes up in prompting. “Avoid Hindi word order” sounds like it might only make Hindi word order more salient. The standard advice is to tell the model what to do, not what to avoid.
That is good advice when the instruction is only a prohibition. Ours should not be.
A useful locale note gives both halves of the instruction:
Use natural Tamil clause flow. Avoid Hindi-influenced word order.
Prefer common Tamil equivalents over literal English calques.
Use Traditional characters, not Simplified characters.
The first half gives the model somewhere to go. The second half names the wrong turn it is likely to take.
That is a much more useful shape than a bare “don’t.” It is less like building a fence and more like putting up a signpost: this is the direction you want; this is the route that keeps causing trouble.
Not every rule needs a negative clause. Punjabi script selection is a straightforward example: use Gurmukhi, not Devanagari. But when there is a known tendency in the output, naming it is valuable.
The defaults are local
The general guidance blocks sit above a table of locale-specific notes. Those notes are keyed by target language or language pair, and when one matches, we append it close to the text the model is about to translate.
That placement is intentional. The most specific constraints are also the easiest to ignore, so they should sit nearest to the input they govern.
A few examples make the point clearer.
Saudi Arabic. The note doesn't teach Arabic. It says: don't hand me Modern Standard Arabic, hand me what someone actually says out loud in Saudi Arabia, and keep it speakable — because this is going to a TTS voice, not a page. Ask a model for Saudi Arabic and you get MSA, because MSA is what's written down and therefore what dominates the training data. Nobody writes Gulf dialect in a newspaper. There's a sibling entry for Emirati Arabic: same shape, different accent.

Hong Kong Chinese. The note says: Cantonese grammar and usage, not Mandarin phrasing — and traditional characters. Ask for Hong Kong Chinese and you get Mandarin written in traditional characters, which is a real thing that exists and is not what a Cantonese speaker says out loud.
For example, it is unnatural to directly traditionalize the Mandarin scripts for Cantonese dubbing:
Tamil. The note doesn’t teach Tamil. It says: keep Tamil clause flow natural, avoid Hindi-influenced word order, and prefer native Tamil equivalents where the model would otherwise reach for English. Ask for Tamil and you can get perfectly valid Tamil words arranged in a Hindi-shaped sentence, with English filling the gaps whenever the model is unsure. Tamil and Hindi are structurally distant, so the problem is usually not borrowed vocabulary but borrowed sentence shape. The result is fluent enough to pass at a glance, but it is not the Tamil people actually speak.

“Indian languages” is not one setting
It is tempting to write one shared “Indic language” block and reuse it everywhere. That would be tidy. It would also erase the reason the locale table exists.
The pressure from Hindi is not the same for every language.
| Group | Languages | What the note pushes against |
|---|---|---|
| Dravidian | Tamil, Telugu, Kannada, Malayalam | Hindi-influenced word order — the risk is syntactic |
| Indo-Aryan, close to Hindi | Marathi, Bengali | Direct Hindi calques — the risk is lexical |
| Indo-Aryan, further out | Gujarati, Odia | No anti-Hindi line at all — here the pull is English |
| Inside the Hindi belt | Bhojpuri | Neither — the drift is toward the standardized written register |
| Plus a writing system | Punjabi | A script line on top of both |
This is a linguistic distinction, not an engineering taxonomy.
Tamil is structurally distant from Hindi, so the risk is not usually direct borrowing of Hindi words. The shape of the sentence leaks instead. Marathi is much closer to Hindi, so lexical calques are more likely. Malayalam belongs with Tamil in this respect because it faces a similar structural problem.
Bhojpuri is different again. It sits so close to Hindi that the boundary between the two is politically contested. Its issue is not “too much Hindi” in the same sense. The output tends to drift toward a standardized, formal written version of Bhojpuri rather than the spoken form you may actually want.
Hindi itself does not need an anti-Hindi note. Its separate problem is grammatical gender, which belongs to a different category altogether.
Defaults, drift, and missing information
The locale table gets the most attention because it contains the sharpest rules, but it is only one part of the system. The guidance blocks solve three different kinds of problems.
Drift
Register and abbreviation handling belong here.
The model is capable of making a good choice. It just does not reliably make the same kind of good choice throughout a job. The fix is to tell it what consistency looks like.
Defaults
MSA instead of Saudi Arabic, Mandarin phrasing instead of Cantonese, Hindi-shaped Tamil, English-heavy wording, Simplified rather than Traditional characters: these are all defaults.
The model has seen one version more often than another and tends to fall back to it. The prompt’s job is to identify the version we want and, where useful, name the version we do not.
Writing systems fit this category too. A locale tag does not always determine the script. Several languages genuinely use more than one, and models will often choose the one that dominates their training data. That is not a configuration detail. It is a localization choice.
Missing information
Grammatical gender is different.
English can say, “I’m tired,” without saying anything about the speaker’s gender. Hindi, Arabic, Marathi, and many other languages cannot always do that. The missing information was not inferred incorrectly. It was never present in the source.
A prompt cannot solve that by itself.
At best, it can ask the model to infer from context. When our pipeline has the answer, we pass speaker gender in as metadata and tell the model to use it. Arabic needs additional handling because gender can affect not only the speaker but also the person being addressed.
This is the limit of prompt design: you can steer a model away from a bad default, but you cannot recover information that the source never contained.
Why do we keep a language table in VMEG?
A per-language table can look like a maintenance problem. Sometimes it is. If a system needs a handwritten table for something it could calculate from the input, that usually means the system is missing a proper model.
Subtitle width is an example. The width of a Devanagari or Kannada cluster can be measured from Unicode properties, font metrics, and rendering. A manual width table would be a workaround for something the layout system should be able to compute.
Language guidance is different. No language tag can tell you that Tamil output may drift toward Hindi-style word order, that Saudi Arabic requests often fall back to MSA, or that Traditional Chinese can still sound like Mandarin rather than Cantonese.
Those are not formatting properties. They are observations about how models behave across particular languages, regions, and use cases.
That is why the locale table is worth maintaining. It is not a list of settings. It is a record of what we have learned from real output.
The short version
Most translation work focuses on helping a model do something it cannot do. This is different.
The VMEG model already knows Tamil, Arabic, Cantonese, Marathi, and many other languages. What it does not know by default is which version of those languages this project needs.
A good prompt block gives it that missing operational context:
- Use spoken Saudi Arabic rather than MSA.
- Use Cantonese phrasing rather than Mandarin written in Traditional characters.
- Keep Tamil syntax natural to Tamil.
- Prefer ordinary spoken words over bookish ones.
- Keep each character’s voice consistent across the whole track.
The model knows the language. Our job is to stop it from choosing the wrong default version of it.