Spaces:
Sleeping
A newer version of the Gradio SDK is available: 6.20.0
title: Vernacular
emoji: π
colorFrom: green
colorTo: purple
sdk: gradio
sdk_version: 6.16.0
python_version: '3.13'
app_file: app.py
pinned: false
license: mit
short_description: Translate games. Keep every character's voice
Vernacular
Character-aware translation pipeline for Riverstone, a narrative mystery mobile game. Every string in the language pack is machine-translated locally; character dialogue additionally passes through a tone model that rewrites the draft in the character's voice (using per-character wikis distilled from the game's own chat logs). A Gradio review tool lets a human approve, reject, or correct every line before the final pack is exported.
English_JSON ββΊ TranslateGemma (llama.cpp) ββΊ tone pass (Ollama gemma4 + character wiki)
β
translations/de/ review records
β
app.py (Gradio review: approve / reject / edit)
β
pipeline/export_pack.py ββΊ German_JSON/
Setup
Two local model servers (both required only for the translation step, not for reviewing or exporting):
# 1. TranslateGemma 12B via llama.cpp (auto-downloads ~7.3GB on first run).
# The official jinja chat template doesn't parse in llama.cpp - the flags
# below plus the raw prompt in pipeline/clients.py handle that.
llama-server -hf bullerwins/translategemma-12b-it-GGUF:Q4_K_M \
--port 8089 --swa-full --ctx-size 4096 --no-jinja --chat-template gemma
# 2. Tone model via Ollama
ollama pull gemma4:12b-mlx # or any Gemma chat model; set TONE_MODEL in config.py
Python side: pip install gradio (plus pytest for tests).
Workflow
python convert.py # English/ -> English_JSON/ (once)
python build_character_data.py # index character chat files (once)
python build_character_wikis.py # build voice wikis via Ollama (once)
python -m pipeline.build_file_context # FILE_MAPPING.md -> file_context.json
python -m pipeline.translate_pack # translate + tone pass (resumable)
python app.py # review tool at localhost:7860
python -m pipeline.export_pack # -> German_JSON/
translate_pack is fully resumable (per-string records + shared translation
cache) and supports incremental runs:
python -m pipeline.translate_pack --dry-run # show pending work
python -m pipeline.translate_pack --filter Initial/ # one unit at a time
python -m pipeline.translate_pack --stage translate # stage 1 only (less RAM)
python -m pipeline.translate_pack --stage tone # stage 2 only
The full pack is ~15,000 strings; expect an overnight run on a 24GB Apple Silicon machine. Export always produces a complete pack: reviewer-corrected text wins, then the character-toned draft, then the plain machine translation (pending/rejected strings are counted in the export report).
Changing the target language
Edit the three TARGET_* values (and PACK_NAME) at the top of config.py -
e.g. fr / French / French_JSON - then rerun translate_pack, review, and
export. TranslateGemma supports 55 languages.
Repository map
| Path | Purpose |
|---|---|
English/, convert.py, converter/ |
source pack and docx/xlsx β JSON converter |
English_JSON/ |
converted source-of-truth strings |
build_character_data.py, character_data/ |
per-character file index |
build_character_wikis.py, character_wikis/ |
LLM-built character voice wikis |
FILE_MAPPING.md, pipeline/build_file_context.py |
per-file context shown in review |
config.py |
target language, paths, model endpoints |
pipeline/ |
rules, clients, translate/tone driver, exporter |
translations/<lang>/ |
per-file review records (the pipeline's database) |
app.py |
Gradio review tool (this Space's entrypoint) |
German_JSON/ |
exported language pack |