Upload 2 files
Browse files- README.md +85 -1
- requirements.txt +2 -0
README.md
CHANGED
|
@@ -21,6 +21,9 @@ localisation actually needs β a project glossary, a pinned register, and
|
|
| 21 |
passthrough for control-code-only lines. See
|
| 22 |
[Keeping 50k strings consistent](#keeping-50k-strings-consistent).
|
| 23 |
|
|
|
|
|
|
|
|
|
|
| 24 |
## How it works
|
| 25 |
|
| 26 |
- **Inference engine**: `llama-server`, taken as-is from the official
|
|
@@ -40,7 +43,85 @@ passthrough for control-code-only lines. See
|
|
| 40 |
- Chat formatting uses the GGUF's embedded Jinja chat template
|
| 41 |
(`llama-server --jinja`), matching the model card's documented usage.
|
| 42 |
|
| 43 |
-
##
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 44 |
|
| 45 |
### `GET /health`
|
| 46 |
Backend status check.
|
|
@@ -130,6 +211,9 @@ Set the `API_KEY` env var on the Space to require an `X-API-Key` header on
|
|
| 130 |
| `CTX_SIZE` | `32768` | total context, split across `PARALLEL_SLOTS` slots (2048 each). Costs VRAM β see [VRAM budget](#vram-budget) |
|
| 131 |
| `MAX_TOKENS` | `512` | max output tokens per translation |
|
| 132 |
| `MAX_BATCH_SIZE` | `200` | max items accepted per `/translate/batch` call |
|
|
|
|
|
|
|
|
|
|
| 133 |
| `PROMPT_FORMAT` | inferred | `hy-mt2` or `rosetta` β see [Switching model family](#switching-model-family). Inferred from `MODEL_REPO`, so you rarely set it by hand |
|
| 134 |
| `TEMPERATURE`/`TOP_P`/`TOP_K`/`REPEAT_PENALTY` | per family | `0.7`/`0.6`/`20`/`1.05` for Hy-MT2 (its model card's values), `0.7`/`0.95`/`64`/`1.0` for Rosetta (Gemma 3 defaults) |
|
| 135 |
| `API_KEY` | *(empty)* | optional shared secret for `X-API-Key` |
|
|
|
|
| 21 |
passthrough for control-code-only lines. See
|
| 22 |
[Keeping 50k strings consistent](#keeping-50k-strings-consistent).
|
| 23 |
|
| 24 |
+
Point it at a zipped RPG Maker MV/MZ `data` folder and it translates the game
|
| 25 |
+
end to end: see [Translating an RPG Maker game](#translating-an-rpg-maker-game).
|
| 26 |
+
|
| 27 |
## How it works
|
| 28 |
|
| 29 |
- **Inference engine**: `llama-server`, taken as-is from the official
|
|
|
|
| 43 |
- Chat formatting uses the GGUF's embedded Jinja chat template
|
| 44 |
(`llama-server --jinja`), matching the model card's documented usage.
|
| 45 |
|
| 46 |
+
## Translating an RPG Maker game
|
| 47 |
+
|
| 48 |
+
Upload the game's data folder as a zip and the whole extract β translate β
|
| 49 |
+
repack cycle runs server-side. Open `/rpgm.html` on the Space for the UI, or
|
| 50 |
+
drive it over the API:
|
| 51 |
+
|
| 52 |
+
```bash
|
| 53 |
+
BASE=https://your-space.hf.space
|
| 54 |
+
ID=$(curl -sF file=@data.zip $BASE/project/upload | jq -r .id)
|
| 55 |
+
curl -s -X POST $BASE/project/$ID/start -H 'Content-Type: application/json' \
|
| 56 |
+
-d '{"target_lang":"tr"}'
|
| 57 |
+
curl -s $BASE/project/$ID/status | jq '.percent, .files'
|
| 58 |
+
curl -so translated.zip $BASE/project/$ID/download
|
| 59 |
+
```
|
| 60 |
+
|
| 61 |
+
Zip the `data` folder (MZ) or `www/data` (MV) β not the whole game. Both
|
| 62 |
+
layouts are detected automatically.
|
| 63 |
+
|
| 64 |
+
### What gets translated
|
| 65 |
+
|
| 66 |
+
Only dialogue, and deliberately so. RPG Maker keeps executable script, plugin
|
| 67 |
+
bindings, asset filenames and engine identifiers in the same arrays as the
|
| 68 |
+
lines an actor speaks, and translating one of those breaks the game rather
|
| 69 |
+
than mistranslating it.
|
| 70 |
+
|
| 71 |
+
| event code | content | translated |
|
| 72 |
+
|---|---|---|
|
| 73 |
+
| 401 / 405 | Show Text / Scrolling Text | **yes** |
|
| 74 |
+
| 102 / 402 | Show Choices / When[choice] | **yes** |
|
| 75 |
+
| 101 | message header, incl. the MZ speaker name | no |
|
| 76 |
+
| 355 / 655 | Script (executable JS) | no |
|
| 77 |
+
| 356 / 357 | Plugin Command | no |
|
| 78 |
+
| 320 / 324 / 325 | Change Name / Nickname / Profile | no |
|
| 79 |
+
|
| 80 |
+
Database files (`Actors.json`, `Items.json`, β¦), `System.json` terms and
|
| 81 |
+
`plugins.js` are left untouched.
|
| 82 |
+
|
| 83 |
+
Three details make the output safe to ship:
|
| 84 |
+
|
| 85 |
+
- **Message boxes stay whole.** A run of consecutive 401 commands is one box
|
| 86 |
+
split across lines, not separate sentences, so the run is merged and
|
| 87 |
+
translated as a single piece β then re-wrapped into exactly the original
|
| 88 |
+
number of lines. Adding or removing entries in an event list would shift
|
| 89 |
+
every index after it and break conditional branches, so the line count is
|
| 90 |
+
an invariant.
|
| 91 |
+
- **Repeats are translated once.** Units are keyed by source text across the
|
| 92 |
+
whole project: in a real game an 800-slot map set collapses to ~150 unique
|
| 93 |
+
strings, and a "Yes" that appears 300 times costs one generation. It also
|
| 94 |
+
keeps a 102 choice and its 402 mirror automatically identical.
|
| 95 |
+
- **A mangled control code is never written.** After each translation the
|
| 96 |
+
multiset of control codes (`\C[2]`, `\N[1]`, `\V[3]`, `\I[5]`,
|
| 97 |
+
`<WordWrap>`, β¦) is compared against the source. On a mismatch the source
|
| 98 |
+
line is kept and the string is listed under *review* in the UI β a leftover
|
| 99 |
+
English line is cosmetic, a broken `\C[2` is a rendering bug in the
|
| 100 |
+
shipped game.
|
| 101 |
+
|
| 102 |
+
Untranslated strings keep their source text, so the download is a playable
|
| 103 |
+
game at any point, not just when the run finishes.
|
| 104 |
+
|
| 105 |
+
### Project endpoints
|
| 106 |
+
|
| 107 |
+
| method | path | purpose |
|
| 108 |
+
|---|---|---|
|
| 109 |
+
| `POST` | `/project/upload` | multipart zip; unpacks, detects MV/MZ, indexes dialogue |
|
| 110 |
+
| `POST` | `/project/{id}/start` | begin (or resume) translating; body `{"target_lang":"tr"}` |
|
| 111 |
+
| `GET` | `/project/{id}/status` | overall %, per-file %, review list |
|
| 112 |
+
| `POST` | `/project/{id}/cancel` | stop after in-flight strings finish |
|
| 113 |
+
| `GET` | `/project/{id}/download` | rebuilt zip, same folder layout |
|
| 114 |
+
| `DELETE` | `/project/{id}` | remove immediately |
|
| 115 |
+
| `GET` | `/project` | list projects and which one holds the GPU |
|
| 116 |
+
|
| 117 |
+
One run at a time β there is a single GPU, so a second concurrent project
|
| 118 |
+
would only make both finish later. Progress is written to disk continuously
|
| 119 |
+
and a run interrupted by the Space sleeping is **resumed on startup**, which
|
| 120 |
+
is why `PROJECT_DIR` defaults to the persistent volume (`/data/projects`)
|
| 121 |
+
when one is mounted. Uploads are deleted after `PROJECT_RETENTION_HOURS`
|
| 122 |
+
(default 24).
|
| 123 |
+
|
| 124 |
+
## Translation endpoints
|
| 125 |
|
| 126 |
### `GET /health`
|
| 127 |
Backend status check.
|
|
|
|
| 211 |
| `CTX_SIZE` | `32768` | total context, split across `PARALLEL_SLOTS` slots (2048 each). Costs VRAM β see [VRAM budget](#vram-budget) |
|
| 212 |
| `MAX_TOKENS` | `512` | max output tokens per translation |
|
| 213 |
| `MAX_BATCH_SIZE` | `200` | max items accepted per `/translate/batch` call |
|
| 214 |
+
| `PROJECT_DIR` | `/data/projects` if mounted, else `/app/projects` | where uploaded RPG Maker projects and their progress live |
|
| 215 |
+
| `PROJECT_RETENTION_HOURS` | `24` | uploaded projects are deleted this long after their last update |
|
| 216 |
+
| `MAX_UPLOAD_MB` | `200` | rejects uploads bigger than this |
|
| 217 |
| `PROMPT_FORMAT` | inferred | `hy-mt2` or `rosetta` β see [Switching model family](#switching-model-family). Inferred from `MODEL_REPO`, so you rarely set it by hand |
|
| 218 |
| `TEMPERATURE`/`TOP_P`/`TOP_K`/`REPEAT_PENALTY` | per family | `0.7`/`0.6`/`20`/`1.05` for Hy-MT2 (its model card's values), `0.7`/`0.95`/`64`/`1.0` for Rosetta (Gemma 3 defaults) |
|
| 219 |
| `API_KEY` | *(empty)* | optional shared secret for `X-API-Key` |
|
requirements.txt
CHANGED
|
@@ -3,3 +3,5 @@ uvicorn[standard]==0.34.0
|
|
| 3 |
httpx==0.28.1
|
| 4 |
pydantic==2.10.5
|
| 5 |
huggingface_hub==0.27.1
|
|
|
|
|
|
|
|
|
| 3 |
httpx==0.28.1
|
| 4 |
pydantic==2.10.5
|
| 5 |
huggingface_hub==0.27.1
|
| 6 |
+
# Required by FastAPI's UploadFile: without it /project/upload raises at import.
|
| 7 |
+
python-multipart==0.0.20
|