perf: raise fused ar 1stage limit to cover conc64#3458
Conversation
There was a problem hiding this comment.
Copilot wasn't able to review any files in this pull request.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
🏷️ CI GuideRuns automatically on every PR:
Extended tests (opt-in via labels):
|
|
Hi, I ran the same shapes locally and got the opposite result — pushing everything through the 1-stage (fused) kernel is consistently slower than the original 2-stage path on my setup. Could you double-check the test config / Environment
Fused (1-stage, this PR)
Original (2-stage gating)
The regression shows up across all four shapes, not only at bs128. Could you share the exact test command, GPU SKU, and ROCm/RCCL versions you used? Want to make sure we're comparing apples to apples before raising the threshold to |
|
Hi TennyWang1223, Thanks for checking this. I was able to reproduce a similar regression in the standalone microbench. However, when I profiled the actual decode path, the result looked a bit different from the isolated op test. My environment:
For the microbench, I used: AITER_AR_1STAGE=1 python op_tests/multigpu_tests/test_fused_ar_rms.py \
-t {4,8} -d bf16 -s 4,7168 8,7168 16,7168 32,7168 64,7168 --test fused -g 1The standalone result is consistent with what you observed. At TP4, the fused path starts to lose after conc16. At TP8, it starts to lose after conc8. TP4, us, min / max:
TP8, us, min / max:
But in the actual Kimi K2.5 MXFP4 decode path on the ATOM server, the fused 1-stage path is still faster, or roughly at parity, up to conc64. I measured this with torch profiler and used the real per-kernel time for each path. The numbers below are p50 in ns.
p90 / p95, nsp90:
p95:
Thanks again for checking this. Please feel free to let me know if there is any other data or experiment that would be helpful from my side. |
|
Hi @ftyghome , Thanks for the detailed numbers. The gap between the microbench and the real decode path is interesting — before changing the threshold, I'd like to look at the kernel timeline directly. Could you capture two torch.profiler traces from the Kimi K2.5 MXFP4 decode path on the ATOM server and attach them to this PR?
Ideally:
That way I can line up the per-kernel times and the surrounding ops (RMSNorm, comm overlap, etc.) and see why the standalone op test and the end-to-end path disagree. Thanks! |
|
Hi @TennyWang1223 , Thanks for following up. I have uploaded the torch profiler traces (since the files are large, I uploaded them in my Cloudflare R2 bucket): trace_fused_conc32.json.gz I used the following SQL snippet in Perfetto to extract the performance data: WITH params AS (
SELECT 32 AS sz
),
decode_name AS (
SELECT 'decode[bs=' || sz || ' tok=' || sz || ' d=' || sz || ']' AS dn
FROM params
),
d AS (
SELECT
CASE
WHEN child.name LIKE '%allreduce_fusion_kernel%' THEN 'allreduce'
WHEN child.name LIKE '%reduce_scatter_cross_device_store%' THEN 'reduce_scatter'
WHEN child.name LIKE '%local_device_load_rmsnorm%' THEN 'load_rmsnorm'
END AS kind,
child.dur
FROM slice AS parent,
descendant_slice(parent.id) AS child
WHERE parent.name = (SELECT dn FROM decode_name)
AND (child.name LIKE '%allreduce_fusion_kernel%'
OR child.name LIKE '%reduce_scatter_cross_device_store%'
OR child.name LIKE '%local_device_load_rmsnorm%')
),
ranked AS (
SELECT
kind, dur,
ROW_NUMBER() OVER (PARTITION BY kind ORDER BY dur) AS rn,
COUNT(*) OVER (PARTITION BY kind) AS n
FROM d
)
SELECT
kind,
n AS cnt,
MAX(CASE WHEN rn = (n + 1) / 2 THEN dur END) AS median_ns,
MAX(CASE WHEN rn = (90 * n + 99) / 100 THEN dur END) AS p90_ns,
MAX(CASE WHEN rn = (95 * n + 99) / 100 THEN dur END) AS p95_ns
FROM ranked
GROUP BY kind, n
ORDER BY kind;Thanks! Let me know if I can help with anything else from my side. |
|
Hi @TennyWang1223, We added a new set of experiments on MI355X with ROCm 7.2.3 to further validate the gating threshold. The updated result is consistent with our previous TP4 observation: for TP4, the 1-stage path still gives clear benefits for shapes up to We also added TP8 measurements. For TP8, the 1-stage path is beneficial up to The new e2e profiling result is shown below. We did not include Baseline: 1-stage vs 2-stage AllReduce path Median latency is reported in ns, lower is better. TP4
TP8
Overall:
Thanks again for your review. Please let me know if there is any other data you would like us to add. |
|
Hi @ftyghome, I tested this pr and compire with main branch on MI355x, but test result alse seems a little different. In tp4, after m larger then 16 (include m=16), main branch get a shorter latency, and latency seems equal in tp8, need double check |
|
Hi @TennyWang1223, Thank you for testing this on the latest main branch!
I may be missing some context here, but I guess your point is that the 1-stage / 2-stage kernels may have been further optimized on the main branch, so the 1-stage gating threshold could have changed. To double check this, I ran another round of profiling on the latest The numbers below are extracted from real e2e traces (using the SQL snippet shared in this PR). TP4
Would it be possible for you to share the benchmarking script or command you used? I can run the same benchmark on my side to make the comparison more direct. Thanks again! |
|
Hi, @ftyghome |
|
Hi @TennyWang1223 , Thanks for sharing the script! I ran your script on my MI355X machine, but the result seems different from yours and is aligned with my previous e2e profiling result. Here are the numbers I got. All 1-stageTP8
TP4
All 2-stageTP8
TP4
I also noticed that some For reference, my environment is: Both Please let me know if there is any other config I should align with your setup. |
|
Hi, @ftyghome |
Co-developed-by: Yankui Wang <yankui87@sjtu.edu.cn> Co-developed-by: Yingyi Hao <jpy794@hotmail.com>
|
Hi @TennyWang1223 , Thanks. I have the conflict resolved. |

Motivation
Currently, the gating for the all-reduce 1-stage (fused path) is total_bytes <= 128K. Under inference paths like Kimi K2.5, only bs4 goes through this path. However, actual testing shows that the 1-stage path yields performance gains across bs8, 16, 32, and 64 (with a regression at bs128), and the 1-stage kernel itself can cover bs64 and above without modification. This PR therefore raises the limit to 1M to cover the bs64 path, while ensuring the kernel can handle this size.
Test Plan
Profile Kimi K2.5 model inference and compare the performance of 1-stage and 2-stage paths.
(tested bs64 and bs128 to locate the boundary.)
Test Result