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