@tduncan / Nvidia-Optimization-Stack-VLLM Mirror · read-only / commits / 9e078d0582
Fork 0

A high-throughput and memory-efficient inference and serving engine for LLMs

Mirrored from https://github.com/tduncan-lum/Nvidia-Optimization-Stack---VLLM.git

Synced Nov 10, 01:30 UTC

[CI/Build][Docker] Add centralized version manifest for Docker builds (#31492)

Signed-off-by: Mritunjay Sharma <mritunjay.sharma@chainguard.dev>

Mritunjay Kumar Sharma committed Jan 17, 2026 at 19:15 UTC 9e078d058253c6ef3079505edc274c1dfab0ccb2
4 files changed +271 -6
.pre-commit-config.yaml
+7
@@ -147,6 +147,13 @@ repos:
147 entry: python tools/pre_commit/validate_config.py
148 language: python
149 additional_dependencies: [regex]
150 + - id: validate-docker-versions
151 + name: Validate docker/versions.json matches Dockerfile
152 + entry: python tools/generate_versions_json.py --check
153 + language: python
154 + files: ^docker/(Dockerfile|versions\.json)$
155 + pass_filenames: false
156 + additional_dependencies: [dockerfile-parse]
157 # Keep `suggestion` last
158 - id: suggestion
159 name: Suggestion
docker/Dockerfile
+33 -6
@@ -5,6 +5,23 @@
5 # docs/contributing/dockerfile/dockerfile.md and
6 # docs/assets/contributing/dockerfile-stages-dependency.png
7
8 +# =============================================================================
9 +# VERSION MANAGEMENT
10 +# =============================================================================
11 +# ARG defaults in this Dockerfile are the source of truth for pinned versions.
12 +# docker/versions.json is auto-generated for use with docker buildx bake.
13 +#
14 +# When updating versions:
15 +# 1. Edit the ARG defaults below
16 +# 2. Run: python tools/generate_versions_json.py
17 +#
18 +# To query versions programmatically:
19 +# jq -r '.variable.CUDA_VERSION.default' docker/versions.json
20 +#
21 +# To build with bake:
22 +# docker buildx bake -f docker/docker-bake.hcl -f docker/versions.json
23 +# =============================================================================
24 +
25 ARG CUDA_VERSION=12.9.1
26 ARG PYTHON_VERSION=3.12
27
@@ -141,6 +158,7 @@ RUN --mount=type=cache,target=/root/.cache/uv \
158 # CUDA arch list used by torch
159 # Explicitly set the list to avoid issues with torch 2.2
160 # See https://github.com/pytorch/pytorch/pull/123243
161 +# From versions.json: .torch.cuda_arch_list
162 ARG torch_cuda_arch_list='7.0 7.5 8.0 8.9 9.0 10.0 12.0'
163 ENV TORCH_CUDA_ARCH_LIST=${torch_cuda_arch_list}
164 #################### BUILD BASE IMAGE ####################
@@ -256,7 +274,8 @@ ENV UV_LINK_MODE=copy
274 WORKDIR /workspace
275
276 # Build DeepGEMM wheel
259 -ARG DEEPGEMM_GIT_REF
277 +# Default moved here from tools/install_deepgemm.sh for centralized version management
278 +ARG DEEPGEMM_GIT_REF=594953acce41793ae00a1233eb516044d604bcb6
279 COPY tools/install_deepgemm.sh /tmp/install_deepgemm.sh
280 RUN --mount=type=cache,target=/root/.cache/uv \
281 mkdir -p /tmp/deepgemm/dist && \
@@ -271,8 +290,9 @@ RUN mkdir -p /tmp/deepgemm/dist && touch /tmp/deepgemm/dist/.deepgemm_skipped
290
291 # Build pplx-kernels and DeepEP wheels
292 COPY tools/ep_kernels/install_python_libraries.sh /tmp/install_python_libraries.sh
274 -ARG PPLX_COMMIT_HASH
275 -ARG DEEPEP_COMMIT_HASH
293 +# Defaults moved here from tools/ep_kernels/install_python_libraries.sh for centralized version management
294 +ARG PPLX_COMMIT_HASH=12cecfd
295 +ARG DEEPEP_COMMIT_HASH=73b6ea4
296 ARG NVSHMEM_VER
297 RUN --mount=type=cache,target=/root/.cache/uv \
298 mkdir -p /tmp/ep_kernels_workspace/dist && \
@@ -474,6 +494,7 @@ RUN --mount=type=cache,target=/root/.cache/uv \
494 # Install FlashInfer pre-compiled kernel cache and binaries
495 # This is ~1.1GB and only changes when FlashInfer version bumps
496 # https://docs.flashinfer.ai/installation.html
497 +# From versions.json: .flashinfer.version
498 ARG FLASHINFER_VERSION=0.5.3
499 RUN --mount=type=cache,target=/root/.cache/uv \
500 uv pip install --system flashinfer-cubin==${FLASHINFER_VERSION} \
@@ -503,14 +524,20 @@ RUN set -eux; \
524
525 # Install vllm-openai dependencies (saves ~2.6s per build)
526 # These are stable packages that don't depend on vLLM itself
527 +# From versions.json: .bitsandbytes.x86_64, .bitsandbytes.arm64
528 +# From versions.json: .openai_server_extras.timm, .openai_server_extras.runai_model_streamer
529 +ARG BITSANDBYTES_VERSION_X86=0.46.1
530 +ARG BITSANDBYTES_VERSION_ARM64=0.42.0
531 +ARG TIMM_VERSION=">=1.0.17"
532 +ARG RUNAI_MODEL_STREAMER_VERSION=">=0.15.3"
533 RUN --mount=type=cache,target=/root/.cache/uv \
534 if [ "$TARGETPLATFORM" = "linux/arm64" ]; then \
508 - BITSANDBYTES_VERSION="0.42.0"; \
535 + BITSANDBYTES_VERSION="${BITSANDBYTES_VERSION_ARM64}"; \
536 else \
510 - BITSANDBYTES_VERSION="0.46.1"; \
537 + BITSANDBYTES_VERSION="${BITSANDBYTES_VERSION_X86}"; \
538 fi; \
539 uv pip install --system accelerate hf_transfer modelscope \
513 - "bitsandbytes>=${BITSANDBYTES_VERSION}" 'timm>=1.0.17' 'runai-model-streamer[s3,gcs]>=0.15.3'
540 + "bitsandbytes>=${BITSANDBYTES_VERSION}" "timm${TIMM_VERSION}" "runai-model-streamer[s3,gcs]${RUNAI_MODEL_STREAMER_VERSION}"
541
542 # ============================================================
543 # VLLM INSTALLATION (depends on build stage)
docker/versions.json new
+92
@@ -0,0 +1,92 @@
1 +{
2 + "_comment": "Auto-generated from Dockerfile ARGs. Do not edit manually. Run: python tools/generate_versions_json.py",
3 + "variable": {
4 + "CUDA_VERSION": {
5 + "default": "12.9.1"
6 + },
7 + "PYTHON_VERSION": {
8 + "default": "3.12"
9 + },
10 + "BUILD_BASE_IMAGE": {
11 + "default": "nvidia/cuda:12.9.1-devel-ubuntu20.04"
12 + },
13 + "FINAL_BASE_IMAGE": {
14 + "default": "nvidia/cuda:12.9.1-base-ubuntu22.04"
15 + },
16 + "GET_PIP_URL": {
17 + "default": "https://bootstrap.pypa.io/get-pip.py"
18 + },
19 + "PYTORCH_CUDA_INDEX_BASE_URL": {
20 + "default": "https://download.pytorch.org/whl"
21 + },
22 + "PIP_KEYRING_PROVIDER": {
23 + "default": "disabled"
24 + },
25 + "UV_KEYRING_PROVIDER": {
26 + "default": "disabled"
27 + },
28 + "INSTALL_KV_CONNECTORS": {
29 + "default": "false"
30 + },
31 + "TORCH_CUDA_ARCH_LIST": {
32 + "default": "7.0 7.5 8.0 8.9 9.0 10.0 12.0"
33 + },
34 + "MAX_JOBS": {
35 + "default": "2"
36 + },
37 + "NVCC_THREADS": {
38 + "default": "8"
39 + },
40 + "SCCACHE_BUCKET_NAME": {
41 + "default": "vllm-build-sccache"
42 + },
43 + "SCCACHE_REGION_NAME": {
44 + "default": "us-west-2"
45 + },
46 + "SCCACHE_S3_NO_CREDENTIALS": {
47 + "default": "0"
48 + },
49 + "vllm_target_device": {
50 + "default": "cuda"
51 + },
52 + "DEEPGEMM_GIT_REF": {
53 + "default": "594953acce41793ae00a1233eb516044d604bcb6"
54 + },
55 + "PPLX_COMMIT_HASH": {
56 + "default": "12cecfd"
57 + },
58 + "DEEPEP_COMMIT_HASH": {
59 + "default": "73b6ea4"
60 + },
61 + "GIT_REPO_CHECK": {
62 + "default": "0"
63 + },
64 + "VLLM_MAX_SIZE_MB": {
65 + "default": "500"
66 + },
67 + "RUN_WHEEL_CHECK": {
68 + "default": "true"
69 + },
70 + "FLASHINFER_VERSION": {
71 + "default": "0.5.3"
72 + },
73 + "GDRCOPY_CUDA_VERSION": {
74 + "default": "12.8"
75 + },
76 + "GDRCOPY_OS_VERSION": {
77 + "default": "Ubuntu22_04"
78 + },
79 + "BITSANDBYTES_VERSION_X86": {
80 + "default": "0.46.1"
81 + },
82 + "BITSANDBYTES_VERSION_ARM64": {
83 + "default": "0.42.0"
84 + },
85 + "TIMM_VERSION": {
86 + "default": ">=1.0.17"
87 + },
88 + "RUNAI_MODEL_STREAMER_VERSION": {
89 + "default": ">=0.15.3"
90 + }
91 + }
92 +}
tools/generate_versions_json.py new
+139
@@ -0,0 +1,139 @@
1 +#!/usr/bin/env python3
2 +# SPDX-License-Identifier: Apache-2.0
3 +# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
4 +"""
5 +Generate docker/versions.json from Dockerfile ARG defaults.
6 +
7 +This script parses the Dockerfile and extracts ARG defaults to create
8 +a bake-native versions.json file that can be used directly with:
9 + docker buildx bake -f docker/docker-bake.hcl -f docker/versions.json
10 +
11 +Usage:
12 + python tools/generate_versions_json.py [--check]
13 +
14 +Options:
15 + --check Verify versions.json matches Dockerfile (for CI validation)
16 +
17 +Requirements:
18 + pip install dockerfile-parse
19 +"""
20 +
21 +import json
22 +import sys
23 +from pathlib import Path
24 +
25 +from dockerfile_parse import DockerfileParser
26 +
27 +REPO_ROOT = Path(__file__).resolve().parent.parent
28 +DOCKERFILE = REPO_ROOT / "docker" / "Dockerfile"
29 +VERSIONS_JSON = REPO_ROOT / "docker" / "versions.json"
30 +
31 +# Map Dockerfile ARG names (lowercase) to bake variable names (uppercase)
32 +# This matches docker-bake.hcl variable naming convention
33 +BAKE_VAR_NAMES = {
34 + "torch_cuda_arch_list": "TORCH_CUDA_ARCH_LIST",
35 + "max_jobs": "MAX_JOBS",
36 + "nvcc_threads": "NVCC_THREADS",
37 +}
38 +
39 +
40 +def parse_dockerfile_args(dockerfile_path: Path) -> dict[str, str]:
41 + """Extract all ARG defaults from Dockerfile using dockerfile-parse."""
42 + parser = DockerfileParser(path=str(dockerfile_path))
43 +
44 + # Extract ARGs from structure (more reliable for multi-stage Dockerfiles)
45 + args = {}
46 + for item in parser.structure:
47 + if item["instruction"] != "ARG":
48 + continue
49 +
50 + value = item["value"]
51 + if "=" not in value:
52 + continue
53 +
54 + # Parse ARG NAME=value (handle quotes)
55 + name, _, default = value.partition("=")
56 + name = name.strip()
57 +
58 + if name in args:
59 + # Keep first occurrence
60 + continue
61 +
62 + # Strip surrounding quotes if present
63 + default = default.strip()
64 + if (default.startswith('"') and default.endswith('"')) or (
65 + default.startswith("'") and default.endswith("'")
66 + ):
67 + default = default[1:-1]
68 +
69 + if default:
70 + args[name] = default
71 +
72 + # Resolve variable interpolation (e.g., ${CUDA_VERSION} -> 12.9.1)
73 + resolved = {}
74 + for name, value in args.items():
75 + if "${" in value:
76 + # Substitute ${VAR} references with their values
77 + for ref_name, ref_value in args.items():
78 + value = value.replace(f"${{{ref_name}}}", ref_value)
79 + # Skip if still has unresolved references (no default available)
80 + if "${" not in value:
81 + resolved[name] = value
82 +
83 + return resolved
84 +
85 +
86 +def generate_bake_native_json(args: dict[str, str]) -> dict:
87 + """Generate bake-native JSON structure."""
88 + variables = {}
89 + for name, value in args.items():
90 + # Use uppercase bake variable name if mapped, otherwise keep as-is
91 + bake_name = BAKE_VAR_NAMES.get(name, name)
92 + variables[bake_name] = {"default": value}
93 +
94 + return {
95 + "_comment": (
96 + "Auto-generated from Dockerfile ARGs. "
97 + "Do not edit manually. Run: python tools/generate_versions_json.py"
98 + ),
99 + "variable": variables,
100 + }
101 +
102 +
103 +def main():
104 + check_mode = "--check" in sys.argv
105 +
106 + # Parse Dockerfile
107 + args = parse_dockerfile_args(DOCKERFILE)
108 +
109 + # Generate bake-native JSON
110 + data = generate_bake_native_json(args)
111 + new_content = json.dumps(data, indent=2) + "\n"
112 +
113 + if check_mode:
114 + # Verify existing file matches
115 + if not VERSIONS_JSON.exists():
116 + print(f"ERROR: {VERSIONS_JSON} does not exist")
117 + sys.exit(1)
118 +
119 + existing_content = VERSIONS_JSON.read_text()
120 + if existing_content != new_content:
121 + print("ERROR: docker/versions.json is out of sync with Dockerfile")
122 + print("Run: python tools/generate_versions_json.py")
123 + sys.exit(1)
124 +
125 + print("✅ docker/versions.json is in sync with Dockerfile")
126 + sys.exit(0)
127 +
128 + # Write versions.json
129 + VERSIONS_JSON.write_text(new_content)
130 + print(f"✅ Generated {VERSIONS_JSON}")
131 +
132 + # Print summary
133 + print("\nExtracted versions:")
134 + for name, value in args.items():
135 + print(f" {name}: {value}")
136 +
137 +
138 +if __name__ == "__main__":
139 + main()