| """Modal deployment: llama.cpp serving Qwen3.5-9B with JSON schema |
| enforcement (ARCHITECTURE.md D3). Built on the official llama.cpp CUDA image. |
| |
| Deploy: modal deploy modal_app/inference.py |
| Secret: modal secret create bds-auth BDS_TOKEN=<random hex> |
| Then set on the HF Space / locally: |
| MODAL_URL=<the printed generate endpoint url> |
| MODAL_TOKEN=<same hex> |
| """ |
| from __future__ import annotations |
|
|
| import json |
| import os |
| import subprocess |
| import time |
| import urllib.request |
|
|
| import modal |
|
|
| |
| |
| MODEL_REPO = "bartowski/Qwen_Qwen3.5-9B-GGUF" |
| MODEL_FILE = "Qwen_Qwen3.5-9B-Q4_K_M.gguf" |
| LLAMA_PORT = 8081 |
|
|
| image = ( |
| modal.Image.from_registry( |
| "ghcr.io/ggml-org/llama.cpp:server-cuda", add_python="3.11") |
| .entrypoint([]) |
| .pip_install("fastapi[standard]", "huggingface_hub") |
| .run_commands( |
| "python -c \"from huggingface_hub import hf_hub_download; " |
| f"hf_hub_download('{MODEL_REPO}', '{MODEL_FILE}', " |
| "local_dir='/models')\"" |
| ) |
| ) |
|
|
| app = modal.App("brad-did-something", image=image) |
|
|
| with image.imports(): |
| from fastapi import HTTPException, Request |
|
|
|
|
| def _find_server_binary() -> str: |
| for path in ("/app/llama-server", "/llama-server", |
| "/usr/local/bin/llama-server"): |
| if os.path.exists(path): |
| return path |
| return "llama-server" |
|
|
|
|
| @app.cls( |
| gpu="L4", |
| scaledown_window=300, |
| timeout=120, |
| secrets=[modal.Secret.from_name("bds-auth")], |
| ) |
| class Llama: |
| @modal.enter() |
| def start_server(self): |
| self.proc = subprocess.Popen([ |
| _find_server_binary(), |
| "--model", f"/models/{MODEL_FILE}", |
| "--ctx-size", "4096", |
| "--n-gpu-layers", "99", |
| "--port", str(LLAMA_PORT), |
| "--host", "127.0.0.1", |
| ]) |
| deadline = time.time() + 120 |
| while time.time() < deadline: |
| try: |
| urllib.request.urlopen( |
| f"http://127.0.0.1:{LLAMA_PORT}/health", timeout=2) |
| return |
| except Exception: |
| time.sleep(1) |
| raise RuntimeError("llama-server did not become healthy") |
|
|
| @modal.exit() |
| def stop_server(self): |
| self.proc.terminate() |
|
|
| @modal.fastapi_endpoint(method="POST") |
| def generate(self, body: dict, request: Request): |
| expected = os.environ.get("BDS_TOKEN", "") |
| sent = request.headers.get("authorization", "") |
| if expected and sent != f"Bearer {expected}": |
| raise HTTPException(401, "bad token") |
|
|
| t0 = time.time() |
| |
| |
| prompt = ( |
| f"<|im_start|>system\n{body['system_prompt']}\n" |
| f"GAME STATE JSON:\n{json.dumps(body.get('context', {}))}\n<|im_end|>\n" |
| f"<|im_start|>user\n{body['user_prompt']}<|im_end|>\n" |
| f"<|im_start|>assistant\n<think>\n\n</think>\n\n" |
| ) |
| payload = json.dumps({ |
| "prompt": prompt, |
| "temperature": 0.4, |
| |
| |
| |
| "n_predict": 1024, |
| "cache_prompt": True, |
| "json_schema": body["schema"], |
| }).encode() |
| req = urllib.request.Request( |
| f"http://127.0.0.1:{LLAMA_PORT}/completion", |
| data=payload, headers={"Content-Type": "application/json"}) |
| try: |
| with urllib.request.urlopen(req, timeout=90) as resp: |
| out = json.loads(resp.read()) |
| data = json.loads(out["content"]) |
| return {"ok": True, "data": data, |
| "ms": int((time.time() - t0) * 1000)} |
| except Exception as exc: |
| return {"ok": False, "error": str(exc)[:200], |
| "ms": int((time.time() - t0) * 1000)} |
|
|