Skip to content
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
name: "disagg-h200-2p2d-pcp8-tp8-dp8-mtp"

# Refresh of the 2P2D topology from Actions run 30133535261 with EAGLE MTP.
# The released SGLang image does not combine MTP with HiSparse, so decode KV
# cache remains GPU-resident. MTP uses the committed GLM-5.2 golden thinking-on
# acceptance length for three speculative steps.

model:
path: "hf:zai-org/GLM-5.2-FP8"
container: "lmsysorg/sglang:v0.5.16-cu130"
precision: "fp8"

dynamo:
install: true
wheel: "1.3.0.dev1"

slurm:
time_limit: "8:00:00"

resources:
gpu_type: h200
gpus_per_node: 8
prefill_nodes: 2
decode_nodes: 2
prefill_workers: 2
decode_workers: 2
gpus_per_prefill: 8
gpus_per_decode: 8

infra:
etcd_nats_dedicated_node: true
nats_max_payload_mb: 32

frontend:
type: dynamo
nginx_session_affinity: true
nginx_session_affinity_header: X-Correlation-ID
env:
DYN_ROUTER_TEMPERATURE: "10000000"
PIP_BREAK_SYSTEM_PACKAGES: "1"
args:
router-mode: "kv"
router-reset-states: true
active-decode-blocks-threshold: "None"
active-prefill-tokens-threshold: "None"
active-prefill-tokens-threshold-frac: "None"

backend:
type: sglang
prefill_environment:
HF_HOME: "/hf_hub_cache"
HF_HUB_CACHE: "/hf_hub_cache"
PIP_BREAK_SYSTEM_PACKAGES: "1"
PYTHONUNBUFFERED: "1"
SGLANG_DISAGGREGATION_WAITING_TIMEOUT: "900"
SGLANG_MOONCAKE_CUSTOM_MEM_POOL: "True"
SGLANG_OPT_USE_TOPK_V2: "1"
SGLANG_TIMEOUT_KEEP_ALIVE: "900"
decode_environment:
HF_HOME: "/hf_hub_cache"
HF_HUB_CACHE: "/hf_hub_cache"
PIP_BREAK_SYSTEM_PACKAGES: "1"
PYTHONUNBUFFERED: "1"
SGLANG_DISAGGREGATION_WAITING_TIMEOUT: "900"
SGLANG_MOONCAKE_CUSTOM_MEM_POOL: "True"
SGLANG_OPT_USE_TOPK_V2: "1"
SGLANG_TIMEOUT_KEEP_ALIVE: "900"
SGLANG_SIMULATE_ACC_LEN: "2.99"
SGLANG_SIMULATE_ACC_METHOD: "match-expected"
SGLANG_SIMULATE_ACC_TOKEN_MODE: "real-draft-token"

sglang_config:
prefill:
host: 0.0.0.0
model-path: /model/
served-model-name: zai-org/GLM-5.2-FP8
trust-remote-code: true
tool-call-parser: glm47
reasoning-parser: glm45
tp-size: 8
ep-size: 1
attn-cp-size: 8
enable-prefill-cp: true
cp-strategy: interleave
enable-dsa-cache-layer-split: true
disaggregation-transfer-backend: mooncake
disaggregation-mode: prefill
kv-cache-dtype: fp8_e4m3
context-length: 1048576
max-total-tokens: 1048576
chunked-prefill-size: 32768
mem-fraction-static: 0.85
max-running-requests: 32
speculative-algorithm: EAGLE
speculative-num-steps: 3
speculative-eagle-topk: 1
speculative-num-draft-tokens: 4
watchdog-timeout: 86400
stream-interval: 60
enable-metrics: true
enable-cache-report: true

