Skip to content

Commit c5aa568

Browse files
committed
agentx: kimik2.7 fp4 mi355x agentic smoke (none + lmcache)
Adds the kimik2.7 fp4 agentic trace-replay recipe (kimik2.7_fp4_mi355x.sh, KV_OFFLOADING none + dram/lmcache) and the kimik2.7-fp4-mi355x-vllm-agentic config key on cluster:mi355x-amds (tp4 conc32, none + lmcache). Recipe clones LMCache to /opt/lmcache-src so the CI checkout never trips over root-owned build artifacts.
1 parent 01e9e73 commit c5aa568

2 files changed

Lines changed: 260 additions & 0 deletions

File tree

Lines changed: 244 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,244 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
set -x
4+
5+
# Agentic trace replay benchmark for Kimi-K2.7 FP4 on MI355X using vLLM.
6+
#
7+
# Variant of kimik2.7_fp4_mi355x.sh that supports TWO KV configs:
8+
# KV_OFFLOADING=none -> GPU KV only
9+
# KV_OFFLOADING=dram KV_OFFLOAD_BACKEND=lmcache -> LMCache MP server + connector
10+
#
11+
# Required env vars:
12+
# MODEL, TP, CONC, KV_OFFLOADING, TOTAL_CPU_DRAM_GB, RESULT_DIR, DURATION, EP_SIZE
13+
14+
15+
source "$(dirname "$0")/../../benchmark_lib.sh"
16+
17+
check_env_vars MODEL TP CONC KV_OFFLOADING TOTAL_CPU_DRAM_GB RESULT_DIR DURATION EP_SIZE
18+
19+
if [[ -n "${SLURM_JOB_ID:-}" ]]; then
20+
echo "JOB $SLURM_JOB_ID running on ${SLURMD_NODENAME:-unknown}"
21+
fi
22+
23+
# ROCR/HIP visibility for vLLM 0.14+
24+
if [ -n "${ROCR_VISIBLE_DEVICES:-}" ]; then
25+
export HIP_VISIBLE_DEVICES="$ROCR_VISIBLE_DEVICES"
26+
fi
27+
28+
# `hf download` creates the target dir if missing and is itself idempotent.
29+
# When MODEL_PATH is unset (stand-alone runs), fall back to the HF_HUB_CACHE
30+
# Either way, MODEL_PATH is what the server is launched with.
31+
if [[ -n "${MODEL_PATH:-}" ]]; then
32+
if [[ ! -d "$MODEL_PATH" || -z "$(ls -A "$MODEL_PATH" 2>/dev/null)" ]]; then
33+
hf download "$MODEL" --local-dir "$MODEL_PATH"
34+
fi
35+
else
36+
hf download "$MODEL"
37+
export MODEL_PATH="$MODEL"
38+
fi
39+
rocm-smi || true
40+
amd-smi || true
41+
42+
# ---- Resolve traces and install deps ----------------------------------------
43+
resolve_trace_source
44+
install_agentic_deps
45+
46+
# Install amd-quark for MXFP4 (manual install due to ROCm vLLM bug)
47+
pip install amd-quark
48+
49+
# Disable AITER RMSNorm for TP < 8 due to accuracy issues
50+
if [ "${TP}" -lt 8 ]; then
51+
export VLLM_ROCM_USE_AITER_RMSNORM=0
52+
fi
53+
# Workaround for MEC FW <177 RCCL memory reclaim issue
54+
version=$(rocm-smi --showfw 2>/dev/null | grep MEC | head -n 1 | awk '{print $NF}')
55+
if [[ "$version" == "" || ${version:-0} -lt 177 ]]; then
56+
export HSA_NO_SCRATCH_RECLAIM=1
57+
fi
58+
59+
export VLLM_ROCM_USE_AITER=1
60+
export VLLM_ROCM_QUICK_REDUCE_QUANTIZATION=INT4
61+
# Avoid intermittent symm_mem all-reduce rendezvous hang at engine init on
62+
# MI35x nodes (see KIMIK27_CONC64_LMCACHE_RUNBOOK error #4).
63+
export VLLM_ALLREDUCE_USE_SYMM_MEM="${VLLM_ALLREDUCE_USE_SYMM_MEM:-0}"
64+
65+
# ---- Server config ----------------------------------------------------------
66+
SERVER_LOG="$RESULT_DIR/server.log"
67+
LMCACHE_LOG="$RESULT_DIR/lmcache_server.log"
68+
mkdir -p "$RESULT_DIR"
69+
70+
OFFLOAD_ARGS=()
71+
PREFIX_CACHE_ARGS=()
72+
73+
# ---- LMCache config ---------------------------------------------------------
74+
LMCACHE_PID=""
75+
76+
cleanup_lmcache_server() {
77+
if [[ -n "$LMCACHE_PID" ]] && kill -0 "$LMCACHE_PID" 2>/dev/null; then
78+
kill "$LMCACHE_PID" 2>/dev/null || true
79+
wait "$LMCACHE_PID" 2>/dev/null || true
80+
fi
81+
}
82+
trap cleanup_lmcache_server EXIT
83+
84+
wait_for_lmcache_ready() {
85+
{ set +x; } 2>/dev/null
86+
local attempts="${LMCACHE_READY_ATTEMPTS:-120}"
87+
local tail_pid=""
88+
89+
while [ ! -f "$LMCACHE_LOG" ]; do
90+
if [[ -n "$LMCACHE_PID" ]] && ! kill -0 "$LMCACHE_PID" 2>/dev/null; then
91+
echo "LMCache server died before creating log file. Exiting." >&2
92+
exit 1
93+
fi
94+
sleep 1
95+
done
96+
97+
tail -f -n +1 "$LMCACHE_LOG" &
98+
tail_pid=$!
99+
100+
for ((i = 1; i <= attempts; i++)); do
101+
if curl --output /dev/null --silent --fail "http://127.0.0.1:${LMCACHE_HTTP_PORT}/healthcheck"; then
102+
kill "$tail_pid" 2>/dev/null || true
103+
wait "$tail_pid" 2>/dev/null || true
104+
return 0
105+
fi
106+
if [[ -n "$LMCACHE_PID" ]] && ! kill -0 "$LMCACHE_PID" 2>/dev/null; then
107+
echo "LMCache server died before becoming healthy. Log follows:" >&2
108+
kill "$tail_pid" 2>/dev/null || true
109+
wait "$tail_pid" 2>/dev/null || true
110+
cat "$LMCACHE_LOG" >&2 || true
111+
exit 1
112+
fi
113+
sleep 1
114+
done
115+
116+
echo "Timed out waiting for LMCache server healthcheck. Log follows:" >&2
117+
kill "$tail_pid" 2>/dev/null || true
118+
wait "$tail_pid" 2>/dev/null || true
119+
cat "$LMCACHE_LOG" >&2 || true
120+
exit 1
121+
}
122+
123+
# Resolve the effective offload backend. When KV_OFFLOADING=none there is no
124+
# backend; when dram, KV_OFFLOAD_BACKEND selects native vs lmcache.
125+
if [[ "$KV_OFFLOADING" == "none" ]]; then
126+
OFFLOAD_MODE="none"
127+
else
128+
OFFLOAD_MODE="${KV_OFFLOAD_BACKEND:?KV_OFFLOAD_BACKEND required when KV_OFFLOADING=dram}"
129+
fi
130+
131+
case "$OFFLOAD_MODE" in
132+
none)
133+
OFFLOAD_ARGS=(--no-enable-prefix-caching)
134+
;;
135+
lmcache)
136+
unset VLLM_USE_SIMPLE_KV_OFFLOAD
137+
138+
# Build LMCache against ROCm if the connector isn't already importable
139+
# (prebuilt kimi-lmcache images already ship it). Clone to a
140+
# container-local dir (NOT the bind-mounted /workspace) so the CI
141+
# checkout's `clean: true` never trips over root-owned build artifacts
142+
# on the next job. Pin a ref for reproducibility.
143+
if ! python3 -c "import lmcache.integration.vllm.lmcache_mp_connector" >/dev/null 2>&1; then
144+
LMCACHE_SRC_DIR="${LMCACHE_SRC_DIR:-/opt/lmcache-src}"
145+
LMCACHE_GIT_REF="${LMCACHE_GIT_REF:-aaf7c0d3}"
146+
rm -rf "$LMCACHE_SRC_DIR"
147+
git clone https://github.com/LMCache/LMCache.git "$LMCACHE_SRC_DIR"
148+
( cd "$LMCACHE_SRC_DIR"
149+
git checkout "$LMCACHE_GIT_REF"
150+
pip install -r requirements/build.txt
151+
CXX=hipcc BUILD_WITH_HIP=1 pip install -e . --no-build-isolation )
152+
python3 -c "import lmcache.integration.vllm.lmcache_mp_connector" >/dev/null
153+
fi
154+
155+
LMCACHE_HOST="${LMCACHE_HOST:-127.0.0.1}"
156+
LMCACHE_PORT="${LMCACHE_PORT:-5555}"
157+
LMCACHE_HTTP_PORT="${LMCACHE_HTTP_PORT:-8080}"
158+
LMCACHE_CONNECT_HOST="${LMCACHE_CONNECT_HOST:-tcp://$LMCACHE_HOST}"
159+
# Let the external MP server own the whole CPU KV pool. The requested
160+
# budget is TOTAL_CPU_DRAM_GB, but LMCache's L1 is SHM-backed: if L1 >
161+
# /dev/shm free it silently disables SHM and falls back to the slow
162+
# pickle path (crashes at load — see kimik27 CI shm-overflow note).
163+
# Cap L1 to 90% of current /dev/shm free space so SHM stays enabled.
164+
SHM_FREE_GB=$(df -BG --output=avail /dev/shm 2>/dev/null | tail -1 | tr -dc '0-9')
165+
SHM_CAP_GB=$(( SHM_FREE_GB * 90 / 100 ))
166+
LMCACHE_L1_SIZE_GB="${LMCACHE_L1_SIZE_GB:-$TOTAL_CPU_DRAM_GB}"
167+
if [ -n "$SHM_CAP_GB" ] && [ "$SHM_CAP_GB" -gt 0 ] && [ "$LMCACHE_L1_SIZE_GB" -gt "$SHM_CAP_GB" ]; then
168+
echo "Capping LMCACHE_L1_SIZE_GB $LMCACHE_L1_SIZE_GB -> $SHM_CAP_GB to fit /dev/shm (${SHM_FREE_GB}G free)"
169+
LMCACHE_L1_SIZE_GB="$SHM_CAP_GB"
170+
fi
171+
LMCACHE_L1_INIT_SIZE_GB="${LMCACHE_L1_INIT_SIZE_GB:-20}"
172+
LMCACHE_L1_READ_TTL_SECONDS="${LMCACHE_L1_READ_TTL_SECONDS:-7200}"
173+
LMCACHE_CHUNK_SIZE="${LMCACHE_CHUNK_SIZE:-256}"
174+
LMCACHE_MAX_WORKERS="${LMCACHE_MAX_WORKERS:-$((TP * 2))}"
175+
export PYTHONHASHSEED="${PYTHONHASHSEED:-0}"
176+
export LMCACHE_BLOCKING_TIMEOUT_SECS=60
177+
178+
echo "Starting LMCache MP server..."
179+
LMCACHE_CMD=(
180+
lmcache server
181+
--host "$LMCACHE_HOST"
182+
--port "$LMCACHE_PORT"
183+
--http-host "$LMCACHE_HOST"
184+
--http-port "$LMCACHE_HTTP_PORT"
185+
--l1-size-gb "$LMCACHE_L1_SIZE_GB"
186+
--l1-init-size-gb "$LMCACHE_L1_INIT_SIZE_GB"
187+
--l1-read-ttl-seconds "$LMCACHE_L1_READ_TTL_SECONDS"
188+
--chunk-size "$LMCACHE_CHUNK_SIZE"
189+
--max-workers "$LMCACHE_MAX_WORKERS"
190+
--eviction-policy LRU
191+
)
192+
printf '%q ' "${LMCACHE_CMD[@]}" > "$RESULT_DIR/lmcache_command.txt"
193+
printf '\n' >> "$RESULT_DIR/lmcache_command.txt"
194+
"${LMCACHE_CMD[@]}" > "$LMCACHE_LOG" 2>&1 &
195+
LMCACHE_PID=$!
196+
echo "LMCache server PID: $LMCACHE_PID"
197+
wait_for_lmcache_ready
198+
199+
OFFLOAD_ARGS=(
200+
--kv-transfer-config
201+
"{\"kv_connector\":\"LMCacheMPConnector\",\"kv_connector_module_path\":\"lmcache.integration.vllm.lmcache_mp_connector\",\"kv_role\":\"kv_both\",\"kv_connector_extra_config\":{\"lmcache.mp.host\":\"$LMCACHE_CONNECT_HOST\",\"lmcache.mp.port\":$LMCACHE_PORT}}"
202+
)
203+
;;
204+
*)
205+
echo "Error: unsupported KV_OFFLOAD_BACKEND '$OFFLOAD_MODE' (expected: lmcache)" >&2
206+
exit 1
207+
;;
208+
esac
209+
210+
EP_ARGS=()
211+
if [ "$EP_SIZE" -gt 1 ]; then
212+
EP_ARGS=(--enable-expert-parallel)
213+
fi
214+
215+
echo "Starting vllm server..."
216+
export PYTHONNOUSERSITE=1
217+
218+
{ set +x; } 2>/dev/null
219+
VLLM_CMD=(
220+
vllm serve "$MODEL_PATH" --served-model-name "$MODEL"
221+
--host 0.0.0.0
222+
--port "$PORT"
223+
--tensor-parallel-size="$TP"
224+
"${EP_ARGS[@]}"
225+
--gpu-memory-utilization 0.90
226+
--block-size=1
227+
--trust-remote-code
228+
--max-num-seqs "$CONC"
229+
--mm-encoder-tp-mode data
230+
"${PREFIX_CACHE_ARGS[@]}"
231+
"${OFFLOAD_ARGS[@]}"
232+
)
233+
printf '%q ' "${VLLM_CMD[@]}" | tee "$RESULT_DIR/vllm_command.txt"
234+
printf '\n' | tee -a "$RESULT_DIR/vllm_command.txt"
235+
"${VLLM_CMD[@]}" > "$SERVER_LOG" 2>&1 &
236+
SERVER_PID=$!
237+
echo "Server PID: $SERVER_PID"
238+
239+
wait_for_server_ready --port "$PORT" --server-log "$SERVER_LOG" --server-pid "$SERVER_PID"
240+
241+
# ---- Run benchmark ----------------------------------------------------------
242+
build_replay_cmd "$RESULT_DIR"
243+
244+
run_agentic_replay_and_write_outputs "$RESULT_DIR"

