# FabledCurator GPU agent — runs on the desktop with the GPU. # # The `base` flavour, not `cudnn-runtime`: CUDA and cuDNN arrive as the # `nvidia-*` pip packages torch and onnxruntime-gpu depend on, so the base only # has to hand the container the driver (it sets NVIDIA_VISIBLE_DEVICES / # NVIDIA_DRIVER_CAPABILITIES for the Container Toolkit). Until #1451 this was # `12.9.2-cudnn-runtime` under a `torch==2.6.0+cu124` — and requirements.txt then # REPLACED that torch with PyPI's CUDA-13 build (ultralytics pulls torchvision, # which pulls its matching torch), beside a CUDA-13 onnxruntime-gpu. The image # ran CUDA 13 on a CUDA-12 base, carrying ~3 GB of base libraries and a ~3 GB # torch nothing loaded: 10 GB compressed. # # 13.0 because that is the line both wheels are built for (torch's cu130 index, # onnxruntime-gpu's `nvidia-cuda-runtime~=13.0`). Needs an NVIDIA driver that # supports CUDA 13 (580+); fc_agent/accel.py logs at startup whether torch and # onnxruntime actually got the GPU, since both fall back to the CPU silently. # ffmpeg for video frames. Ubuntu 24.04 → Python 3.12. FROM nvidia/cuda:13.0.3-base-ubuntu24.04 # PIP_BREAK_SYSTEM_PACKAGES: Ubuntu 24.04 marks its system Python as externally # managed (PEP 668), so a global `pip install` errors without this. It's a # single-purpose container — we own the whole environment, so installing into # the system site-packages is fine (and simplest — no venv on PATH to manage). ENV DEBIAN_FRONTEND=noninteractive PYTHONUNBUFFERED=1 PIP_BREAK_SYSTEM_PACKAGES=1 RUN apt-get update \ && apt-get install -y --no-install-recommends python3 python3-pip ffmpeg \ && rm -rf /var/lib/apt/lists/* WORKDIR /app # torch AND torchvision from the cu130 index, together and first. Installing # torch alone is what let the next step swap it out: ultralytics needs # torchvision, PyPI's torchvision pins its own torch, and pip replaced ours to # match. With both present, requirements.txt finds them satisfied. RUN pip3 install --no-cache-dir --index-url https://download.pytorch.org/whl/cu130 \ torch torchvision COPY requirements.txt . RUN pip3 install --no-cache-dir -r requirements.txt COPY fc_agent ./fc_agent # imgutils ONNX models + the transformers SigLIP weights both cache here; mount # a volume to persist them across restarts (the SigLIP download is ~3.5 GB once). ENV HF_HOME=/models # Declared LAST on purpose, exactly as the web Dockerfile does: an ARG/ENV # invalidates every layer below it, and these are the only values that differ # between builds of otherwise identical source. Any earlier and the ~6.3 GB # CUDA + torch layers could never be shared between the dev and main builds of # one commit — which is the cost #3114 measured at 9m26s cold. # # Three values, never folded together (rule 149) — the NAME a person reads, the # CHANNEL it came from, and the REVISION that identifies the content. See # fc_agent/build_info.py; CI derives all three from scripts/artifacts.sh. ARG FC_CHANNEL="" ENV FC_CHANNEL=${FC_CHANNEL} ARG FC_VERSION="" ENV FC_VERSION=${FC_VERSION} ARG FC_REVISION="" ENV FC_REVISION=${FC_REVISION} EXPOSE 8770 # The control UI; the worker is started from it (or POST /start). CMD ["uvicorn", "fc_agent.app:app", "--host", "0.0.0.0", "--port", "8770"]