| # media-analyzer: JoyCaption (via vLLM, OpenAI-compatible) + GPU face | |
| # detection/embedding (InsightFace buffalo_l on onnxruntime-gpu), fronted by | |
| # one FastAPI gateway owning bearer auth and instrumentation. | |
| # | |
| # Patterns follow ~/huggingface-engines (tts-dialogue-engine-moss), the | |
| # proven docker-Space template: uid-1000 user (HF chowns /data to 1000), | |
| # HF_HOME on LOCAL disk (mmap from the network-backed /data volume hangs | |
| # mid-load), PYTHONUNBUFFERED, app_port 7860. | |
| # | |
| # Base: the official vLLM image β its torch/vllm/CUDA/cuDNN are aligned, | |
| # which is exactly the versioning we don't want to hand-roll. onnxruntime-gpu | |
| # >=1.19 targets the same CUDA 12 / cuDNN 9 family. | |
| FROM vllm/vllm-openai:latest | |
| RUN apt-get update && apt-get install -y --no-install-recommends \ | |
| unzip curl \ | |
| && rm -rf /var/lib/apt/lists/* | |
| # The vllm image's python is pip-managed; PIP_BREAK_SYSTEM_PACKAGES covers | |
| # newer Debian/Ubuntu externally-managed setups either way. | |
| ENV PIP_BREAK_SYSTEM_PACKAGES=1 | |
| # insightface depends on plain `onnxruntime` (the CPU wheel), and both ORT | |
| # packages unpack into the SAME `onnxruntime` module directory β whichever | |
| # installs last wins file-by-file. So: install insightface (and friends) | |
| # first, then purge every ORT flavor, then force-reinstall the GPU wheel | |
| # LAST so all module files belong to it. | |
| RUN pip install --no-cache-dir \ | |
| insightface \ | |
| "fastapi>=0.115" \ | |
| "uvicorn>=0.30" \ | |
| "httpx>=0.27" \ | |
| opencv-python-headless \ | |
| hf_transfer | |
| RUN pip uninstall -y onnxruntime onnxruntime-gpu 2>/dev/null || true | |
| RUN pip install --no-cache-dir --force-reinstall --no-deps onnxruntime-gpu \ | |
| # numpy/protobuf etc. are already present via insightface; --no-deps keeps | |
| # this step from dragging anything else in. Then PROVE the CUDA provider | |
| # is at least available in the installed package at build time. | |
| && python3 -c "import onnxruntime as ort; assert 'CUDAExecutionProvider' in ort.get_available_providers(), ort.get_available_providers()" | |
| # Pre-bake buffalo_l (SCRFD detector + ArcFace w600k) so the face endpoint is | |
| # ready at container start. FaceAnalysis(root=/opt/insightface) resolves | |
| # {root}/models/buffalo_l. | |
| RUN mkdir -p /opt/insightface/models/buffalo_l \ | |
| && curl -L -o /tmp/buffalo_l.zip \ | |
| https://github.com/deepinsight/insightface/releases/download/v0.7/buffalo_l.zip \ | |
| && unzip -o /tmp/buffalo_l.zip -d /opt/insightface/models/buffalo_l \ | |
| && rm /tmp/buffalo_l.zip \ | |
| # fail the BUILD if the zip layout ever changes β a missing file here | |
| # would otherwise surface as a runtime re-download attempt into a | |
| # read-only path | |
| && test -f /opt/insightface/models/buffalo_l/det_10g.onnx \ | |
| && test -f /opt/insightface/models/buffalo_l/w600k_r50.onnx \ | |
| && chmod -R a+rX /opt/insightface | |
| # Claim uid 1000 β the uid HF Spaces chowns the persistent /data volume to. | |
| RUN userdel -r ubuntu 2>/dev/null || true \ | |
| && useradd -m -u 1000 user | |
| WORKDIR /app | |
| COPY gateway.py start.sh ./ | |
| RUN chmod +x start.sh && chown -R user:user /app | |
| USER user | |
| # Reduce VRAM fragmentation (set before CUDA init). vLLM and the ONNX face | |
| # session share the GPU; vLLM's slice is bounded by GPU_MEM_UTIL below. | |
| ENV PYTORCH_CUDA_ALLOC_CONF="expandable_segments:True" | |
| ENV PYTHONUNBUFFERED=1 | |
| # HF_HOME must be LOCAL disk (weights are mmap'd from here). If the Space has | |
| # persistent storage, start.sh restores a previously saved cache from | |
| # HF_PERSIST_DIR before downloading. | |
| ENV HF_HOME=/app/.hf-cache \ | |
| HF_PERSIST_DIR=/model-storage/huggingface \ | |
| HF_HUB_ENABLE_HF_TRANSFER=1 \ | |
| MODEL_ID=fancyfeast/llama-joycaption-beta-one-hf-llava \ | |
| SERVED_MODEL_NAME=joycaption-beta-one \ | |
| VLLM_PORT=8001 \ | |
| GPU_MEM_UTIL=0.85 \ | |
| VLLM_ENFORCE_EAGER=0 \ | |
| MAX_MODEL_LEN=4096 \ | |
| PORT=7860 | |
| EXPOSE 7860 | |
| ENTRYPOINT ["./start.sh"] | |