VladKha's picture
public CUDA inference base image (image-vllm)
b2b5c30 verified
Raw
History Blame Contribute Delete
3.31 kB
# syntax=docker/dockerfile:1.6
# PUBLIC base image for GPU inference jobs (HF Jobs) β€” vLLM serving variant.
#
# Same contract as demo/image/Dockerfile: ONLY open-source, generic dependencies
# β€” NO proprietary code, and no names that reveal which models/techniques the
# pipeline uses. The Job's bootstrap (/opt/run-job.sh) pulls the private wheel +
# demo modules + the remaining runtime dependencies at startup and runs run_job.py.
#
# Built FROM vLLM's official OpenAI-server image rather than the llama.cpp
# CUDA-runtime base: vLLM's Triton JIT needs a CUDA build chain + a matched torch
# (gcc/ninja/nvcc are absent from the runtime base). torch therefore comes from the
# base and is omitted from the generated pyproject (JOB_IMAGE_BASE_PROVIDES=torch).
#
# Build: JOB_IMAGE_DIR=image-vllm JOB_IMAGE_BASE_PROVIDES=torch make demo-deploy-job
# (run-job.sh + the dataset_reviewer stub are shared from demo/image/.)
# Pinned (not :latest) so the serving CLI contract can't shift under a live demo run:
# vLLM 0.12 renamed the structured-outputs backend flag, and this repo's serve argv +
# fp8 flags target >=0.12. v0.19.1 validated on l40sx1 (boots fp8 + 6/6 valid structured
# JSON via the default auto backend, 2026-06-23) β€” bump deliberately, re-validating each.
FROM vllm/vllm-openai:v0.19.1
# The base image sets ENTRYPOINT to the OpenAI server; reset it so HF Jobs'
# `bash /opt/run-job.sh` (and the idle Space CMD) run as plain commands. The Job
# starts its own server as a co-located subprocess (demo/job/llm_server.py).
ENTRYPOINT []
ENV DEBIAN_FRONTEND=noninteractive \
PIP_NO_CACHE_DIR=0 \
PYTHONUNBUFFERED=1 \
HF_HUB_ENABLE_HF_TRANSFER=1 \
PIP_BREAK_SYSTEM_PACKAGES=1
# git/curl/ca-certificates for the HF pulls at bootstrap. python3.12 + pip are
# already present in the base image.
RUN apt-get update && apt-get install -y --no-install-recommends \
git curl ca-certificates \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
# Install the generic DEPENDENCIES only β€” the generated pyproject omits torch
# (base-provided, stays at the base image's pinned build). A stub package (empty
# dataset_reviewer/__init__.py) lets `pip install .` resolve the deps WITHOUT
# shipping any proprietary source into this public image. At runtime the Job
# replaces the stub with the real wheel and installs the remaining
# (technique-revealing) deps.
COPY pyproject.toml /app/pyproject.toml
COPY dataset_reviewer /app/dataset_reviewer
RUN --mount=type=cache,target=/root/.cache/pip pip install /app
# Explicit pins for the bootstrap + demo modules (transitive above, pinned so the
# bootstrap never depends on resolution order). telethon is the Telegram client the
# Job uses to DM a submitter β€” not a dataset_reviewer dep.
RUN --mount=type=cache,target=/root/.cache/pip \
pip install "huggingface_hub[hf_transfer]" python-dotenv "telethon==1.43.2"
COPY run-job.sh /opt/run-job.sh
RUN chmod +x /opt/run-job.sh
# This image defaults to the vLLM engine; every other serving knob stays
# env-overridable by the launching Job.
ENV LLM_PORT=8080 \
LLM_ENGINE=vllm
# Default command keeps the Space itself idle+RUNNING (so the image publishes
# cleanly); HF Jobs override this with `bash /opt/run-job.sh`.
EXPOSE 7860
CMD ["python3", "-m", "http.server", "7860"]