public CUDA inference base image (image-estimate)
Browse files- Dockerfile +57 -0
- README.md +13 -5
- dataset_reviewer/__init__.py +4 -0
- pyproject.toml +36 -0
- run-job.sh +40 -0
Dockerfile
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# syntax=docker/dockerfile:1.6
|
| 2 |
+
# PUBLIC base image for the cheap CPU ESTIMATE job (HF Jobs) — slim, no GPU stack.
|
| 3 |
+
#
|
| 4 |
+
# Same contract as demo/image/Dockerfile: ONLY open-source, generic dependencies — NO proprietary
|
| 5 |
+
# code, and no names that reveal which models/techniques the pipeline uses. The Job's bootstrap
|
| 6 |
+
# (/opt/run-job.sh) pulls the private wheel + demo modules at startup and runs run_job.py.
|
| 7 |
+
#
|
| 8 |
+
# This variant is CPU-ONLY and slim: it omits CUDA/torch and the GPU inference servers (the estimate
|
| 9 |
+
# runs zero signals and starts no model server — run_job.py returns at the ESTIMATE_ONLY branch
|
| 10 |
+
# before anything loads), and it omits an optional dependency group that `import dataset_reviewer`
|
| 11 |
+
# no longer pulls eagerly. Both shrink the image and its pull time, which is the bulk of the
|
| 12 |
+
# estimate's wall-clock. A lightweight tokenizer loads via the Rust `tokenizers` backend, so no
|
| 13 |
+
# torch is needed.
|
| 14 |
+
#
|
| 15 |
+
# Build: JOB_IMAGE_DIR=image-estimate JOB_IMAGE_BASE_PROVIDES=torch \
|
| 16 |
+
# JOB_IMAGE_SPACE=<owner>/cpu-estimate-base make demo-deploy-job
|
| 17 |
+
# (run-job.sh + the dataset_reviewer stub are shared from demo/image/; the omitted dep group is
|
| 18 |
+
# applied automatically for this variant — see demo/deploy_job.py.)
|
| 19 |
+
|
| 20 |
+
FROM python:3.12-slim
|
| 21 |
+
|
| 22 |
+
ENV DEBIAN_FRONTEND=noninteractive \
|
| 23 |
+
PIP_NO_CACHE_DIR=0 \
|
| 24 |
+
PYTHONUNBUFFERED=1 \
|
| 25 |
+
HF_HUB_ENABLE_HF_TRANSFER=1 \
|
| 26 |
+
PIP_BREAK_SYSTEM_PACKAGES=1
|
| 27 |
+
|
| 28 |
+
# git/curl/ca-certificates for the HF pulls at bootstrap. python3.12 + pip are in the base.
|
| 29 |
+
RUN apt-get update && apt-get install -y --no-install-recommends \
|
| 30 |
+
git curl ca-certificates \
|
| 31 |
+
&& rm -rf /var/lib/apt/lists/*
|
| 32 |
+
|
| 33 |
+
WORKDIR /app
|
| 34 |
+
|
| 35 |
+
# Install the generic DEPENDENCIES only — the generated pyproject omits torch
|
| 36 |
+
# (JOB_IMAGE_BASE_PROVIDES=torch) since the estimate needs no torch/CUDA. A stub package
|
| 37 |
+
# (empty dataset_reviewer/__init__.py) lets `pip install .` resolve the deps WITHOUT shipping
|
| 38 |
+
# proprietary source into this public image. At runtime the Job replaces the stub with the
|
| 39 |
+
# real wheel; run-job.sh skips the technique-revealing runtime deps for ESTIMATE_ONLY (never
|
| 40 |
+
# imported on this path).
|
| 41 |
+
COPY pyproject.toml /app/pyproject.toml
|
| 42 |
+
COPY dataset_reviewer /app/dataset_reviewer
|
| 43 |
+
RUN --mount=type=cache,target=/root/.cache/pip pip install /app
|
| 44 |
+
|
| 45 |
+
# Explicit pins for the bootstrap + demo modules (transitive above, pinned so the bootstrap
|
| 46 |
+
# never depends on resolution order). telethon is the Telegram client the Job imports — not a
|
| 47 |
+
# dataset_reviewer dep.
|
| 48 |
+
RUN --mount=type=cache,target=/root/.cache/pip \
|
| 49 |
+
pip install "huggingface_hub[hf_transfer]" python-dotenv "telethon==1.43.2"
|
| 50 |
+
|
| 51 |
+
COPY run-job.sh /opt/run-job.sh
|
| 52 |
+
RUN chmod +x /opt/run-job.sh
|
| 53 |
+
|
| 54 |
+
# Default command keeps the Space itself idle+RUNNING (so the image publishes cleanly);
|
| 55 |
+
# HF Jobs override this with `bash /opt/run-job.sh`.
|
| 56 |
+
EXPOSE 7860
|
| 57 |
+
CMD ["python3", "-m", "http.server", "7860"]
|
README.md
CHANGED
|
@@ -1,10 +1,18 @@
|
|
| 1 |
---
|
| 2 |
-
title:
|
| 3 |
-
emoji:
|
| 4 |
-
colorFrom:
|
| 5 |
-
colorTo:
|
| 6 |
sdk: docker
|
|
|
|
| 7 |
pinned: false
|
|
|
|
| 8 |
---
|
| 9 |
|
| 10 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
---
|
| 2 |
+
title: CUDA LLM Inference Base
|
| 3 |
+
emoji: 🧱
|
| 4 |
+
colorFrom: gray
|
| 5 |
+
colorTo: indigo
|
| 6 |
sdk: docker
|
| 7 |
+
app_port: 7860
|
| 8 |
pinned: false
|
| 9 |
+
short_description: CUDA inference base image for GPU jobs.
|
| 10 |
---
|
| 11 |
|
| 12 |
+
Public base image: CUDA + torch + a GPU inference server + generic ML/runtime
|
| 13 |
+
dependencies, for running GPU inference jobs on HF Jobs. It contains **no
|
| 14 |
+
proprietary code**; application code and any remaining dependencies are installed
|
| 15 |
+
at runtime from a private repo.
|
| 16 |
+
|
| 17 |
+
This Space exists only to build + publish the image; it serves a trivial idle
|
| 18 |
+
endpoint.
|
dataset_reviewer/__init__.py
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Stub package — present only so `pip install .` resolves dataset-reviewer's
|
| 2 |
+
dependencies into this public base image WITHOUT shipping any proprietary source.
|
| 3 |
+
The real dataset_reviewer wheel is force-reinstalled over this stub at Job runtime
|
| 4 |
+
(see /opt/run-job.sh)."""
|
pyproject.toml
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[project]
|
| 2 |
+
name = "dataset-reviewer"
|
| 3 |
+
version = "0.1.0"
|
| 4 |
+
requires-python = ">=3.12"
|
| 5 |
+
dependencies = [
|
| 6 |
+
"datasets>=4.5.0",
|
| 7 |
+
"datatrove[io]>=0.9.0",
|
| 8 |
+
"duckdb>=1.4.4",
|
| 9 |
+
"httpx",
|
| 10 |
+
"jinja2>=3.1.6",
|
| 11 |
+
"openai>=1.0",
|
| 12 |
+
"markdownify",
|
| 13 |
+
"pyarrow>=23.0.1",
|
| 14 |
+
"pydantic>=2.12.5",
|
| 15 |
+
"markdown-it-py>=4.0.0",
|
| 16 |
+
"rich>=14.3.3",
|
| 17 |
+
"loguru",
|
| 18 |
+
"python-dotenv",
|
| 19 |
+
"huggingface-hub",
|
| 20 |
+
"pandas",
|
| 21 |
+
"requests",
|
| 22 |
+
"markupsafe",
|
| 23 |
+
"fsspec",
|
| 24 |
+
"transformers>=4.40",
|
| 25 |
+
"tiktoken>=0.12.0",
|
| 26 |
+
"tenacity>=9.1.4",
|
| 27 |
+
"pillow>=12.2.0",
|
| 28 |
+
"nh3>=0.2",
|
| 29 |
+
]
|
| 30 |
+
|
| 31 |
+
[build-system]
|
| 32 |
+
requires = ["setuptools>=61"]
|
| 33 |
+
build-backend = "setuptools.build_meta"
|
| 34 |
+
|
| 35 |
+
[tool.setuptools.packages.find]
|
| 36 |
+
include = ["dataset_reviewer*"]
|
run-job.sh
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env bash
|
| 2 |
+
# HF Job bootstrap: pull the private dataset_reviewer wheel + demo modules +
|
| 3 |
+
# runtime requirements from JOB_CODE_REPO (authenticated by HF_TOKEN), install the
|
| 4 |
+
# wheel over the baked stub, install the technique-revealing deps kept out of the
|
| 5 |
+
# public image, then run the headless pipeline. Each phase is timed so its cost is
|
| 6 |
+
# visible in the Job log. Keeps proprietary code + model/technique names OUT of the
|
| 7 |
+
# public base image.
|
| 8 |
+
set -euo pipefail
|
| 9 |
+
|
| 10 |
+
: "${JOB_CODE_REPO:?JOB_CODE_REPO is required}"
|
| 11 |
+
|
| 12 |
+
t=$SECONDS
|
| 13 |
+
echo "[bootstrap] downloading job code from ${JOB_CODE_REPO}"
|
| 14 |
+
python3 - <<'PY'
|
| 15 |
+
import os
|
| 16 |
+
from huggingface_hub import snapshot_download
|
| 17 |
+
snapshot_download(repo_id=os.environ["JOB_CODE_REPO"], repo_type="model", local_dir="/code")
|
| 18 |
+
PY
|
| 19 |
+
echo "[bootstrap] job code downloaded in $((SECONDS - t))s"
|
| 20 |
+
|
| 21 |
+
t=$SECONDS
|
| 22 |
+
echo "[bootstrap] installing dataset_reviewer wheel over the baked stub"
|
| 23 |
+
pip install --no-deps --force-reinstall --no-index /code/wheels/*.whl
|
| 24 |
+
echo "[bootstrap] wheel installed in $((SECONDS - t))s"
|
| 25 |
+
|
| 26 |
+
# The estimate job runs no signals (run_job.py returns at the ESTIMATE_ONLY branch before any
|
| 27 |
+
# signal loads), so skip the technique-revealing runtime deps it never imports — they dominate the
|
| 28 |
+
# bootstrap, and `import dataset_reviewer` succeeds without them (its heavy backends import lazily).
|
| 29 |
+
if [ -f /code/requirements-runtime.txt ] && [ "${ESTIMATE_ONLY:-}" != "1" ]; then
|
| 30 |
+
t=$SECONDS
|
| 31 |
+
echo "[bootstrap] installing runtime ML dependencies"
|
| 32 |
+
pip install -r /code/requirements-runtime.txt
|
| 33 |
+
echo "[bootstrap] runtime deps installed in $((SECONDS - t))s"
|
| 34 |
+
elif [ "${ESTIMATE_ONLY:-}" = "1" ]; then
|
| 35 |
+
echo "[bootstrap] estimate-only run — skipping runtime ML dependencies"
|
| 36 |
+
fi
|
| 37 |
+
|
| 38 |
+
echo "[bootstrap] launching run_job.py"
|
| 39 |
+
cd /code
|
| 40 |
+
exec python3 -u run_job.py
|