11#! /usr/bin/env bash
2- set -euo pipefail
2+ set -eo pipefail
33set -x
44
55# Agentic trace replay benchmark for DeepSeek-V4-Pro FP4 on B200 using vLLM.
@@ -14,21 +14,25 @@ set -x
1414# Highest aggregate throughput at large CONC.
1515#
1616# Image is configured in nvidia-master.yaml. block_size=256,
17- # kv-cache-dtype=fp8, FP4 indexer cache enabled, FULL_AND_PIECEWISE cudagraph
18- # capture with custom_ops=all (per the vLLM blog recipe at
19- # https://vllm.ai/blog/deepseek-v4).
17+ # kv-cache-dtype=fp8, FLASHINFER_MLA_SPARSE_DSV4 attention with the FP4 indexer
18+ # cache, FULL_DECODE_ONLY cudagraph capture, and (in EP tiers) mega-MoE backend.
2019#
2120# Required env vars:
2221# MODEL, TP, CONC, KV_OFFLOADING, TOTAL_CPU_DRAM_GB, RESULT_DIR
2322#
24- # KV_OFFLOADING=dram requires KV_OFFLOAD_BACKEND=mooncake.
23+ # Pure TP is GPU-resident (KV_OFFLOADING=none). DEP tiers offload KV to host
24+ # DRAM: KV_OFFLOADING=dram requires KV_OFFLOAD_BACKEND=vllm-simple or mooncake.
2525
2626source " $( dirname " $0 " ) /../../benchmark_lib.sh"
2727
2828check_env_vars MODEL TP CONC KV_OFFLOADING TOTAL_CPU_DRAM_GB RESULT_DIR DURATION EP_SIZE DP_ATTENTION
2929
30- DCP_SIZE=" ${DCP_SIZE:- 1} "
31- PCP_SIZE=" ${PCP_SIZE:- 1} "
30+ if [ -z " $DCP_SIZE " ]; then
31+ DCP_SIZE=1
32+ fi
33+ if [ -z " $PCP_SIZE " ]; then
34+ PCP_SIZE=1
35+ fi
3236VLLM_CP_ARGS=()
3337if [ " $DCP_SIZE " -gt 1 ]; then
3438 VLLM_CP_ARGS+=(--decode-context-parallel-size " $DCP_SIZE " )
@@ -37,21 +41,21 @@ if [ "$PCP_SIZE" -gt 1 ]; then
3741 VLLM_CP_ARGS+=(--prefill-context-parallel-size " $PCP_SIZE " )
3842fi
3943
40- GPU_COUNT=" ${GPU_COUNT :- $((TP * PCP_SIZE))} "
44+ GPU_COUNT=$TP
4145if [[ ! " $GPU_COUNT " =~ ^[1-9][0-9]* $ ]]; then
4246 echo " Error: GPU_COUNT must be a positive integer, got '$GPU_COUNT '" >&2
4347 exit 1
4448fi
4549export GPU_COUNT
4650
47- if [[ -n " ${ SLURM_JOB_ID:- } " ]]; then
48- echo " JOB $SLURM_JOB_ID running on ${ SLURMD_NODENAME:- unknown} "
51+ if [[ -n " $SLURM_JOB_ID " ]]; then
52+ echo " JOB $SLURM_JOB_ID running on $SLURMD_NODENAME "
4953fi
5054
5155# `hf download` creates the target dir if missing and is itself idempotent.
5256# When MODEL_PATH is unset (stand-alone runs), fall back to the HF_HUB_CACHE
5357# Either way, MODEL_PATH is what the server is launched with.
54- if [[ -n " ${ MODEL_PATH:- } " ]]; then
58+ if [[ -n " $MODEL_PATH " ]]; then
5559 if [[ ! -d " $MODEL_PATH " || -z " $( ls -A " $MODEL_PATH " 2> /dev/null) " ]]; then
5660 hf download " $MODEL " --local-dir " $MODEL_PATH "
5761 fi
@@ -65,12 +69,6 @@ nvidia-smi
6569resolve_trace_source
6670install_agentic_deps
6771
68- # vLLM v0.22.1 can ship CUTLASS DSL 4.5.2 with stale native MLIR bindings,
69- # which fails DSV4 indexer compilation with mlir_global_dtors(..., data).
70- # Reinstall the matching native wheel until NVIDIA/cutlass#3259 is resolved.
71- agentic_pip_install --quiet --force-reinstall --no-deps \
72- ' nvidia-cutlass-dsl-libs-cu13==4.5.2'
73-
7472# vllm-project/router expands the one HTTP backend into one logical worker per
7573# DP rank and sends X-data-parallel-rank on forwarded requests. aiperf's
7674# X-Correlation-ID is stable for every turn of a conversation; alias it to the
@@ -94,6 +92,10 @@ export VLLM_ENGINE_READY_TIMEOUT_S=3600
9492# vllm-project/vllm#44774 applies the same reachability policy to Mooncake's
9593# store mask. 32k matches the trace-replay tuning validated for this workload.
9694export VLLM_PREFIX_CACHE_RETENTION_INTERVAL=32768
95+ export VLLM_USE_V2_MODEL_RUNNER=1
96+ export VLLM_USE_RUST_FRONTEND=1
97+ export VLLM_DSV4_MEGA_FP8_COMBINE=1
98+ export VLLM_RPC_TIMEOUT=600000
9799
98100# ---- Server config ----------------------------------------------------------
99101SERVER_LOG=" $RESULT_DIR /server.log"
@@ -106,8 +108,34 @@ ROUTER_PID=""
106108MOONCAKE_MASTER_PID=" "
107109
108110OFFLOAD_ARGS=()
109-
110- if require_agentic_kv_offload_backend mooncake; then
111+ case " $KV_OFFLOAD_BACKEND " in
112+ " " )
113+ require_agentic_kv_offload_none
114+ ;;
115+ vllm-simple)
116+ require_agentic_kv_offload_backend vllm-simple
117+ CPU_BYTES_PER_RANK=$(( TOTAL_CPU_DRAM_GB * 1000 * 1000 * 1000 / GPU_COUNT ))
118+ # Identical prefixes must hash to identical block keys across DP ranks.
119+ export PYTHONHASHSEED=42
120+ OFFLOAD_CONFIG=$( cat << EOF
121+ {
122+ "kv_connector": "SimpleCPUOffloadConnector",
123+ "kv_role": "kv_both",
124+ "kv_connector_extra_config": {
125+ "cpu_bytes_to_use_per_rank": ${CPU_BYTES_PER_RANK} ,
126+ "lazy_offload": false,
127+ "enable_cross_layers_blocks": "true"
128+ }
129+ }
130+ EOF
131+ )
132+ OFFLOAD_ARGS=(
133+ --kv-transfer-config
134+ " $OFFLOAD_CONFIG "
135+ )
136+ ;;
137+ mooncake)
138+ require_agentic_kv_offload_backend mooncake
111139 # Embedded mode contributes one segment per GPU rank to a shared
112140 # distributed store, so pre-divide the aggregate host-memory budget.
113141 PER_RANK_GB=$(( TOTAL_CPU_DRAM_GB / GPU_COUNT))
@@ -127,16 +155,14 @@ if require_agentic_kv_offload_backend mooncake; then
127155 "global_segment_size": "${PER_RANK_GB} GB",
128156 "local_buffer_size": "4GB",
129157 "protocol": "rdma",
130- "device_name": "mlx5_0",
158+ "device_name": "mlx5_0,mlx5_1,mlx5_2,mlx5_3,mlx5_4,mlx5_5,mlx5_10,mlx5_11 ",
131159 "enable_offload": false
132160}
133161EOF
134162 export MOONCAKE_CONFIG_PATH
163+ export MC_ENABLE_DEST_DEVICE_AFFINITY=1
135164 # Identical prefixes must hash to identical store keys across DP ranks.
136165 export PYTHONHASHSEED=0
137- # B200 GPU memory registration works through DMA-BUF, but the compute
138- # nodes do not expose nvidia_peermem. Force Mooncake's DMA-BUF
139- # GPUDirect RDMA path instead of its legacy ibv_reg_mr path.
140166 export WITH_NVIDIA_PEERMEM=0
141167 export MC_SLICE_SIZE=1048576
142168 export MC_WORKERS_PER_CTX=4
@@ -167,16 +193,27 @@ EOF
167193 --kv-transfer-config
168194 ' {"kv_connector":"MooncakeStoreConnector","kv_role":"kv_both","kv_connector_extra_config":{"load_async":true}}'
169195 )
170- fi
196+ ;;
197+ * )
198+ echo " Error: unsupported B200 KV_OFFLOAD_BACKEND='$KV_OFFLOAD_BACKEND '" >&2
199+ exit 1
200+ ;;
201+ esac
171202
172203PARALLEL_ARGS=(--tensor-parallel-size " $TP " --data-parallel-size 1)
173204if [ " $DP_ATTENTION " = " true" ]; then
174205 PARALLEL_ARGS=(--tensor-parallel-size 1 --data-parallel-size " $TP " )
175206fi
176207
177208EP_ARGS=()
209+ FAST_MOE_ARGS=()
178210if [ " $EP_SIZE " -gt 1 ]; then
179211 EP_ARGS=(--enable-expert-parallel)
212+ FAST_MOE_ARGS=(
213+ --moe-backend deep_gemm_amxf4_mega_moe
214+ --enable-ep-weight-filter
215+ --prefill-schedule-interval 16
216+ )
180217fi
181218
182219# AgentX concurrency counts live session trees, not individual requests.
@@ -197,18 +234,23 @@ VLLM_CMD=(
197234 --trust-remote-code
198235 --kv-cache-dtype fp8
199236 --block-size 256
200- " ${PARALLEL_ARGS[@]} "
201- " ${VLLM_CP_ARGS[@]} "
202- " ${EP_ARGS[@]} "
203- --compilation-config ' {"cudagraph_mode":"FULL_AND_PIECEWISE","custom_ops":["all"]} '
204- --attention_config.use_fp4_indexer_cache=True
237+ --max-model-len 1048576
238+ --gpu-memory-utilization 0.92
239+ --numa-bind
240+ --enable-cumem-allocator
241+ --no-enable-flashinfer-autotune
205242 --tokenizer-mode deepseek_v4
206- --tool-call-parser deepseek_v4
207- --enable-auto-tool-choice
208243 --reasoning-parser deepseek_v4
209- --enable-prefix-caching
244+ --attention-config ' {"backend":"FLASHINFER_MLA_SPARSE_DSV4","use_prefill_query_quantization":true,"use_fp4_indexer_cache":true} '
210245 --no-disable-hybrid-kv-cache-manager
246+ --disable-uvicorn-access-log
247+ --compilation-config ' {"cudagraph_mode":"FULL_DECODE_ONLY","mode":0}'
211248 --max-num-seqs " $MAX_NUM_SEQS "
249+ --max-cudagraph-capture-size " $MAX_NUM_SEQS "
250+ " ${PARALLEL_ARGS[@]} "
251+ " ${VLLM_CP_ARGS[@]} "
252+ " ${EP_ARGS[@]} "
253+ " ${FAST_MOE_ARGS[@]} "
212254 " ${OFFLOAD_ARGS[@]} "
213255)
214256printf ' %q ' " ${VLLM_CMD[@]} " | tee " $RESULT_DIR /vllm_command.txt"
0 commit comments