Add decode batch-grid stability experiment

This commit is contained in:
2026-07-23 16:55:55 +08:00
parent cb67ac8621
commit c1c200b7cd
11 changed files with 2498 additions and 0 deletions

View File

@@ -0,0 +1,174 @@
#!/usr/bin/env bash
set -euo pipefail
TP="${TP:?TP is required}"
PROFILE_BATCH="${PROFILE_BATCH:?PROFILE_BATCH is required}"
OUTPUT_ROOT="${OUTPUT_ROOT:?OUTPUT_ROOT is required}"
SERVER_PORT="${SERVER_PORT:?SERVER_PORT is required}"
VENV_ROOT="${VENV_ROOT:-/home/admin/cpfs/wjh/venvs/vllm-0.20.0-cu129-workload-regime-v2}"
MODEL_ROOT="${MODEL_ROOT:-/home/admin/cpfs/wjh/models/Qwen/Qwen3-30B-A3B}"
GPU_MEMORY_UTILIZATION="${GPU_MEMORY_UTILIZATION:-0.92}"
SERVER_READY_ATTEMPTS="${SERVER_READY_ATTEMPTS:-900}"
ACTIVE_ITERATIONS="${ACTIVE_ITERATIONS:-16}"
SCRIPT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "${SCRIPT_ROOT}/../.." && pwd)"
MATERIALIZER="${SCRIPT_ROOT}/materialize_decode_batch.py"
CLIENT="${PROJECT_ROOT}/runs/frontier-fidelity-envelope-v1/qwen30_exact_trace_client.py"
SERVER_PID=""
if [[ ! "${PROFILE_BATCH}" =~ ^(2|4|6|8)$ ]]; then
echo "ERROR: PROFILE_BATCH must be 2, 4, 6, or 8" >&2
exit 1
fi
IFS=',' read -r -a GPU_IDS <<< "${CUDA_VISIBLE_DEVICES:?GPU allocation is required}"
if [[ "${#GPU_IDS[@]}" -ne "${TP}" ]]; then
echo "ERROR: TP=${TP}, but CUDA_VISIBLE_DEVICES=${CUDA_VISIBLE_DEVICES}" >&2
exit 1
fi
mkdir -p "${OUTPUT_ROOT}"
OUTPUT_ROOT="$(cd "${OUTPUT_ROOT}" && pwd)"
mkdir -p "${OUTPUT_ROOT}/logs" "${OUTPUT_ROOT}/provenance" \
"${OUTPUT_ROOT}/requests" "${OUTPUT_ROOT}/results" \
"${OUTPUT_ROOT}/trace-staging" "${OUTPUT_ROOT}/traces/profile"
exec > >(tee -a "${OUTPUT_ROOT}/logs/controller.log") 2>&1
cleanup() {
if [[ -n "${SERVER_PID}" ]] && kill -0 "${SERVER_PID}" 2>/dev/null; then
kill -TERM -- "-${SERVER_PID}" 2>/dev/null || true
for _ in $(seq 1 30); do
kill -0 "${SERVER_PID}" 2>/dev/null || break
sleep 1
done
kill -KILL -- "-${SERVER_PID}" 2>/dev/null || true
fi
SERVER_PID=""
}
trap cleanup EXIT INT TERM
sha256sum "${BASH_SOURCE[0]}" "${MATERIALIZER}" "${CLIENT}" \
"${MODEL_ROOT}/config.json" > "${OUTPUT_ROOT}/provenance/inputs.sha256"
"${VENV_ROOT}/bin/python" -c \
'import torch, transformers, vllm; print(f"torch={torch.__version__}"); print(f"transformers={transformers.__version__}"); print(f"vllm={vllm.__version__}")' \
> "${OUTPUT_ROOT}/provenance/runtime.versions"
nvidia-smi --query-gpu=index,name,uuid,driver_version,memory.total \
--format=csv,noheader > "${OUTPUT_ROOT}/provenance/gpus.before.csv"
ps -eo user,pid,ppid,etimes,pcpu,pmem,args --sort=pid \
> "${OUTPUT_ROOT}/provenance/processes.before.txt"
uptime > "${OUTPUT_ROOT}/provenance/uptime.before.txt"
env | sort > "${OUTPUT_ROOT}/provenance/environment.txt"
PROFILE_CONFIG="$("${VENV_ROOT}/bin/python" - "${OUTPUT_ROOT}/trace-staging" \
"${ACTIVE_ITERATIONS}" <<'PY'
import json
import sys
print(json.dumps({
"profiler": "torch",
"torch_profiler_dir": sys.argv[1],
"torch_profiler_with_stack": False,
"torch_profiler_record_shapes": True,
"torch_profiler_use_gzip": True,
"ignore_frontend": True,
"wait_iterations": 0,
"warmup_iterations": 2,
"active_iterations": int(sys.argv[2]),
}, separators=(",", ":")))
PY
)"
printf '%s\n' "${PROFILE_CONFIG}" \
> "${OUTPUT_ROOT}/provenance/profiler-config.json"
export TOKENIZERS_PARALLELISM=false
export VLLM_USE_V1=1
export HF_HUB_OFFLINE=1
export TRANSFORMERS_OFFLINE=1
export FLASHINFER_WORKSPACE_BASE="${FLASHINFER_WORKSPACE_BASE:-${OUTPUT_ROOT}/flashinfer-workspace}"
mkdir -p "${FLASHINFER_WORKSPACE_BASE}"
ulimit -n 65536
"${VENV_ROOT}/bin/python" "${MATERIALIZER}" --model "${MODEL_ROOT}" \
--batch "${PROFILE_BATCH}" --input-tokens 2048 --output-tokens 128 \
--output "${OUTPUT_ROOT}/requests/b${PROFILE_BATCH}.jsonl"
printf 'LAUNCH host=%s tp=%s batch=%s gpus=%s output=%s\n' \
"$(hostname)" "${TP}" "${PROFILE_BATCH}" "${CUDA_VISIBLE_DEVICES}" \
"${OUTPUT_ROOT}"
setsid "${VENV_ROOT}/bin/vllm" serve "${MODEL_ROOT}" \
--host 127.0.0.1 --port "${SERVER_PORT}" \
--served-model-name qwen30-decode-batch-profile \
--tensor-parallel-size "${TP}" \
--gpu-memory-utilization "${GPU_MEMORY_UTILIZATION}" \
--max-model-len 40960 --max-num-batched-tokens 8192 --max-num-seqs 16 \
--no-enable-prefix-caching --enable-chunked-prefill --no-enable-log-requests \
--enable-logging-iteration-details --profiler-config "${PROFILE_CONFIG}" \
> "${OUTPUT_ROOT}/logs/server.log" 2>&1 &
SERVER_PID=$!
READY=0
for _ in $(seq 1 "${SERVER_READY_ATTEMPTS}"); do
if curl -fsS --max-time 2 \
"http://127.0.0.1:${SERVER_PORT}/v1/models" \
> "${OUTPUT_ROOT}/results/models.json" 2>/dev/null; then
READY=1
break
fi
if ! kill -0 "${SERVER_PID}" 2>/dev/null; then
tail -200 "${OUTPUT_ROOT}/logs/server.log"
exit 1
fi
sleep 3
done
if [[ "${READY}" -ne 1 ]]; then
echo "ERROR: server readiness timeout" >&2
tail -200 "${OUTPUT_ROOT}/logs/server.log"
exit 1
fi
run_client() {
local label="$1"
"${VENV_ROOT}/bin/python" "${CLIENT}" \
--port "${SERVER_PORT}" \
--requests-file "${OUTPUT_ROOT}/requests/b${PROFILE_BATCH}.jsonl" \
--served-model qwen30-decode-batch-profile \
--output "${OUTPUT_ROOT}/results/${label}.json" \
--tpot-slo-ms 150 --timeout-seconds 1800
}
# Exercise the same graph and scheduler path twice before profiling.
run_client warmup-1
run_client warmup-2
curl -fsS -X POST "http://127.0.0.1:${SERVER_PORT}/start_profile" \
> "${OUTPUT_ROOT}/logs/start-profile.txt"
run_client profile
deadline=$((SECONDS + 120))
while (( SECONDS < deadline )); do
trace_count="$(find "${OUTPUT_ROOT}/trace-staging" -maxdepth 1 -type f \
-name '*.pt.trace.json*' | wc -l)"
if (( trace_count >= TP )); then
break
fi
sleep 2
done
trace_count="$(find "${OUTPUT_ROOT}/trace-staging" -maxdepth 1 -type f \
-name '*.pt.trace.json*' | wc -l)"
if (( trace_count < TP )); then
echo "ERROR: expected ${TP} rank traces, found ${trace_count}" >&2
exit 1
fi
find "${OUTPUT_ROOT}/trace-staging" -maxdepth 1 -type f \
-name '*.pt.trace.json*' -exec mv -t "${OUTPUT_ROOT}/traces/profile" {} +
curl -fsS -X POST "http://127.0.0.1:${SERVER_PORT}/stop_profile" \
> "${OUTPUT_ROOT}/logs/stop-profile.txt"
cleanup
nvidia-smi --query-gpu=index,name,uuid,driver_version,memory.total \
--format=csv,noheader > "${OUTPUT_ROOT}/provenance/gpus.after.csv"
find "${OUTPUT_ROOT}" -type f \
! -path '*/provenance/artifacts.sha256' -print0 \
| sort -z | xargs -0 sha256sum \
> "${OUTPUT_ROOT}/provenance/artifacts.sha256"
echo DECODE_BATCH_PROFILE_COMPLETE