| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147 |
- # DeepSeek-V4.1-Flash — DGX Spark (arm64, sm_121a), clone-at-pin.
- #
- # One Dockerfile for tonyd2wild's overlay1/3/5 chain (MIT; see versions.env
- # header + patches/README note). No fallbacks: every gate fails loud.
- #
- # base pinned vllm/vllm-openai nightly (arm64 digest)
- # vLLM vllm-project/vllm @ dsv41-feat commit+tree (day-0 DSV4.1 support)
- # ext _C_stable_libtorch rebuilt for sm_121a (stable-only cmake build)
- # FI FlashInfer 0.7.0rc1 from pinned source (0.6.18 lacks the SM120
- # sparse-MLA decode kernel for page_block_size=32)
- # warm sparse-MLA + mxfp8 JIT kernels prebuilt in the image runtime env
- # patches the 7 boot-10 file replacements, baked over dist-packages,
- # md5-gated against the published manifest
- #
- # Model: deepseek-ai/DeepSeek-V4.1-Flash (510 GB; Engram tables stay on disk
- # via the baked engram.py patch — DSV41_ENGRAM_DISK=1 at serve time).
- ARG VLLM_BASE_IMAGE
- FROM ${VLLM_BASE_IMAGE}
- ARG VLLM_REPO
- ARG VLLM_REF
- ARG VLLM_REF_TREE
- ARG VLLM_PRETEND_VERSION
- ARG CUTLASS_TAG
- ARG CUTLASS_URL
- ARG FI_SHA
- ARG FI_CUTLASS_SHA
- ARG FI_CCCL_SHA
- ARG FI_SPDLOG_SHA
- ENV DEBIAN_FRONTEND=noninteractive \
- PIP_DISABLE_PIP_VERSION_CHECK=1 \
- MAX_JOBS=4
- # ---- vLLM python tree @ pin (clone-at-pin: commit + tree hash gates) ----
- RUN set -eux; \
- apt-get update -qq && apt-get install -y --no-install-recommends git ca-certificates >/dev/null && rm -rf /var/lib/apt/lists/*; \
- git config --global protocol.version 0; \
- git init -q /src/vllm; \
- git -C /src/vllm fetch --depth 1 ${VLLM_REPO} ${VLLM_REF}; \
- git -C /src/vllm checkout -q ${VLLM_REF}; \
- test "$(git -C /src/vllm rev-parse HEAD)" = "${VLLM_REF}"; \
- test "$(git -C /src/vllm rev-parse 'HEAD^{tree}')" = "${VLLM_REF_TREE}"; \
- echo "vLLM pinned at ${VLLM_REF} / tree ${VLLM_REF_TREE}"
- # ---- _C_stable_libtorch rebuilt for sm_121a (their build_stable_ext.sh) ----
- # stable-only build: external_projects includes commented out, cutlass fetched
- # at the pinned tag, Release build of the single C extension target.
- RUN set -eux; \
- apt-get update -qq && apt-get install -y --no-install-recommends cmake ninja-build g++ >/dev/null && rm -rf /var/lib/apt/lists/*; \
- cd /src/vllm; \
- mkdir -p build/_deps/cutlass-src; \
- curl -sL -m 600 ${CUTLASS_URL} | tar xz -C build/_deps/cutlass-src --strip-components=1; \
- ls build/_deps/cutlass-src/include/cutlass/cutlass.h >/dev/null; \
- cp CMakeLists.txt CMakeLists.txt.orig; \
- sed -i -E "s|^(\s*)include\(cmake/external_projects/|\1# STABLE-ONLY: include(cmake/external_projects/|" CMakeLists.txt; \
- PYPATH=$(python3 -c "import sys;print(':'.join(p for p in sys.path if p))"); \
- TORCH_PREFIX=$(python3 -c "import torch;print(torch.utils.cmake_prefix_path)"); \
- NVRTC=$(ls /usr/local/cuda/lib64/libnvrtc.so /usr/local/cuda/lib64/libnvrtc.so.* /usr/local/lib/python3.12/dist-packages/nvidia/*/lib/libnvrtc.so* /usr/lib/aarch64-linux-gnu/libnvrtc.so* 2>/dev/null | head -1); \
- test -n "${NVRTC}"; \
- cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release -DVLLM_TARGET_DEVICE=cuda \
- -DVLLM_PYTHON_EXECUTABLE=$(which python3) -DVLLM_PYTHON_PATH="$PYPATH" \
- -DFETCHCONTENT_BASE_DIR=build/_deps -DFETCHCONTENT_SOURCE_DIR_CUTLASS=build/_deps/cutlass-src \
- -DCMAKE_PREFIX_PATH="$TORCH_PREFIX" -DNVCC_THREADS=2 -DCUDA_nvrtc_LIBRARY="$NVRTC" -DTORCH_CUDA_ARCH_LIST=12.1a; \
- cmake --build build --target _C_stable_libtorch -j 20; \
- find build vllm -maxdepth 2 -name "_C_stable_libtorch*.so" | tee /tmp/stable_ext.so; \
- # place the built extension in the package dir (vLLM imports vllm._C_stable_libtorch)
- cp -v $(find build vllm -maxdepth 2 -name "_C_stable_libtorch*.so" | head -1) vllm/
- # ---- merge the branch python tree (+ the sm121 .so) over the base install ----
- RUN set -eux; \
- SITE=/usr/local/lib/python3.12/dist-packages/vllm; \
- cp -a /src/vllm/vllm/. ${SITE}/; \
- find ${SITE} -name "__pycache__" -type d -prune -exec rm -rf {} +; \
- python3 -c "import vllm; print('vllm', vllm.__version__)"; \
- # existence check only: dlopen of the CUDA extension needs libcuda.so.1
- # (GPU driver), which the build container does not have — the real import
- # happens at serve time on the GPU node
- ls ${SITE}/_C_stable_libtorch*.so
- # ---- FlashInfer 0.7.0rc1 from pinned source (0.6.18 has no SM120 sparse-MLA) ----
- RUN set -eux; \
- pip uninstall -y -q flashinfer-jit-cache flashinfer-cubin flashinfer-python || true; \
- rm -rf /root/.cache/flashinfer; \
- mkdir -p /opt/fi-src; \
- curl -sL -m 900 "https://codeload.github.com/flashinfer-ai/flashinfer/tar.gz/${FI_SHA}" | tar xz -C /opt/fi-src --strip-components=1; \
- mkdir -p /opt/fi-src/3rdparty/cutlass /opt/fi-src/3rdparty/cccl /opt/fi-src/3rdparty/spdlog; \
- curl -sL -m 900 "https://codeload.github.com/NVIDIA/cutlass/tar.gz/${FI_CUTLASS_SHA}" | tar xz -C /opt/fi-src/3rdparty/cutlass --strip-components=1; \
- curl -sL -m 900 "https://codeload.github.com/NVIDIA/cccl/tar.gz/${FI_CCCL_SHA}" | tar xz -C /opt/fi-src/3rdparty/cccl --strip-components=1; \
- curl -sL -m 900 "https://codeload.github.com/gabime/spdlog/tar.gz/${FI_SPDLOG_SHA}" | tar xz -C /opt/fi-src/3rdparty/spdlog --strip-components=1; \
- ls /opt/fi-src/3rdparty/cutlass/include/cutlass/cutlass.h /opt/fi-src/3rdparty/cccl/README.md /opt/fi-src/3rdparty/spdlog/include/spdlog/spdlog.h; \
- cd /opt/fi-src && BUILD_NVEP=0 FLASHINFER_BUILD_NO_PIP=1 pip install --no-deps --no-build-isolation -q .; \
- rm -rf /opt/fi-src/build; \
- python3 -c "import flashinfer; assert '0.7.0rc1' in flashinfer.__version__, flashinfer.__version__; print('flashinfer', flashinfer.__version__)"
- ENV VLLM_HAS_FLASHINFER_CUBIN=1
- # ---- prebuild the SM120 sparse-MLA + mxfp8 GEMM JIT kernels ----
- # Exact runtime env (no verbose/debug nvcc flags — those change the cache key).
- # The compiled modules persist in /root/.cache/flashinfer inside the image.
- COPY patches/prewarm5.py /tmp/prewarm5.py
- RUN set -eux; \
- FLASHINFER_CUDA_ARCH_LIST=12.1a TORCH_CUDA_ARCH_LIST=12.1a \
- FLASHINFER_DISABLE_VERSION_CHECK=1 VLLM_HAS_FLASHINFER_CUBIN=1 \
- FLASHINFER_NVCC_THREADS=1 MAX_JOBS=4 \
- python3 /tmp/prewarm5.py | tee /tmp/prewarm.log; \
- grep -q "SPARSE-BUILT+LOADED" /tmp/prewarm.log || { echo "sparse MLA prewarm FAILED"; exit 1; }
- # ---- bake the 7 boot-10 patch files (md5-gated against their manifest) ----
- COPY patches/ /tmp/patches/
- RUN set -eux; \
- python3 - <<'PY'
- import hashlib, os, shutil, sys
- SITE = "/usr/local/lib/python3.12/dist-packages/vllm"
- # md5 prefixes from tonyd2wild patch/README.md (boot-10 manifest)
- MD5 = {
- "engram.py": "c0329107", "model_state.py": "0a14bee6",
- "weight_utils.py": "7e1027f1", "attention.py": "da9ef196",
- "flashinfer_sparse.py": "af0f8447", "sparse_swa.py": "cc419353",
- "sparse_attn_indexer.py": "a9b73756",
- }
- bad = []
- for line in open("/tmp/patches/mounts.txt"):
- line = line.strip()
- if not line or line.startswith("#"):
- continue
- f, rel = line.split()
- src = f"/tmp/patches/{f}"
- m = hashlib.md5(open(src, "rb").read()).hexdigest()[:8]
- if m != MD5.get(f):
- bad.append(f"{f}: {m} != {MD5.get(f)}")
- continue
- dst = os.path.join(SITE, rel)
- os.makedirs(os.path.dirname(dst), exist_ok=True)
- shutil.copyfile(src, dst)
- print(f"baked {f} -> {rel} (md5 {m})")
- sys.exit("\n".join(bad) if bad else None)
- PY
- # ---- final gates ----
- RUN set -eux; \
- python3 -c "import vllm; print('vllm', vllm.__version__)"; \
- ls /usr/local/lib/python3.12/dist-packages/vllm/_C_stable_libtorch*.so; \
- python3 -c "import flashinfer; print('flashinfer', flashinfer.__version__)"; \
- grep -q "DSV41_ENGRAM_DISK" /usr/local/lib/python3.12/dist-packages/vllm/models/deepseek_v4_1/common/engram.py; \
- echo "=== image gates passed ==="
|