Skip to content

[ROCm][Perf][Kimi-K3] Accumulate the latent-MoE up-projection in aiter a16w16 atomic - #58944

Draft
nsusanto wants to merge 1 commit into
vllm-project:mainfrom
nsusanto:rocm-k3-upproj-atomic-accumulate
Draft

nsusanto wants to merge 1 commit into
vllm-project:mainfrom
nsusanto:rocm-k3-upproj-atomic-accumulate

Conversation

@nsusanto

@nsusanto nsusanto commented Sep 27, 2026 •

Copy link
Copy Markdown

Purpose

The sharded latent-MoE tail adds each rank's routed up-projection into the shared-expert partial with hidden_shard.addmm_(latent, up_proj_shard.T). On MI355X this is hipBLASLt Cijk_..._MT16x16x512, 8.57 us per layer at decode (M=16, N=896, K=3584). This PR runs it through aiter's gemm_a16w16_atomic with accumulate=True, which adds into hidden_shard (a column slice of [M, 7168]) in place: 4.35 us per layer.

Per layer-step, rank 0, 1k/1k c16 decode trace:

Kernel Before (us) After (us)
Cijk_..._MT16x16x512 (addmm_) 8.57 -
_gemm_a16_w16_atomic_kernel (16x32x128, split-K 14) - 4.35

Depends on ROCm/aiter#5895 (accumulate=True);

Test Plan

lm_eval \
  --model local-completions \
  --model_args "model=/data/Kimi-K3,base_url=http://localhost:8001/v1/completions,num_concurrent=64,max_retries=3,tokenized_requests=False,tokenizer_backend=None,trust_remote_code=True" \
  --tasks gsm8k \
  --num_fewshot 5 \
  --seed 42 \
  --output_path /app/lm_eval_out --log_samples

Server command:

#!/bin/bash

export VLLM_ROCM_USE_AITER=1
export SAFETENSORS_FAST_GPU=1
# Must agree with VLLM_ROCM_USE_AITER_MOE_SITUV2_A8W4 (both 1 -> a8w4 routed experts).
export AITER_SITUV2_A8W4=1
export VLLM_ROCM_USE_AITER_MOE_SITUV2_A8W4=1
export AITER_BF16_FP8_MOE_BOUND=0
export VLLM_USE_BREAKABLE_CUDAGRAPH=0
export VLLM_USE_RUST_FRONTEND=1
vllm serve /data/Kimi-K3 \
  --trust-remote-code \
  --port 8001 \
  --moe-backend auto \
  --tensor-parallel-size 8 \
  --load-format auto \
  --gpu-memory-utilization 0.95 \
  --mm-encoder-tp-mode data \
  --max-num-batched-tokens 4096 \
  --enable-auto-tool-choice \
  --tool-call-parser kimi_k3 \
  --reasoning-parser kimi_k3 \
  --max-num-seqs 128 --enable-prefix-caching \
  --enable-return-routed-experts \
  --compilation-config '{"cudagraph_mode":"FULL_DECODE_ONLY","custom_ops":["+fused_rms_norm_gated"]}' \
  "$@"

Bench Command:

vllm bench serve --backend vllm --model /data/Kimi-K3 \
  --host localhost --port ${PORT:-8001} --endpoint /v1/completions \
  --dataset-name random --random-input-len 1024 --random-output-len 1024 \
  --random-range-ratio 0 --request-rate=inf --random-prefix-len 0 \
  --num-prompts 160 --max-concurrency 16 --ignore-eos --trust-remote-code

Test Results

baseline
image
using tuned kernel but with additional add kernel (SE + RE outputs)
image
using tuned kernel with addm fusion in a16w16 atomic
image

|Tasks|Version|     Filter     |n-shot|  Metric   |   |Value |   |Stderr|
|-----|------:|----------------|-----:|-----------|---|-----:|---|-----:|
|gsm8k|      3|flexible-extract|     5|exact_match|↑  |0.9636|±  |0.0052|
|     |       |strict-match    |     5|exact_match|↑  |0.9636|±  |0.0052|

Before:

============ Serving Benchmark Result ============
Successful requests:                     160       
Failed requests:                         0         
Maximum request concurrency:             16        
Benchmark duration (s):                  248.84    
Total input tokens:                      163840    
Total generated tokens:                  163840    
Request throughput (req/s):              0.64      
Output token throughput (tok/s):         658.42    
Peak output token throughput (tok/s):    688.00    
Peak concurrent requests:                32.00     
Total token throughput (tok/s):          1316.83   
---------------Time to First Token----------------
Mean TTFT (ms):                          478.38    
Median TTFT (ms):                        489.75    
P99 TTFT (ms):                           533.62    
-----Time per Output Token (excl. 1st token)------
Mean TPOT (ms):                          23.86     
Median TPOT (ms):                        23.83     
P99 TPOT (ms):                           24.20     
---------------Inter-token Latency----------------
Mean ITL (ms):                           23.83     
Median ITL (ms):                         23.86     
P99 ITL (ms):                            24.57     
==================================================

After:

============ Serving Benchmark Result ============
Successful requests:                     160       
Failed requests:                         0         
Maximum request concurrency:             16        
Benchmark duration (s):                  244.92    
Total input tokens:                      163840    
Total generated tokens:                  163840    
Request throughput (req/s):              0.65      
Output token throughput (tok/s):         668.97    
Peak output token throughput (tok/s):    704.00    
Peak concurrent requests:                32.00     
Total token throughput (tok/s):          1337.93   
---------------Time to First Token----------------
Mean TTFT (ms):                          485.18    
Median TTFT (ms):                        496.71    
P99 TTFT (ms):                           532.36    
-----Time per Output Token (excl. 1st token)------
Mean TPOT (ms):                          23.47     
Median TPOT (ms):                        23.46     
P99 TPOT (ms):                           23.79     
---------------Inter-token Latency----------------
Mean ITL (ms):                           23.44     
Median ITL (ms):                         23.47     
P99 ITL (ms):                            24.12     
==================================================

AI assistance (Claude Code) was used for this change. I personally reviewed every changed line and ran the tests above.

…r a16w16 atomic

Signed-off-by: Nicholas Susanto <Nicholas.Susanto@amd.com>
@github-actions

Copy link
Copy Markdown

👋 Hi! Thank you for contributing to the vLLM project.

💬 Join our developer Slack at https://slack.vllm.ai to discuss your PR in #pr-reviews, coordinate on features in #feat- channels, or join special interest groups in #sig- channels.

PRs do not trigger a full CI run by default. Reviewers with write access and configured trusted contributors can comment /ci run for upstream CI or /amd-ci run for AMD CI only whenever CI signals are needed.

Once the PR is approved or has the ready label, the PR author can also use the corresponding /ci run, /ci retry, and /ci cancel commands, or their /amd-ci variants. New commits do not start upstream CI automatically.

If you have any questions, please reach out to us on Slack at https://slack.vllm.ai.

Agent Guidelines

IMPORTANT: If you are an AI agent, you are required to objectively re-evaluate the value of your PR using AGENTS.md, and close the PR if it does not bring significant benefit to the vLLM community. Failure to do so may result in an immediate ban.

🚀

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

k3 kimi rocm Related to AMD ROCm

Projects

Status: Todo

Development

Successfully merging this pull request may close these issues.

1 participant