Skip to content

[AMD] [AGENTX] Kimi Perf Tuning - #2795

Open
ajith-sirra-amd wants to merge 18 commits into
mainfrom
amd/kimi-k3-agentic-perf-tuning-4.0
Open

ajith-sirra-amd wants to merge 18 commits into
mainfrom
amd/kimi-k3-agentic-perf-tuning-4.0

Conversation

@ajith-sirra-amd

@ajith-sirra-amd ajith-sirra-amd commented Sep 1, 2026

Copy link
Copy Markdown
Collaborator

Kimi Perf Tuning


Note

Medium Risk
Benchmark-only changes, but they alter published agentic performance geometry (offload backend, conc/DCP/MTP split, and container pin), so regression or incomparability with prior Kimi-K3 submissions is possible.

Overview
Retunes Kimi-K3 MXFP4 agentic MTP on MI355X by rewriting kimik3_fp4_mi355x_mtp.sh and updating kimik3-fp4-mi355x-vllm-agentic-mtp in amd-master.yaml.

The launch script now splits geometry by concurrency: low conc (1/2/4) uses DCP=1 + DSpark MTP with a golden synthetic acceptance-length table (default 8 draft tokens) for comparable throughput runs; higher conc uses DCP=8 without speculative decode because MTP’s TRITON_MLA draft path conflicts with DCP. It bumps ROCm/AITER env flags, switches to FULL_DECODE_ONLY cudagraphs with tuned max-num-seqs / batched-token limits, fastsafetensors, and --no-async-scheduling, and drops the LMCache sidecar in favor of SimpleCPUOffloadConnector when DRAM offload is enabled.

The benchmark matrix pins a new vLLM ROCm nightly image, raises dram-utilization to 0.80, and narrows the search space to c1 GPU-resident plus c32/c72/c76 with DCP 8 and vllm-simple offload (replacing the prior LMCache multi-point sweep). perf-changelog.yaml records the image change.

Reviewed by Cursor Bugbot for commit 042b7fb. Bugbot is set up for automated code reviews on this repo. Configure here.

Signed-off-by: Sirra <asirra@amd.com>
@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Thanks for the contribution! Please reach out to respective companies' CODEOWNER to fill in the latest PR_REVIEW_CHECKLIST.md before pinging core maintainer on Slack for review. In order for the signoff PR check bot to trigger, you must follow the PR_REVIEW_CHECKLIST.md template correctly, including the phrase As a PR reviewer and CODEOWNER, I have reviewed this and have.

For PR verification, add the full-sweep-fail-fast label (strongly recommended) to this PR — the benchmark sweep only runs on labeled PRs. Use full-sweep-enabled only if you need matrix jobs to keep running past a failure.

PR authors are responsible for ensuring that after merging, all GitHub Action jobs fully pass. A lot of the time, failures are just flakes and simply re-running the failed jobs will fix it. See GitHub's docs on re-running failed jobs


感谢你的贡献!请联系相应公司的 CODEOWNER 填写最新的 PR_REVIEW_CHECKLIST.md,然后再在 Slack 上联系核心维护者进行审阅。为了触发 signoff PR 检查机器人,你必须正确遵循 PR_REVIEW_CHECKLIST.md 模板,包括保留英文语句 As a PR reviewer and CODEOWNER, I have reviewed this and have

如需进行 PR 验证,请为此 PR 添加 full-sweep-fail-fast 标签(强烈推荐)— 基准测试 sweep 仅在带有标签的 PR 上运行。仅当需要矩阵任务在失败后继续运行时才使用 full-sweep-enabled

PR 作者有责任确保合并后所有 GitHub Action 任务完全通过。 很多时候失败只是偶发抖动(flake),重新运行失败的任务即可解决。参见 GitHub 关于重新运行失败任务的文档

@ajith-sirra-amd ajith-sirra-amd added AMD agentx AgentX benchmarks, recipes, and infrastructure full-sweep-fail-fast labels Sep 1, 2026
Comment thread benchmarks/single_node/agentic/kimik3_fp4_mi355x_mtp.sh Outdated
@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Comment thread benchmarks/single_node/agentic/kimik3_fp4_mi355x_mtp.sh Outdated

