main
sh 258 lines 8.02 KB
Raw
1 #!/bin/bash
2 set -euo pipefail
3
4 declare -a PIDS=()
5
6 ###############################################################################
7 # Configuration -- override via env before running
8 ###############################################################################
9 MODEL="${MODEL:-Qwen/Qwen2.5-VL-3B-Instruct}"
10 LOG_PATH="${LOG_PATH:-./logs}"
11 mkdir -p "$LOG_PATH"
12
13 ENCODE_PORT="${ENCODE_PORT:-19534}"
14 PREFILL_PORT="${PREFILL_PORT:-19535}"
15 DECODE_PORT="${DECODE_PORT:-19536}"
16 PROXY_PORT="${PROXY_PORT:-10001}"
17
18 GPU_E="${GPU_E:-2}"
19 GPU_P="${GPU_P:-2}"
20 GPU_D="${GPU_D:-3}"
21
22 # Device platform and affinity env name.
23 # DEVICE_PLATFORM supports: cuda, xpu
24 DEVICE_PLATFORM="${DEVICE_PLATFORM:-cuda}"
25 if [[ -z "${DEVICE_AFFINITY_ENV:-}" ]]; then
26 if [[ "${DEVICE_PLATFORM,,}" == "xpu" ]]; then
27 DEVICE_AFFINITY_ENV="ZE_AFFINITY_MASK"
28 else
29 DEVICE_AFFINITY_ENV="CUDA_VISIBLE_DEVICES"
30 fi
31 fi
32
33 EC_SHARED_STORAGE_PATH="${EC_SHARED_STORAGE_PATH:-/tmp/ec_cache}"
34 TIMEOUT_SECONDS="${TIMEOUT_SECONDS:-12000}" # wait_for_server timeout
35
36 NUM_PROMPTS="${NUM_PROMPTS:-100}" # number of prompts to send in benchmark
37
38 # Serve args
39 GPU_MEMORY_UTILIZATION_E="${GPU_MEMORY_UTILIZATION_E:-0.01}"
40 GPU_MEMORY_UTILIZATION_P="${GPU_MEMORY_UTILIZATION_P:-0.7}"
41 GPU_MEMORY_UTILIZATION_D="${GPU_MEMORY_UTILIZATION_D:-0.7}"
42 MAX_NUM_SEQS="${MAX_NUM_SEQS:-128}"
43 MAX_MODEL_LEN="${MAX_MODEL_LEN:-32768}"
44
45 export UCX_TLS=all
46 export UCX_NET_DEVICES=all
47
48 ###############################################################################
49 # Helpers
50 ###############################################################################
51 # Find the git repository root directory
52 GIT_ROOT=$(git rev-parse --show-toplevel)
53
54 START_TIME=$(date +"%Y%m%d_%H%M%S")
55 ENC_LOG=$LOG_PATH/encoder_${START_TIME}.log
56 P_LOG=$LOG_PATH/p_${START_TIME}.log
57 D_LOG=$LOG_PATH/d_${START_TIME}.log
58 PROXY_LOG=$LOG_PATH/proxy_${START_TIME}.log
59
60 wait_for_server() {
61 local port=$1
62 timeout "$TIMEOUT_SECONDS" bash -c "
63 until curl -s localhost:$port/v1/chat/completions > /dev/null; do
64 sleep 1
65 done" && return 0 || return 1
66 }
67
68 # Cleanup function
69 cleanup() {
70 echo "Stopping everything…"
71 trap - INT TERM USR1 # prevent re-entrancy
72
73 # Kill all tracked PIDs
74 for pid in "${PIDS[@]}"; do
75 if kill -0 "$pid" 2>/dev/null; then
76 echo "Killing process $pid"
77 kill "$pid" 2>/dev/null
78 fi
79 done
80
81 # Wait a moment for graceful shutdown
82 sleep 2
83
84 # Force kill any remaining processes
85 for pid in "${PIDS[@]}"; do
86 if kill -0 "$pid" 2>/dev/null; then
87 echo "Force killing process $pid"
88 kill -9 "$pid" 2>/dev/null
89 fi
90 done
91
92 # Kill the entire process group as backup
93 kill -- -$$ 2>/dev/null
94
95 echo "All processes stopped."
96 exit 0
97 }
98
99 trap cleanup INT
100 trap cleanup USR1
101 trap cleanup TERM
102
103 # clear previous cache
104 echo "remove previous ec cache folder"
105 rm -rf "$EC_SHARED_STORAGE_PATH"
106
107 echo "make ec cache folder"
108 mkdir -p "$EC_SHARED_STORAGE_PATH"
109
110 ###############################################################################
111 # Encoder worker
112 ###############################################################################
113 env "$DEVICE_AFFINITY_ENV=$GPU_E" vllm serve "$MODEL" \
114 --gpu-memory-utilization "$GPU_MEMORY_UTILIZATION_E" \
115 --port "$ENCODE_PORT" \
116 --enforce-eager \
117 --enable-request-id-headers \
118 --no-enable-prefix-caching \
119 --max-num-batched-tokens 114688 \
120 --max-num-seqs "$MAX_NUM_SEQS" \
121 --allowed-local-media-path "${GIT_ROOT}"/tests/v1/ec_connector/integration \
122 --ec-transfer-config '{
123 "ec_connector": "ECExampleConnector",
124 "ec_role": "ec_producer",
125 "ec_connector_extra_config": {
126 "shared_storage_path": "'"$EC_SHARED_STORAGE_PATH"'"
127 }
128 }' \
129 >"${ENC_LOG}" 2>&1 &
130
131 PIDS+=($!)
132
133 ###############################################################################
134 # Prefill worker
135 ###############################################################################
136 env "$DEVICE_AFFINITY_ENV=$GPU_P" \
137 UCX_NET_DEVICES=all \
138 VLLM_NIXL_SIDE_CHANNEL_PORT=5559 \
139 vllm serve "$MODEL" \
140 --gpu-memory-utilization "$GPU_MEMORY_UTILIZATION_P" \
141 --port "$PREFILL_PORT" \
142 --enforce-eager \
143 --enable-request-id-headers \
144 --max-num-seqs "$MAX_NUM_SEQS" \
145 --max-model-len "$MAX_MODEL_LEN" \
146 --allowed-local-media-path "${GIT_ROOT}"/tests/v1/ec_connector/integration \
147 --ec-transfer-config '{
148 "ec_connector": "ECExampleConnector",
149 "ec_role": "ec_consumer",
150 "ec_connector_extra_config": {
151 "shared_storage_path": "'"$EC_SHARED_STORAGE_PATH"'"
152 }
153 }' \
154 --kv-transfer-config '{
155 "kv_connector": "NixlConnector",
156 "kv_role": "kv_producer"
157 }' \
158 >"${P_LOG}" 2>&1 &
159
160 PIDS+=($!)
161
162 ###############################################################################
163 # Decode worker
164 ###############################################################################
165 env "$DEVICE_AFFINITY_ENV=$GPU_D" \
166 UCX_NET_DEVICES=all \
167 VLLM_NIXL_SIDE_CHANNEL_PORT=6000 \
168 vllm serve "$MODEL" \
169 --gpu-memory-utilization "$GPU_MEMORY_UTILIZATION_D" \
170 --port "$DECODE_PORT" \
171 --enforce-eager \
172 --enable-request-id-headers \
173 --max-num-seqs "$MAX_NUM_SEQS" \
174 --max-model-len "$MAX_MODEL_LEN" \
175 --allowed-local-media-path "${GIT_ROOT}"/tests/v1/ec_connector/integration \
176 --kv-transfer-config '{
177 "kv_connector": "NixlConnector",
178 "kv_role": "kv_consumer"
179 }' \
180 >"${D_LOG}" 2>&1 &
181
182 PIDS+=($!)
183
184 # Wait for workers
185 wait_for_server "$ENCODE_PORT"
186 wait_for_server "$PREFILL_PORT"
187 wait_for_server "$DECODE_PORT"
188
189 ###############################################################################
190 # Proxy
191 ###############################################################################
192 PROXY_ARGS=()
193 if [[ "${DYNAMIC_REGISTRATION:-0}" == "1" ]]; then
194 : "${ADMIN_API_KEY:?Set ADMIN_API_KEY for dynamic registration}"
195 export ADMIN_API_KEY
196 PROXY_ARGS=(--dynamic-registration)
197 else
198 PROXY_ARGS=(
199 --encode-servers-urls "http://localhost:$ENCODE_PORT"
200 --prefill-servers-urls "http://localhost:$PREFILL_PORT"
201 --decode-servers-urls "http://localhost:$DECODE_PORT"
202 )
203 fi
204 python disagg_epd_proxy.py \
205 --host "0.0.0.0" \
206 --port "$PROXY_PORT" \
207 "${PROXY_ARGS[@]}" \
208 >"${PROXY_LOG}" 2>&1 &
209
210 PIDS+=($!)
211
212 wait_for_server "$PROXY_PORT"
213 if [[ "${DYNAMIC_REGISTRATION:-0}" == "1" ]]; then
214 for endpoint in "encode:$ENCODE_PORT" "prefill:$PREFILL_PORT" "decode:$DECODE_PORT"; do
215 curl --fail-with-body "http://127.0.0.1:$PROXY_PORT/instances" \
216 -H "X-API-Key: $ADMIN_API_KEY" -H 'Content-Type: application/json' \
217 -d "{\"role\":\"${endpoint%%:*}\",\"url\":\"http://127.0.0.1:${endpoint#*:}\"}"
218 done
219 fi
220 echo "All services are up!"
221
222 ###############################################################################
223 # Benchmark
224 ###############################################################################
225 echo "Running benchmark (stream)..."
226 vllm bench serve \
227 --model "$MODEL" \
228 --backend openai-chat \
229 --endpoint /v1/chat/completions \
230 --dataset-name hf \
231 --dataset-path lmarena-ai/VisionArena-Chat \
232 --seed 0 \
233 --num-prompts "$NUM_PROMPTS" \
234 --port "$PROXY_PORT"
235
236 PIDS+=($!)
237
238 ###############################################################################
239 # Single request with local image
240 ###############################################################################
241 echo "Running single request with local image (non-stream)..."
242 curl http://127.0.0.1:"${PROXY_PORT}"/v1/chat/completions \
243 -H "Content-Type: application/json" \
244 -d '{
245 "model": "'"${MODEL}"'",
246 "messages": [
247 {"role": "system", "content": "You are a helpful assistant."},
248 {"role": "user", "content": [
249 {"type": "image_url", "image_url": {"url": "file://'"${GIT_ROOT}"'/tests/v1/ec_connector/integration/hato.jpg"}},
250 {"type": "text", "text": "What is in this image?"}
251 ]}
252 ]
253 }'
254
255
256 # cleanup
257 echo "cleanup..."
258 cleanup