decode:
host: 0.0.0.0
model-path: /model/
served-model-name: zai-org/GLM-5.2-FP8
trust-remote-code: true
tool-call-parser: glm47
reasoning-parser: glm45
tp-size: 8
dp-size: 8
ep-size: 1
enable-dp-attention: true
disaggregation-transfer-backend: mooncake
disaggregation-mode: decode
kv-cache-dtype: fp8_e4m3
dsa-decode-backend: flashmla_kv
context-length: 1048576
max-total-tokens: 1048576
mem-fraction-static: 0.85
max-running-requests: 200
page-size: 64
disable-radix-cache: true
speculative-algorithm: EAGLE
speculative-num-steps: 3
speculative-eagle-topk: 1
speculative-num-draft-tokens: 4
watchdog-timeout: 86400
stream-interval: 60
enable-metrics: true
enable-cache-report: true

sbatch_directives:
mem: "0"

srun_options:
mem: "0"
container-remap-root: ""

benchmark:
type: custom
command: bash /infmax-workspace/benchmarks/multi_node/agentic_srt.sh
env:
INFMAX_CONTAINER_WORKSPACE: /infmax-workspace
RESULT_DIR: /logs/agentic
PORT: "8000"
IS_MULTINODE: "true"
AIPERF_USE_DYNAMO_CONV_AWARE_ROUTING: "0"
AIPERF_HTTP_X_DYNAMO_SESSION_ID_FROM_CORRELATION_ID: "true"
AIPERF_REQUIRED_SERVER_METRIC_PREFIX: "sglang:"
AIPERF_DATASET_MMAP_CACHE_DIR: "/aiperf_mmap_cache"
HF_HUB_CACHE: "/hf_hub_cache"
WEKA_LOADER_OVERRIDE: "semianalysis_cc_traces_weka_062126"
67 changes: 67 additions & 0 deletions configs/nvidia-master.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7609,6 +7609,73 @@ qwen3.5-fp8-gb300-dynamo-sglang:
ep: 16
dp-attn: true

# GLM-5.2 FP8 full-context AgentX refresh on H200. This preserves the 2P2D
# PCP8/TP8-DP8 topology and c8/c12/c16 curve from Actions run 30133535261 while
# enabling native EAGLE MTP with golden AL and GPU-resident decode KV cache.
glm5.2-fp8-h200-dynamo-sglang-agentic-mtp-2p2d:
image: lmsysorg/sglang:v0.5.16-cu130
model: zai-org/GLM-5.2-FP8
model-prefix: glm5.2
runner: cluster:h200-dgxc
precision: fp8
framework: dynamo-sglang
router: { name: dynamo-router, version: "1.3.0.dev1" }
kv-p2p-transfer: mooncake
multinode: true
disagg: true
scenarios:
agentic-coding:
- dram-utilization: 0.80
search-space:
- spec-decoding: mtp
conc-list: [8]
kv-offloading: none
prefill:
num-worker: 2
tp: 1
pcp-size: 8
ep: 1
dp-attn: false
additional-settings:
- "CONFIG_FILE=recipes/sglang/glm5.2/agentic/disagg-h200-2p2d-pcp8-tp8-dp8-mtp.yaml"
decode:
num-worker: 2
tp: 8
ep: 1
dp-attn: true
- spec-decoding: mtp
conc-list: [12]
kv-offloading: none
prefill:
num-worker: 2
tp: 1
pcp-size: 8
ep: 1
dp-attn: false
additional-settings:
- "CONFIG_FILE=recipes/sglang/glm5.2/agentic/disagg-h200-2p2d-pcp8-tp8-dp8-mtp.yaml"
decode:
num-worker: 2
tp: 8
ep: 1
dp-attn: true
- spec-decoding: mtp
conc-list: [16]
kv-offloading: none
prefill:
num-worker: 2
tp: 1
pcp-size: 8
ep: 1
dp-attn: false
additional-settings:
- "CONFIG_FILE=recipes/sglang/glm5.2/agentic/disagg-h200-2p2d-pcp8-tp8-dp8-mtp.yaml"
decode:
num-worker: 2
tp: 8
ep: 1
dp-attn: true