@claude claude Bot left a comment

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.

Findings marked 🟡 are optional suggestions and need no follow-up push.

Comment on lines 70 to 82
if [ "$CONC" -le 4 ]; then
SPEC_NUM_TOKENS="${SPEC_NUM_TOKENS:-8}"
SPEC_ROWS=$(( SPEC_NUM_TOKENS + 1 ))
SPEC_ARGS=(--speculative-config "{\"model\":\"Inferact/Kimi-K3-DSpark\",\"num_speculative_tokens\":$SPEC_NUM_TOKENS,\"method\":\"dspark\",\"attention_backend\":\"TRITON_MLA\",\"kv_cache_dtype\":\"fp8\",\"draft_sample_method\":\"probabilistic\",\"rejection_sample_method\":\"synthetic\",\"synthetic_acceptance_length\":4.0}")
MAX_NUM_SEQS=1
MAX_BATCHED_TOKENS=8192
DCP_SIZE=1
else
MAX_NUM_SEQS=$(( CONC + CONC / 4 ))
if [ "$MAX_NUM_SEQS" -gt 80 ]; then MAX_NUM_SEQS=80; fi
MAX_BATCHED_TOKENS=16384
DCP_SIZE=8
fi

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.

🔴 For CONC>4 the else branch sets DCP_SIZE=8/MAX_BATCHED_TOKENS but never populates SPEC_ARGS, so the server starts with no --speculative-config at all. The second amd-master.yaml search-space arm (conc-list [8,16,32,48,52]) is labeled spec-decoding: mtp but every one of its concurrencies is >4, so this 'mtp' benchmark arm silently runs as a non-speculative baseline. Fix: give the else branch (CONC>4) its own SPEC_ARGS/SPEC_NUM_TOKENS just like the CONC<=4 branch so every conc value in an mtp arm actually enables DSpark speculative decoding.

Extended reasoning...

SPEC_ARGS is initialized to () and only populated inside if [ "$CONC" -le 4 ]; the else branch (line 77-82) only sets MAX_NUM_SEQS/MAX_BATCHED_TOKENS/DCP_SIZE, leaving SPEC_ARGS empty. VLLM_CMD later expands "${SPEC_ARGS[@]}" (line 131) which is a no-op, so vllm serve runs without --speculative-config. Old script's case statement gave nonzero SPEC_NUM_TOKENS for CONC in {1,2,4,8,10,12,14}; the new threshold only covers CONC<=4, silently dropping speculative decoding for CONC=8,16,32,48,52 even though amd-master.yaml's second search-space row explicitly sets spec-decoding: mtp for exactly those concurrencies. Results collected for that arm at conc>=8 will reflect baseline (no-spec) throughput/latency, not MTP-accelerated numbers, while being reported/labeled as the mtp benchmark.

Verification: normal. SPEC_ARGS=() is initialized at kimik3_fp4_mi355x_mtp.sh:68 and populated ONLY inside the if [ "$CONC" -le 4 ] branch (line 73). The else branch (lines 77-82, CONC>4) sets MAX_NUM_SEQS/MAX_BATCHED_TOKENS/DCP_SIZE but never touches SPEC_ARGS, so it stays empty. VLLM_CMD expands "${SPEC_ARGS[@]}" at line 131, which is a no-op when empty, so vllm serve starts with no… | normal.…

Comment on lines +68 to +73
SPEC_ARGS=()
SPEC_ROWS=1
if [ "$CONC" -le 4 ]; then
SPEC_NUM_TOKENS="${SPEC_NUM_TOKENS:-8}"
SPEC_ROWS=$(( SPEC_NUM_TOKENS + 1 ))
SPEC_ARGS=(--speculative-config "{\"model\":\"Inferact/Kimi-K3-DSpark\",\"num_speculative_tokens\":$SPEC_NUM_TOKENS,\"method\":\"dspark\",\"attention_backend\":\"TRITON_MLA\",\"kv_cache_dtype\":\"fp8\",\"draft_sample_method\":\"probabilistic\",\"rejection_sample_method\":\"synthetic\",\"synthetic_acceptance_length\":4.0}")

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.

