cvpfus Codex commited on
Commit ·
718f2c4
1
Parent(s): a988b59
Reduce reader brain Modal memory use
Browse filesCo-authored-by: Codex <codex@openai.com>
- DEPLOY_SPACES.md +3 -2
- README.md +2 -2
- app.py +1 -1
- modal_workers/reader_brain.py +7 -9
- scripts/verify.py +2 -1
DEPLOY_SPACES.md
CHANGED
|
@@ -107,7 +107,8 @@ llama-server \
|
|
| 107 |
--alias narrator-brain \
|
| 108 |
--host 0.0.0.0 \
|
| 109 |
--port 8080 \
|
| 110 |
-
--ctx-size
|
|
|
|
| 111 |
--reasoning off \
|
| 112 |
--n-gpu-layers 999 \
|
| 113 |
--api-key your-random-token
|
|
@@ -248,7 +249,7 @@ curl https://<YOUR_USERNAME>-tiny-narrator.hf.space/api/submission-readiness
|
|
| 248 |
### Modal reader-brain cold starts are slow
|
| 249 |
|
| 250 |
- Keep `scaledown_window` higher in `modal_workers/reader_brain.py` if you want the container to stay warm longer.
|
| 251 |
-
- Use a
|
| 252 |
- Keep `min_containers=0` for cheapest operation; use a warm container only if you accept continuous cost.
|
| 253 |
|
| 254 |
### External services unreachable
|
|
|
|
| 107 |
--alias narrator-brain \
|
| 108 |
--host 0.0.0.0 \
|
| 109 |
--port 8080 \
|
| 110 |
+
--ctx-size 4096 \
|
| 111 |
+
--parallel 1 \
|
| 112 |
--reasoning off \
|
| 113 |
--n-gpu-layers 999 \
|
| 114 |
--api-key your-random-token
|
|
|
|
| 249 |
### Modal reader-brain cold starts are slow
|
| 250 |
|
| 251 |
- Keep `scaledown_window` higher in `modal_workers/reader_brain.py` if you want the container to stay warm longer.
|
| 252 |
+
- Use a larger GPU by editing `gpu="T4"` in `modal_workers/reader_brain.py` before deploying.
|
| 253 |
- Keep `min_containers=0` for cheapest operation; use a warm container only if you accept continuous cost.
|
| 254 |
|
| 255 |
### External services unreachable
|
README.md
CHANGED
|
@@ -49,7 +49,7 @@ Copy-Item .env.example .env
|
|
| 49 |
Start the llama.cpp reader-brain server locally:
|
| 50 |
|
| 51 |
```powershell
|
| 52 |
-
llama-server -hf nvidia/NVIDIA-Nemotron-3-Nano-4B-GGUF:Q4_K_M --alias narrator-brain --port 8080 --host 0.0.0.0 --ctx-size
|
| 53 |
```
|
| 54 |
|
| 55 |
Start the app:
|
|
@@ -77,7 +77,7 @@ LLAMA_CPP_MODEL=narrator-brain
|
|
| 77 |
LLAMA_CPP_TOKEN=your-random-token
|
| 78 |
```
|
| 79 |
|
| 80 |
-
The Modal worker starts Nemotron with `--ctx-size
|
| 81 |
|
| 82 |
## Modal Klein Image Generation
|
| 83 |
|
|
|
|
| 49 |
Start the llama.cpp reader-brain server locally:
|
| 50 |
|
| 51 |
```powershell
|
| 52 |
+
llama-server -hf nvidia/NVIDIA-Nemotron-3-Nano-4B-GGUF:Q4_K_M --alias narrator-brain --port 8080 --host 0.0.0.0 --ctx-size 4096 --parallel 1 --reasoning off --n-gpu-layers 999
|
| 53 |
```
|
| 54 |
|
| 55 |
Start the app:
|
|
|
|
| 77 |
LLAMA_CPP_TOKEN=your-random-token
|
| 78 |
```
|
| 79 |
|
| 80 |
+
The Modal worker starts Nemotron on T4 with `--ctx-size 4096`, `--parallel 1`, `--reasoning off`, full GPU offload, and `--api-key` when `LLAMA_CPP_TOKEN` is configured. It uses the prebuilt `ghcr.io/ggml-org/llama.cpp:server-cuda12` image instead of compiling llama.cpp during deploy, clears that image's entrypoint so Modal can start its Python runner, and allows up to 10 minutes for the first GGUF download/load. It scales down when idle, so the first request after a cold start can be slower.
|
| 81 |
|
| 82 |
## Modal Klein Image Generation
|
| 83 |
|
app.py
CHANGED
|
@@ -218,7 +218,7 @@ def runtime_setup_core() -> dict[str, Any]:
|
|
| 218 |
"command": (
|
| 219 |
"llama-server -hf nvidia/NVIDIA-Nemotron-3-Nano-4B-GGUF:Q4_K_M "
|
| 220 |
"--alias narrator-brain --port 8080 --host 0.0.0.0 "
|
| 221 |
-
"--ctx-size
|
| 222 |
),
|
| 223 |
"modal_command": "modal deploy modal_workers/reader_brain.py",
|
| 224 |
"env": {
|
|
|
|
| 218 |
"command": (
|
| 219 |
"llama-server -hf nvidia/NVIDIA-Nemotron-3-Nano-4B-GGUF:Q4_K_M "
|
| 220 |
"--alias narrator-brain --port 8080 --host 0.0.0.0 "
|
| 221 |
+
"--ctx-size 4096 --parallel 1 --reasoning off --n-gpu-layers 999"
|
| 222 |
),
|
| 223 |
"modal_command": "modal deploy modal_workers/reader_brain.py",
|
| 224 |
"env": {
|
modal_workers/reader_brain.py
CHANGED
|
@@ -71,7 +71,7 @@ reader_brain_image = (
|
|
| 71 |
|
| 72 |
@app.function(
|
| 73 |
image=reader_brain_image,
|
| 74 |
-
gpu=
|
| 75 |
volumes={CACHE_DIR: model_cache},
|
| 76 |
secrets=_secret_names(),
|
| 77 |
timeout=900,
|
|
@@ -81,10 +81,6 @@ reader_brain_image = (
|
|
| 81 |
@modal.concurrent(max_inputs=20)
|
| 82 |
@modal.web_server(SERVER_PORT, startup_timeout=600)
|
| 83 |
def reader_brain_server():
|
| 84 |
-
model_ref = os.getenv("READER_BRAIN_MODEL_REF", MODEL_REF)
|
| 85 |
-
model_alias = os.getenv("READER_BRAIN_MODEL_ALIAS", MODEL_ALIAS)
|
| 86 |
-
context_size = os.getenv("READER_BRAIN_CTX_SIZE", "0")
|
| 87 |
-
gpu_layers = os.getenv("READER_BRAIN_GPU_LAYERS", "999")
|
| 88 |
api_key = os.getenv("LLAMA_CPP_TOKEN", "")
|
| 89 |
|
| 90 |
command = [
|
|
@@ -94,15 +90,17 @@ def reader_brain_server():
|
|
| 94 |
"--port",
|
| 95 |
str(SERVER_PORT),
|
| 96 |
"-hf",
|
| 97 |
-
|
| 98 |
"--alias",
|
| 99 |
-
|
| 100 |
"--ctx-size",
|
| 101 |
-
|
|
|
|
|
|
|
| 102 |
"--reasoning",
|
| 103 |
"off",
|
| 104 |
"--n-gpu-layers",
|
| 105 |
-
|
| 106 |
]
|
| 107 |
if api_key:
|
| 108 |
command.extend(["--api-key", api_key])
|
|
|
|
| 71 |
|
| 72 |
@app.function(
|
| 73 |
image=reader_brain_image,
|
| 74 |
+
gpu="T4",
|
| 75 |
volumes={CACHE_DIR: model_cache},
|
| 76 |
secrets=_secret_names(),
|
| 77 |
timeout=900,
|
|
|
|
| 81 |
@modal.concurrent(max_inputs=20)
|
| 82 |
@modal.web_server(SERVER_PORT, startup_timeout=600)
|
| 83 |
def reader_brain_server():
|
|
|
|
|
|
|
|
|
|
|
|
|
| 84 |
api_key = os.getenv("LLAMA_CPP_TOKEN", "")
|
| 85 |
|
| 86 |
command = [
|
|
|
|
| 90 |
"--port",
|
| 91 |
str(SERVER_PORT),
|
| 92 |
"-hf",
|
| 93 |
+
MODEL_REF,
|
| 94 |
"--alias",
|
| 95 |
+
MODEL_ALIAS,
|
| 96 |
"--ctx-size",
|
| 97 |
+
"4096",
|
| 98 |
+
"--parallel",
|
| 99 |
+
"1",
|
| 100 |
"--reasoning",
|
| 101 |
"off",
|
| 102 |
"--n-gpu-layers",
|
| 103 |
+
"999",
|
| 104 |
]
|
| 105 |
if api_key:
|
| 106 |
command.extend(["--api-key", api_key])
|
scripts/verify.py
CHANGED
|
@@ -483,7 +483,8 @@ def verify_modal_klein_integration() -> None:
|
|
| 483 |
assert_true("cmake --build" not in reader_worker_source, "Reader-brain worker should avoid slow CMake builds on Modal")
|
| 484 |
assert_true("NVIDIA-Nemotron-3-Nano-4B-GGUF:Q4_K_M" in reader_worker_source, "Reader-brain worker should serve the Nemotron GGUF")
|
| 485 |
assert_true('"--reasoning"' in reader_worker_source and '"off"' in reader_worker_source, "Reader-brain worker should disable reasoning mode")
|
| 486 |
-
assert_true('"--ctx-size"' in reader_worker_source and '"
|
|
|
|
| 487 |
assert_true('"--n-gpu-layers"' in reader_worker_source and '"999"' in reader_worker_source, "Reader-brain worker should request full GPU offload")
|
| 488 |
assert_true("modal.Volume" in reader_worker_source, "Reader-brain worker should cache model downloads in a Modal volume")
|
| 489 |
assert_true("tiny-narrator-reader-brain-token" in reader_worker_source, "Reader-brain worker should use a fixed Modal token secret")
|
|
|
|
| 483 |
assert_true("cmake --build" not in reader_worker_source, "Reader-brain worker should avoid slow CMake builds on Modal")
|
| 484 |
assert_true("NVIDIA-Nemotron-3-Nano-4B-GGUF:Q4_K_M" in reader_worker_source, "Reader-brain worker should serve the Nemotron GGUF")
|
| 485 |
assert_true('"--reasoning"' in reader_worker_source and '"off"' in reader_worker_source, "Reader-brain worker should disable reasoning mode")
|
| 486 |
+
assert_true('"--ctx-size"' in reader_worker_source and '"4096"' in reader_worker_source, "Reader-brain worker should use T4-safe context size")
|
| 487 |
+
assert_true('"--parallel"' in reader_worker_source and '"1"' in reader_worker_source, "Reader-brain worker should use one parallel slot on T4")
|
| 488 |
assert_true('"--n-gpu-layers"' in reader_worker_source and '"999"' in reader_worker_source, "Reader-brain worker should request full GPU offload")
|
| 489 |
assert_true("modal.Volume" in reader_worker_source, "Reader-brain worker should cache model downloads in a Modal volume")
|
| 490 |
assert_true("tiny-narrator-reader-brain-token" in reader_worker_source, "Reader-brain worker should use a fixed Modal token secret")
|