# GLM-5.2 B300 NVFP4 AgentX with EAGLE/MTP speculative decoding, following the
# AgentX speculative-decoding policy in MODELS.md. SGLang EAGLE runs off
# GLM-5.2's built-in nextn head (num-steps 3,
Expand Down
12 changes: 12 additions & 0 deletions perf-changelog.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5665,3 +5665,15 @@
- "Refresh submission with up to date AgentX harness."
- "Capture the vLLM backend Prometheus endpoint for every topology and require vllm: metrics before publishing AgentX results."
pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/2516

- config-keys:
- glm5.2-fp8-h200-dynamo-sglang-agentic-mtp-2p2d
scenario-type:
- agentic-coding
description:
- "Refresh submission with up to date AgentX harness."
- "Retain the 2P2D PCP8 prefill, TP8/DP8 decode, Mooncake, 1M-context topology, and c8/c12/c16 search space; use GPU-resident decode KV cache because released SGLang does not support combining HiSparse with MTP"
- "Use EAGLE with three speculative steps, top-k 1, four draft tokens, and the committed GLM-5.2 thinking-on golden synthetic acceptance length of 2.99; evals retain real verification"
- "Use lmsysorg/sglang:v0.5.16-cu130 and the latest NVIDIA/srt-slurm release, v1.0.44, which includes logical-worker Prometheus URL injection for AIPerf"
- "Enable SGLang cache reporting on both prefill and decode workers so AIPerf records prompt-cache read-token usage alongside all logical-worker Prometheus metrics"
pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/2529
69 changes: 57 additions & 12 deletions runners/launch_h200-dgxc-slurm.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,26 @@ source "$(dirname "${BASH_SOURCE[0]}")/slurm_utils.sh"

if [[ "$IS_MULTINODE" == "true" ]]; then

if [[ -z "${CONFIG_FILE:-}" ]]; then
echo "Error: CONFIG_FILE is not set. The srt-slurm path requires a CONFIG_FILE in additional-settings." >&2
exit 1
fi
CONFIG_PATH="${CONFIG_FILE%%:*}"
LOCAL_CONFIG_FILE="$GITHUB_WORKSPACE/benchmarks/multi_node/srt-slurm-recipes/${CONFIG_PATH#recipes/}"

# MODEL_PATH: Override with pre-downloaded paths on H200 runner
# The yaml files specify HuggingFace model IDs for portability, but we use
# local paths to avoid repeated downloading on the shared H200 cluster.
Comment on lines 11 to 23

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 This PR's title and description are English-only, but AGENTS.md requires PR titles/bodies to be bilingual (title format <English> / <中文标题>, plus a ## 中文说明 section in the body). Please add a Chinese title counterpart and a Chinese translation section to the description.

Extended reasoning...

The rule. AGENTS.md line 7 explicitly states: "PR and GitHub-issue titles & descriptions must be bilingual — include a Simplified Chinese version in addition to English. Title format: <English title> / <中文标题>. In the PR/issue body, follow the English content with its Chinese translation (e.g. a ## 中文说明 section mirroring the summary...)." This is phrased as a hard requirement ("must be bilingual") and applies "to every PR and every issue" — it is not a subjective style preference, it's a mandated repo convention that CLAUDE.md points to as authoritative.

How this PR violates it. The PR title is "Refresh GLM-5.2 FP8 H200 AgentX 2P2D with MTP" — English only, with no / <中文标题> counterpart. The body contains What/Why/Impact/Checks sections, all in English, with no ## 中文说明 (or equivalent) section translating the summary into Simplified Chinese.

Why the PR's own checklist doesn't cover this. The PR's Checks section includes "Diff is English-only" — but that check item is about the code/config diff (recipe YAML, shell script, master-config keys) correctly staying in English, per the separate rule that internal config/code should not be localized. It says nothing about the PR title/description prose, so satisfying that check does not satisfy the bilingual title/body rule.