🔴 The rejection_sample_method is now always "synthetic" for the spec-decode arm; the EVAL_ONLY branch that used "block" (real target-logit verification) was dropped, so running this script with EVAL_ONLY=true now silently commits synthetic-accepted drafts instead of verifying against the target model, corrupting the accuracy score. Fix: restore the EVAL_ONLY check so eval runs use rejection_sample_method="block" and only non-eval runs use synthetic acceptance, as the sibling kimik3_fp4_b300_vllm_mtp.sh (which explicitly documents this exact hazard) still does.

Extended reasoning...

Old script: if [ "${EVAL_ONLY:-false}" = "true" ] selected rejection_sample_method "block", else "synthetic". New script (lines 70-73) builds SPEC_ARGS unconditionally with "rejection_sample_method":"synthetic","synthetic_acceptance_length":4.0 regardless of EVAL_ONLY. Later (line 144) if [ "${EVAL_ONLY:-false}" = "true" ]; then run_eval still runs the accuracy eval against a server started with synthetic acceptance, so every draft token is accepted without checking target logits, making eval scores meaningless/inflated for CONC<=4 (the only branch where SPEC_ARGS is set) — exactly the bug the b300 sibling script's comment warns against.

Verification: normal. The diff removes the EVAL_ONLY guard that previously selected rejection_sample_method "block" for eval runs. New lines 70-73 unconditionally build SPEC_ARGS with "rejection_sample_method":"synthetic","synthetic_acceptance_length":4.0 (the CONC<=4 arm), and line 144 still runs run_eval --port "$PORT" when EVAL_ONLY=true. So an EVAL_ONLY run at CONC<=4 now serves with…

Comment on lines +96 to +99
OFFLOAD_ARGS=()
if agentic_kv_offload_enabled; then
CPU_BYTES_PER_RANK=$(( TOTAL_CPU_DRAM_GB * 1000 * 1000 * 1000 / TOTAL_RANKS ))
OFFLOAD_ARGS=(--kv-transfer-config "{\"kv_connector\":\"SimpleCPUOffloadConnector\",\"kv_role\":\"kv_both\",\"kv_connector_extra_config\":{\"cpu_bytes_to_use_per_rank\":$CPU_BYTES_PER_RANK,\"lazy_offload\":false}}")

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.

🟡 (optional) KV_OFFLOAD_BACKEND is no longer validated or dispatched on: the old case statement (vllm-simple vs lmcache vs error) is gone, so any non-empty, non-"none" value silently produces the same SimpleCPUOffloadConnector config, ignoring the requested backend. Fix: re-add a check that KV_OFFLOAD_BACKEND equals the supported value(s) for this script (e.g. "vllm-simple") and error otherwise, instead of unconditionally building OFFLOAD_ARGS whenever agentic_kv_offload_enabled is true.

Extended reasoning...

benchmark_lib.sh's sourced validation (lines 88-109) only checks KV_OFFLOADING is none/dram and KV_OFFLOAD_BACKEND is non-empty when dram; it never checks the backend name. Previously this script's own case/esac (removed) rejected unsupported names like a typo or "lmcache" (which this script no longer implements) with an explicit error. Now, if KV_OFFLOAD_BACKEND=lmcache or any other non-empty string is passed, agentic_kv_offload_enabled() (line 97) returns true and the script silently builds the vllm-simple SimpleCPUOffloadConnector config anyway, running a benchmark under a different KV-offload mechanism than what was requested/labeled, with no error.

Verification: nit. Factually accurate: the diff removes the case "${KV_OFFLOAD_BACKEND:-}" in vllm-simple)...lmcache)...*) echo "Error: unsupported KV_OFFLOAD_BACKEND"...esac dispatch. The replacement at kimik3_fp4_mi355x_mtp.sh:96-100 unconditionally builds SimpleCPUOffloadConnector whenever agentic_kv_offload_enabled is true and never reads KV_OFFLOAD_BACKEND. The sourced validation in… | Severity:…

