scripts/run_trtllm_pytorch_profile_host.sh
scripts/run_trtllm_pytorch_profile_host.shBrowse 18 files
3,262 tokens
10,825 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_trtllm_pytorch_profile_host.sh \8 --model Qwen/Qwen3-8B \9 --run-dir /data/bbuf/validate/unified_llm_profiler_skill/runs/example \10 --stage prefill \11 --port 32188 \12 --gpus 013 14 run_trtllm_pytorch_profile_host.sh \15 --model openai/gpt-oss-20b \16 --run-dir /data/bbuf/validate/unified_llm_profiler_skill/runs/example_4gpu \17 --stage prefill \18 --port 32188 \19 --gpus 2,3,4,5 \20 --tp-size 421 22Options:23 --model TEXT Hugging Face model id.24 --run-dir PATH Shared /data run directory for logs and traces.25 --stage prefill|decode Capture window. Prefill profiles 4090->1 by26 default; decode profiles 1->2048 by default.27 --port INT Host port for trtllm-serve.28 --gpus TEXT CUDA_VISIBLE_DEVICES value, for example 0 or 2,3,4,5.29 --gpu TEXT Alias for --gpus.30 --tp-size INT Tensor parallel size. Defaults to the visible GPU count.31 --image TEXT Container image.32 --shared-root PATH Shared validation root mounted into the container.33 --hf-cache PATH Host Hugging Face cache path.34 --override-py-executor PATH Optional py_executor.py override path.35 --disable-cudagraph Generate/use a YAML override with cuda_graph_config: null.36 --input-len INT Synthetic prompt length for this stage.37 Defaults: prefill 4090, decode 1.38 --request-max-tokens INT Generation length for this stage.39 Defaults: prefill 1, decode 2048.40 --output-len INT Alias for --request-max-tokens.41 --prompt TEXT Probe prompt. Defaults to a synthetic prompt42 sized by --input-len.43 --warmup-steps INT Warmup steps before the profiler window. Defaults to 10.44 --active-steps INT Active profiler steps to capture. Defaults to 5.45 --max-seq-len INT Serve max sequence length.46 --kv-fraction FLOAT KV cache free GPU memory fraction.47 --container-name TEXT Override container name.48 --trust-remote-code Pass --trust_remote_code to trtllm-serve.49 --help Show this message.50 51Environment:52 HF_TOKEN or HUGGINGFACE_HUB_TOKEN must be set.53 54Notes:55 - Run this on the H100 host, not inside `sglang_bbuf`.56 - It always pins TensorRT-LLM to `--backend pytorch`.57 - The default image tag is floating; record the resolved TensorRT-LLM version58 in the run manifest and pass --image for reproducible validation.59 - Profiling uses `TLLM_PROFILE_START_STOP` and `TLLM_TORCH_PROFILE_TRACE`.60 - For Python-location recovery, prefer a `py_executor.py` override with `with_stack=True`.61 - A small benchmark summary is written after the trace is emitted.62EOF63}64 65IMAGE="nvcr.io/nvidia/tensorrt-llm/release:latest"66SHARED_ROOT="/data/bbuf/validate/unified_llm_profiler_skill"67HF_CACHE="/data/.cache/huggingface"68OVERRIDE_PY_EXECUTOR=""69DISABLE_CUDAGRAPH=070REQUEST_MAX_TOKENS=""71INPUT_LEN=""72PROMPT=""73WARMUP_STEPS=1074ACTIVE_STEPS=575MAX_SEQ_LEN=409676KV_FRACTION=0.8577CONTAINER_NAME=""78TRUST_REMOTE_CODE=079TP_SIZE=""80SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"81 82MODEL=""83RUN_DIR=""84STAGE=""85PORT=""86GPUS=""87 88while [[ $# -gt 0 ]]; do89 case "$1" in90 --model)91 MODEL="$2"92 shift 293 ;;94 --run-dir)95 RUN_DIR="$2"96 shift 297 ;;98 --stage)99 STAGE="$2"100 shift 2101 ;;102 --port)103 PORT="$2"104 shift 2105 ;;106 --gpu)107 GPUS="$2"108 shift 2109 ;;110 --gpus)111 GPUS="$2"112 shift 2113 ;;114 --tp-size)115 TP_SIZE="$2"116 shift 2117 ;;118 --image)119 IMAGE="$2"120 shift 2121 ;;122 --shared-root)123 SHARED_ROOT="$2"124 shift 2125 ;;126 --hf-cache)127 HF_CACHE="$2"128 shift 2129 ;;130 --override-py-executor)131 OVERRIDE_PY_EXECUTOR="$2"132 shift 2133 ;;134 --disable-cudagraph)135 DISABLE_CUDAGRAPH=1136 shift137 ;;138 --input-len)139 INPUT_LEN="$2"140 shift 2141 ;;142 --request-max-tokens)143 REQUEST_MAX_TOKENS="$2"144 shift 2145 ;;146 --output-len)147 REQUEST_MAX_TOKENS="$2"148 shift 2149 ;;150 --prompt)151 PROMPT="$2"152 shift 2153 ;;154 --warmup-steps)155 WARMUP_STEPS="$2"156 shift 2157 ;;158 --active-steps)159 ACTIVE_STEPS="$2"160 shift 2161 ;;162 --max-seq-len)163 MAX_SEQ_LEN="$2"164 shift 2165 ;;166 --kv-fraction)167 KV_FRACTION="$2"168 shift 2169 ;;170 --container-name)171 CONTAINER_NAME="$2"172 shift 2173 ;;174 --trust-remote-code)175 TRUST_REMOTE_CODE=1176 shift177 ;;178 --help|-h)179 usage180 exit 0181 ;;182 *)183 echo "Unknown argument: $1" >&2184 usage >&2185 exit 2186 ;;187 esac188done189 190if [[ -z "${HF_TOKEN:-}" && -z "${HUGGINGFACE_HUB_TOKEN:-}" ]]; then191 echo "Set HF_TOKEN or HUGGINGFACE_HUB_TOKEN before running." >&2192 exit 2193fi194if [[ -z "${HF_TOKEN:-}" ]]; then195 HF_TOKEN="$HUGGINGFACE_HUB_TOKEN"196fi197if [[ -z "${HUGGINGFACE_HUB_TOKEN:-}" ]]; then198 HUGGINGFACE_HUB_TOKEN="$HF_TOKEN"199fi200 201if [[ -z "$MODEL" || -z "$RUN_DIR" || -z "$STAGE" || -z "$PORT" || -z "$GPUS" ]]; then202 usage >&2203 exit 2204fi205 206IFS=',' read -r -a GPU_LIST <<< "$GPUS"207GPU_COUNT="${#GPU_LIST[@]}"208if [[ "$GPU_COUNT" -lt 1 ]]; then209 echo "Could not parse --gpus: $GPUS" >&2210 exit 2211fi212if [[ -z "$TP_SIZE" ]]; then213 TP_SIZE="$GPU_COUNT"214fi215if (( TP_SIZE < 1 || TP_SIZE > GPU_COUNT )); then216 echo "--tp-size must be between 1 and the visible GPU count ($GPU_COUNT)." >&2217 exit 2218fi219 220case "$STAGE" in221 prefill)222 TRACE_PATH="$RUN_DIR/trace-prefill.json"223 LOG_PATH="$RUN_DIR/server-prefill.log"224 BENCHMARK_PATH="$RUN_DIR/benchmark-prefill.json"225 if [[ -z "$INPUT_LEN" ]]; then226 INPUT_LEN=4090227 fi228 if [[ -z "$REQUEST_MAX_TOKENS" ]]; then229 REQUEST_MAX_TOKENS=1230 fi231 ;;232 decode)233 TRACE_PATH="$RUN_DIR/trace-decode.json"234 LOG_PATH="$RUN_DIR/server-decode.log"235 BENCHMARK_PATH="$RUN_DIR/benchmark-decode.json"236 if [[ -z "$INPUT_LEN" ]]; then237 INPUT_LEN=1238 fi239 if [[ -z "$REQUEST_MAX_TOKENS" ]]; then240 REQUEST_MAX_TOKENS=2048241 fi242 ;;243 *)244 echo "--stage must be prefill or decode." >&2245 exit 2246 ;;247esac248 249if (( WARMUP_STEPS < 0 || ACTIVE_STEPS < 1 )); then250 echo "--warmup-steps must be >= 0 and --active-steps must be >= 1." >&2251 exit 2252fi253 254case "$STAGE" in255 prefill)256 profile_start=$((WARMUP_STEPS + 1))257 ;;258 decode)259 profile_start=$((WARMUP_STEPS + 2))260 ;;261esac262profile_stop=$((profile_start + ACTIVE_STEPS - 1))263PROFILE_START_STOP="${profile_start}-${profile_stop}"264 265if [[ -z "$CONTAINER_NAME" ]]; then266 model_slug="${MODEL##*/}"267 model_slug="${model_slug//\//-}"268 model_slug="${model_slug//./-}"269 model_slug="${model_slug//_/-}"270 model_slug="${model_slug// /-}"271 gpu_slug="${GPUS//,/-}"272 CONTAINER_NAME="trtllm-${model_slug}-${STAGE}-g${gpu_slug}-p${PORT}"273fi274 275EXTRA_LLM_OPTIONS=""276if [[ "$DISABLE_CUDAGRAPH" -eq 1 ]]; then277 EXTRA_CFG_PATH="$SHARED_ROOT/tmp/trt_no_cudagraph.yaml"278 docker exec sglang_bbuf bash -lc "mkdir -p '$(dirname "$EXTRA_CFG_PATH")' && printf 'cuda_graph_config: null\n' > '$EXTRA_CFG_PATH'"279 EXTRA_LLM_OPTIONS="--extra_llm_api_options $EXTRA_CFG_PATH"280fi281 282docker exec sglang_bbuf bash -lc "mkdir -p '$RUN_DIR'"283docker rm -f "$CONTAINER_NAME" >/dev/null 2>&1 || true284 285docker_args=(286 run -d --rm287 --name "$CONTAINER_NAME"288 --gpus all289 --ipc=host290 --network host291 --entrypoint bash292 -e "CUDA_VISIBLE_DEVICES=$GPUS"293 -e "HF_TOKEN=$HF_TOKEN"294 -e "HUGGINGFACE_HUB_TOKEN=$HUGGINGFACE_HUB_TOKEN"295 -e "TLLM_PROFILE_START_STOP=$PROFILE_START_STOP"296 -e "TLLM_LLMAPI_ENABLE_NVTX=1"297 -e "TLLM_TORCH_PROFILE_TRACE=$TRACE_PATH"298 -e "RUN_DIR=$RUN_DIR"299 -e "LOG_PATH=$LOG_PATH"300 -e "MODEL_ID=$MODEL"301 -e "SERVE_PORT=$PORT"302 -v "$HF_CACHE:/root/.cache/huggingface"303 -v "$SHARED_ROOT:$SHARED_ROOT"304)305 306if [[ -n "$OVERRIDE_PY_EXECUTOR" ]]; then307 docker_args+=(308 -v "$OVERRIDE_PY_EXECUTOR:/usr/local/lib/python3.12/dist-packages/tensorrt_llm/_torch/pyexecutor/py_executor.py:ro"309 )310fi311 312trust_remote_code_arg=""313if [[ "$TRUST_REMOTE_CODE" -eq 1 ]]; then314 trust_remote_code_arg="--trust_remote_code"315fi316 317container_cmd=$(318 cat <<EOF319mkdir -p "$RUN_DIR" && trtllm-serve serve "$MODEL" \320 --backend pytorch \321 --tp_size "$TP_SIZE" \322 --gpus_per_node "$GPU_COUNT" \323 --host 0.0.0.0 \324 --port "$PORT" \325 --max_seq_len "$MAX_SEQ_LEN" \326 --kv_cache_free_gpu_memory_fraction "$KV_FRACTION" \327 $trust_remote_code_arg \328 $EXTRA_LLM_OPTIONS \329 > "$LOG_PATH" 2>&1330EOF331)332 333docker_args+=("$IMAGE" -lc "$container_cmd")334docker "${docker_args[@]}" >/dev/null335 336cleanup() {337 docker rm -f "$CONTAINER_NAME" >/dev/null 2>&1 || true338}339trap cleanup EXIT340 341ready=0342for _ in $(seq 1 180); do343 if curl -sf "http://127.0.0.1:${PORT}/v1/models" >/dev/null; then344 ready=1345 break346 fi347 sleep 2348done349if [[ "$ready" -ne 1 ]]; then350 echo "Server did not become ready on port ${PORT}. Recent logs:" >&2351 docker logs "$CONTAINER_NAME" 2>&1 | tail -n 120 >&2 || true352 exit 1353fi354 355python3 - <<PY356import json357import sys358import urllib.request359 360sys.path.insert(0, ${SCRIPT_DIR@Q})361from profile_common import extract_openai_chat_text, synthetic_prompt362 363prompt = ${PROMPT@Q} or synthetic_prompt(int(${INPUT_LEN@Q}))364stage = ${STAGE@Q}365warmup_steps = int(${WARMUP_STEPS@Q})366active_steps = int(${ACTIVE_STEPS@Q})367request_count = warmup_steps + active_steps if stage == "prefill" else 1368 369payload = {370 "model": ${MODEL@Q},371 "messages": [{"role": "user", "content": prompt}],372 "temperature": 0,373 "max_tokens": int(${REQUEST_MAX_TOKENS@Q}),374}375for request_idx in range(request_count):376 req = urllib.request.Request(377 "http://127.0.0.1:${PORT}/v1/chat/completions",378 data=json.dumps(payload).encode(),379 headers={"Content-Type": "application/json"},380 )381 with urllib.request.urlopen(req, timeout=600) as resp:382 body = json.loads(resp.read().decode())383text, source = extract_openai_chat_text(body)384print(text[:400] if text else f"[empty completion; source={source}]")385PY386 387for _ in $(seq 1 120); do388 if [[ -s "$TRACE_PATH" ]]; then389 break390 fi391 sleep 2392done393 394if [[ ! -s "$TRACE_PATH" ]]; then395 echo "Trace was not written: $TRACE_PATH" >&2396 exit 1397fi398 399python3 "$SCRIPT_DIR/probe_llm_server.py" \400 --framework trtllm \401 --url "http://127.0.0.1:${PORT}" \402 --model "$MODEL" \403 | docker exec -i sglang_bbuf bash -lc "cat > '$BENCHMARK_PATH'" >/dev/null404 405echo "TRACE_PATH=$TRACE_PATH"406echo "LOG_PATH=$LOG_PATH"407echo "BENCHMARK_PATH=$BENCHMARK_PATH"408