Cnass commited on
Commit
577251f
·
verified ·
1 Parent(s): 40924ff

Update README.md

Browse files
Files changed (1) hide show
  1. README.md +85 -7
README.md CHANGED
@@ -18,8 +18,17 @@ instance.
18
  ## How it works
19
 
20
  - **Inference engine**: `llama-server` (from [llama.cpp](https://github.com/ggml-org/llama.cpp)),
21
- compiled from source in the Docker build (see the note in the `Dockerfile`
22
- about the STQ kernel this GGUF depends on — it needs a recent llama.cpp).
 
 
 
 
 
 
 
 
 
23
  It's started with `--threads 8 --parallel 8 --cont-batching`, which uses
24
  llama.cpp's continuous batching to combine multiple in-flight requests'
25
  forward passes into shared compute instead of running them one at a time.
@@ -47,12 +56,11 @@ Hy-MT2 documents support for).
47
  ```json
48
  {
49
  "text": "Where is the nearest potion shop?",
50
- "target_lang": "tr",
51
- "preserve_placeholders": true
52
  }
53
  ```
54
  ```json
55
- { "translation": "En yakın iksir dükkanı nerede?", "elapsed_seconds": 0.41 }
56
  ```
57
 
58
  ### `POST /translate/batch` — many strings in one call (recommended: 50-100 per call)
@@ -88,7 +96,7 @@ server-side safety cap on a single call.
88
  | `source_lang` | string, optional | omit to let the model auto-detect |
89
  | `style` | string, optional | e.g. `"casual, playful"` — injected as a style instruction |
90
  | `glossary` | object, optional | `{"HP": "Can Puanı"}` — forces specific term translations |
91
- | `preserve_placeholders` | bool, default `true` | instructs the model to never touch `\N[1]`, `\V[1]`, `{var}`, `%s`, `%1`, etc. — important for RPG Maker / game strings |
92
 
93
  ### Auth
94
  Set the `API_KEY` env var on the Space to require an `X-API-Key` header on
@@ -98,7 +106,8 @@ Set the `API_KEY` env var on the Space to require an `X-API-Key` header on
98
 
99
  | var | default | meaning |
100
  |---|---|---|
101
- | `MODEL_FILE` | `Hy-MT2-7B-Q4_K_M.gguf` | switch to `HY-MT2-7B-Q6_K.gguf` or `HY-MT2-7B-Q8_0.gguf` for higher quality / slower |
 
102
  | `THREADS` | `8` | CPU threads for llama-server |
103
  | `PARALLEL_SLOTS` | `8` | concurrent generation slots (continuous batching) |
104
  | `CTX_SIZE` | `16384` | total context, split across `PARALLEL_SLOTS` slots |
@@ -128,3 +137,72 @@ docker run -p 7860:7860 --cpus 8 --memory 32g hy-mt2-api
128
 
129
  Then open `test-ui/index.html` in a browser, point it at
130
  `http://localhost:7860`, and use it to benchmark single vs. batch requests.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
  ## How it works
19
 
20
  - **Inference engine**: `llama-server` (from [llama.cpp](https://github.com/ggml-org/llama.cpp)),
21
+ compiled from source in the Docker build. This GGUF depends on the
22
+ `STQ1_0` quant kernel from
23
+ [PR #22836](https://github.com/ggml-org/llama.cpp/pull/22836), which is
24
+ **not yet merged into llama.cpp `master`** (verified directly) — a plain
25
+ `pip install llama-cpp-python` or a vanilla clone of master will compile
26
+ but fail to load this GGUF at runtime. The `Dockerfile` clones master and
27
+ cherry-picks the 3 commits that make up that PR (verified to apply
28
+ cleanly, zero conflicts); it auto-skips the cherry-pick once upstream
29
+ merges it, so no edits are needed later.
30
+ The build is pinned to `-j2` (`BUILD_JOBS`) — see
31
+ [Build notes](#build-notes), this is what stopped the build from hanging.
32
  It's started with `--threads 8 --parallel 8 --cont-batching`, which uses
33
  llama.cpp's continuous batching to combine multiple in-flight requests'
34
  forward passes into shared compute instead of running them one at a time.
 
56
  ```json
57
  {
58
  "text": "Where is the nearest potion shop?",
59
+ "target_lang": "tr"
 
60
  }
61
  ```
62
  ```json
63
+ { "translation": "En yakın iksir dükkanı nerede?", "elapsed_seconds": 4.82 }
64
  ```
65
 
66
  ### `POST /translate/batch` — many strings in one call (recommended: 50-100 per call)
 
96
  | `source_lang` | string, optional | omit to let the model auto-detect |
97
  | `style` | string, optional | e.g. `"casual, playful"` — injected as a style instruction |
98
  | `glossary` | object, optional | `{"HP": "Can Puanı"}` — forces specific term translations |
99
+ | `preserve_placeholders` | bool, default `false` | adds an explicit "keep placeholders verbatim" clause. **Leave it off**: Hy-MT2 already preserves `\V[1]`, `%1`, `{var}` etc. on its own (measured — see [Verified behaviour](#verified-behaviour)), so the clause only costs prompt tokens |
100
 
101
  ### Auth
102
  Set the `API_KEY` env var on the Space to require an `X-API-Key` header on
 
106
 
107
  | var | default | meaning |
108
  |---|---|---|
109
+ | `MODEL_REPO` | `tencent/Hy-MT2-7B-GGUF` | set to `tencent/Hy-MT2-1.8B-GGUF` (with a matching `MODEL_FILE`) to trade quality for a large throughput win on bulk jobs |
110
+ | `MODEL_FILE` | `Hy-MT2-7B-Q4_K_M.gguf` | `HY-MT2-7B-Q6_K.gguf` / `HY-MT2-7B-Q8_0.gguf` for higher quality (both fit in 32 GB), or `Hy-MT2-1.8B-Q4_K_M.gguf` with the 1.8B repo |
111
  | `THREADS` | `8` | CPU threads for llama-server |
112
  | `PARALLEL_SLOTS` | `8` | concurrent generation slots (continuous batching) |
113
  | `CTX_SIZE` | `16384` | total context, split across `PARALLEL_SLOTS` slots |
 
137
 
138
  Then open `test-ui/index.html` in a browser, point it at
139
  `http://localhost:7860`, and use it to benchmark single vs. batch requests.
140
+
141
+ ## Verified behaviour
142
+
143
+ The stack below was actually run end to end against
144
+ `Hy-MT2-7B-Q4_K_M.gguf` (real model, real llama-server built exactly as the
145
+ `Dockerfile` builds it) on a **4-core / 15 GB** box — smaller than the 8 vCPU
146
+ Space, so treat these as a floor, not a target.
147
+
148
+ - The STQ1_0 cherry-pick works: the model loads and generates. This was the
149
+ whole open question, and it is settled.
150
+ - Translation quality spot-checks (EN→TR): `"Potion"` → `"İksir"`,
151
+ `"Are you sure you want to quit the game?"` →
152
+ `"Oyundan çıkmak istediğinizden emin misiniz?"`.
153
+ - **Placeholders survive untouched with no special instruction**:
154
+ `"You have obtained \V[1] gold."` → `"\V[1] altın elde ettiniz."`, and
155
+ `"Press %1 to open your inventory."` →
156
+ `"Envanterinizi açmak için %1'e basın."`.
157
+ - `glossary` and `style` both take effect: with `{"gold": "altın", "HP": "Can
158
+ Puanı"}` the model returned `"50 altınınız ve dolu Can Puanınız var."`;
159
+ with style `medieval, formal`, `"Hey, watch out!"` → `"Ey dostum, dikkatli
160
+ ol!"`.
161
+ - Throughput, 8 short game strings, 4 slots on 4 cores:
162
+ **sequential 19.2 s vs. batch 12.2 s (1.58×)**. A 24-item batch of longer
163
+ sentences ran at 0.34 items/s. Expect roughly double on 8 vCPU.
164
+
165
+ Planning number: at ~0.7 items/s (8 vCPU, 7B, sentence-length strings)
166
+ 50,000 strings is on the order of a day of wall-clock time. If that matters
167
+ more than the last few quality points, switch `MODEL_REPO`/`MODEL_FILE` to
168
+ the 1.8B GGUF — same API, same prompts, several times faster.
169
+
170
+ ### A note on `preserve_placeholders`
171
+
172
+ An earlier version of this API sent a long "never translate `\N[..]`,
173
+ `{variable}`, `%s` …" instruction on every request, with that list spelled
174
+ out. Hy-MT2 is a pure translation model, not a general chat model: it
175
+ **translated the instruction** instead of following it, and short inputs were
176
+ destroyed outright — `"Potion"` came back as the Turkish text of the
177
+ instruction, with the actual word gone. Anything the model is meant to obey
178
+ has to live inside the single instruction line of the model card's documented
179
+ templates, never as its own paragraph in front of the source text. The flag
180
+ now defaults to off and, when enabled, adds one short clause with no literal
181
+ placeholder examples.
182
+
183
+ ## Build notes
184
+
185
+ The Docker build compiles llama.cpp, which is the slow part. Earlier builds
186
+ **hung at 24% for 5+ hours and then died with no error message** — the giveaway
187
+ was that they stopped at exactly the same source file every time. Cause:
188
+ `-j$(nproc)` reads the *host's* core count on a Hugging Face build worker
189
+ while the worker's memory ceiling is much lower, so dozens of concurrent g++
190
+ processes thrash it into swap. Bounding it (`BUILD_JOBS=2`, plus
191
+ `LLAMA_BUILD_UI=OFF` so the build stops fetching a UI tarball over the
192
+ network) is the fix: the same target builds in **about 4 minutes at -j4** on a
193
+ 4-core machine.
194
+
195
+ This cost is paid once — Docker layer caching skips the whole compile on
196
+ later deploys as long as you don't edit the `Dockerfile`. Editing only
197
+ `app/` or `test-ui/` rebuilds in seconds.
198
+
199
+ Two other latent problems were fixed at the same time:
200
+
201
+ - The old build produced a **shared** llama-server (`libllama.so`,
202
+ `libggml*.so`) but the runtime stage copied only the executable, so even a
203
+ successful build would have crashed at startup on a missing shared library.
204
+ The build is now static (`BUILD_SHARED_LIBS=OFF`), one file, and
205
+ `llama-server --version` runs as a build-time smoke test.
206
+ - `--mlock` is deprecated in current llama.cpp (superseded by `--load-mode`),
207
+ so `entrypoint.sh` does not use it; the default mmap loading is right for a
208
+ 4.6 GB model on 32 GB of RAM.