Comment on lines +69 to +83
SPEC_ROWS=1
if [ "$CONC" -le 4 ]; then
SPEC_NUM_TOKENS="${SPEC_NUM_TOKENS:-8}"
SPEC_ROWS=$(( SPEC_NUM_TOKENS + 1 ))
SPEC_ARGS=(--speculative-config "{\"model\":\"Inferact/Kimi-K3-DSpark\",\"num_speculative_tokens\":$SPEC_NUM_TOKENS,\"method\":\"dspark\",\"attention_backend\":\"TRITON_MLA\",\"kv_cache_dtype\":\"fp8\",\"draft_sample_method\":\"probabilistic\",\"rejection_sample_method\":\"synthetic\",\"synthetic_acceptance_length\":4.0}")
MAX_NUM_SEQS=1
MAX_BATCHED_TOKENS=8192
DCP_SIZE=1
else
MAX_NUM_SEQS=$(( CONC + CONC / 4 ))
if [ "$MAX_NUM_SEQS" -gt 80 ]; then MAX_NUM_SEQS=80; fi
MAX_BATCHED_TOKENS=16384
DCP_SIZE=8
fi
export DCP_SIZE

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.

🟡 (optional) DCP_SIZE is now unconditionally derived from CONC (1 or 8) instead of honoring the DCP_SIZE env var the workflow sets from configs/amd-master.yaml's dcp-size field, so that field silently has no effect (base script used DCP_SIZE="${DCP_SIZE:-8}", respecting the passed-in value). Fix: default from the incoming ${DCP_SIZE:-...} env var per branch instead of hardcoding, so config edits to dcp-size actually change server behavior instead of being silently discarded.

Extended reasoning...

benchmark-tmpl.yml sets env DCP_SIZE from inputs.dcp-size, itself populated from amd-master.yaml's per-arm dcp-size field via generate_sweep_configs.py (lines ~322/957/1052). Before this diff the script did DCP_SIZE="${DCP_SIZE:-8}", so that config value drove --decode-context-parallel-size. Now lines 74-82 always set DCP_SIZE=1 (CONC<=4) or DCP_SIZE=8 (CONC>4) regardless of the env var, and line 83 exports the overwritten value. Currently both yaml arms happen to match, masking the bug, but any future arm that sets a different dcp-size (e.g. testing dcp-size=4 at high CONC) will silently run with 8 instead, with no warning, and result metadata (via benchmark_lib.sh's "dcp_size": ${DCP_SIZE:-1}) will misleadingly report the actually-used value as if it were intentional.

Verification: nit. The factual claim is correct: the new script overwrites DCP_SIZE unconditionally rather than honoring the env var. In the diff, the CONC branch sets DCP_SIZE=1 and the else branch sets DCP_SIZE=8, followed by export DCP_SIZE; there is no ${DCP_SIZE:-...} fallback anywhere, unlike the base's DCP_SIZE="${DCP_SIZE:-8}". The env var really is plumbed from config:… | nit. The env-var…

Signed-off-by: Sirra <asirra@amd.com>
@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Stale Bugbot comment from a previous run.

Comment thread benchmarks/single_node/agentic/kimik3_fp4_mi355x_mtp.sh
Signed-off-by: Sirra <asirra@amd.com>
@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Signed-off-by: Sirra <asirra@amd.com>
Signed-off-by: Sirra <asirra@amd.com>
Signed-off-by: Sirra <asirra@amd.com>
Signed-off-by: Sirra <asirra@amd.com>
Signed-off-by: Sirra <asirra@amd.com>

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Want higher recall? High effort reviews run extra passes and find more bugs. A team admin can switch effort levels in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit ec99717. Configure here.

Comment thread benchmarks/single_node/agentic/kimik3_fp4_mi355x_mtp.sh

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agentx AgentX benchmarks, recipes, and infrastructure AMD

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

2 participants