Dockerfile 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. # syntax=docker/dockerfile:1.7
  2. # GLM-5.3-Flash r12 (jovian-judgement) — CLEAN build for DGX Spark (aarch64/sm_121a)
  3. #
  4. # Per operator direction: start from a raw CUDA image (solar-open2-nvfp4
  5. # pattern), NOT the day-0 vllm image. No baked-vllm contamination: torch,
  6. # flashinfer, vLLM and b12x all come from pinned sources in this file.
  7. #
  8. # Stack: vLLM/b12x pins live in versions.env (single source of truth — the
  9. # staged vllm-src.tar.gz / b12x-src.tar.gz on the build host are built from
  10. # those pins, composition notes included). torch = 2.13.0 cu130 (the fork's
  11. # requirements/cuda.txt pin); flashinfer = 0.6.17 (not a pip dep of the fork
  12. # since 0.6.14, installed from the flashinfer.ai wheel index). b12x is
  13. # pure-Python: CuTe-DSL / tvm-ffi JIT (nvidia-cutlass-dsl 4.6.2), no CUDA
  14. # compile at install time.
  15. #
  16. # GB10 sm_121 fix baked in (patch_cuda_sm12x.py): the sm12x auto-priority
  17. # list in vllm/platforms/cuda.py offers only TRITON_MLA (no sparse) and
  18. # FLASHINFER_MLA_SPARSE_SM120 (head 576 only) — neither fits GLM head-512.
  19. # B12X (supports (12,0)/(12,1)) is inserted first.
  20. #
  21. # Build: cd docker-images/glm53-jovian-r12 && bash build.sh (on a Spark node)
  22. ARG CUDA_BASE_IMAGE
  23. ARG CUDA_BASE_DIGEST
  24. ARG UV_VERSION
  25. FROM ${CUDA_BASE_IMAGE}@${CUDA_BASE_DIGEST} AS apt-base
  26. ARG PYPI_INDEX_URL
  27. ENV DEBIAN_FRONTEND=noninteractive \
  28. PIP_BREAK_SYSTEM_PACKAGES=1 \
  29. UV_SYSTEM_PYTHON=1 UV_BREAK_SYSTEM_PACKAGES=1 UV_LINK_MODE=copy
  30. COPY locks/apt-sources.list /tmp/apt-sources.list
  31. COPY locks/apt-packages.txt /tmp/apt-packages.txt
  32. COPY locks/python-bootstrap.txt /tmp/python-bootstrap.txt
  33. RUN rm -f /etc/apt/sources.list.d/*.list /etc/apt/sources.list.d/*.sources \
  34. && cp /tmp/apt-sources.list /etc/apt/sources.list \
  35. && apt-get update \
  36. && grep -vE '^\s*(#|$)' /tmp/apt-packages.txt \
  37. | xargs apt-get install -y --no-install-recommends \
  38. && rm -rf /var/lib/apt/lists/* \
  39. && python3 -m pip install --no-cache-dir --no-deps \
  40. -r /tmp/python-bootstrap.txt --index-url ${PYPI_INDEX_URL}
  41. FROM apt-base AS torch-base
  42. ARG PYPI_INDEX_URL
  43. ARG PYTORCH_INDEX_URL
  44. ARG TORCH_VERSION TORCHVISION_VERSION TORCHAUDIO_VERSION
  45. ARG FLASHINFER_VERSION
  46. RUN --mount=type=cache,id=uv-cache,target=/root/.cache/uv \
  47. uv pip install \
  48. --index-url ${PYPI_INDEX_URL} \
  49. --extra-index-url ${PYTORCH_INDEX_URL} \
  50. --index-strategy unsafe-best-match \
  51. "torch==${TORCH_VERSION}" \
  52. "torchvision==${TORCHVISION_VERSION}" \
  53. "torchaudio==${TORCHAUDIO_VERSION}" \
  54. "flashinfer-python==${FLASHINFER_VERSION}"
  55. # The fork's r12 composition: base branch + sequential merge of the open
  56. # PR heads (ascending). The PR head pseudo-refs are GitHub's stable refs.
  57. FROM torch-base AS deepgemm-builder
  58. ARG DEEPGEMM_REPO DEEPGEMM_REF DEEPGEMM_BRANCH
  59. RUN set -eux; \
  60. git config --global protocol.version 0; \
  61. git clone --branch ${DEEPGEMM_BRANCH} ${DEEPGEMM_REPO} /deps/deepgemm; \
  62. cd /deps/deepgemm; \
  63. git checkout ${DEEPGEMM_REF}; \
  64. git submodule update --init --depth 1 -- third-party/cutlass third-party/fmt
  65. FROM deepgemm-builder AS deps-src
  66. # Pre-fetched vllm build sub-deps (deps-src.tar.gz in the build context, staged
  67. # on the build host): the node's direct github.com access is flaky (FetchContent
  68. # git clones get "could not read Username" / hung-up) — these SRC_DIR env vars
  69. # are each cmake's documented local-source escape hatch.
  70. COPY deps-src.tar.gz /tmp/deps-src.tar.gz
  71. RUN set -eux; \
  72. mkdir -p /deps2; \
  73. tar xzf /tmp/deps-src.tar.gz -C /deps2; \
  74. mv /deps2/triton/python/triton_kernels/triton_kernels /deps2/triton_kernels; \
  75. rm -rf /deps2/triton /tmp/deps-src.tar.gz
  76. FROM deepgemm-builder AS vllm-builder
  77. ARG VLLM_REPO
  78. ARG VLLM_BASE_REF
  79. ARG VLLM_PR_HEADS
  80. ARG SOURCE_DATE_EPOCH
  81. ARG BUILD_JOBS
  82. ENV TORCH_CUDA_ARCH_LIST=12.1a GIT_PROTOCOL=0 DEEPGEMM_SRC_DIR=/deps/deepgemm
  83. # Pre-staged r12 source tree (vllm-src.tar.gz in the build context, assembled
  84. # on the build host: base VLLM_BASE_REF + VLLM_PR_HEADS merged in order, fresh
  85. # lightweight .git). The node's github.com git access is WAF-blocked
  86. # (401 on git-upload-pack; curl GET works) so no in-build git is possible.
  87. COPY vllm-src.tar.gz /tmp/vllm-src.tar.gz
  88. RUN set -eux; \
  89. mkdir -p /workspace/vllm; \
  90. tar xzf /tmp/vllm-src.tar.gz -C /workspace/vllm; \
  91. rm -f /tmp/vllm-src.tar.gz; \
  92. git config --global --add safe.directory /workspace/vllm; \
  93. cd /workspace/vllm; \
  94. git rev-parse HEAD
  95. WORKDIR /workspace/vllm
  96. # eugr/spark-vllm-docker build-time patches (main, 2026-09-02): the lab's
  97. # Spark-tuned vllm fixes. All are source-aware/idempotent (skip when the
  98. # vulnerable pattern is absent), so running the full set is safe. The two env
  99. # gates are opt-in and ON for this build (sm_121a + b12x):
  100. # - preserve_sm12x_target: keep 12.1a in CUDA_SUPPORTED_ARCHS (their
  101. # standard CUDA-13 build collapses 12.1a -> 12.0)
  102. # - sm120_cooperative_topk: cooperative_topk fails on SM12.x at launch;
  103. # keep SM90-only (Spark fix)
  104. # - mrv2_speculator_cudagraph_pool: MTP speculator cudagraph pool fix
  105. # - spark_kv_cache_cleanup: DGX Spark UMA allocator cleanup
  106. # - b12x_c128a_topk_alignment / flashinfer_b12x_swigluoai: b12x kernel fixes
  107. # - routed_experts_weight_shape: modelopt MoE 2-element weight_shape load
  108. # - topk_softplus_sqrt_control_flow: dead CUDA kernel fix (upstream bug)
  109. # Provenance: https://github.com/eugr/spark-vllm-docker (docker/patch_vllm_*.py)
  110. COPY patches-eugr/patch_vllm_*.py /tmp/eugr-patches/
  111. RUN VLLM_PRESERVE_SM12X_TARGET=1 \
  112. VLLM_PATCH_B12X_C128A_ALIGNMENT=1 \
  113. python3 /tmp/eugr-patches/patch_vllm_mrv2_speculator_cudagraph_pool.py . \
  114. && python3 /tmp/eugr-patches/patch_vllm_b12x_c128a_topk_alignment.py . \
  115. && python3 /tmp/eugr-patches/patch_vllm_flashinfer_b12x_swigluoai.py . \
  116. && python3 /tmp/eugr-patches/patch_vllm_topk_softplus_sqrt_control_flow.py . \
  117. && python3 /tmp/eugr-patches/patch_vllm_preserve_sm12x_target.py . \
  118. && python3 /tmp/eugr-patches/patch_vllm_diffusion_tensor_causal.py . \
  119. && python3 /tmp/eugr-patches/patch_vllm_gemma4_mtp_embedding_share.py . \
  120. && python3 /tmp/eugr-patches/patch_vllm_sm120_cooperative_topk.py . \
  121. && python3 /tmp/eugr-patches/patch_vllm_autogptq_symmetric_moe_qzeros.py . \
  122. && python3 /tmp/eugr-patches/patch_vllm_disable_minimax_qk_rmsnorm_ipc.py . \
  123. && python3 /tmp/eugr-patches/patch_vllm_routed_experts_weight_shape.py . \
  124. && python3 /tmp/eugr-patches/patch_vllm_spark_kv_cache_cleanup.py .
  125. COPY --from=deps-src /deps2 /deps2
  126. RUN --mount=type=cache,id=uv-cache,target=/root/.cache/uv \
  127. --mount=type=cache,id=ccache,target=/root/.ccache \
  128. --mount=type=cache,id=cargo-registry,target=/root/.cargo/registry \
  129. --mount=type=cache,id=rust-target,target=/workspace/vllm/vllm/target \
  130. git config --global protocol.version 0 \
  131. && uv pip install setuptools-rust setuptools-scm \
  132. && (command -v cargo >/dev/null 2>&1 || curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal --default-toolchain stable --no-modify-path) \
  133. && export PATH=/root/.cargo/bin:$PATH \
  134. && (command -v protoc >/dev/null 2>&1 || (apt-get update -qq && apt-get install -y --no-install-recommends protobuf-compiler libprotobuf-dev >/dev/null && rm -rf /var/lib/apt/lists/*)) \
  135. && _j="${BUILD_JOBS:-$(nproc)}" \
  136. && export GIT_PROTOCOL=0 MAX_JOBS="${_j}" CMAKE_BUILD_PARALLEL_LEVEL="${_j}" \
  137. VLLM_REQUIRE_RUST_FRONTEND=1 CARGO_BUILD_JOBS="${_j}" \
  138. TRITON_KERNELS_SRC_DIR=/deps2/triton_kernels \
  139. FMHA_SM100_SRC_DIR=/deps2/MSA \
  140. FLASH_MLA_SRC_DIR=/deps2/FlashMLA \
  141. FLASH_KDA_SRC_DIR=/deps2/FlashKDA \
  142. VLLM_FLASH_ATTN_SRC_DIR=/deps2/flash-attention \
  143. QUTLASS_SRC_DIR=/deps2/qutlass \
  144. TML_FA4_SRC_DIR=/deps2/tml-fa4 \
  145. VLLM_CUTLASS_SRC_DIR=/deps2/cutlass \
  146. CUTLASS_INCLUDE_DIR_PRE=/deps2/cutlass/include \
  147. && python3 use_existing_torch.py \
  148. && uv build --no-build-isolation --wheel . --out-dir=/wheels -v
  149. FROM torch-base AS b12x-builder
  150. ARG B12X_REPO
  151. ARG B12X_BASE_REF
  152. ARG B12X_PRS
  153. ARG SOURCE_DATE_EPOCH
  154. # Pre-staged r12 b12x tree (same reason as vllm: node github WAF block);
  155. # base B12X_BASE_REF + B12X_PRS merged on the build host.
  156. COPY b12x-src.tar.gz /tmp/b12x-src.tar.gz
  157. RUN set -eux; \
  158. mkdir -p /workspace/b12x; \
  159. tar xzf /tmp/b12x-src.tar.gz -C /workspace/b12x; \
  160. rm -f /tmp/b12x-src.tar.gz; \
  161. git config --global --add safe.directory /workspace/b12x; \
  162. cd /workspace/b12x; \
  163. git rev-parse HEAD
  164. WORKDIR /workspace/b12x
  165. RUN --mount=type=cache,id=uv-cache,target=/root/.cache/uv \
  166. uv build --no-build-isolation --wheel . --out-dir=/wheels -v
  167. FROM torch-base AS runner
  168. ARG PYPI_INDEX_URL
  169. COPY checksums/tiktoken.sha256 /tmp/tiktoken.sha256
  170. COPY patch_cuda_sm12x.py /tmp/patch_cuda_sm12x.py
  171. WORKDIR /workspace
  172. RUN mkdir -p tiktoken_encodings \
  173. && wget -O tiktoken_encodings/o200k_base.tiktoken https://openaipublic.blob.core.windows.net/encodings/o200k_base.tiktoken \
  174. && wget -O tiktoken_encodings/cl100k_base.tiktoken https://openaipublic.blob.core.windows.net/encodings/cl100k_base.tiktoken \
  175. && cd tiktoken_encodings && sha256sum -c /tmp/tiktoken.sha256
  176. ENV TIKTOKEN_ENCODINGS_BASE=/workspace/tiktoken_encodings
  177. RUN --mount=type=bind,from=vllm-builder,source=/wheels,target=/vllm-wheels \
  178. --mount=type=bind,from=b12x-builder,source=/wheels,target=/b12x-wheels \
  179. --mount=type=cache,id=uv-cache,target=/root/.cache/uv \
  180. pip install --no-cache-dir --no-build-isolation /vllm-wheels/*.whl \
  181. && pip install --no-cache-dir /b12x-wheels/*.whl \
  182. && python3 /tmp/patch_cuda_sm12x.py \
  183. && find /usr/local/lib/python3.12/dist-packages/vllm -name "__pycache__" \
  184. -type d -prune -exec rm -rf {} + 2>/dev/null || true
  185. # Build gate: the r12 stack must import with the GB10 patches in place.
  186. RUN set -eux; \
  187. python3 -c "import vllm; print('vllm', vllm.__version__)"; \
  188. python3 -c "import b12x; print('b12x ok')"; \
  189. python3 -c "import vllm._flashkda_C; print('flashkda_C ok')"; \
  190. python3 -c "from vllm.config.attention import AttentionBackendEnum as E; \
  191. assert E.B12X.value and 'b12x' in E.B12X.value.lower(); print('B12X enum ok')"; \
  192. grep -q "AttentionBackendEnum.B12X," /usr/local/lib/python3.12/dist-packages/vllm/platforms/cuda.py
  193. ENTRYPOINT []
  194. CMD ["bash"]