@tduncan / Nvidia-Optimization-Stack-VLLM Mirror · read-only / commits / 53700bf49b
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 7, 11:30 UTC

[ci] Add Ray compatibility check informational CI job (#34672)

Signed-off-by: Jeffrey Wang <jeffreywang@anyscale.com>

Jeffrey Wang committed Mar 2, 2026 at 12:06 UTC 53700bf49b578b7114c9049d41d01aea93869535
2 files changed +221
.buildkite/scripts/check-ray-compatibility.sh new
+205
@@ -0,0 +1,205 @@
1 +#!/bin/bash
2 +# SPDX-License-Identifier: Apache-2.0
3 +# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
4 +#
5 +# Check if Ray LLM can generate lock files that are compatible with this
6 +# version of vllm. Downloads Ray's requirement files and runs a full
7 +# dependency resolution with the installed vllm's constraints to see if
8 +# a valid lock file can be produced.
9 +#
10 +# See: https://github.com/vllm-project/vllm/issues/33599
11 +
12 +set -eo pipefail
13 +
14 +RAY_BASE_URL="https://raw.githubusercontent.com/ray-project/ray/master/python"
15 +
16 +WORK_DIR=$(mktemp -d)
17 +trap 'rm -rf "$WORK_DIR"' EXIT
18 +
19 +# Fetch all Ray requirement files used in the LLM depset pipeline
20 +echo ">>> Fetching Ray requirement files"
21 +RAY_FILES=(
22 + "requirements.txt"
23 + "requirements/cloud-requirements.txt"
24 + "requirements/base-test-requirements.txt"
25 + "requirements/llm/llm-requirements.txt"
26 + "requirements/llm/llm-test-requirements.txt"
27 +)
28 +for FILE in "${RAY_FILES[@]}"; do
29 + LOCAL_PATH="${WORK_DIR}/$(basename "$FILE")"
30 + echo " ${FILE}"
31 + curl -fsSL -o "$LOCAL_PATH" "${RAY_BASE_URL}/${FILE}"
32 +done
33 +
34 +# Extract installed vllm deps
35 +echo ">>> Extracting installed vllm dependency constraints"
36 +python3 - "${WORK_DIR}/vllm-constraints.txt" <<'PYEOF'
37 +"""Write out the installed vllm's dependencies as pip constraint lines.
38 +
39 +Ray uses vllm[audio], so audio-extra deps are included with their extra
40 +markers stripped. The resolver cannot evaluate extra markers for a
41 +package that is not itself being resolved from an index, so we activate
42 +them manually here.
43 +"""
44 +import importlib.metadata
45 +import re
46 +import sys
47 +
48 +out_path = sys.argv[1]
49 +raw_reqs = importlib.metadata.requires("vllm") or []
50 +
51 +# Ray uses vllm[audio] – activate that extra.
52 +ACTIVE_EXTRAS = {"audio"}
53 +EXTRA_RE = re.compile(r"""extra\s*==\s*['"]([^'"]+)['"]""")
54 +
55 +lines = []
56 +for r in raw_reqs:
57 + if ";" not in r:
58 + # Unconditional dep — always include.
59 + lines.append(r.strip())
60 + continue
61 +
62 + req_part, _, marker_part = r.partition(";")
63 + marker_part = marker_part.strip()
64 +
65 + extra_matches = EXTRA_RE.findall(marker_part)
66 + if not extra_matches:
67 + # Non-extra marker (python_version, etc.) — keep as-is.
68 + lines.append(r.strip())
69 + continue
70 +
71 + if not ACTIVE_EXTRAS.intersection(extra_matches):
72 + continue # Skip inactive extras (tensorizer, bench, …).
73 +
74 + # Strip the extra== conditions but keep any remaining markers
75 + # (e.g. python_version).
76 + cleaned = EXTRA_RE.sub("", marker_part)
77 + cleaned = re.sub(r"\band\b\s*\band\b", "and", cleaned)
78 + cleaned = re.sub(r"^\s*and\s+|\s+and\s*$", "", cleaned).strip()
79 +
80 + if cleaned:
81 + lines.append(f"{req_part.strip()} ; {cleaned}")
82 + else:
83 + lines.append(req_part.strip())
84 +
85 +with open(out_path, "w") as f:
86 + for line in lines:
87 + f.write(line + "\n")
88 +
89 +print(f"Wrote {len(lines)} constraints to {out_path}")
90 +PYEOF
91 +
92 +echo ">>> Installed vllm deps (first 20 lines):"
93 +head -20 "${WORK_DIR}/vllm-constraints.txt"
94 +
95 +# Remove Ray's vllm pin — the installed vllm's transitive deps
96 +# (written above) replace it in the resolution. vllm itself cannot
97 +# be resolved from PyPI for in-development versions, so we test
98 +# whether Ray's requirements can coexist with vllm's dependency
99 +# constraints instead.
100 +sed -i '/^vllm/d' "${WORK_DIR}/llm-requirements.txt"
101 +
102 +# Install uv if needed
103 +if ! command -v uv &>/dev/null; then
104 + echo ">>> Installing uv"
105 + pip install uv -q
106 +fi
107 +
108 +# Resolve: given vllm's constraints, can Ray compile a lock file?
109 +#
110 +# vllm's dependency constraints are the fixed side — Ray is flexible and
111 +# can regenerate its lock files. We pass vllm's constraints via -c so
112 +# the resolver treats them as non-negotiable bounds, then check whether
113 +# Ray's own requirements can still be satisfied within those bounds.
114 +echo ""
115 +echo "============================================================"
116 +echo ">>> Resolving: Can Ray generate compatible lock files?"
117 +echo "============================================================"
118 +
119 +set +e
120 +uv pip compile \
121 + "${WORK_DIR}/requirements.txt" \
122 + "${WORK_DIR}/cloud-requirements.txt" \
123 + "${WORK_DIR}/base-test-requirements.txt" \
124 + "${WORK_DIR}/llm-requirements.txt" \
125 + "${WORK_DIR}/llm-test-requirements.txt" \
126 + -c "${WORK_DIR}/vllm-constraints.txt" \
127 + --python-version 3.12 \
128 + --python-platform x86_64-manylinux_2_31 \
129 + --extra-index-url https://download.pytorch.org/whl/cu129 \
130 + --index-strategy unsafe-best-match \
131 + --unsafe-package setuptools \
132 + --unsafe-package ray \
133 + --no-header \
134 + -o "${WORK_DIR}/resolved.txt" \
135 + 2>&1
136 +EXIT_CODE=$?
137 +set -e
138 +
139 +echo ""
140 +echo "=========================================="
141 +if [ $EXIT_CODE -eq 0 ]; then
142 + echo "SUCCESS: Ray can generate lock files compatible with this vllm."
143 + echo ""
144 + echo "Key resolved versions:"
145 + grep -E '^(protobuf|torch|numpy|transformers)==' \
146 + "${WORK_DIR}/resolved.txt" | sort || true
147 + echo "=========================================="
148 + exit 0
149 +fi
150 +
151 +echo "FAILURE: Ray cannot generate lock files compatible with this vllm."
152 +echo "This means a fundamental dependency conflict exists that Ray"
153 +echo "cannot resolve by regenerating its lock files."
154 +echo "See: https://github.com/vllm-project/vllm/issues/33599"
155 +echo "=========================================="
156 +
157 +# Buildkite annotation
158 +if [ -f /usr/bin/buildkite-agent ]; then
159 + buildkite-agent annotate --style 'warning' --context 'ray-compat' << EOF
160 +### :warning: Ray Dependency Compatibility Warning
161 +This PR introduces dependencies that **cannot** be resolved with Ray's requirements.
162 +Ray would not be able to regenerate its lock files to accommodate this vllm version.
163 +
164 +Please check the **Ray Dependency Compatibility Check** step logs for details.
165 +See [issue #33599](https://github.com/vllm-project/vllm/issues/33599) for context.
166 +EOF
167 +fi
168 +
169 +# Notify Slack if webhook is configured.
170 +if [ -n "$RAY_COMPAT_SLACK_WEBHOOK_URL" ]; then
171 + echo ">>> Sending Slack notification"
172 + # Single quotes are intentional: the f-string expressions are Python, not shell.
173 + # shellcheck disable=SC2016
174 + PAYLOAD=$(python3 -c '
175 +import json, os, sys
176 +pr = os.getenv("BUILDKITE_PULL_REQUEST", "N/A")
177 +branch = os.getenv("BUILDKITE_BRANCH", "unknown")
178 +url = os.getenv("BUILDKITE_BUILD_URL", "#")
179 +data = {
180 + "text": ":warning: Ray Dependency Compatibility Check Failed",
181 + "blocks": [{
182 + "type": "section",
183 + "text": {
184 + "type": "mrkdwn",
185 + "text": (
186 + "*:warning: Ray Dependency Compatibility Check Failed*\n"
187 + f"PR #{pr} on branch `{branch}` introduces dependencies "
188 + f"that cannot be resolved with Ray'\''s requirements.\n"
189 + f"<{url}|View Build>"
190 + ),
191 + },
192 + }],
193 +}
194 +print(json.dumps(data))
195 +')
196 +
197 + HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" -X POST "$RAY_COMPAT_SLACK_WEBHOOK_URL" \
198 + -H 'Content-type: application/json' \
199 + -d "$PAYLOAD")
200 + echo " Slack webhook response: $HTTP_CODE"
201 +else
202 + echo ">>> Skipping Slack notification (RAY_COMPAT_SLACK_WEBHOOK_URL not set)"
203 +fi
204 +
205 +exit 1
.buildkite/test_areas/ray_compat.yaml new
+16
@@ -0,0 +1,16 @@
1 +group: Ray Compatibility
2 +depends_on:
3 + - image-build
4 +steps:
5 +- label: Ray Dependency Compatibility Check
6 + # Informational only — does not block the pipeline.
7 + # If this fails, it means the PR introduces a dependency that
8 + # conflicts with Ray's dependency constraints.
9 + # See https://github.com/vllm-project/vllm/issues/33599
10 + soft_fail: true
11 + timeout_in_minutes: 10
12 + source_file_dependencies:
13 + - requirements/
14 + - setup.py
15 + commands:
16 + - bash /vllm-workspace/.buildkite/scripts/check-ray-compatibility.sh