Proof by walkthrough.

  1. Open AGENTS.md and read line 7 — it mandates <English title> / <中文标题> as the title format for "every PR."
  2. Look at the actual PR title in the metadata: Refresh GLM-5.2 FP8 H200 AgentX 2P2D with MTP. There is no / followed by a Chinese title segment.
  3. Look at the PR body: it has ## What, ## Why, ## Impact, ## Checks — no ## 中文说明 or any Chinese paragraph.
  4. Compare to the norm already established in this repo's history: e.g. commit 8cc24c3 in the recent log is titled "...Kimi-K2.5/2.6/2.7-Code retirement / 执行 2026 年 8 月 6 日 Kimi-K2.5/2.6/2.7-Code 完全退役 ([Klaud Cold] Enact the August 6, 2026 Kimi-K2.5/2.6/2.7-Code retirement / 执行 2026 年 8 月 6 日 Kimi-K2.5/2.6/2.7-Code 完全退役 #2527)" — bilingual, as the rule requires. This PR breaks that pattern.
  5. Therefore the PR fails the AGENTS.md-mandated bilingual title/body convention.

Fix. Update the PR title to Refresh GLM-5.2 FP8 H200 AgentX 2P2D with MTP / 使用 MTP 刷新 GLM-5.2 FP8 H200 AgentX 2P2D, and append a ## 中文说明 section to the body mirroring the What/Why/Impact summary in Simplified Chinese.

This is a documentation/process convention issue, not a code-correctness bug — it doesn't affect runtime behavior of the shell script or recipe changes, so it should not block merge but should be fixed per repo policy.

if [[ $FRAMEWORK == "dynamo-sglang" ]]; then
if [[ $MODEL_PREFIX == "dsr1" && $PRECISION == "fp8" ]]; then
export MODEL_PATH="/models/DeepSeek-R1-0528"
export SRT_SLURM_MODEL_PREFIX="dsr1-fp8"
elif [[ $MODEL_PREFIX == "glm5.2" && $PRECISION == "fp8" ]]; then
export MODEL_PATH="${GLM52_FP8_MODEL_PATH:-/models/GLM-5.2-FP8}"
if [[ ! -d "$MODEL_PATH" ]]; then
export MODEL_PATH="hf:zai-org/GLM-5.2-FP8"
fi
export SRT_SLURM_MODEL_PREFIX="glm5.2-fp8"
else
echo "Unsupported model prefix/precision for dynamo-sglang: $MODEL_PREFIX/$PRECISION"
exit 1
Expand Down Expand Up @@ -51,7 +64,12 @@ if [[ "$IS_MULTINODE" == "true" ]]; then
rm -rf "$SRT_REPO_DIR"
fi

if [[ $IS_AGENTIC == "1" && $FRAMEWORK == "vllm" && $MODEL_PREFIX == "kimik3" ]]; then
if [[ $IS_AGENTIC == "1" && $FRAMEWORK == "dynamo-sglang" && $MODEL_PREFIX == "glm5.2" ]]; then
# v1.0.44 includes the AgentX custom benchmark integration and passes
# every logical SGLang worker's Prometheus URL to AIPerf.
git clone --branch v1.0.44 --single-branch https://github.com/NVIDIA/srt-slurm.git "$SRT_REPO_DIR"
cd "$SRT_REPO_DIR"
elif [[ $IS_AGENTIC == "1" && $FRAMEWORK == "vllm" && $MODEL_PREFIX == "kimik3" ]]; then
git clone https://github.com/functionstackx/srt-slurm-nv.git "$SRT_REPO_DIR"
cd "$SRT_REPO_DIR"
git checkout df5baa93f4caf5169dea2a4236ad2cc742fe40e7
Expand Down Expand Up @@ -87,7 +105,11 @@ if [[ "$IS_MULTINODE" == "true" ]]; then

if [[ $FRAMEWORK == "dynamo-sglang" ]]; then
# SGLang container mapping
SQUASH_FILE="/data/containers/$(echo "$IMAGE" | sed 's/[\/:@#]/+/g').sqsh"
if [[ $MODEL_PREFIX == "glm5.2" ]]; then
SQUASH_FILE="/data/gharunners/containers/$(echo "$IMAGE" | sed 's/[\/:@#]/_/g').sqsh"
else
SQUASH_FILE="/data/containers/$(echo "$IMAGE" | sed 's/[\/:@#]/+/g').sqsh"
fi
CONTAINER_KEY="$IMAGE"
elif [[ $FRAMEWORK == "dynamo-trt" ]]; then
# TRT-LLM container mapping - convert IMAGE to srt-slurm format (nvcr.io/ -> nvcr.io#)
Expand All @@ -98,6 +120,26 @@ if [[ "$IS_MULTINODE" == "true" ]]; then
SQUASH_FILE="/data/gharunners/containers/$(echo "$IMAGE" | sed 's/[\/:@#]/_/g').sqsh"
fi