configs/amd-master.yaml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,22 @@ kimik2.5-fp4-mi355x-vllm-agentic:
548548
- { tp: 4, kv-offloading: none, conc-list: [16, 24, 32, 40] }
549549
- { tp: 4, kv-offloading: dram, kv-offload-backend: { name: vllm-native }, conc-list: [16, 24, 32, 40] }
550550

551+
kimik2.7-fp4-mi355x-vllm-agentic:
552+
image: vllm/vllm-openai-rocm:v0.24.0
553+
model: amd/Kimi-K2.7-Code-MXFP4
554+
model-prefix: kimik2.7
555+
runner: cluster:mi355x-amds
556+
precision: fp4
557+
framework: vllm
558+
multinode: false
559+
scenarios:
560+
agentic-coding:
561+
- dram-utilization: 0.80
562+
search-space:
563+
- { tp: 4, kv-offloading: none, conc-list: [32] }
564+
- { tp: 4, kv-offloading: dram, kv-offload-backend: lmcache, conc-list: [32] }
565+
566+
551567
kimik2.5-fp4-mi355x-atom:
552568
image: rocm/atom:rocm7.2.4_ubuntu24.04_py3.12_pytorch_release_2.10.0_atom0.1.4_202607091539
553569
model: amd/Kimi-K2.5-MXFP4

0 commit comments

Comments
 (0)