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 4, 12:30 UTC
[CI/Build] Auto-detect manylinux ABI tag for nightly wheels (#41149)
Signed-off-by: Shengqi Chen <harry-chen@outlook.com> Co-authored-by: Claude <noreply@anthropic.com>
Shengqi Chen committed
Apr 29, 2026 at 15:37 UTC
e48cb85185d792f5b4a595c2af3cbc37ac742aac
8 files changed
+352
-49
.buildkite/release-pipeline.yaml
+6
-6
@@ -27,7 +27,7 @@ steps:
27
- "DOCKER_BUILDKIT=1 docker build --build-arg max_jobs=16 --build-arg USE_SCCACHE=1 --build-arg GIT_REPO_CHECK=1 --build-arg CUDA_VERSION=12.9.1 --build-arg torch_cuda_arch_list=\"${CUDA_ARCH_AARCH64_CU129}\" --tag vllm-ci:build-image --target build --progress plain -f docker/Dockerfile ."
28
- "mkdir artifacts"
29
- "docker run --rm -v $(pwd)/artifacts:/artifacts_host vllm-ci:build-image bash -c 'cp -r dist /artifacts_host && chmod -R a+rw /artifacts_host'"
30
- - "bash .buildkite/scripts/upload-nightly-wheels.sh manylinux_2_31"
30
+ - "bash .buildkite/scripts/upload-nightly-wheels.sh"
31
env:
32
DOCKER_BUILDKIT: "1"
33
@@ -40,7 +40,7 @@ steps:
40
- "DOCKER_BUILDKIT=1 docker build --build-arg max_jobs=16 --build-arg USE_SCCACHE=1 --build-arg GIT_REPO_CHECK=1 --build-arg CUDA_VERSION=13.0.2 --build-arg torch_cuda_arch_list=\"${CUDA_ARCH_AARCH64}\" --build-arg BUILD_BASE_IMAGE=nvidia/cuda:13.0.2-devel-ubuntu22.04 --tag vllm-ci:build-image --target build --progress plain -f docker/Dockerfile ."
41
- "mkdir artifacts"
42
- "docker run --rm -v $(pwd)/artifacts:/artifacts_host vllm-ci:build-image bash -c 'cp -r dist /artifacts_host && chmod -R a+rw /artifacts_host'"
43
- - "bash .buildkite/scripts/upload-nightly-wheels.sh manylinux_2_35"
43
+ - "bash .buildkite/scripts/upload-nightly-wheels.sh"
44
env:
45
DOCKER_BUILDKIT: "1"
46
@@ -53,7 +53,7 @@ steps:
53
- "DOCKER_BUILDKIT=1 docker build --build-arg max_jobs=16 --build-arg GIT_REPO_CHECK=1 --build-arg VLLM_BUILD_ACL=ON --tag vllm-ci:build-image --target vllm-build --progress plain -f docker/Dockerfile.cpu ."
54
- "mkdir artifacts"
55
- "docker run --rm -v $(pwd)/artifacts:/artifacts_host vllm-ci:build-image bash -c 'cp -r dist /artifacts_host && chmod -R a+rw /artifacts_host'"
56
- - "bash .buildkite/scripts/upload-nightly-wheels.sh manylinux_2_35"
56
+ - "bash .buildkite/scripts/upload-nightly-wheels.sh"
57
env:
58
DOCKER_BUILDKIT: "1"
59
@@ -66,7 +66,7 @@ steps:
66
- "DOCKER_BUILDKIT=1 docker build --build-arg max_jobs=16 --build-arg USE_SCCACHE=1 --build-arg GIT_REPO_CHECK=1 --build-arg CUDA_VERSION=12.9.1 --build-arg torch_cuda_arch_list=\"${CUDA_ARCH_X86_CU129}\" --tag vllm-ci:build-image --target build --progress plain -f docker/Dockerfile ."
67
- "mkdir artifacts"
68
- "docker run --rm -v $(pwd)/artifacts:/artifacts_host vllm-ci:build-image bash -c 'cp -r dist /artifacts_host && chmod -R a+rw /artifacts_host'"
69
- - "bash .buildkite/scripts/upload-nightly-wheels.sh manylinux_2_31"
69
+ - "bash .buildkite/scripts/upload-nightly-wheels.sh"
70
env:
71
DOCKER_BUILDKIT: "1"
72
@@ -79,7 +79,7 @@ steps:
79
- "DOCKER_BUILDKIT=1 docker build --build-arg max_jobs=16 --build-arg USE_SCCACHE=1 --build-arg GIT_REPO_CHECK=1 --build-arg CUDA_VERSION=13.0.2 --build-arg torch_cuda_arch_list=\"${CUDA_ARCH_X86}\" --build-arg BUILD_BASE_IMAGE=nvidia/cuda:13.0.2-devel-ubuntu22.04 --tag vllm-ci:build-image --target build --progress plain -f docker/Dockerfile ."
80
- "mkdir artifacts"
81
- "docker run --rm -v $(pwd)/artifacts:/artifacts_host vllm-ci:build-image bash -c 'cp -r dist /artifacts_host && chmod -R a+rw /artifacts_host'"
82
- - "bash .buildkite/scripts/upload-nightly-wheels.sh manylinux_2_35"
82
+ - "bash .buildkite/scripts/upload-nightly-wheels.sh"
83
env:
84
DOCKER_BUILDKIT: "1"
85
@@ -92,7 +92,7 @@ steps:
92
- "DOCKER_BUILDKIT=1 docker build --build-arg max_jobs=16 --build-arg GIT_REPO_CHECK=1 --build-arg VLLM_CPU_X86=true --tag vllm-ci:build-image --target vllm-build --progress plain -f docker/Dockerfile.cpu ."
93
- "mkdir artifacts"
94
- "docker run --rm -v $(pwd)/artifacts:/artifacts_host vllm-ci:build-image bash -c 'cp -r dist /artifacts_host && chmod -R a+rw /artifacts_host'"
95
- - "bash .buildkite/scripts/upload-nightly-wheels.sh manylinux_2_35"
95
+ - "bash .buildkite/scripts/upload-nightly-wheels.sh"
96
env:
97
DOCKER_BUILDKIT: "1"
98
.buildkite/scripts/detect-manylinux-tag.py
new
+142
@@ -0,0 +1,142 @@
1
+#!/usr/bin/env python3
2
+# SPDX-License-Identifier: Apache-2.0
3
+# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
4
+"""Detect the manylinux platform tag for a wheel and rename it in place.
5
+
6
+vLLM's build images produce wheels with the generic ``linux_<arch>`` platform
7
+tag, which installers like ``pip`` won't accept off PyPI/our index. We need to
8
+rewrite the platform tag to the appropriate ``manylinux_<major>_<minor>_<arch>``
9
+before uploading.
10
+
11
+Historically the tag was hard-coded per build (``manylinux_2_31`` for the
12
+Ubuntu 20.04-based image, ``manylinux_2_35`` for the Ubuntu 22.04-based
13
+images). That is brittle: bumping the base image silently produces wheels
14
+labelled with the wrong glibc requirement. This script asks ``auditwheel``
15
+to derive the tag from the symbol versions actually referenced by the
16
+binaries inside the wheel, so the label tracks reality.
17
+
18
+We can't simply call ``auditwheel repair`` -- it tries to graft external
19
+shared libraries into the wheel and fails on vLLM's CUDA/cuBLAS dependencies.
20
+Instead we use ``auditwheel.wheel_abi.analyze_wheel_abi`` directly, which is
21
+the same call that powers ``auditwheel show``, and read off
22
+``winfo.sym_policy.name``.
23
+
24
+Usage:
25
+ detect-manylinux-tag.py <wheel_path>
26
+
27
+The wheel is renamed in place; the new path is printed on stdout. All
28
+diagnostics go to stderr so callers can capture stdout safely.
29
+"""
30
+
31
+from __future__ import annotations
32
+
33
+import argparse
34
+import sys
35
+from pathlib import Path
36
+
37
+from auditwheel.error import (
38
+ AuditwheelError,
39
+ NonPlatformWheelError,
40
+ WheelToolsError,
41
+)
42
+from auditwheel.wheel_abi import analyze_wheel_abi
43
+from auditwheel.wheeltools import get_wheel_architecture, get_wheel_libc
44
+
45
+
46
+def detect_platform_tag(wheel_path: Path) -> str:
47
+ """Return the most precise platform tag the wheel is consistent with.
48
+
49
+ Mirrors ``auditwheel show`` but returns ``sym_policy`` rather than
50
+ ``overall_policy``: we only care about the glibc symbol versions used,
51
+ not about other policy axes (ISA extensions, blacklist, etc.) that
52
+ ``overall_policy`` folds in.
53
+ """
54
+ fn = wheel_path.name
55
+
56
+ try:
57
+ arch = get_wheel_architecture(fn)
58
+ except (WheelToolsError, NonPlatformWheelError):
59
+ # Architecture isn't deducible from the filename; let auditwheel
60
+ # infer it from the ELF binaries inside the wheel.
61
+ arch = None
62
+
63
+ try:
64
+ libc = get_wheel_libc(fn)
65
+ except WheelToolsError:
66
+ # An unrepaired wheel uses ``linux_<arch>``, which doesn't encode
67
+ # libc. Let auditwheel infer it from the ELF binaries.
68
+ libc = None
69
+
70
+ winfo = analyze_wheel_abi(
71
+ libc,
72
+ arch,
73
+ wheel_path,
74
+ frozenset(),
75
+ disable_isa_ext_check=False,
76
+ allow_graft=False,
77
+ )
78
+ return winfo.sym_policy.name
79
+
80
+
81
+def rename_wheel(wheel_path: Path, new_platform_tag: str) -> Path:
82
+ """Rename the wheel in place, replacing only its platform tag."""
83
+ # Wheel filename per PEP 427:
84
+ # {distribution}-{version}(-{build})?-{python}-{abi}-{platform}.whl
85
+ # The platform tag is always the last ``-``-separated token before
86
+ # ``.whl``. Compound tags like ``manylinux_2_31_x86_64`` use ``_`` as the
87
+ # internal separator, so ``-``-splitting is unambiguous.
88
+ parts = wheel_path.stem.split("-")
89
+ if len(parts) < 5:
90
+ raise ValueError(f"Unrecognised wheel filename: {wheel_path.name}")
91
+ parts[-1] = new_platform_tag
92
+ new_path = wheel_path.with_name("-".join(parts) + ".whl")
93
+ if new_path != wheel_path:
94
+ wheel_path.rename(new_path)
95
+ return new_path
96
+
97
+
98
+def main() -> int:
99
+ parser = argparse.ArgumentParser(
100
+ description="Detect a wheel's manylinux platform tag with "
101
+ "auditwheel and rename the wheel in place."
102
+ )
103
+ parser.add_argument(
104
+ "wheel",
105
+ type=Path,
106
+ help="Path to the wheel to inspect and rename.",
107
+ )
108
+ args = parser.parse_args()
109
+
110
+ wheel_path: Path = args.wheel
111
+ if not wheel_path.is_file():
112
+ print(f"error: {wheel_path} is not a file", file=sys.stderr)
113
+ return 1
114
+
115
+ # Catch the things that ``analyze_wheel_abi`` and ``rename_wheel`` can
116
+ # raise: any subclass of ``AuditwheelError`` (pure-Python wheels,
117
+ # invalid libc, malformed wheels), filesystem errors, or our own
118
+ # ``ValueError`` for an unrecognised wheel filename. Print a single
119
+ # ``ERROR_TYPE: message`` line to stderr instead of a Python
120
+ # traceback, which is much friendlier in CI logs.
121
+ try:
122
+ new_tag = detect_platform_tag(wheel_path)
123
+ print(f"detected platform tag: {new_tag}", file=sys.stderr)
124
+ new_path = rename_wheel(wheel_path, new_tag)
125
+ except (AuditwheelError, ValueError, OSError) as e:
126
+ print(
127
+ f"error: failed to retag {wheel_path.name}: {type(e).__name__}: {e}",
128
+ file=sys.stderr,
129
+ )
130
+ return 2
131
+
132
+ if new_path != wheel_path:
133
+ print(f"renamed {wheel_path.name} -> {new_path.name}", file=sys.stderr)
134
+ else:
135
+ print(f"wheel already tagged {new_tag}", file=sys.stderr)
136
+
137
+ print(new_path)
138
+ return 0
139
+
140
+
141
+if __name__ == "__main__":
142
+ sys.exit(main())
.buildkite/scripts/generate-and-upload-nightly-index.sh
+4
-11
@@ -10,20 +10,13 @@ set -ex
10
BUCKET="vllm-wheels"
11
INDICES_OUTPUT_DIR="indices"
12
DEFAULT_VARIANT_ALIAS="cu130" # align with vLLM_MAIN_CUDA_VERSION in vllm/envs.py
13
-PYTHON="${PYTHON_PROG:-python3}" # try to read from env var, otherwise use python3
13
SUBPATH=$BUILDKITE_COMMIT
14
S3_COMMIT_PREFIX="s3://$BUCKET/$SUBPATH/"
15
17
-# detect if python3.12+ is available
18
-has_new_python=$($PYTHON -c "print(1 if __import__('sys').version_info >= (3,12) else 0)")
19
-if [[ "$has_new_python" -eq 0 ]]; then
20
- # use new python from docker
21
- docker pull python:3-slim
22
- PYTHON="docker run --rm -u $(id -u):$(id -g) -v $(pwd):/app -w /app python:3-slim python3"
23
-fi
24
-
25
-echo "Using python interpreter: $PYTHON"
26
-echo "Python version: $($PYTHON --version)"
16
+# Select python3 (>= 3.12) -- local if available, else a docker fallback.
17
+# shellcheck source=lib/select-python.sh
18
+source .buildkite/scripts/lib/select-python.sh
19
+select_python
20
21
# ======== generate and upload indices ========
22
.buildkite/scripts/lib/manylinux.sh
new
+127
@@ -0,0 +1,127 @@
1
+#!/usr/bin/env bash
2
+# SPDX-License-Identifier: Apache-2.0
3
+# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
4
+#
5
+# Shared helper for rewriting a wheel's platform tag from the generic
6
+# ``linux_<arch>`` to the correct ``manylinux_<major>_<minor>_<arch>``.
7
+# After sourcing, call ``apply_manylinux_tag <wheel>`` on each wheel
8
+# that still carries the generic tag; the renamed path is printed on
9
+# stdout (logs go to stderr).
10
+#
11
+# Why a pinned Docker container instead of using whatever Python
12
+# happens to be on the agent:
13
+# - vLLM's release agents are heterogeneous -- they don't agree on
14
+# a Python minor version, and we can't rely on a particular
15
+# ``auditwheel`` being installed.
16
+# - ``detect-manylinux-tag.py`` reads ``auditwheel.wheel_abi`` and
17
+# ``Policy.sym_policy``, which are *internal* APIs without a
18
+# stability promise. Pinning both Python and auditwheel makes the
19
+# detected tag a function of the inputs alone, and shifts version
20
+# bumps from "implicit drift" to "deliberate, retested change".
21
+# - Other release scripts (``generate-and-upload-nightly-index.sh``,
22
+# ``upload-rocm-wheels.sh``) already use the python:3-slim image
23
+# when the agent's interpreter is too old; this is the same idea
24
+# made stricter.
25
+#
26
+# To keep the per-wheel cost down (the ROCm upload retags ~10 wheels
27
+# each run), we install auditwheel into a long-lived helper container
28
+# once on source, then ``docker exec`` into it for each call.
29
+#
30
+# Trap behaviour:
31
+# - Sourcing installs an EXIT trap that calls ``manylinux_cleanup`` to
32
+# tear down the helper container. Any EXIT trap that was already in
33
+# place when this file was sourced is captured and run AFTER our
34
+# cleanup, so we don't silently clobber it.
35
+# - If a caller sets a new EXIT trap *after* sourcing, that trap will
36
+# replace ours; in that case the caller should call
37
+# ``manylinux_cleanup`` from their own handler.
38
+
39
+if [[ -n "${_MANYLINUX_LIB_SOURCED:-}" ]]; then
40
+ return 0
41
+fi
42
+_MANYLINUX_LIB_SOURCED=1
43
+
44
+# Pin both sides. Bump these deliberately and re-run a representative
45
+# wheel from each build target through the detection.
46
+_MANYLINUX_PYTHON_IMAGE="python:3.12-slim"
47
+_MANYLINUX_AUDITWHEEL_VERSION="6.6.0"
48
+
49
+# Resolve our own directory (and the sibling detect script) using the
50
+# canonical, symlink-resolved path. The container mounts cwd at the
51
+# same absolute path on both sides, so all paths we hand to it -- the
52
+# script, the wheel -- must canonicalise to a location under cwd.
53
+_MANYLINUX_LIB_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
54
+_MANYLINUX_DETECT_SCRIPT="$(cd "${_MANYLINUX_LIB_DIR}/.." && pwd -P)/detect-manylinux-tag.py"
55
+_MANYLINUX_CWD="$(pwd -P)"
56
+
57
+docker pull --quiet "$_MANYLINUX_PYTHON_IMAGE" >/dev/null
58
+
59
+# Spin up a long-lived helper container so we install auditwheel once
60
+# and then ``docker exec`` into it for each wheel.
61
+#
62
+# The container runs as root so ``pip install`` can write into the
63
+# system site-packages; individual ``docker exec`` calls below pin
64
+# themselves to the host UID so any file rename happens with host
65
+# ownership, not root.
66
+_MANYLINUX_CONTAINER="$(docker run -d --rm \
67
+ -v "$_MANYLINUX_CWD:$_MANYLINUX_CWD" \
68
+ -w "$_MANYLINUX_CWD" \
69
+ "$_MANYLINUX_PYTHON_IMAGE" \
70
+ sleep infinity)"
71
+docker exec "$_MANYLINUX_CONTAINER" \
72
+ pip install --quiet --disable-pip-version-check \
73
+ --root-user-action=ignore \
74
+ "auditwheel==${_MANYLINUX_AUDITWHEEL_VERSION}"
75
+
76
+# Public cleanup -- safe to call multiple times.
77
+manylinux_cleanup() {
78
+ if [[ -n "${_MANYLINUX_CONTAINER:-}" ]]; then
79
+ docker rm -f "$_MANYLINUX_CONTAINER" >/dev/null 2>&1 || true
80
+ _MANYLINUX_CONTAINER=""
81
+ fi
82
+}
83
+
84
+# Capture any EXIT trap that was already in place so we can chain to
85
+# it rather than overwrite it. ``trap -p EXIT`` prints the handler in
86
+# eval-able form (``trap -- 'CMD' EXIT``) or nothing if unset; we
87
+# strip the wrapper to recover ``CMD``. Handles the common case --
88
+# CMDs without embedded single quotes -- and degrades gracefully (we
89
+# still run our own cleanup) for the pathological case.
90
+_manylinux_prev_exit_trap_cmd=""
91
+_manylinux_existing_exit_trap="$(trap -p EXIT)"
92
+if [[ -n "$_manylinux_existing_exit_trap" ]]; then
93
+ _tmp="${_manylinux_existing_exit_trap#trap -- \'}"
94
+ _manylinux_prev_exit_trap_cmd="${_tmp%\' EXIT}"
95
+ unset _tmp
96
+fi
97
+unset _manylinux_existing_exit_trap
98
+
99
+_manylinux_run_exit_chain() {
100
+ manylinux_cleanup
101
+ if [[ -n "$_manylinux_prev_exit_trap_cmd" ]]; then
102
+ eval "$_manylinux_prev_exit_trap_cmd"
103
+ fi
104
+}
105
+trap _manylinux_run_exit_chain EXIT
106
+
107
+# Detect the manylinux platform tag for a single wheel and rename it
108
+# in place, printing the renamed wheel path on stdout. Returns
109
+# non-zero on failure (which under ``set -e`` propagates to caller).
110
+#
111
+# The wheel must be reachable via a path under the host cwd so it's
112
+# visible inside the helper container; in CI the wheels always live
113
+# under ``artifacts/`` so this is fine.
114
+apply_manylinux_tag() {
115
+ local wheel="$1"
116
+ local abs_wheel
117
+ abs_wheel="$(realpath "$wheel")"
118
+ local new_wheel
119
+ new_wheel="$(docker exec -u "$(id -u):$(id -g)" \
120
+ "$_MANYLINUX_CONTAINER" \
121
+ python "$_MANYLINUX_DETECT_SCRIPT" "$abs_wheel")"
122
+ if [[ -z "$new_wheel" || ! -f "$new_wheel" ]]; then
123
+ echo "apply_manylinux_tag: detect-manylinux-tag.py did not produce a valid wheel path for $wheel" >&2
124
+ return 1
125
+ fi
126
+ printf '%s\n' "$new_wheel"
127
+}
.buildkite/scripts/lib/select-python.sh
new
+41
@@ -0,0 +1,41 @@
1
+#!/usr/bin/env bash
2
+# SPDX-License-Identifier: Apache-2.0
3
+# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
4
+#
5
+# Pick a Python interpreter for buildkite scripts: prefer a local
6
+# ``python3`` if it is recent enough (>= 3.12), otherwise fall back to
7
+# a one-shot Docker container running ``python:3-slim``. After
8
+# ``select_python`` returns, ``$PYTHON`` is set in the caller's shell
9
+# and is safe to use as a command (e.g. ``$PYTHON some_script.py``).
10
+#
11
+# The 3.12 threshold matches what the existing nightly-index work
12
+# expects -- typing features used by ``generate-nightly-index.py``.
13
+# This helper does not pin the *minor* version; if you need stricter
14
+# reproducibility (e.g. relying on auditwheel internals), invoke
15
+# Docker yourself with a pinned tag rather than calling this.
16
+
17
+if [[ -n "${_SELECT_PYTHON_LIB_SOURCED:-}" ]]; then
18
+ return 0
19
+fi
20
+_SELECT_PYTHON_LIB_SOURCED=1
21
+
22
+# Sets ``PYTHON`` in the caller's shell and exports it. Idempotent --
23
+# calling twice is safe and the second call simply re-runs the probe.
24
+select_python() {
25
+ local py="${PYTHON_PROG:-python3}"
26
+ local has_new_python
27
+ has_new_python=$("$py" -c \
28
+ "print(1 if __import__('sys').version_info >= (3,12) else 0)" \
29
+ 2>/dev/null || echo 0)
30
+ if [[ "$has_new_python" -eq 0 ]]; then
31
+ # ``-u $(id -u):$(id -g)`` so files created via the container
32
+ # end up owned by the host user, not root.
33
+ docker pull python:3-slim
34
+ PYTHON="docker run --rm -u $(id -u):$(id -g) -v $(pwd):/app -w /app python:3-slim python3"
35
+ else
36
+ PYTHON="$py"
37
+ fi
38
+ export PYTHON
39
+ echo "Using python interpreter: $PYTHON"
40
+ echo "Python version: $($PYTHON --version)"
41
+}
.buildkite/scripts/upload-nightly-wheels.sh
+8
-14
@@ -2,14 +2,18 @@
2
3
set -ex
4
5
-# Upload a single wheel to S3 (rename linux -> manylinux).
5
+# Upload a single wheel to S3, after detecting and applying the appropriate
6
+# manylinux platform tag with auditwheel.
7
# Index generation is handled separately by generate-and-upload-nightly-index.sh.
8
9
+# shellcheck source=lib/manylinux.sh
10
+source .buildkite/scripts/lib/manylinux.sh
11
+
12
BUCKET="vllm-wheels"
13
SUBPATH=$BUILDKITE_COMMIT
14
S3_COMMIT_PREFIX="s3://$BUCKET/$SUBPATH/"
15
12
-# ========= collect, rename & upload the wheel ==========
16
+# ========= locate the wheel ==========
17
18
# Assume wheels are in artifacts/dist/*.whl
19
wheel_files=(artifacts/dist/*.whl)
@@ -21,19 +25,9 @@ if [[ ${#wheel_files[@]} -ne 1 ]]; then
25
fi
26
wheel="${wheel_files[0]}"
27
24
-# default build image uses ubuntu 20.04, which corresponds to manylinux_2_31
25
-# we also accept params as manylinux tag
26
-# refer to https://github.com/mayeut/pep600_compliance?tab=readme-ov-file#acceptable-distros-to-build-wheels
27
-manylinux_version="${1:-manylinux_2_31}"
28
+# ========= detect manylinux tag and rename ==========
29
29
-# Rename 'linux' to the appropriate manylinux version in the wheel filename
30
-if [[ "$wheel" != *"linux"* ]]; then
31
- echo "Error: Wheel filename does not contain 'linux': $wheel"
32
- exit 1
33
-fi
34
-new_wheel="${wheel/linux/$manylinux_version}"
35
-mv -- "$wheel" "$new_wheel"
36
-wheel="$new_wheel"
30
+wheel="$(apply_manylinux_tag "$wheel")"
31
echo "Renamed wheel to: $wheel"
32
33
# Extract the version from the wheel
.buildkite/scripts/upload-rocm-wheels.sh
+23
-18
@@ -20,10 +20,6 @@ BUCKET="${S3_BUCKET:-vllm-wheels}"
20
ROCM_SUBPATH="rocm/${BUILDKITE_COMMIT}"
21
S3_COMMIT_PREFIX="s3://$BUCKET/$ROCM_SUBPATH/"
22
INDICES_OUTPUT_DIR="rocm-indices"
23
-PYTHON="${PYTHON_PROG:-python3}"
24
-
25
-# ROCm uses manylinux_2_35 (Ubuntu 22.04 based)
26
-MANYLINUX_VERSION="manylinux_2_35"
23
24
echo "========================================"
25
echo "ROCm Wheel Upload Configuration"
@@ -34,19 +30,21 @@ echo "Commit: $BUILDKITE_COMMIT"
30
echo "Branch: $BUILDKITE_BRANCH"
31
echo "========================================"
32
37
-# ======== Part 0: Setup Python ========
33
+# ======== Part 0: Setup Python and helpers ========
34
39
-# Detect if python3.12+ is available
40
-has_new_python=$($PYTHON -c "print(1 if __import__('sys').version_info >= (3,12) else 0)" 2>/dev/null || echo 0)
41
-if [[ "$has_new_python" -eq 0 ]]; then
42
- # Use new python from docker
43
- # Use --user to ensure files are created with correct ownership (not root)
44
- docker pull python:3-slim
45
- PYTHON="docker run --rm --user $(id -u):$(id -g) -v $(pwd):/app -w /app python:3-slim python3"
46
-fi
35
+# Pick a Python interpreter for index generation -- local if recent
36
+# enough, else a one-shot docker fallback.
37
+# shellcheck source=lib/select-python.sh
38
+source .buildkite/scripts/lib/select-python.sh
39
+select_python
40
48
-echo "Using python interpreter: $PYTHON"
49
-echo "Python version: $($PYTHON --version)"
41
+# Set up auditwheel-in-a-container for the manylinux retagging step.
42
+# Distinct from select_python: ``manylinux.sh`` deliberately pins both
43
+# the Python and auditwheel versions (the script reads auditwheel
44
+# internals) and so always runs in a known-good container regardless
45
+# of what's on the agent.
46
+# shellcheck source=lib/manylinux.sh
47
+source .buildkite/scripts/lib/manylinux.sh
48
49
# ======== Part 1: Collect and prepare wheels ========
50
@@ -63,11 +61,18 @@ if [ "$WHEEL_COUNT" -eq 0 ]; then
61
exit 1
62
fi
63
66
-# Rename linux to manylinux in wheel filenames
64
+# Detect the appropriate manylinux platform tag for any wheel that still
65
+# carries the generic ``linux_<arch>`` tag, and rename it in place. We use
66
+# auditwheel via ``apply_manylinux_tag`` (see lib/manylinux.sh) rather than
67
+# a hard-coded ``manylinux_2_35`` string so that the label tracks the actual
68
+# glibc symbol versions used by the binaries (and stays correct if the
69
+# rocm_base image is rebased).
70
+#
71
+# The ``linux``/``manylinux`` filter below skips both pre-tagged wheels
72
+# (e.g. upstream torch) and pure-Python ``-any.whl`` wheels.
73
for wheel in all-rocm-wheels/*.whl; do
74
if [[ "$wheel" == *"linux"* ]] && [[ "$wheel" != *"manylinux"* ]]; then
69
- new_wheel="${wheel/linux/$MANYLINUX_VERSION}"
70
- mv -- "$wheel" "$new_wheel"
75
+ new_wheel="$(apply_manylinux_tag "$wheel")"
76
echo "Renamed: $(basename "$wheel") -> $(basename "$new_wheel")"
77
fi
78
done
.gitignore
+1
@@ -237,6 +237,7 @@ ep_kernels_workspace/
237
238
# Allow tracked library source folders under submodules (e.g., benchmarks/lib)
239
!vllm/benchmarks/lib/
240
+!.buildkite/scripts/lib/
241
242
# Generated gRPC protobuf files (compiled at build time from vllm_engine.proto)
243
vllm/grpc/vllm_engine_pb2.py