MB5 PD-disagg pipeline: working end-to-end
Three independent bugs were blocking PD-disagg smoke; each fix is
isolated so the next PD experiment doesn't re-hit them.
1. mb5_launch.sh
- stop_all() also kills mb5_pd_proxy.py (our vendored copy),
not just the upstream filename, and asserts ports 8000-8007 +
PROXY_PORT are free before launching — stale proxies were
silently passing the readiness check.
- Proxy readiness uses a generic "any HTTP response" probe;
mooncake_connector_proxy only exposes /v1/completions so
/v1/models 404 is expected.
2. mb5_pd_proxy.py (vendored from third_party so deploy.sh ships it)
- Force min_tokens=1 on the prefill leg. Clients that set
min_tokens == max_tokens (our replayer does) collide with
vLLM's min_tokens<=max_tokens check after the proxy caps
max_tokens=1.
3. instrument_kv_snapshot.py
- Adds a second patch target: initialize
MooncakeConnectorWorker.bootstrap_server = None in __init__.
vLLM 0.18.1 only sets it under the is_kv_producer branch, so
kv_consumer hits AttributeError as soon as the first remote
prefill request lands.
- apply/revert refactored to iterate over (path, patches) pairs.
plot_kv_pool_timeline.py also handles snapshot files that never
captured a running request (would otherwise IndexError on an empty
stackplot input).
Smoke: 4P+4D × 20 reqs → 20/20 success, mean 3.9s, p99 17s, 8 PIDs
all writing snapshots (601 total), well above the 8C baseline.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -28,7 +28,7 @@ VENV="${FRESH_ROOT}/.venv"
|
||||
MODEL="${MODEL:-/home/admin/cpfs/wjh/models/Qwen/Qwen3-Coder-30B-A3B-Instruct}"
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
INSTRUMENT="${SCRIPT_DIR}/instrument_kv_snapshot.py"
|
||||
PROXY_SRC="${SCRIPT_DIR}/../../third_party/vllm/examples/online_serving/disaggregated_serving/mooncake_connector/mooncake_connector_proxy.py"
|
||||
PROXY_SRC="${SCRIPT_DIR}/mb5_pd_proxy.py"
|
||||
|
||||
CONFIG="${CONFIG:-8C}"
|
||||
RUN_LABEL="${RUN_LABEL:-default}"
|
||||
@@ -44,10 +44,21 @@ BASE_BP=8998
|
||||
BASE_MASTER=29500
|
||||
|
||||
stop_all() {
|
||||
pkill -9 -f "mb5_pd_proxy.py" 2>/dev/null || true
|
||||
pkill -9 -f "mooncake_connector_proxy.py" 2>/dev/null || true
|
||||
pkill -9 -f "vllm serve" 2>/dev/null || true
|
||||
pkill -9 -f "EngineCore" 2>/dev/null || true
|
||||
sleep 3
|
||||
# Hard guarantee: required ports must be free before we start. If they
|
||||
# aren't, an earlier run left a stale process holding the socket and the
|
||||
# readiness check would (silently) probe the stale proxy.
|
||||
for port in 8000 8001 8002 8003 8004 8005 8006 8007 "${PROXY_PORT}"; do
|
||||
if ss -ltn 2>/dev/null | awk '{print $4}' | grep -qE "[:.]${port}\$"; then
|
||||
echo "[mb5] FATAL port ${port} still in use after stop_all; manual cleanup needed"
|
||||
ss -ltnp 2>/dev/null | grep -E "[:.]${port}\$" || true
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
case "${1:-start}" in
|
||||
@@ -183,9 +194,11 @@ if [ "${ROLES}" = "pd" ]; then
|
||||
nohup python "${PROXY_SRC}" "${proxy_args[@]}" --port "${PROXY_PORT}" --host 0.0.0.0 \
|
||||
> "${LOGS_DIR}/proxy.log" 2>&1 &
|
||||
disown
|
||||
# wait for proxy
|
||||
# wait for proxy. Official mooncake_connector_proxy only handles
|
||||
# /v1/completions, so /health and /v1/models return 404 — accept any
|
||||
# HTTP response as "alive".
|
||||
tries=0
|
||||
while ! curl -sf "http://127.0.0.1:${PROXY_PORT}/v1/models" >/dev/null 2>&1; do
|
||||
while ! curl -s -o /dev/null -w "%{http_code}" "http://127.0.0.1:${PROXY_PORT}/" 2>/dev/null | grep -qE "^[0-9]"; do
|
||||
tries=$((tries+1))
|
||||
if [ ${tries} -gt 60 ]; then
|
||||
echo "[mb5] FATAL proxy did not come up in 2 min"
|
||||
@@ -194,7 +207,7 @@ if [ "${ROLES}" = "pd" ]; then
|
||||
fi
|
||||
sleep 2
|
||||
done
|
||||
echo " proxy port=${PROXY_PORT} ready"
|
||||
echo " proxy port=${PROXY_PORT} ready (HTTP responding)"
|
||||
ENDPOINTS="http://127.0.0.1:${PROXY_PORT}"
|
||||
fi
|
||||
|
||||
|
||||
Reference in New Issue
Block a user