scripts/run_vllm_torch_profile_host.sh
scripts/run_vllm_torch_profile_host.shBrowse 18 files
2,818 tokens
9,141 bytes
Token encoding: o200k_base
Snapshot a9fb1c3
← Back to SKILL.md
1#!/usr/bin/env bash2set -euo pipefail3 4usage() {5 cat <<'EOF'6Usage:7 run_vllm_torch_profile_host.sh \8 --model Qwen/Qwen3-8B \9 --run-dir /data/bbuf/validate/unified_llm_profiler_skill/runs/example_vllm_formal \10 --port 31088 \11 --gpus 112 13 run_vllm_torch_profile_host.sh \14 --model openai/gpt-oss-20b \15 --run-dir /data/bbuf/validate/unified_llm_profiler_skill/runs/example_vllm_4gpu \16 --port 31088 \17 --gpus 2,3,4,5 \18 --tensor-parallel-size 419 20Options:21 --model TEXT Hugging Face model id.22 --run-dir PATH Shared /data directory for logs and traces.23 --port INT Host port for vllm serve.24 --gpus TEXT CUDA_VISIBLE_DEVICES value, for example 1 or 2,3,4,5.25 --gpu TEXT Alias for --gpus.26 --image TEXT Container image.27 --hf-cache PATH Host Hugging Face cache path.28 --gpu-memory-util FLOAT vLLM --gpu-memory-utilization.29 --max-model-len INT vLLM --max-model-len.30 --tensor-parallel-size INT vLLM --tensor-parallel-size. Defaults to the visible GPU count.31 --profiler-active-iterations INT32 Torch-profiler active iterations.33 --enforce-eager Launch vLLM with --enforce-eager for mapping traces.34 --trust-remote-code Pass --trust-remote-code.35 --request-max-tokens INT Generation length for the probe request.36 --prompt TEXT Probe prompt.37 --warmup-steps INT Warmup steps before profiling. Defaults to 10.38 --profile-workload TEXT legacy|prefill|decode|both. Defaults to both.39 --prefill-input-len INT Synthetic prefill prompt length. Defaults to 4090.40 --prefill-output-len INT Synthetic prefill output length. Defaults to 1.41 --decode-input-len INT Synthetic decode prompt length. Defaults to 1.42 --decode-output-len INT Synthetic decode output length. Defaults to 2048.43 --container-name TEXT Override container name.44 --help Show this message.45 46Environment:47 HF_TOKEN or HUGGINGFACE_HUB_TOKEN must be set.48 49Notes:50 - Run this on the H100 host, not inside `sglang_bbuf`.51 - This uses the vLLM torch-profiler flow: `--profiler-config`, then POST52 `/start_profile` and `/stop_profile`.53 - Default capture is two labeled profiles: prefill 4090->1 and decode 1->2048.54 - Current vLLM profiler config already defaults `torch_profiler_with_stack=true`.55 - A small benchmark summary is written after profiling.56EOF57}58 59IMAGE="vllm/vllm-openai:latest"60HF_CACHE="/data/.cache/huggingface"61GPU_MEMORY_UTIL=0.9062MAX_MODEL_LEN=409663TP_SIZE=""64ENFORCE_EAGER=065TRUST_REMOTE_CODE=066REQUEST_MAX_TOKENS=1267PROFILER_ACTIVE_ITERATIONS=568PROMPT="Explain the difference between CUDA graph mode and eager mode in two sentences."69WARMUP_STEPS=1070PROFILE_WORKLOAD="both"71PREFILL_INPUT_LEN=409072PREFILL_OUTPUT_LEN=173DECODE_INPUT_LEN=174DECODE_OUTPUT_LEN=204875CONTAINER_NAME=""76SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"77 78MODEL=""79RUN_DIR=""80PORT=""81GPUS=""82 83while [[ $# -gt 0 ]]; do84 case "$1" in85 --model)86 MODEL="$2"87 shift 288 ;;89 --run-dir)90 RUN_DIR="$2"91 shift 292 ;;93 --port)94 PORT="$2"95 shift 296 ;;97 --gpu)98 GPUS="$2"99 shift 2100 ;;101 --gpus)102 GPUS="$2"103 shift 2104 ;;105 --image)106 IMAGE="$2"107 shift 2108 ;;109 --hf-cache)110 HF_CACHE="$2"111 shift 2112 ;;113 --gpu-memory-util)114 GPU_MEMORY_UTIL="$2"115 shift 2116 ;;117 --max-model-len)118 MAX_MODEL_LEN="$2"119 shift 2120 ;;121 --tensor-parallel-size)122 TP_SIZE="$2"123 shift 2124 ;;125 --profiler-active-iterations)126 PROFILER_ACTIVE_ITERATIONS="$2"127 shift 2128 ;;129 --enforce-eager)130 ENFORCE_EAGER=1131 shift132 ;;133 --trust-remote-code)134 TRUST_REMOTE_CODE=1135 shift136 ;;137 --request-max-tokens)138 REQUEST_MAX_TOKENS="$2"139 shift 2140 ;;141 --prompt)142 PROMPT="$2"143 shift 2144 ;;145 --warmup-steps)146 WARMUP_STEPS="$2"147 shift 2148 ;;149 --profile-workload)150 PROFILE_WORKLOAD="$2"151 shift 2152 ;;153 --prefill-input-len)154 PREFILL_INPUT_LEN="$2"155 shift 2156 ;;157 --prefill-output-len)158 PREFILL_OUTPUT_LEN="$2"159 shift 2160 ;;161 --decode-input-len)162 DECODE_INPUT_LEN="$2"163 shift 2164 ;;165 --decode-output-len)166 DECODE_OUTPUT_LEN="$2"167 shift 2168 ;;169 --container-name)170 CONTAINER_NAME="$2"171 shift 2172 ;;173 --help|-h)174 usage175 exit 0176 ;;177 *)178 echo "Unknown argument: $1" >&2179 usage >&2180 exit 2181 ;;182 esac183done184 185if [[ -z "${HF_TOKEN:-}" && -z "${HUGGINGFACE_HUB_TOKEN:-}" ]]; then186 echo "Set HF_TOKEN or HUGGINGFACE_HUB_TOKEN before running." >&2187 exit 2188fi189if [[ -z "${HF_TOKEN:-}" ]]; then190 HF_TOKEN="$HUGGINGFACE_HUB_TOKEN"191fi192if [[ -z "${HUGGINGFACE_HUB_TOKEN:-}" ]]; then193 HUGGINGFACE_HUB_TOKEN="$HF_TOKEN"194fi195 196if [[ -z "$MODEL" || -z "$RUN_DIR" || -z "$PORT" || -z "$GPUS" ]]; then197 usage >&2198 exit 2199fi200 201IFS=',' read -r -a GPU_LIST <<< "$GPUS"202GPU_COUNT="${#GPU_LIST[@]}"203if [[ "$GPU_COUNT" -lt 1 ]]; then204 echo "Could not parse --gpus: $GPUS" >&2205 exit 2206fi207if [[ -z "$TP_SIZE" ]]; then208 TP_SIZE="$GPU_COUNT"209fi210if (( TP_SIZE < 1 || TP_SIZE > GPU_COUNT )); then211 echo "--tensor-parallel-size must be between 1 and the visible GPU count ($GPU_COUNT)." >&2212 exit 2213fi214if (( PROFILER_ACTIVE_ITERATIONS < 1 )); then215 echo "--profiler-active-iterations must be >= 1." >&2216 exit 2217fi218 219PROFILE_DIR="$RUN_DIR/vllm_profile"220LOG_PATH="$RUN_DIR/server.log"221ANALYSIS_PATH="$RUN_DIR/analysis_vllm_live.txt"222BENCHMARK_PATH="$RUN_DIR/benchmark_vllm.json"223 224if [[ -z "$CONTAINER_NAME" ]]; then225 model_slug="${MODEL##*/}"226 model_slug="${model_slug//\//-}"227 model_slug="${model_slug//./-}"228 model_slug="${model_slug//_/-}"229 gpu_slug="${GPUS//,/-}"230 CONTAINER_NAME="vllm-${model_slug}-g${gpu_slug}-p${PORT}"231 if [[ "$ENFORCE_EAGER" -eq 1 ]]; then232 CONTAINER_NAME="${CONTAINER_NAME}-eager"233 fi234fi235 236docker exec sglang_bbuf bash -lc "mkdir -p '$PROFILE_DIR'"237docker rm -f "$CONTAINER_NAME" >/dev/null 2>&1 || true238 239profiler_config=$(python3 - <<PY240import json241print(json.dumps({242 "profiler": "torch",243 "torch_profiler_dir": ${PROFILE_DIR@Q},244 "active_iterations": int(${PROFILER_ACTIVE_ITERATIONS@Q}),245}))246PY247)248 249docker_args=(250 run -d --rm251 --name "$CONTAINER_NAME"252 --gpus all253 --ipc=host254 --network host255 -e "CUDA_VISIBLE_DEVICES=$GPUS"256 -e "HF_TOKEN=$HF_TOKEN"257 -e "HUGGINGFACE_HUB_TOKEN=$HUGGINGFACE_HUB_TOKEN"258 -e "VLLM_RPC_TIMEOUT=1800000"259 -v "$HF_CACHE:/root/.cache/huggingface"260 -v "$RUN_DIR:$RUN_DIR"261)262 263docker_cmd=(264 "$IMAGE"265 "$MODEL"266 --host 0.0.0.0267 --port "$PORT"268 --tensor-parallel-size "$TP_SIZE"269 --max-model-len "$MAX_MODEL_LEN"270 --gpu-memory-utilization "$GPU_MEMORY_UTIL"271 --profiler-config "$profiler_config"272)273 274if [[ "$ENFORCE_EAGER" -eq 1 ]]; then275 docker_cmd+=(--enforce-eager)276fi277if [[ "$TRUST_REMOTE_CODE" -eq 1 ]]; then278 docker_cmd+=(--trust-remote-code)279fi280 281docker "${docker_args[@]}" "${docker_cmd[@]}" >/dev/null282cleanup() {283 docker rm -f "$CONTAINER_NAME" >/dev/null 2>&1 || true284}285trap cleanup EXIT286 287ready=0288for _ in $(seq 1 180); do289 if curl -sf "http://127.0.0.1:${PORT}/v1/models" >/dev/null; then290 ready=1291 break292 fi293 sleep 2294done295if [[ "$ready" -ne 1 ]]; then296 echo "Server did not become ready on port ${PORT}. Recent logs:" >&2297 docker logs "$CONTAINER_NAME" 2>&1 | tail -n 120 >&2 || true298 exit 1299fi300 301python3 "$SCRIPT_DIR/analyze_llm_torch_profile.py" \302 --framework vllm \303 --url "http://127.0.0.1:${PORT}" \304 --output-dir "$PROFILE_DIR" \305 --num-steps "$PROFILER_ACTIVE_ITERATIONS" \306 --warmup-steps "$WARMUP_STEPS" \307 --probe-requests 1 \308 --no-profile-by-stage \309 --profile-workload "$PROFILE_WORKLOAD" \310 --probe-prompt "$PROMPT" \311 --probe-max-new-tokens "$REQUEST_MAX_TOKENS" \312 --prefill-input-len "$PREFILL_INPUT_LEN" \313 --prefill-output-len "$PREFILL_OUTPUT_LEN" \314 --decode-input-len "$DECODE_INPUT_LEN" \315 --decode-output-len "$DECODE_OUTPUT_LEN" \316 > "$ANALYSIS_PATH"317 318profile_found=0319for _ in $(seq 1 240); do320 if find "$PROFILE_DIR" -type f \( -name '*.pt.trace.json' -o -name '*.pt.trace.json.gz' -o -name '*.trace.json' -o -name '*.trace.json.gz' \) | grep -q .; then321 profile_found=1322 break323 fi324 sleep 2325done326if [[ "$profile_found" -ne 1 ]]; then327 echo "No vLLM profiler traces appeared under $PROFILE_DIR" >&2328 docker logs "$CONTAINER_NAME" 2>&1 | tail -n 120 >&2 || true329 exit 1330fi331 332python3 "$SCRIPT_DIR/probe_llm_server.py" \333 --framework vllm \334 --url "http://127.0.0.1:${PORT}" \335 --model "$MODEL" \336 | docker exec -i sglang_bbuf bash -lc "cat > '$BENCHMARK_PATH'" >/dev/null337 338docker logs "$CONTAINER_NAME" 2>&1 | docker exec -i sglang_bbuf bash -lc "cat > '$LOG_PATH'" || true339sed -n '1,240p' "$ANALYSIS_PATH"340echo "PROFILE_DIR=$PROFILE_DIR"341echo "LOG_PATH=$LOG_PATH"342echo "ANALYSIS_PATH=$ANALYSIS_PATH"343echo "BENCHMARK_PATH=$BENCHMARK_PATH"344