-
Notifications
You must be signed in to change notification settings - Fork 237
Expand file tree
/
Copy pathenv.sh
More file actions
executable file
·374 lines (329 loc) · 17.5 KB
/
Copy pathenv.sh
File metadata and controls
executable file
·374 lines (329 loc) · 17.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
#!/bin/bash
# Dual-engine environment setup for multi-node disaggregated serving.
#
# ENGINE=sglang (default): SGLang/MoRI environment
# ENGINE=vllm: vLLM/Nixl environment
#
# REQUIRED ENVIRONMENT VARIABLES:
# IBDEVICES - RDMA/InfiniBand device names (e.g., ionic_0,ionic_1,... or mlx5_0,mlx5_1,...)
# Set by runner or auto-detected from hostname.
set -x
ENGINE="${ENGINE:-sglang-disagg}"
export PYTHONDONTWRITEBYTECODE=1
# =============================================================================
# HiCache / Mooncake settings from job.slurm
# =============================================================================
# job.slurm writes the recipe-provided HiCache/Mooncake tunables to
# hicache_mc_<JID>.env and mounts it read-only at /config/hicache_mc.env. Source
# it here (auto-export) so values like HICACHE_PAGE_SIZE=256 reach the container
# before server_sglang.sh applies its "${VAR:-default}" fallbacks. Without this
# the vars arrive unset and server_sglang.sh defaults HICACHE_PAGE_SIZE to 1,
# overriding the recipe's --page-size. Empty values in the file are harmless:
# the "${VAR:-default}" fallbacks still treat "" as unset.
if [[ -f /config/hicache_mc.env ]]; then
set -a
source /config/hicache_mc.env
set +a
echo "[env.sh] sourced HiCache config from /config/hicache_mc.env (HICACHE_PAGE_SIZE=${HICACHE_PAGE_SIZE:-unset})"
fi
# =============================================================================
# Shared: IBDEVICES detection
# =============================================================================
# Prefer IBDEVICES set by runner (runners/launch_mi355x-amds.sh)
# Fall back to hostname detection if not set (for direct script execution)
if [[ -z "$IBDEVICES" ]]; then
DETECTED=$(ibv_devinfo 2>/dev/null | grep "hca_id:" | awk '{print $2}' | paste -sd',')
if [[ -n "$DETECTED" ]]; then
export IBDEVICES="$DETECTED"
echo "[INFO] Auto-detected IBDEVICES=$IBDEVICES via ibv_devinfo on $(hostname -s)"
else
echo "ERROR: Unable to detect RDMA devices. Set IBDEVICES explicitly." >&2
exit 1
fi
else
echo "[INFO] Using IBDEVICES=$IBDEVICES (set by runner or environment)"
fi
export IBDEVICES
# Shared: Auto-detect default network interface (portable across clusters)
# Only auto-detect if not already set by the runner/environment
if [[ -z "$GLOO_SOCKET_IFNAME" ]]; then
export GLOO_SOCKET_IFNAME=$(ip route 2>/dev/null | grep '^default' | awk '{print $5}' | head -n 1)
fi
if [[ -z "$NCCL_SOCKET_IFNAME" ]]; then
export NCCL_SOCKET_IFNAME=$(ip route 2>/dev/null | grep '^default' | awk '{print $5}' | head -n 1)
fi
set +x
export NCCL_IB_HCA=${NCCL_IB_HCA:-$IBDEVICES}
# =============================================================================
# MoRI-specific environment
# =============================================================================
# Shared by the vLLM MoRIIOConnector and the SGLang/MoRI KV-transfer path.
export MORI_IO_SQ_BACKOFF_TIMEOUT_US="${MORI_IO_SQ_BACKOFF_TIMEOUT_US:-50000}"
export MORI_IO_QP_MAX_SEND_WR="${MORI_IO_QP_MAX_SEND_WR:-16384}"
export MORI_IO_QP_MAX_CQE="${MORI_IO_QP_MAX_CQE:-32768}"
export MORI_IO_QP_MAX_SGE="${MORI_IO_QP_MAX_SGE:-2}"
export MORI_IO_TC_DISABLE="${MORI_IO_TC_DISABLE:-0}"
# QoS/DSCP configuration
# Priority order: 1) Set by runner, 2) Detect via nicctl, 3) Detect from hostname
if [[ -n "$MORI_RDMA_TC" ]]; then
echo "[INFO] Using MORI_RDMA_TC=$MORI_RDMA_TC (set by runner or environment)"
elif command -v nicctl &> /dev/null; then
ND_PRIO=$(nicctl show qos 2>/dev/null | awk '/PFC no-drop priorities/ {print $NF; exit}')
ND_DSCP=$(nicctl show qos 2>/dev/null| awk -v p="$ND_PRIO" '
$1 == "DSCP" && $2 == ":" && $NF == p {
print $3; exit
}')
# nicctl may emit trailing commas (e.g. "24,"); keep the leading integer so the
# arithmetic can't choke and unparseable output falls back to hostname detection.
ND_PRIO="${ND_PRIO%%,*}"; ND_PRIO="${ND_PRIO//[!0-9]/}"
ND_DSCP="${ND_DSCP%%,*}"; ND_DSCP="${ND_DSCP//[!0-9]/}"
if [[ "$ND_DSCP" =~ ^[0-9]+$ ]] && [[ "$ND_PRIO" =~ ^[0-9]+$ ]]; then
TC=$(( 4 * ND_DSCP ))
export MORI_RDMA_SL=$ND_PRIO
export MORI_IO_SL=$ND_PRIO
export MORI_RDMA_TC=$TC
export MORI_IO_TC=$TC
echo "[INFO] Detected QoS config from nicctl: MORI_RDMA_TC=$MORI_RDMA_TC, MORI_RDMA_SL=$MORI_RDMA_SL, MORI_IO_TC=$MORI_IO_TC, MORI_IO_SL=$MORI_IO_SL"
else
echo "[WARN] nicctl available but QoS data unavailable; trying hostname detection."
# Fall back to hostname-based detection
NODENAME=$(hostname -s)
if [[ $NODENAME == GPU* ]] || [[ $NODENAME == smci355-ccs-aus* ]]; then
export MORI_RDMA_TC=96
export MORI_IO_TC=96
echo "[INFO] Auto-detected MORI_RDMA_TC=$MORI_RDMA_TC from hostname $NODENAME"
elif [[ $NODENAME == mia1* ]]; then
export MORI_RDMA_TC=104
export MORI_IO_TC=104
echo "[INFO] Auto-detected MORI_RDMA_TC=$MORI_RDMA_TC from hostname $NODENAME"
else
echo "[INFO] Unable to detect MORI_RDMA_TC from hostname. Skipping RDMA QoS configuration."
fi
fi
else
# nicctl not available, try hostname-based detection
NODENAME=$(hostname -s)
if [[ $NODENAME == GPU* ]] || [[ $NODENAME == smci355-ccs-aus* ]]; then
export MORI_RDMA_TC=96
export MORI_IO_TC=96
echo "[INFO] Auto-detected MORI_RDMA_TC=$MORI_RDMA_TC from hostname $NODENAME"
elif [[ $NODENAME == mia1* ]]; then
export MORI_RDMA_TC=104
export MORI_IO_TC=104
echo "[INFO] Auto-detected MORI_RDMA_TC=$MORI_RDMA_TC from hostname $NODENAME"
else
echo "[INFO] nicctl not found and unable to detect from hostname. Skipping RDMA QoS configuration."
echo " This is normal for clusters without QoS or outside Docker containers."
fi
fi
# =============================================================================
# Engine-specific environment
# =============================================================================
if [[ "$ENGINE" == "vllm-disagg" ]]; then
# =========================================================================
# vLLM/Nixl-specific environment
# =========================================================================
export VLLM_USE_V1=1
export VLLM_SERVER_DEV_MODE=0
export VLLM_DISABLE_REQUEST_ID_RANDOMIZATION=1
set -x
# UCX_NET_DEVICES: Use the first tw-eth interface for UCX TCP transport
if [[ -z "$UCX_NET_DEVICES" ]]; then
UCX_NET_DEV=$(ip -o link show 2>/dev/null | awk -F': ' '/tw-eth/{print $2}' | head -1)
if [[ -n "$UCX_NET_DEV" ]]; then
export UCX_NET_DEVICES="$UCX_NET_DEV"
else
FIRST_IB=$(echo "$IBDEVICES" | cut -d',' -f1)
if [[ -n "$FIRST_IB" ]]; then
export UCX_NET_DEVICES="${FIRST_IB}:1"
fi
fi
echo "[INFO] Auto-set UCX_NET_DEVICES=$UCX_NET_DEVICES"
else
echo "[INFO] Using UCX_NET_DEVICES=$UCX_NET_DEVICES (set by environment)"
fi
# RoCEv2: use IPv4-mapped GID (index 1) for inter-node RDMA routing
export UCX_IB_GID_INDEX=${UCX_IB_GID_INDEX:-1}
# QoS/DSCP configuration for lossless RoCEv2 fabric.
if [[ -n "$UCX_IB_TRAFFIC_CLASS" ]]; then
echo "[INFO] Using UCX_IB_TRAFFIC_CLASS=$UCX_IB_TRAFFIC_CLASS (set by environment)"
elif command -v nicctl &> /dev/null; then
ND_PRIO=$(nicctl show qos 2>/dev/null | awk '/PFC no-drop priorities/ {print $NF; exit}')
ND_DSCP=$(nicctl show qos 2>/dev/null | awk -v p="$ND_PRIO" '
$1 == "DSCP" && $2 == ":" && $NF == p {
print $3; exit
}')
# nicctl may emit trailing commas (e.g. "24,"); keep the leading integer so the
# arithmetic can't choke and unparseable output falls back to hostname detection.
ND_PRIO="${ND_PRIO%%,*}"; ND_PRIO="${ND_PRIO//[!0-9]/}"
ND_DSCP="${ND_DSCP%%,*}"; ND_DSCP="${ND_DSCP//[!0-9]/}"
if [[ "$ND_DSCP" =~ ^[0-9]+$ ]] && [[ "$ND_PRIO" =~ ^[0-9]+$ ]]; then
export UCX_IB_TRAFFIC_CLASS=$(( 4 * ND_DSCP ))
export UCX_IB_SL=$ND_PRIO
echo "[INFO] Detected QoS from nicctl: UCX_IB_TRAFFIC_CLASS=$UCX_IB_TRAFFIC_CLASS, UCX_IB_SL=$UCX_IB_SL"
else
echo "[WARN] nicctl available but QoS data unavailable; trying hostname detection."
NODENAME=$(hostname -s)
if [[ $NODENAME == GPU* ]] || [[ $NODENAME == smci355-ccs-aus* ]]; then
export UCX_IB_TRAFFIC_CLASS=96
echo "[INFO] Auto-detected UCX_IB_TRAFFIC_CLASS=$UCX_IB_TRAFFIC_CLASS from hostname $NODENAME"
elif [[ $NODENAME == mia1* ]]; then
export UCX_IB_TRAFFIC_CLASS=104
echo "[INFO] Auto-detected UCX_IB_TRAFFIC_CLASS=$UCX_IB_TRAFFIC_CLASS from hostname $NODENAME"
fi
fi
else
NODENAME=$(hostname -s)
if [[ $NODENAME == GPU* ]] || [[ $NODENAME == smci355-ccs-aus* ]]; then
export UCX_IB_TRAFFIC_CLASS=96
echo "[INFO] Auto-detected UCX_IB_TRAFFIC_CLASS=$UCX_IB_TRAFFIC_CLASS from hostname $NODENAME"
elif [[ $NODENAME == mia1* ]]; then
export UCX_IB_TRAFFIC_CLASS=104
echo "[INFO] Auto-detected UCX_IB_TRAFFIC_CLASS=$UCX_IB_TRAFFIC_CLASS from hostname $NODENAME"
else
echo "[INFO] No nicctl and unable to detect from hostname. Skipping QoS configuration."
fi
fi
set +x
echo "[INFO] IBDEVICES=$IBDEVICES UCX_NET_DEVICES=$UCX_NET_DEVICES NCCL_SOCKET_IFNAME=$NCCL_SOCKET_IFNAME UCX_IB_GID_INDEX=$UCX_IB_GID_INDEX UCX_IB_TRAFFIC_CLASS=${UCX_IB_TRAFFIC_CLASS:-unset}"
else
# =========================================================================
# SGLang-specific environment
# =========================================================================
export SGLANG_USE_AITER=1
export AITER_LOG_LEVEL=ERROR
export SGLANG_MORI_DISPATCH_DTYPE=auto
# export MORI_COMBINE_DTYPE_PREFILL=fp8_direct_cast
# export MORI_COMBINE_DTYPE_DECODE=fp8
export MORI_COMBINE_DTYPE_PREFILL=""
export MORI_COMBINE_DTYPE_DECODE=""
export SGLANG_MORI_QP_PER_TRANSFER=4
export SGLANG_MORI_NUM_WORKERS=4
# Keep these as overridable defaults (not hard assignments), otherwise
# later tuning blocks cannot raise them for high-concurrency runs.
# export MORI_IO_SQ_BACKOFF_TIMEOUT_US="${MORI_IO_SQ_BACKOFF_TIMEOUT_US:-500000}"
# export MORI_IO_QP_MAX_SEND_WR="${MORI_IO_QP_MAX_SEND_WR:-16384}"
# export MORI_IO_QP_MAX_CQE=32768
# export MORI_IO_QP_MAX_SGE=1
# export MORI_IO_TC_DISABLE=0
export SGLANG_DISAGGREGATION_BOOTSTRAP_TIMEOUT=3600
export SGLANG_DISAGGREGATION_WAITING_TIMEOUT=3600
export SGLANG_HEALTH_CHECK_TIMEOUT=600
# GLM-5: uses NSA (not MLA), needs fused-decode-MLA disabled + fast loading
if [[ "$MODEL_NAME" == "GLM-5-FP8" ]]; then
export SGLANG_ROCM_FUSED_DECODE_MLA=0
export ROCM_QUICK_REDUCE_QUANTIZATION=INT4
export SAFETENSORS_FAST_GPU=1
fi
# Disable allocating memory in one pass
export MORI_SHMEM_MODE=ISOLATION
# Enable spec v2
export SGLANG_ENABLE_SPEC_V2=1
export SGLANG_ENABLE_OVERLAP_PLAN_STREAM=0
export SGLANG_LOG_MS=true
export SGLANG_DISAGGREGATION_NUM_PRE_ALLOCATE_REQS=32
export MORI_MAX_DISPATCH_TOKENS_PREFILL=8192
export MORI_MAX_DISPATCH_TOKENS_DECODE=512
export MORI_MOE_MAX_INPUT_TOKENS_PREFILL=32768
export MORI_MOE_MAX_INPUT_TOKENS_DECODE=2703
# set MTP size=1 when EP16
export SGLANG_MORI_DISPATCH_INTER_KERNEL_SWITCH_THRESHOLD=$((MORI_MAX_DISPATCH_TOKENS_DECODE * 2))
export MORI_EP_LAUNCH_CONFIG_MODE=AUTO
# Default to WARNING to cut per-op MoRI log spam on long multinode/eval
# runs; override with MORI_APP_LOG_LEVEL=INFO when debugging.
export MORI_APP_LOG_LEVEL="${MORI_APP_LOG_LEVEL:-WARNING}"
# Router logging control:
# 0 (default) keeps noisy per-request access logs out of stdout while still logging to file.
# 1 mirrors router logs to stdout via tee (useful for live debugging).
export SGLANG_ROUTER_STDOUT_LOGS="${SGLANG_ROUTER_STDOUT_LOGS:-0}"
# FIXME: WA for latest upstream 0305 image
export PYTHONPATH=/sgl-workspace/aiter:${PYTHONPATH}
# Decode CUDA-graph capture crash on ROCm 7.2.0 (TP8+EP8, mori a2a).
# Symptom: during decode cuda-graph capture, the torch ProcessGroupNCCL
# *watchdog* thread calls hipEventQuery() to poll in-flight NCCL work.
# ROCm <= 7.2.0's HIP runtime does NOT honor cudaStreamCaptureModeThreadLocal,
# so the watchdog's cross-thread query touches the main thread's active
# capture and invalidates it -> "HIP error: operation not permitted on an
# event last recorded in a capturing stream (hipErrorCapturedEvent)" ->
# watchdog aborts -> "Rank 0 scheduler died during initialization" (-6).
# This is a HIP runtime bug, not OOM and not a mori/deepep-mode bug (it
# fires for --deepep-mode normal and auto alike; EP8+mori just adds NCCL
# PGs that make the watchdog race fire). Refs: sgl-project/sglang#29235,
# #24011; ROCm/hip#3876; pytorch/pytorch#176251.
# Real fix = ROCm 7.2.2+ (honors THREAD_LOCAL). Until the base image is
# bumped, TORCH_NCCL_BLOCKING_WAIT=true makes NCCL work completion use a
# blocking wait instead of the async watchdog hipEventQuery poll, so no
# event is queried during capture. CUDA graph stays fully enabled.
export TORCH_NCCL_BLOCKING_WAIT="${TORCH_NCCL_BLOCKING_WAIT:-1}"
export NCCL_BLOCKING_WAIT="${NCCL_BLOCKING_WAIT:-1}"
# export NCCL_DEBUG="${NCCL_DEBUG:-INFO}"
# =========================================================================
# DeepSeek-V4-Pro PD recipe overrides
# Placed at the end of the SGLang env block so it wins over the global
# MoRI/SGLang defaults set above. Mirrors the validated DSv4 manual PD
# commands (ported from InferenceX amd/dsv4_sgl_di). These SGLANG_OPT_* /
# AITER_* kernel-routing knobs steer DSv4 away from the default aiter CK
# fused-MoE path, which raises "Unsupported kernel config for moe heuristic
# dispatch" at decode time on this fp4 model (job 19034 crash). Only the
# SGLang/MoRI env knobs are pinned here; CLI flags live in models.yaml and
# the cluster NIC/socket vars stay runner-derived.
# =========================================================================
if [[ "$MODEL_NAME" == "DeepSeek-V4-Pro" ]]; then
# MoRI RDMA send-queue depth for DSv4 (overrides the global default above).
export MORI_IO_QP_MAX_SEND_WR=32767
# Unified radix tree: cache impl with per-component (full-attn / SWA)
# management for hybrid-attention models. Set unconditionally (not gated on
# hicache) so all SGLang runs use it.
export SGLANG_ENABLE_UNIFIED_RADIX_TREE=1
# Proactively free out-of-window SWA KV slots during chunked prefill.
# Without it, in-flight requests pin SWA KV for their whole context, keeping
# the SWA pool under constant eviction pressure; under LRU the trailing
# window of cached sessions gets flushed, making prefix-cache hits bimodal
# and collapsing the effective hit rate on multi-turn agentic workloads.
export SGLANG_OPT_UNIFIED_CACHE_FREE_OUT_OF_WINDOW_SLOTS=1
# MoRI dispatch/combine dtypes: auto for both roles (not the fp8 split default)
export SGLANG_MORI_DISPATCH_DTYPE=auto
export MORI_COMBINE_DTYPE_PREFILL=auto
export MORI_COMBINE_DTYPE_DECODE=auto
# Per-role MoRI dispatch sizing (used by the harness chunked/MoE math)
export MORI_MAX_DISPATCH_TOKENS_PREFILL=8192
export MORI_MAX_DISPATCH_TOKENS_DECODE=64
unset MORI_MOE_MAX_INPUT_TOKENS_PREFILL
unset MORI_MOE_MAX_INPUT_TOKENS_DECODE
# PER_RANK dispatch tokens pinned independently (16384 prefill / 128
# decode); server_sglang.sh prefers these over the MORI_MAX_DISPATCH_*
# coupling when set.
export MORI_NUM_MAX_DISPATCH_TOKENS_PER_RANK_PREFILL=16384
export MORI_NUM_MAX_DISPATCH_TOKENS_PER_RANK_DECODE=128
# Fixed inter-kernel switch threshold (not derived).
export SGLANG_MORI_DISPATCH_INTER_KERNEL_SWITCH_THRESHOLD=4096
# Overlap plan stream on for DSv4 (global default is 0)
# export SGLANG_ENABLE_OVERLAP_PLAN_STREAM=0
# DSv4 model kernel routing (mirrors the single-node / manual PD recipe)
export SGLANG_DEFAULT_THINKING=1
export SGLANG_DSV4_REASONING_EFFORT=high
export SGLANG_OPT_DEEPGEMM_HC_PRENORM=false
export SGLANG_USE_AITER=1
export SGLANG_USE_ROCM700A=0
export SGLANG_OPT_USE_FUSED_COMPRESS=true
export SGLANG_HACK_FLASHMLA_BACKEND=unified_kv_triton
export SGLANG_OPT_FP8_WO_A_GEMM=false
export SGLANG_OPT_USE_JIT_INDEXER_METADATA=false
export SGLANG_OPT_USE_TOPK_V2=false
export SGLANG_OPT_USE_AITER_INDEXER=${SGLANG_OPT_USE_AITER_INDEXER:-true}
export SGLANG_OPT_USE_TILELANG_INDEXER=false
export SGLANG_OPT_USE_TILELANG_MHC_PRE=false
export SGLANG_OPT_USE_TILELANG_MHC_POST=false
export SGLANG_FP8_PAGED_MQA_LOGITS_TORCH=1
export SGLANG_OPT_USE_FUSED_COMPRESS_TRITON=true
export SGLANG_OPT_USE_MULTI_STREAM_OVERLAP=false
export SGLANG_ROCM_USE_MULTI_STREAM=false
export AITER_BF16_FP8_MOE_BOUND=0
export SGLANG_EAGER_INPUT_NO_COPY=true
export SGLANG_SHARED_EXPERT_TP1=1
export SGLANG_DP_SHARED_EXPERT_LOCAL=1
export SGLANG_DP_USE_GATHERV=1
export SGLANG_DP_USE_REDUCE_SCATTER=1
export GPU_MAX_HW_QUEUES=5
fi
fi