# FabledCurator GPU agent A desktop-GPU worker that embeds characters (CCIP) + figure crops for FabledCurator. It talks to FC **only over HTTP** — it leases jobs, fetches image pixels, runs the models on your GPU, and posts results back. Your FC database and Redis stay private; the agent never touches them. You run it when you want a burst and stop it to reclaim the card. ## 1. Get a token In FC: **Settings → Tagging → GPU agent → Generate token** (or Rotate). Copy it. ## 2. Pull (CI publishes it alongside the web/ml images) ```sh docker pull git.fabledsword.com/bvandeusen/fabledcurator-agent:latest ``` > Local build for development instead: `docker build -t fc-gpu-agent agent/` ## 3. Run (on the machine with the GPU) ```sh docker run --rm --gpus all -p 8770:8770 \ -e FC_URL=http://curator.traefik.internal \ -e FC_TOKEN= \ -v fc-agent-models:/models \ git.fabledsword.com/bvandeusen/fabledcurator-agent:latest ``` Then open — the control page. Click **Start** to begin draining the queue; **Pause**/**Stop** to yield the GPU. The `-v fc-agent-models` volume caches the downloaded ONNX models so restarts are fast. Kick off a backfill from FC (**GPU agent card → Queue character embedding**), then watch the queue counts on the control page (or FC's card) drain. ## Config (env) | var | default | meaning | |---|---|---| | `FC_URL` | `http://localhost:8000` | FC base URL | | `FC_TOKEN` | — | the bearer token (required) | | `AGENT_ID` | `desktop-agent` | identifies this agent's leases | | `BATCH_SIZE` | `4` | jobs leased per round (still processed one at a time) | | `CCIP_MODEL` | imgutils default | CCIP model name | | `DETECTOR_LEVEL` | `m` | person-detector size: `n` < `s` < `m` < `x` | | `POLL_IDLE_SECONDS` | `10` | wait between empty leases | ## ⚠️ Verify on first run This part can't be CI-tested (no GPU/models in CI), so confirm against your installed `dghs-imgutils` (`pip show dghs-imgutils`) — see `fc_agent/models.py`: - `imgutils.detect.detect_person(image, level=...)` returns `[((x0,y0,x1,y1), label, score), ...]`. - `imgutils.metrics.ccip_extract_feature(image, model=...)` returns a vector (768-d for caformer). If you want the F1-0.94 variant, set `CCIP_MODEL=ccip-caformer_b36-24` (verify the exact string in imgutils). If FC's matcher under/over-fires, tune the cosine threshold in `backend/app/services/ml/ccip.py` (`DEFAULT_SIM_THRESHOLD`) and use `GET /api/ccip/overview` + `/api/ccip/images/` to spot-check. ## CPU fallback Swap `onnxruntime-gpu` → `onnxruntime` in `requirements.txt` and drop `--gpus all` to grind it slowly on the server instead. Same agent, no card.