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()