if [[ $MODEL_PREFIX == "glm5.2" ]] && ! unsquashfs -l "$SQUASH_FILE" >/dev/null 2>&1; then
DOCKER_IMAGE=$(echo "$IMAGE" | sed 's/#/\//g')
LOCK_FILE="${SQUASH_FILE}.lock"
mkdir -p "$(dirname "$SQUASH_FILE")"
srun --partition="$SLURM_PARTITION" --account="$SLURM_ACCOUNT" \
--nodes=1 --ntasks=1 --time=30 --job-name="$RUNNER_NAME" \
bash -c "
set -euo pipefail
exec 9>\"$LOCK_FILE\"
flock -w 1800 9
if unsquashfs -l \"$SQUASH_FILE\" >/dev/null 2>&1; then
exit 0
fi
rm -f \"$SQUASH_FILE\"
export ENROOT_CACHE_PATH=\${HOME}/.cache/enroot
mkdir -p \"\$ENROOT_CACHE_PATH\"
enroot import -o \"$SQUASH_FILE\" docker://$DOCKER_IMAGE
"
fi
Comment on lines +123 to +141

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 This new multinode squash-build block re-implements the existing flock+unsquashfs-check+enroot-import sequence (already present in this same file's non-multinode else-branch, and factored into a shared import_squash() helper in sibling launchers like launch_gb200-nv.sh, launch_b200-dgxc.sh, launch_gb300-nv.sh, and launch_b200-nscale-slurm.sh) instead of reusing it. This is a pre-existing pattern in this repo (this PR is the third copy in this file), and the new copy also drops the descriptive || { echo Failed to acquire lock...; exit 1; } error message the other copies have and uses a different lock-wait (1800s vs 600s). Not a correctness blocker, but worth factoring into a shared helper to avoid further drift.

Extended reasoning...

What the duplication is: runners/launch_h200-dgxc-slurm.sh:123-141 adds a new block that acquires an flock on a per-squashfs lock file, checks whether the squashfs already exists via unsquashfs -l, and if not, removes any stale file and runs enroot import to rebuild it. This exact sequence — lock, check, remove, import — already exists in this very file's non-multinode else-branch (lines ~347-357), and is factored into a reusable import_squash() helper in several sibling launcher scripts (launch_gb200-nv.sh:266, launch_b200-dgxc.sh:206, launch_gb300-nv.sh:112, launch_b200-nscale-slurm.sh:103).\n\nWhere it diverges, and why that's a problem: the new copy is not identical to the existing in-file copy — it uses flock -w 1800 instead of flock -w 600, and critically drops the descriptive error handler || { echo 'Failed to acquire lock for ...'; exit 1; } that the other copy has. Concretely, walking through the new code at line 132 (flock -w 1800 9) versus the existing code at line 351 (flock -w 600 9 || { echo 'Failed to acquire lock for '; exit 1; }): if the new block's flock call times out after 1800 seconds without acquiring the lock, execution falls through to the subsequent commands under set -euo pipefail inside the bash -c subshell — flock's own nonzero exit under set -e will abort the subshell, but with no descriptive message, so the srun job simply fails with an opaque non-zero exit and no explanation of what went wrong (vs. the sibling copy which fails loudly with 'Failed to acquire lock for ...'). This is exactly the kind of silent drift that happens when the same logic is copy-pasted rather than shared.\n\nWhy nothing in the existing code prevents this: there's no shared helper in this file (unlike launch_gb200-nv.sh and others, which already define a local import_squash() function used from multiple call sites). Because this file inlines the pattern per-callsite, each new addition is free to subtly diverge, and lint/tests don't catch behavioral differences between near-identical shell blocks.\n\nImpact: low — this is not a correctness bug in the sense of producing wrong output; a lock timeout is a rare edge case (contention on the same squash file for over 30 minutes), and when it happens the job merely fails without a clear diagnostic message instead of failing with one. It does not block merging.\n\nSuggested fix: factor the flock+unsquashfs-check+enroot-import sequence into a local import_squash() helper within this file (mirroring launch_gb200-nv.sh), parameterized by squash file path, docker image, and lock wait time, and call it from both the multinode and non-multinode branches. This would eliminate the divergence, restore the descriptive lock-failure message in the new block, and prevent a fourth copy from drifting further in the future.


export ISL="$ISL"
export OSL="$OSL"
export EVAL_ONLY="${EVAL_ONLY:-false}"
Expand Down Expand Up @@ -150,22 +192,25 @@ EOF
echo "Running make setup..."
make setup ARCH=x86_64

if [[ -f "$LOCAL_CONFIG_FILE" ]]; then
mkdir -p "$(dirname "$CONFIG_PATH")"
cp "$LOCAL_CONFIG_FILE" "$CONFIG_PATH"
fi
Comment on lines 192 to +198

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Nit: the new generic recipe-staging block (runners/launch_h200-dgxc-slurm.sh:195-198) duplicates the pre-existing kimik3-specific mkdir -p recipes/vllm/kimi-k3/agentic; cp -rT ... copy earlier in the script (~line 76). For kimik3 runs, both mechanisms now stage the same recipe file into the same destination — harmless but redundant.

Extended reasoning...

This PR introduces a generic single-file staging mechanism for CONFIG_FILE recipes. Lines 18-19 compute CONFIG_PATH="${CONFIG_FILE%%:*}" and LOCAL_CONFIG_FILE="$GITHUB_WORKSPACE/benchmarks/multi_node/srt-slurm-recipes/${CONFIG_PATH#recipes/}" for every IS_MULTINODE run, and lines 195-198 (if [[ -f "$LOCAL_CONFIG_FILE" ]]; then mkdir -p "$(dirname "$CONFIG_PATH")"; cp "$LOCAL_CONFIG_FILE" "$CONFIG_PATH"; fi) copy that single recipe file into the cloned srt-slurm repo after make setup. This was added specifically to support the new GLM-5.2 recipe, but the guard is generic and fires for any model whose local recipe file exists — including kimik3.

Kimi K3 already has a bespoke staging path, unchanged by this PR, right after the repo clone (around line 76): mkdir -p recipes/vllm/kimi-k3/agentic; cp -rT "$GITHUB_WORKSPACE/benchmarks/multi_node/srt-slurm-recipes/vllm/kimi-k3/agentic" recipes/vllm/kimi-k3/agentic. For a kimik3 H200 agentic run, CONFIG_FILE resolves (per configs/nvidia-master.yaml) to recipes/vllm/kimi-k3/agentic/agg-h200-tp16dp2ep32-latency-agentic.yaml, so LOCAL_CONFIG_FILE resolves to the exact same source file already staged by the kimik3-specific block, and CONFIG_PATH resolves to the exact same destination. Both mechanisms therefore copy the identical recipe file into the identical destination on every kimik3 run: one via a whole-directory cp -rT immediately after clone (staging all sibling recipes too), the other via a single-file cp keyed off CONFIG_FILE that runs after make setup.

This isn't a functional bug — the copy is idempotent and both copies produce identical file content, so nothing breaks. But it does leave two divergent, overlapping code paths doing the same job for kimik3: one broad (whole directory, pre-setup) and one narrow (single file, post-setup). Since the new generic mechanism already covers per-model recipe staging (and the PR's own design proves make setup doesn't require the recipe to be pre-staged, since GLM-5.2 relies solely on the post-setup copy), the kimik3-specific mkdir -p .../agentic; cp -rT ... staging lines are now redundant and could be removed — while keeping the surrounding kimik3-specific git clone/git checkout of the forked srt-slurm-nv repo, which is still required.

Step-by-step proof for a concrete kimik3 run:

  1. MODEL_PREFIX=kimik3, FRAMEWORK=vllm, IS_AGENTIC=1, and CONFIG_FILE=recipes/vllm/kimi-k3/agentic/agg-h200-tp16dp2ep32-latency-agentic.yaml:... (from configs/nvidia-master.yaml).
  2. Lines 18-19 compute CONFIG_PATH=recipes/vllm/kimi-k3/agentic/agg-h200-tp16dp2ep32-latency-agentic.yaml and LOCAL_CONFIG_FILE=$GITHUB_WORKSPACE/benchmarks/multi_node/srt-slurm-recipes/vllm/kimi-k3/agentic/agg-h200-tp16dp2ep32-latency-agentic.yaml.
  3. The kimik3-specific elif branch clones functionstackx/srt-slurm-nv, checks out the pinned commit, then runs cp -rT "$GITHUB_WORKSPACE/benchmarks/multi_node/srt-slurm-recipes/vllm/kimi-k3/agentic" recipes/vllm/kimi-k3/agentic — this stages the target file (plus 7 siblings) into recipes/vllm/kimi-k3/agentic/ inside the cloned repo.
  4. make setup runs.
  5. The new generic block checks -f "$LOCAL_CONFIG_FILE" (true — the file exists), creates recipes/vllm/kimi-k3/agentic (already exists, no-op) and runs cp "$LOCAL_CONFIG_FILE" "$CONFIG_PATH", copying the exact same source file to the exact same destination path a second time.
  6. srtctl apply -f "$CONFIG_FILE" then applies the file, which is unaffected by having been copied twice.

Since every original bug source for this finding is prefixed [quality] and the issue is a DRY/dedup cleanup with no behavioral impact, this should be graded nit — worth cleaning up but not blocking merge.


# Export eval-related env vars for srt-slurm post-benchmark eval
export INFMAX_WORKSPACE="$GITHUB_WORKSPACE"

echo "Submitting job with srtctl..."

if [[ -z "$CONFIG_FILE" ]]; then
echo "Error: CONFIG_FILE is not set. The srt-slurm path requires a CONFIG_FILE in additional-settings." >&2
echo "Config: MODEL_PREFIX=${MODEL_PREFIX} PRECISION=${PRECISION} FRAMEWORK=${FRAMEWORK}" >&2
exit 1
fi

# Override the job name in the config file with the runner name
sed -i "s/^name:.*/name: \"${RUNNER_NAME}\"/" "$CONFIG_FILE"
sed -i '/^health_check:/,/^[^ ]/{ /^health_check:/d; /^ /d; }' "${CONFIG_FILE%%:*}"
printf '\nhealth_check:\n max_attempts: 720\n interval_seconds: 10\n' >> "${CONFIG_FILE%%:*}"
SRTCTL_OUTPUT=$(srtctl apply -f "$CONFIG_FILE" --tags "h200,${MODEL_PREFIX},${PRECISION},${ISL}x${OSL},infmax-$(date +%Y%m%d)" 2>&1)
sed -i "s/^name:.*/name: \"${RUNNER_NAME}\"/" "$CONFIG_PATH"
sed -i '/^health_check:/,/^[^ ]/{ /^health_check:/d; /^ /d; }' "$CONFIG_PATH"
printf '\nhealth_check:\n max_attempts: 720\n interval_seconds: 10\n' >> "$CONFIG_PATH"
WORKLOAD_TAG="${ISL}x${OSL}"
if [[ "$IS_AGENTIC" == "1" ]]; then
WORKLOAD_TAG="agentic"
fi
SRTCTL_OUTPUT=$(srtctl apply -f "$CONFIG_FILE" --tags "h200,${MODEL_PREFIX},${PRECISION},${WORKLOAD_TAG},infmax-$(date +%Y%m%d)" 2>&1)
echo "$SRTCTL_OUTPUT"

# Extract JOB_ID from srtctl output
Expand Down