# InferenceX Articles — Full Content
> By SemiAnalysis
This file contains the full text of all articles from InferenceX (https://inferencex.semianalysis.com/blog).
It is intended for consumption by large language models and AI assistants.
---
# Ultra-High Interactivity on NVIDIA GPUs? TileRT on InferenceX
> Can TileRT software on NVIDIA GPUs compete with Cerebras, Groq LPU, and SambaNova? Batch size 1, disaggregated engine, high-throughput prefill engine, high-interactivity decode engine
- **Author**: SemiAnalysis
- **Date**: 2026-08-10
- **URL**: https://inferencex.semianalysis.com/blog/ultra-high-interactivity-on-nvidia
- **Tags**: benchmark, gpu, inference, nvidia, b200, gb300, tilert, vllm, glm5
- **Reading time**: 18 min
_Originally published on the [SemiAnalysis newsletter](https://newsletter.semianalysis.com/p/ultra-high-interactivity-on-nvidia) on August 10, 2026._
Premium-priced "fast modes" are proving that users will pay more for lower latency and faster tokens, potentially yielding higher gross margins. Frontier AI labs such as OpenAI are therefore evaluating purpose-built inference systems, including Cerebras and NVIDIA Groq LPUs, that prioritize ultra-high interactivity over maximum batched throughput. Ultra-low latency matters most in interactive workloads, including real-time assistants and full-duplex voice. [OpenAI GPT-Live](https://x.com/OpenAI/status/2080378182469857576), for example, can listen and speak simultaneously, making response delay immediately perceptible to the user.
GPUs perform exceptionally well at high throughput and low-to-medium interactivity, but their architecture is less suited for ultra-low-latency inference. An 8-GPU HGX B200 server provides a theoretical HBM memory bandwidth of 64 TB/s in aggregate. At batch size 1, GLM-5 at NVFP4 requires only approximately 21 GB of active-parameter traffic per generated token. The B200 HBM bandwidth roofline would therefore suggest up to 3,047 tokens/s/user without speculative decoding. In practice, GPUs come nowhere close to this limit.
The gap comes from latency rather than bandwidth. The traditional GPU programming model launches and synchronizes many individual kernels, whose setup and teardown overhead becomes significant at ultra-high levels of interactivity. While these latency costs are less visible at conventional serving speeds, even with CUDA graphs, they dominate as token latency approaches the sub-millisecond Time Per Output Token (TPOT) range. Furthermore, although [GPU memory bandwidth increases by roughly 2–3× each generation, memory latency has not improved at all](https://newsletter.semianalysis.com/p/vera-rubin-nvl72-vs-gb200-nvl72-inference).
While using alternative hardware is popular, there are ways to use GPUs to do this too. This is where [TileRT](https://github.com/tile-ai/TileRT)'s persistent engine comes in. TileRT statically compiles the entire decode graph into a single persistent kernel on NVIDIA GPUs, maximizing overlap across computation, memory loads and stores, and communication. On the InferenceX GLM-5 FP8 744B benchmark on a single B200 decode server, TileRT has been verified to reach up to 500 tokens/s/user, approximately 3× faster than GB300 NVL72 running traditional inference engines. Iso-cost per output token, TileRT can achieve up to 2× faster interactivity than traditional engines.
We thank the TileRT maintainers for collaborating on TileRT InferenceX benchmarks, and we are also grateful to the [vLLM community](https://vllm-project.github.io/) for their design on the V1 connector. TileRT comes from the same community maintainer organization that built the widely popular [TileLang DSL](https://github.com/tile-ai/tilelang).
With PD disaggregation, the hyperspecialized TileRT engine handles latency-sensitive decode while throughput-optimized engines such as vLLM and SGLang continue to serve prefill. The TileRT decode engine is already being deployed in production at Xiaomi for [MiMo V2.5 Pro UltraSpeed](https://mimo.mi.com/docs/en-US/news/latest/1000tps) and ZAI with [GLM 5.1 HighSpeed](https://www.tilert.ai/).
In this article we deep dive into the TileRT InferenceX results, what TileRT is, and how it composes with the existing inference ecosystem, along with the tradeoffs and challenges of TileRT. We will also elaborate on the tradeoffs of using TileRT on standard GPUs versus ultra-low-latency specialized chips like NVIDIA Groq LPU, Cerebras, and SambaNova, weighing in on whether there is potential for TileRT software running on GPUs to disrupt these specialist chips' TAM. The [SemiAnalysis Accelerator Model](https://semianalysis.com/accelerator-hbm-model/) provides quarter-by-quarter estimates of NVIDIA LPU30, LPU40, Cerebras WSE-3 and WSE-4 shipments and much more.
Click to see the full InferenceX dashboard →
## InferenceX
InferenceX is our open-source, vendor-neutral, continuously updated AI inference benchmarking and research platform. We measure leading models, inference frameworks, and hardware across the latency-throughput Pareto frontier, tracking how real-world inference performance and economics improve over time.
Our benchmark has been [widely reproduced, validated and/or supported](https://inferencemax.semianalysis.com/quotes) by almost every major buyer of compute from [Google Cloud](https://cloud.google.com/blog/products/compute/scaling-moe-inference-with-nvidia-dynamo-on-google-cloud-a4x) to [Microsoft Azure](https://blog.aks.azure.com/2025/10/24/dynamo-on-aks#enterprise-scale-inference-experiments--dynamo-with-gb200-running-on-aks) to Oracle, to Meta and many more. Furthermore, it has the support of the ML community including from vLLM, LMCache, SGLang, PyTorch, Hugging Face, and the support of major labs like OpenAI, MiniMax, ZAI, Qwen, Moonshot Kimi, etc.
Star the [InferenceX GitHub repository](https://github.com/SemiAnalysisAI/InferenceX) if you find the open-source benchmark and data useful. As previously mentioned, NVIDIA has committed to submitting verifiable Vera Rubin numbers to InferenceX. We will have Google TPUv7 results soon, and AMD has committed to MI455X UALoE72 this year too.
## Throughput vs Interactivity Curve
Every inference system must balance two competing goals.
- **Interactivity (tok/s/user)** measures how quickly a single user receives tokens, the inverse of time per output token (TPOT). It determines whether a response feels snappy or sluggish.
- **Throughput (tok/s/GPU)** measures how many tokens the system produces in total across all users. It largely determines the cost per token.
Batching increases aggregate throughput by processing more requests together, but each user typically waits longer for each token. Small batches do the opposite: they improve per-user speed while reducing the amount of useful work each GPU completes in aggregate.
A bus amortizes its cost across many passengers but makes each passenger wait for shared stops. A race car carries only one or two people and reaches the destination faster, but at much higher cost per passenger. Inference has the same trade-off: batching improves aggregate throughput and cost per token, while small batches improve per-user responsiveness. There is no one-size-fits-all operating point.
In the configuration shown below, increasing interactivity from roughly 25 to 260 tokens/s/user reduces per-GPU throughput from about 5,900 to 200 tokens/s/GPU. That is roughly a 30× reduction in aggregate throughput for a 10× increase in per-user speed.
## TileRT Results
As we describe in the next section, GPUs already perform well in high-throughput scenarios but struggle in high-interactivity ones. This weakness has created an entire market segment for dataflow chips. TileRT targets the same weakness and therefore focuses exclusively on high-interactivity operating points.
TileRT on B200 is in a class of its own. For the 8k/1k input/output token scenario, TileRT reached 340 tokens/s/user on an eight-GPU B200 node. The fastest result in the current dataset was previously 181.4 tokens/s/user on GB300 NVL72 with NVFP4 and MTP, making TileRT 1.9× faster on this metric. Of course, this is on batch size 1, where all that extra trouble to set up the complicated copper backplane in the case of the GB300 NVL72 does not come into play at all in boosting interactivity.
Meanwhile, the fastest FP8 result was 113.6 tokens/s/user on B300 with MTP, making TileRT 3.0× faster at the same precision.
At 1k/1k input/output, TileRT FP8 reached 494.2 tokens/s/user. That was 1.9× the best conventional result, at 256.3 tokens/s/user using FP4, and 3.6× the best conventional FP8 result, at 136.3 tokens/s/user. TileRT doesn't yet have FP4 support, but it is already beating non-TileRT FP4 implementations. The result is also notable because it comes from an eight-GPU B200 node rather than the 72-GPU NVLink scale-up domain of GB200 or GB300 NVL72. This comparison concerns per-user interactivity, not aggregate throughput or cost.
However, there are always tradeoffs when it comes to inference. TileRT's interactivity advantage comes with lower aggregate throughput. Conventional engines can amortize weight loads and fixed kernel costs across more users as concurrency rises. At 8k/1k input/output, the GB300 FP4+MTP point at concurrency 12 delivers approximately 240 total tokens/s/GPU while maintaining 154 tokens/s/user. TileRT delivers 160.4 total tokens/s/GPU while reaching 340 tokens/s/user.
The trade-off is therefore: TileRT provides much higher per-user speed, but the conventional GB300 point completes more aggregate work per GPU. TileRT as of publication also serves only one in-flight request per decode node, making this a deliberately specialized operating point rather than a general throughput configuration. Thus, with support only for a batch size of one user, TileRT is not just a race car, it is more like a private rocket ship with room for just one passenger. Engineering TileRT to support more passengers might be possible, but it is an ambitious goal.
For end-to-end latency, TileRT at FP8 outperforms the best previously recorded GLM-5.1 result by 4.5× at 1k/1k and 3.0× at 8k/1k. As expected, TileRT's time to first token (TTFT) is good but not exceptional. The decisive advantage comes from the decode tail: 3.01 seconds, compared with 6.54 seconds for the best NVFP4 + MTP competitor and 18.18 seconds for MI355X.
## But What Exactly is TileRT?
We briefly introduced what TileRT does and showed some benchmark results, but let's pause and explain more deeply what TileRT is and how it works. Traditional serving engines run as thousands of separate GPU kernels launched one after another. All that setup and teardown means the GPU spends a surprising amount of time waiting, and while this setup/teardown time might not matter for low-to-medium interactivity inference, it definitely does for ultra-high interactivity inference (aka low-latency inference). Worse, each kernel writes its half-finished work out to HBM. At small batch sizes this is a bigger problem, as kernels aren't large enough to amortize launch latency, synchronization, and scheduling overhead.
As mentioned earlier, when running TileRT at batch size 1 for just a single HGX H200 server (38.4 TB/s of aggregate HBM memory bandwidth), the active parameter memory bandwidth stands at 42 GB per token at MXFP8. In theory, if we were only bound by memory bandwidth, then even without speculative decoding, inference should be able to reach up to 1,000 tok/s/user interactivity. This is obviously not the case in the real world. The roadblock is that GPUs' programming and architecture model is traditionally not built for low latency. Even though memory bandwidth per GPU increases 2-3× each generation, memory latency has not improved at all, even as HBM prices continually increase.
Instead of continuously launching kernels, TileRT has the GPU continuously execute a persistent pipeline, statically compiling the whole model ahead of time into a persistent Engine Kernel: the host launches once, execution stays resident on the GPU for the whole decode lifecycle, and most runtime orchestration moves into compile time.
This is different from CUDA graphs, which capture the DAGs (directed acyclic graphs) of kernel launches and memcpys once, then replay them with a single `cudaGraphLaunch`. But the kernels themselves are still separate kernels; this boundary between kernels carries device-side costs and the on-chip state is wiped at every boundary. A CUDA graph optimizes the launching of kernels, while TileRT abolishes the kernel as the unit of execution.
Also, through decomposing work into tile-level tasks with warp and block specialization, the runtime dynamically reschedules computation, I/O, and communication in a highly overlapped way. Inside the Engine Kernel, different warp groups take on different jobs: asynchronous data movement, tensor computation, and communication overlap. Where stages used to run serially as load → barrier → compute → barrier, they now overlap at tile granularity, and intermediate results flow forward through registers, shared memory, and L2 instead of repeatedly spilling to global memory. Effectively, each CTA (Cooperative Thread Array) becomes a small heterogeneous factory rather than a uniform SIMT (Single Instruction Multiple Threads) worker.
The next optimization TileRT introduces is specialization extended to whole GPUs. Most TP frameworks assume all ranks execute identical logic synchronously, but sparse routing, Top-K selection, dynamic indexing, long-context attention, and MTP don't fit homogeneous scale-out well; they're not compute-heavy but depend on global information, so forcing every rank through them adds redundant work and synchronization amplification. So, if warps can specialize, so can GPUs. In GLM-5.1's attention layer, GPU 0 becomes a Sparse Indexer worker handling Top-K selection, sparse index construction, and routing, while GPUs 1 through 7 run the MLA workers doing RMSNorm, GEMM, flash sparse attention, and AllReduce.
Finally, instead of treating communication as an external stage, broadcasts, reductions, and synchronization execute directly inside the tile-level flow; with TileRT, an entire attention layer corresponds to a single kernel launch at the host, and execution shifts from compute → sync → compute toward a continuously overlapping compute ↔ communication ↔ compute pipeline.
## PD Disaggregated Engine with vLLM and TileRT
LLM inference consists of two distinct phases: prefill and decode. Prefill processes the input prompt in parallel and is primarily compute-intensive, making aggregate throughput the key performance metric. Decode generates tokens sequentially and repeatedly accesses the growing KV cache, making it memory-intensive and highly sensitive to per-token latency.
TileRT does not replace vLLM. vLLM remains the high-throughput prefill engine and the surrounding serving layer, including its scheduler, chunked prefill, prefix caching, OpenAI-compatible API, and operational tooling. Only latency-critical decode traffic moves to TileRT. TileRT is engineered to be a single-passenger rocket ship, and vLLM remains the plane, car, bus, and train.
The prefill and decode phases can be [disaggregated](https://arxiv.org/abs/2401.09670) into separate nodes. With disagg, one shared vLLM prefill pool can feed two entirely different decode pools.
- **Pool A: Ultra-high interactivity decode with TileRT.** Latency-critical requests pass through the TileRT PD Router, which instructs vLLM to generate the first token and marks the request with the destination TileRT node in `kv_transfer_params`.
- **Pool B: General low-to-medium interactivity decode with vLLM decode.** General traffic continues through vLLM's native disaggregation proxy to a conventional vLLM decode pool.
This is done via [vLLM's MultiConnector API](https://vllm-project.github.io/2026/07/14/vllm-tilert-pd.html) that composes the TileRTConnector with its native connector. The TileRT connector claims only marked high-interactivity traffic-class requests and becomes a no-op for everything else, meaning both traffic classes can share the same prefill server. Between the prefill and decode, TileRT uses Mooncake Transfer Engine and NIXL Transfer Engine to move KV cache. In TileRT v0.1.5, each decode node serves one in-flight request at a time. The router gates dispatch and applies back-pressure when the node is occupied.
## How does TileRT compare to Cerebras/Groq/SambaNova?
Purpose-built inference vendors identified the same execution bottleneck years ago, but encoded more of the solution in hardware. The [SemiAnalysis Accelerator Model](https://semianalysis.com/accelerator-hbm-model/) has our quarter-by-quarter estimates of NVIDIA LPU30, LPU40, Cerebras WSE-3 and WSE-4 shipments.
Groq uses deterministic, compiler-orchestrated execution and a large on-chip SRAM hierarchy. Cerebras maps computation spatially across a wafer-scale processor; the CS-3 provides approximately 900,000 cores, 44 GB of on-chip SRAM, and 21 PB/s of memory bandwidth. SambaNova maps model graphs onto reconfigurable dataflow units backed by a tiered SRAM, HBM, and DDR memory system.
The silicon differs, but the systems share the same idea: latency-sensitive inference benefits from reducing runtime scheduling, operator boundaries, synchronization, and unnecessary movement through external memory. At large batch sizes, those costs are easier to amortize. At batch size 1, they occupy a much larger share of each token's latency.
TileRT imports software analogues of several dataflow ideas: AoT scheduling, persistent execution, specialized workers, and tighter overlap between communication and computation. The resemblance is architectural rather than literal. TileRT still runs on a SIMT GPU with dynamic hardware scheduling, HBM, and a model-specific compiled schedule.
However, TileRT is still software only: dataflow is imposed on a machine that was never specially designed for it. A GPU carries dynamic warp schedulers, a SIMT model, and an HBM hierarchy, and TileRT gets its numbers by spending enormous compiler effort convincing that machinery to impersonate a spatial pipeline through statically expanded persistent kernels, hand-carved warp specialization, and per-model compilation against pinned driver stacks. Native dataflow silicon never fights its own substrate. Purpose-built accelerators encode more of the execution model in hardware and can avoid some of the overhead TileRT must hide in software. Their advantage still depends on the model, precision, memory hierarchy, compiler quality, system scale, and serving configuration. That is why Cerebras serves a dense 70B at speeds no eight-GPU node can reach regardless of scheduling: software can approach the HBM roofline, but it cannot raise it.
The market's early answer is that purity is negotiable. TileRT's decode engine is already in production behind Xiaomi's MiMo V2.5 Pro UltraSpeed and Z.ai's GLM-5.1 HighSpeed, and the deployment pattern is the tell. Neither company procured a new dataflow chip. They carved a speed tier out of the accelerator cluster they already ran, with vLLM keeping prefill, scheduling, and the API while TileRT takes over decode behind the same endpoint. Good enough on hardware you already own tends to beat architecturally pure on hardware you have to buy.
That points at the deeper structural problem: fungibility and flexibility in prefill-decode (PD) ratio.
A GPU pool is one liquid resource, excellent at prefill, excellent at high-to-medium-batch decode, and now somewhat credibly strong at ultra-interactive decode, with capacity moving between those roles as a software scheduler decision that can follow demand hour by hour. An ASIC fleet is the opposite: the ratio of speed-tier capacity to everything else is fixed in hardware the day the purchase order is signed. Changing the ratio of the physical fleet will take months to physically re-rack and re-cable. That would be fine if the workload mix were stable and known. Unfortunately, the split between users who need ordinary conversational latency and users, increasingly agents, who will pay for extreme-interactivity SLOs has a lot of different variables at play when estimating. Guess wrong with GPUs and you rebalance in software. Guess wrong with dedicated silicon and you either strand capital in idle speed machines or turn away the exact premium traffic you bought them for. On top of that, requirements may shift over time, so a correct guess will only be right for a limited period of time.
Going back to the shared prefill pool mentioned earlier, providers do not need to pay the TileRT premium for all traffic. General requests can stay on throughput-optimized vLLM or SGLang decode pools, while only latency-critical requests are routed to the TileRT decode pool.
None of this kills the top of the speed market. The SRAM roofline is still better, certain sizes of models still favor it, and some workloads will always want maximum tokens per second at any price. But TileRT reframes what most buyers need: not a speed machine, but a speed tier, provisioned dynamically out of the fleet they were going to own anyway. Cerebras, Groq, and SambaNova are no longer competing against a clumsy kernel-launcher. They are competing against their own execution model, running on fungible hardware, reallocated by a config file. TileRT may be a single-passenger rocket ship, but it allows providers to strap solid rocket boosters to your Metro Bus instead of having to design an entirely new launch vehicle.
## Why Is TileRT Development Slow?
GLM-5.1 is a generation behind, and has already been deprecated on mainline InferenceX. TileRT's model catalog is very limited, currently supporting GLM-5/5.1 and DeepSeek-V3.2. MiMo-V2.5-Pro-UltraSpeed is the result of a co-design partnership and has yet to be open-sourced.
TileRT inherits ASIC vendors' biggest weakness. Static ahead-of-time compilation means a tiny model catalog, hard-pinned dependencies, and real engineering effort per new architecture. There is no fully generic path. A persistent engine kernel means the model is statically expanded ahead of time into one resident program, so decisions have to be made on tile shapes, pipeline depth, buffer residency across registers/shared memory/L2, how warp groups split between loading, compute, and communication, where collectives get fused into the tile flow, and which GPUs take specialized roles like GLM-5.1's dedicated sparse indexer rank. Change the attention mechanism or the routing scheme and much of that schedule is invalidated. Dataflow chips also face this same issue; good compilers can be notoriously difficult to create.
Work is being done to simplify this, especially as software development can be accelerated with AI. [TileOPs](https://github.com/tile-ai/TileOPs) is intended to reduce this burden. Each operator is declared in a machine-readable manifest specifying its signature, workloads, and roofline model. The manifest drives code generation, testing, and benchmarking against hardware bounds rather than only against earlier implementations.
AI coding agents accelerate tuning within known templates, but novel transformations still require expert judgment. A monolithic persistent kernel also reduces the usefulness of conventional per-kernel profiler timelines, making automated feedback loops more difficult.
## Next steps with TileRT and InferenceX
We are actively working on moving TileRT benchmarking from InferenceX's single-turn 8k/1k to our new agentic coding benchmark, which we call AgentX. This scenario replays real Claude Code and Codex traces with long-context, multi-turn requests, realistic subagent activity, and dynamic tool-use delays. Its median input length is 140k tokens, while the theoretical median cache-hit rate roofline reaches 99.2%.
This workload will test the entire TileRT and vLLM system, not just decode speed, including incremental KV transfer, prefix-cache reuse, cache retention and offloading, routing, and scheduling. The critical question is whether TileRT can transfer only the newly introduced context between turns while preserving its ultra-high interactivity advantage.
The second step is to move beyond just batch size one. We will also benchmark TileRT at batch sizes 2, 4, and 8. The goal is to map its throughput-interactivity Pareto frontier and identify the point at which the persistent Engine Kernel's latency advantage begins to flatten.
The full perf-per-TCO analysis — TileRT's cost per million output tokens at ultra-high interactivity compared against decode at normal lower-interactivity operating points, using the [SemiAnalysis AI Cloud TCO Model](https://semianalysis.com/ai-cloud-tco-model/) as the capex and opex baseline — is available to subscribers in the [full article on the SemiAnalysis newsletter](https://newsletter.semianalysis.com/p/ultra-high-interactivity-on-nvidia).
Click to see the full InferenceX dashboard →
{`{
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [
{
"@type": "Question",
"name": "How fast is TileRT on NVIDIA B200 compared to conventional inference engines?",
"acceptedAnswer": {
"@type": "Answer",
"text": "On the InferenceX 8k/1k input/output scenario, TileRT reached 340 tokens/s/user on an eight-GPU B200 node, against a previous best of 181.4 tokens/s/user on GB300 NVL72 with NVFP4 and MTP, making TileRT 1.9x faster. Against the fastest FP8 result of 113.6 tokens/s/user on B300 with MTP, TileRT is 3.0x faster at the same precision. At 1k/1k, TileRT FP8 reached 494.2 tokens/s/user, 1.9x the best conventional result of 256.3 tokens/s/user using FP4 and 3.6x the best conventional FP8 result of 136.3 tokens/s/user."
}
},
{
"@type": "Question",
"name": "What is TileRT and how does it differ from CUDA graphs?",
"acceptedAnswer": {
"@type": "Answer",
"text": "TileRT statically compiles the entire decode graph ahead of time into a single persistent Engine Kernel on NVIDIA GPUs. The host launches once and execution stays resident on the GPU for the whole decode lifecycle, moving most runtime orchestration into compile time. CUDA graphs capture the directed acyclic graph of kernel launches and memcpys once and replay it with a single cudaGraphLaunch, but the kernels remain separate, so each kernel boundary still carries device-side cost and wipes on-chip state. A CUDA graph optimizes the launching of kernels, while TileRT abolishes the kernel as the unit of execution."
}
},
{
"@type": "Question",
"name": "What is the trade-off for TileRT's higher interactivity?",
"acceptedAnswer": {
"@type": "Answer",
"text": "TileRT's interactivity advantage comes with lower aggregate throughput. At 8k/1k, the GB300 FP4 plus MTP point at concurrency 12 delivers approximately 240 total tokens/s/GPU while maintaining 154 tokens/s/user, whereas TileRT delivers 160.4 total tokens/s/GPU while reaching 340 tokens/s/user. TileRT as of publication serves only one in-flight request per decode node, making this a deliberately specialized operating point rather than a general throughput configuration."
}
},
{
"@type": "Question",
"name": "Does TileRT replace vLLM?",
"acceptedAnswer": {
"@type": "Answer",
"text": "No. vLLM remains the high-throughput prefill engine and the surrounding serving layer, including its scheduler, chunked prefill, prefix caching, OpenAI-compatible API, and operational tooling. Only latency-critical decode traffic moves to TileRT, via vLLM's MultiConnector API composing the TileRTConnector with the native connector. One shared vLLM prefill pool can feed both a TileRT ultra-high interactivity decode pool and a conventional vLLM decode pool. TileRT uses Mooncake Transfer Engine and NIXL Transfer Engine to move KV cache between prefill and decode."
}
},
{
"@type": "Question",
"name": "Can TileRT on GPUs displace Cerebras, Groq, and SambaNova?",
"acceptedAnswer": {
"@type": "Answer",
"text": "TileRT imports software analogues of dataflow ideas including ahead-of-time scheduling, persistent execution, specialized workers, and tighter compute-communication overlap, but it still runs on a SIMT GPU with dynamic hardware scheduling and an HBM hierarchy. Software can approach the HBM roofline but cannot raise it, which is why Cerebras serves a dense 70B at speeds no eight-GPU node can reach. The structural argument favoring GPUs is fungibility: a GPU pool can shift capacity between prefill, general decode, and ultra-interactive decode as a scheduler decision, while an ASIC fleet fixes that ratio in hardware on the day the purchase order is signed."
}
},
{
"@type": "Question",
"name": "Why is TileRT development slow?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Static ahead-of-time compilation means a tiny model catalog, currently GLM-5/5.1 and DeepSeek-V3.2, plus hard-pinned dependencies and real engineering effort per new architecture. A persistent engine kernel requires up-front decisions on tile shapes, pipeline depth, buffer residency across registers, shared memory and L2, how warp groups split between loading, compute and communication, where collectives fuse into the tile flow, and which GPUs take specialized roles. Changing the attention mechanism or routing scheme invalidates much of that schedule. TileOPs is intended to reduce this burden by declaring each operator in a machine-readable manifest that drives code generation, testing, and benchmarking against hardware bounds."
}
}
]
}`}
---
# Kimi K3: The Manos, The Mythos, The Legendos
> Kimi K3's architecture: compressed memory, attention across depth, latent expert routing, and serving performance
- **Author**: SemiAnalysis
- **Date**: 2026-08-03
- **URL**: https://inferencex.semianalysis.com/blog/kimi-k3-the-manos-the-mythos-the
- **Tags**: inference, benchmark, gpu, kimi, vllm, nvidia, b200, b300, dynamo
- **Reading time**: 25 min
_Originally published on the [SemiAnalysis newsletter](https://newsletter.semianalysis.com/p/kimi-k3-the-manos-the-mythos-the) on August 3, 2026._
Kimi K3 took the world by storm at its announcement, sweeping leaderboards and establishing itself as the open frontier model. While the community is eager to understand how Kimi K3 works, many have been surprised by the unconventional techniques driving its performance. This article serves as a primer to understanding the core techniques of the Kimi K3 model architecture.
## Kimi Delta Attention
Kimi Delta Attention (KDA) is the linear attention layer in Kimi K3's hybrid attention mechanism. We trace the origins of KDA, starting from linear attention, DeltaNet, Gated DeltaNet (GDN), then to KDA.
### Linear Attention
The derivation of linear attention stems from **removing the softmax operation in the standard softmax attention**. Below we compare the iterative inference formulas, which show the computation of the output vector at token position t:
By removing the softmax operation, we can reorder the operations and reduce the computation complexity of attention from quadratic to linear:
The new equations are as follows:
Vectors q, k, v, have dimensions _L_ by _d_. The computational complexity of both equations are O(*Ld*²), thereby making the computation linear. Comparing the new equations with softmax attention's equation, we see that **softmax attention requires accessing all past key and value vectors**, whereas **linear attention compresses all past key and value vectors** **into one hidden state S**.
We reinterpret the new equations as an **online learning objective**. We view matrix S as an associative memory that stores the associations between key vector k and value vector v, and we retrieve v by multiplying S with k. We can then interpret the first equation as **continuously updating the matrix S at every position to perfect the retrieval**. Finally, we can interpret the vt @ kt.T term as the gradient of loss function -(S @ kt.T) @ vt with respect to S.
$$
\begin{aligned}
\textbf{Objective:}\quad
\mathcal{L}_t(\mathbf{S})
&=
-\left\langle
\mathbf{S}\mathbf{k}_t,\mathbf{v}_t
\right\rangle
\\[8pt]
\textbf{SGD update:}\quad
\mathbf{S}_t
&=
\mathbf{S}_{t-1}
-\beta_t\nabla\mathcal{L}_t(\mathbf{S}_{t-1})
\\
&=
\mathbf{S}_{t-1}
+\beta_t\mathbf{v}_t\mathbf{k}_t^\top
\end{aligned}
$$
### DeltaNet
Under the online learning objective view, we see the values of matrix S will grow unboundedly: old and new information gets blurred together in S as the sequence grows, which destabilizes learning. Without softmax giving well-scaled and bounded outputs, linear attention typically lags behind softmax attention on long-range recall tasks.
DeltaNet improves upon linear attention by **changing the loss function to minimizing the L2 norm of the value retrieval**. Unlike linear attention's loss function, DeltaNet's loss function regularizes the growth of S. This creates a new matrix S update rule, the Delta Rule, as below:
$$
\begin{aligned}
\textbf{Objective:}\quad
\mathcal{L}_t(\mathbf{S})
&=
\frac{1}{2}
\left\|
\mathbf{S}\mathbf{k}_t-\mathbf{v}_t
\right\|^2
\\[6pt]
\textbf{SGD update:}\quad
\mathbf{S}_t
&=
\mathbf{S}_{t-1}
-\beta_t\nabla\mathcal{L}_t\!\left(\mathbf{S}_{t-1}\right)
\\
&=
\mathbf{S}_{t-1}
-\beta_t
\left(
\mathbf{S}_{t-1}\mathbf{k}_t-\mathbf{v}_t
\right)
\mathbf{k}_t^\top
\end{aligned}
$$
Source: [Linear Attention and Beyond (Interactive Tutorial with Songlin Yang)](https://www.youtube.com/watch?v=d0HJvGSWw8A)
The Delta Rule becomes the basis of DeltaNet's attention equation:
$$
\mathbf{S}_t
=
\mathbf{S}_{t-1}
-
\beta_t
\left(
\mathbf{S}_{t-1}\mathbf{k}_t-\mathbf{v}_t
\right)
\mathbf{k}_t^\top
$$
Conceptually, Sₜ-1 @ kₜ - vₜ represents the associations irrelevant to the current key and value, and DeltaNet performs targeted removal of those associations.
### Gated DeltaNet
GDN and KDA are adaptations of DeltaNet. Gated DeltaNet applies the LSTM forget gate _alpha_ on the matrix S, allowing the model to control memory lifespan with weight decay. KDA further expands _alpha_ into a diagonal matrix that enables fine-grained per-channel memory decay and positional awareness.
### FlashKDA Algorithm
Moonshot developed FlashKDA, their custom kernels for KDA, and [open-sourced it](https://github.com/MoonshotAI/FlashKDA/tree/master). Here we explain the algorithm and derive the arithmetic intensity.
#### Algorithm
First, let's start from an alternative formulation of the recurrence formula:
```text
u_t = beta_t * (v_t - (D_t @ S_t-1).T @ k_t)
S_t = D_t @ S_t-1 + k_t @ u_t.T
o_t.T = q_t.T @ S_t
```
Here, D_t is the diagonal matrix of the alpha forget gate, and u_t is the delta in the delta rule. For decode, the kernel roughly follows the formula. For prefill, we parallelize the operation by unrolling the recurrence formula in chunks of tokens, in order to efficiently execute the operations on GPUs. Assume we unroll token i to j, and the starting state is S_i-1, we get:
```text
S_j = D_j:i @ S_i-1 + sum(D_j:t+1 @ k_t @ u_t.T, t=i:j)
o_j.T = q_j.T @ S_j
= q_j.T @ D_j:i @ S_i-1 + sum(q_j.T @ D_j:t+1 @ k_t @ u_t.T, t=i:j)
```
D_j:i refers to the cumulative decay from token i to j: D_j @ D_j-1 @ D_j-2 @ … @ D_i. In FlashKDA's matrix form, the formula becomes:
```text
S_out = D_j:i @ S_in + K_restore.T @ U
M_qk = tril(Q_decay @ K_inv.T)
O = Q_decay @ S_in + M_qk @ U
```
The vector to matrix mapping is as follows:
- S_in refers to the state at the starting position of a chunk
- S_out refers to the state at the end position of a chunk
- K_restore is the matrix form of D_j:t+1 @ k_t
- Q_decay is the matrix form of q_j.T @ D_j:i
- Q_decay @ K_inv.T the matrix form of q_j.T @ D_j:t+1 @ k_t, derived from (q_j.T @ D_j:i) @ (D_t:i^-1 @ k_t)
- M_qk is the causal mask, so it's a lower triangular matrix
U is the matrix form of unrolled u_t. To compute this, we apply UT transform and compute the following:
```text
B = Diag(beta) @ (V - K_decay @ S_in)
L = StrictTril(Diag(beta) @ K_decay @ K_inv.T)
U = (I + L)^-1 @ B
```
Please consult [Songlin Yang's blog post](https://sustcsonglin.github.io/blog/2024/deltanet-2/) and [Kimi Linear paper section 3.1](https://arxiv.org/abs/2510.26692) for the full derivation. Note that here U corresponds to the pseudo-value term in the Kimi Linear paper.
Implementation-wise, FlashKDA launches 2 kernels: K1 and K2. K1 prepares chunk-level tensors in parallel, including:
```text
a = exp2(cumsum(g))
K_decay = Diag(a) @ K
Q_decay = Diag(a) @ Q
K_inv = Diag(a)^-1 @ K
K_restore = a[-1] * K_inv
L = StrictTril(Diag(beta) @ K_decay @ K_inv.T); INV = (I + L)^-1
M_qk = tril(Q_decay @ K_inv.T)
```
Here `a` is the cumulative decay, where each element is the cumulative decay at a token position.
K2 performs chunk-level recurrent computation:
```text
U = INV @ Diag(beta) @ (V - K_decay @ S)
O = Q_decay @ S + M_qk @ U
S = Diag(a[-1]) @ S + K_restore.T @ U
```
#### Complexity Analysis
Here we analyze the complexity of an attention head. For decode, the critical path computations are:
- D_t @ S_t-1: Element-wise multiplication, D × D
- S_t-1.T @ k_t: D × D × 1
- k_t @ u_t.T: D × 1 × D
- q_t.T @ S_t: 1 D × D
The decode kernel roughly performs `7*D²` FLOPs.
Reading and writing the FP32 recurrent state dominates the memory traffic, so the memory traffic is roughly `8*D²` bytes.
For prefill, the critical path of K1 is at computing L, INV, and M_qk.
- L: C × D × C
- INV: [Neumann factorization](https://github.com/MoonshotAI/FlashKDA/blob/1ce47ea3bb22c84eb9cc665028399cf35e8ffb0b/csrc/smxx/utils.cuh#L190), performs 6 C × C × C matrix multiplications
- M_qk: C × D × C
For K2,
- K_decay @ S: C × D × D
- Q_decay @ S: C × D × D
- M_qk @ U: C × C × D
- INV @ B: C × C × D
- K_restore.T @ U: D × C × D
Combining K1 and K2, FlashKDA performs `12*C^3 + 8*C²*D + 6*C*D²` FLOPs. Since we analyzed at the chunk level (chunk size C), assuming sequence length T `>>` C, the overall FLOPs is `T/C * O(C*D²) = O(T*D²)`.
For memory traffic:
- K1 read Q, K, g: C × D
- K1 write and K2 read Q_decay, K_decay, K_restore: C × D
- K1 write and K2 read INV, M_qk: C × C
- K2 read V and write O: C × D
- K2 read and write S once per kernel: D × D
In total, FlashKDA accesses `3 * 2*C*D + 2 * (3 * 2*C*D + 2 * 2*C*C) + 2 * 2*C*D = 8*C² + 22*C*D` bytes. At the kernel level, it accesses `T/C * (8*C² + 22*C*D) + 8*D² ~ O(TC + TD + D²)`.
This concretely shows that the computational complexity of KDA:
- Prefill: Linear to sequence length for both computation and memory
- Decode: Constant to sequence length for both computation and memory
## Kimi Linear
Moonshot trained Kimi Linear models as proof of concept for their KDA design, so we can infer Kimi K3's architecture design from Kimi Linear. Comparing the K3 release tech blog with Kimi Linear, we see Kimi K3 shares the shared expert count, the hybrid linear attention ratio, and the general attention module design.
The diagram above shows the operations performed on the inputs of KDA. For the query, key, and value, we apply linear transformation and short convolution. Applying short convolution effectively capturing local token dependencies, and doing a left padding convolution avoids breaking causality. We additionally apply L2 norm to the query and key to stabilize the eigenvector of the transition and the output matrices. For the decay memory gates, alpha is a low rank projection, and beta is a down projection. The KDA output is normalized per head and controlled by an output forget gate, implemented as a linear transformation in K3, instead of a low rank projection in Kimi Linear. Finally, we apply a linear layer to mix per-head information.
Kimi Linear interleaves KDA with full attention Multi-head Latent Attention (MLA). Kimi Linear showed that 3:1 is the ideal KDA to MLA ratio that balances performance and efficiency. KDA also serves as a strong position-aware operator, replacing the RoPE in MLA.
Keeping MLA as full attention is an interesting choice, as all other open weight models move to Grouped Query Attention (GQA). MLA uses an absorption trick to reduce the computation of a decode step at the cost of extra computation during the prefill step. This is a sensible trade-off for decode-dominant reasoning workloads, but for prefill-dominant agentic workloads, extra computation becomes a high cost with little benefits. As a result, all frontier open weight models use GQA-based attention mechanisms: GLM 5.2 DeepSeek Sparse Attention, DeepSeek V4 Compressed Sparse Attention, MiniMax M3 MiniMax Sparse Attention, and MiMo V3 HySparse are all based on GQA. We suspect Moonshot's future models such as Kimi K4 will feature attention mechanisms that replace MLA.
## KV Cache Efficiency
We argue that **one should not infer KV cache efficiency solely based on KV cache space complexity**. KV cache size is not a standalone factor but a property of the model design: no open weight models are released with static KV cache compression techniques, and model architecture inference efficiency affects KV cache efficiency. The effects of KV cache size also vary, depending on the total memory capacity of a deployed model instance. For example, deploying a model with wide expert parallelism has very different memory profiles than doing so with tensor parallelism, which affects the memory capacity left for KV cache. Thus, we propose considering both the model architecture system efficiency and the KV cache size to understand the KV cache efficiency, and we quantify that with **KV throughput**.
### KV Throughput
KV throughput is defined as KV cache size divided by the prefill time (Time to first token), given a specific sequence length. KV throughput represents the minimum bandwidth required to reliably serve a model with PD disaggregation, but it is also a good proxy for understanding KV cache efficiency. Prefill time encapsulates the efficiency of the model architecture, and as the sequence length increases, we will see the memory-bounded and the compute-bounded situations. As shown in the table below, we can see the benefits of hybrid linear attention become more pronounced as sequence length increases.
This is also a good way to understand the bandwidth requirements of KV cache offloading to different memory tiers in a cluster.
### KV Cache Residency
The location where KV cache is stored follows the memory hierarchy. First, KV cache resides in HBM, the fastest memory in a GPU cluster, consuming whatever capacity is left by model weights and activations. As KV cache size exceeds the HBM capacity, it spills into server DRAM, a higher capacity but lower bandwidth memory pool. Finally, when KV cache exceeds DRAM capacity, it spills to disk storage such as SSD. This is analogous to the computer architecture cache hierarchy: register, cache memory, main memory, disk storage.
The analogy continues for memory coherency. Popular distributed KV cache framework Mooncake Store supports write-through and write-back policies for KV cache loading. Mooncake Store features a distributed KV cache pool that makes all KV cache visible to all workers. Implementing write-through policy between DRAM and the lower-level distributed KV cache pool offers multiple benefits in multi-node scenarios, including sharing prefix cache across nodes, avoid KV cache duplication for tensor parallelized MLA, and KV cache redundancy when a node goes down.
### KDA Prefix Cache Management
At each token position in a request, Kimi K3 KDA's recurrent state is fixed in size, whereas standard attention KV cache grows with sequence length. This KV cache space reduction comes at the cost of complicating prefix caching, especially when Kimi K3 is a hybrid attention of KDA and MLA.
Roughly speaking, modern inference engines identify prefix cache hits by matching the longest token prefix in the existing cache.
Identifying the longest prefix becomes a problem for linear attentions like KDA. Without prior knowledge of where the boundary of a prefix is, we will have to cache KDA's recurrent state at every token position. This means every token has a cache, and the KV cache memory usage regresses to growing with sequence length, defeating the purpose of using linear attention. To tackle this problem, Moonshot saves recurrent states at a coarse granularity, e.g. vLLM caches every 32K tokens. vLLM additionally caches at prompt boundaries, since for agentic workloads, a new turn typically starts at the end of a prompt.
This shows that even though linear attentions like KDA greatly reduce KV cache memory consumption, **realistically during serving, they do not consume a constant amount of KV cache memory**.
## Attention Residuals
### Residual Connections
Residual connections are one of the key innovations that allowed us to build bigger deep neural networks through scaling model depth. The deeper the neural network, the more expressive they become but training them naively is hard. Signals from the earlier layer need to be preserved till the last layer and gradient need to survive from output to first without vanishing.
Instead of modeling whole networks as a single function, passing information only through nonlinear transformations, residual networks connect smaller blocks with identity paths. Each block fᵢ learns a change to its input xᵢ, given by the recurrence:
$$
x_{l+1} = x_l + f_l(x_l)
$$
The identity mapping allows features to carry from shallower units to any deeper unit and gives the gradient a path highway so they do not vanish.
$$
\frac{\partial x_{l+1}}{\partial x_l} = I + f_l'(x_l)
$$
While residual connections allow us to build deeper networks, they come with challenges.
Early layers heavily influence residual stream to have effect on final output. Because of which residual stream has irreversible information loss with increasing depth. Later layers increase output gain to have effect on this modified residual stream which can destabilize training. Another variant like highway networks allow gating mechanisms for information flow but they suffer from the same crucial problem. Layers don't have selective access to information from earlier layers.
### Recurrence In Time and Depth
Sequence modeling dominated by recurrent neural networks had the same recurrence formulation.
$$
h_{t+1} = h_t + f(h_t, x_{t+1})
$$
Where each step has identity mapping with previous state for direct information flow and the sequence model faced the same challenge: depth in the time axis dilutes signal.
Attention machines transformer removed this constrained by retrieving any token in past with powerful and expensive attention mechanism
### Attention on residual stream
Motivated by attention mechanism in sequence modeling, kimi developed attention residual, where they take attention over depth blocks,
Standard causal self-attention computes the output of token _t_ as a weighted sum of previous token representations:
$$
\mathbf{o}_t
=
\sum_{i=1}^{t}
\alpha_{i\rightarrow t}\,\mathbf{v}_i,
\qquad
\alpha_{i\rightarrow t}
=
\frac{\phi(\mathbf{q}_t,\mathbf{k}_i)}
{\sum_{j=1}^{t}\phi(\mathbf{q}_t,\mathbf{k}_j)}
$$
Attention Residuals use the same attention mechanism, but replace the sequence dimension with the depth dimension. Instead of attending over previous tokens, each layer attends over representations produced by previous layers.
Unlike standard attention, the query is a learned parameter for each layer rather than being generated from the current token.
$$
\alpha_{i \to l}
=
\frac{\phi(\mathbf{q}_l,\mathbf{k}_i)}
{\displaystyle\sum_{j=0}^{l-1}\phi(\mathbf{q}_l,\mathbf{k}_j)}
$$
For each layer ℓ, we define:
$$
\mathbf{q}_l=\mathbf{w}_l,
\qquad
\mathbf{k}_i=\mathbf{v}_i=
\begin{cases}
\mathbf{h}_1, & i=0,\\
f_i(\mathbf{h}_i), & 1\le i
Attention residual allows the model to get fine grained control over what inputs to pick from past layers making the model more expressive.
### Block Attention Residuals
Attention residual need to all past layer outputs for attention. For large models distributed over many GPUs this creates O(Ld) communication overhead. To overcome this block attention residual dividends layers L into N blocks of S layers. Block AttnRes applies attention over completed block outputs and for current block its evolving partial sum.
Block Attention has minimal tread over full attention residual but they cut down communication from O*(Ld)* to O*(Nd).*
Let bₙⁱ denote the partial sum over the first _i_ layers in block _n_, such that
$$
\mathbf{b}_n=\mathbf{b}_n^S,
\qquad
\mathbf{b}_0=\mathbf{h}_1.
$$
For the _i_-th layer in block _n_, the available block representations are
$$
\mathbf{V}_l=
\begin{cases}
[\mathbf{b}_0,\mathbf{b}_1,\ldots,\mathbf{b}_{n-1}]^\top,
& i=1,\\[4pt]
[\mathbf{b}_0,\mathbf{b}_1,\ldots,\mathbf{b}_{n-1},
\mathbf{b}_n^{i-1}]^\top,
& i>1.
\end{cases}
$$
Unlike standard attention, the query is not input-dependent. Each layer learns a query vector:
$$
\mathbf{q}_l=\mathbf{w}_l
$$
Attention weights over the available block representations are computed as
$$
\boldsymbol{\alpha}_l
=
\operatorname{softmax}
\left(
\mathbf{K}_l\mathbf{w}_l
\right).
$$
The output is the weighted sum of previous layer representations
$$
\mathbf{h}_l
=
\boldsymbol{\alpha}_l^\top\mathbf{V}_l.
$$
Rather than depending only on the residual stream to preserve information, Attention Residuals give every layer direct, selective access to earlier representations. This block based variant of attention residuals greatly reduces communication overhead while having competitive performance.
Block residuals show better scaling compared standard residual connection achieving 1.25× compute efficiency. Consistently lower validation loss compared to baseline and gap widening with decay phase. Unlike standard residual networks where output magnitude increases as depth increases. selective aggregation of block attention has bounded output. And consistent gradient magnitude.
### Training
Unlike standard residual networks, attention residuals need all N-1 block input for computation of the Nth layer. This becomes a problem for pipeline parallelism as all N layer blocks output need to be transferred across stages.
With clever cross stage caching and activation checkpointing, Kimi reduced overhead to only 4% compared to standard architecture for pipeline parallelism.
#### Cross-stage caching
For _P_ physical stages and _V_ virtual stages. Each block _N_ needs _C=PV_ communication for each chunk. Naively this needs transferring all accumulated blocks for each stage. This is quadratic cost growth for each physical and virtual stage
$$
\mathrm{Comm}_{\mathrm{naive}}
=
\sum_{j=1}^{C-1} jN_p \cdot d
=
\frac{C(C-1)}{2}N_p d
$$
This high communication can be reduced by caching input across virtual stages. Blocks computed in earlier layer can be stored in local memory,
For the first virtual stage all block embedding needs to be transferred in the physical stage, each completed block is stored on respective rank. For all subsequent virtual stages all cached blocks can be reused for computation. Only the block not present on rank need to be transferred for attention to residual computation.
These split communication costs for first and subsequent virtual stages. For the first virtual stage its need incur the same quadratic cost for all physical layers. In subsequent virtual stages we need cached inputs from local devices and Transfer of only PNp chunks needed cutting down total communication from O*(C)* to O*(P)*
$$
\mathrm{Comm}_{\mathrm{cached}}
=
\underbrace{\frac{P(P-1)}{2}N_p d}_{\text{first virtual stage}}
+
\underbrace{(V-1)P^2N_p d}_{\text{subsequent virtual stages}}
$$
The cutdown of communication is directly proportional to virtual stages V. Because of this for full stage of one forward and backward pass all computation and communication can be overlapped
#### Memory overhead
Due to cross stage caching all blocks are stored once across all V virtual stages. With Activation checkpointing all inter-block chunks for attention are eliminated. Each stage activation checkpoint _Pl_ matches memory size of H*l* of standard architecture and has no extra memory cost.
### Inference
Because Attention Residuals need the output of all previous blocks to compute attention, a naive implementation has excessive memory accesses. To reduce overhead, inference is split into two phases which mirror prefill and decode stages of autoregressive attention. This computation is divided into inter-block attention for completed blocks and intra-block attention for evolving attention in the running block.
#### Phase 1: Parallel Inter-Block Attention
During decoding, we have to output the completed block and the query vector learned per layer. All inter block layers simultaneously with a single batched query against the completed block representations, returning both outputs and softmax statistics which can be reused for further computation. This phase is similar to prefill phase decoding
#### Phase 2: Sequential Intra-Block Attention
This phase is analogous to the decode phase, Similar to flash attention, evolving sum can be computed with online softmax for intra blocks combined with precomputed inter block results. Which reduces redundant memory access.
With this two phase design, the IO footprint is similar to standard residual architecture, with only the addition of phase ones inter block computation, amortized by batching all queries in the block.
## LatentMoE
LatentMoE compresses the routed tokens before the dispatch operation, and then decompresses them after the aggregation operation. In Kimi K3's Stable LatentMoE, they apply an RMSNorm before the up-projection (decompressing) operation to reduce sensitivity to scale variations and improve model performance.
Here we explain the design principles behind LatentMoE regarding MoE communication. As shown in the LatentMoE paper, the communication volume is proportional to total routed tokens _t_, number of active experts _K_, and expert input dimension _d_, while being inversely proportional to the expert parallel size _E_. This is potentially the reason behind Kimi K3's latent MoE dimension size and active expert count configuration. Kimi K2 series feature 8 active experts with input dimension size 7168, so Kimi K3's latent input dimension size being 3584 (half of 7168) would allow the active expert count to double to 16 without increasing the communication volume.
However, the **ratio of communication to computation** **time** is arguably more important for estimating system efficiency (Discussions [here](https://x.com/chhillee/status/2077966168304787769) and [here](https://x.com/chhillee/status/2078130513546723531)). The ratio indicates the roofline of how well MoE kernels can overlap communication with computation at a throughput-bound regime, and **expert intermediate dimension size** is the only model configuration that affects the ratio. Specifically, increasing the expert intermediate dimension size would decrease the ratio, meaning that the theoretical maximum fraction of communication that can be hidden is higher. Here we derive the formula:
- _t_: total input tokens across the expert parallel (EP) domain
- _K_: number of active experts per token
- _N_: number of total experts
- _E_: Ranks in the EP domain
- _d_: Expert input dimension
- _m_: Expert intermediate dimension
- _P_: Aggregate bytes communicated per activation element (dispatch + combine)
- _F_: Effective FFN expert (modeled as SwiGLU) computation throughput per GPU, FLOP/s
- _B_: Effective uni-directional network bandwidth per GPU, B/s
1. Assuming uniform expert routing, each GPU is assigned _t \* K / E_ tokens
2. Assuming uniform expert routing, an average _1 / E_ tokens are local to the source GPUs, so each GPU dispatches _(t\*K/E) \* (1-1/E)_ tokens
3. Each token is a d dimensional vector, so the communication volume per token is _d \* P_
4. The communication volume per GPU is _(t\*K/E) \* (1-1/E) \* d \* P_
5. The communication time T*comm = *(t \* K \* d \* P) / (E \* B) \* (1-1/E)\_
6. The SwiGLU computation involves 3 matrix multiplications:
1. Up (First) projection: _d_ to _m_
2. Gate projection: _d_ to _m_
3. Down (Second) projection: _m_ to _d_
So the computation is `2*d*m + 2*d*m + 2*m*d = 6*d*m` FLOPs per token
7. The computation time per GPU is `T_comp = (6*d*m) * (t*K/E) / F`
8. The communication to computation time ratio is
`T_comm / T_comp`
`= ((t * K * d * P) / (E * B) * (1-1/E)) / ((6*d*m) * (t*K/E) / F)`
`= (P*F) / (6*m*B) * (1-1/E)`
We believe this formula also motivates an increase in expert intermediate dimension to 3072 in not just Kimi K2 to K3, but all recent open weight models, including DeepSeek V4 Pro, MiniMax M3, MiMo V2.5 Pro, and Inkling. As hardware improves and expert weight precision reduces to save memory capacity, the compute throughput increases, so one way of reducing the ratio is by increasing the expert intermediate dimension.
### Quantile load balancing (QB)
Many previous load balancing methods require careful hyperparameter tuning. Quantile balancing is hyperparameter free aux-loss free load balancing technique developed by Jianlin Su in [Feb 2026 blog post](https://kexue.fm/archives/11619)
Base principle QB is the same as auxfree load balancing where router biases are updated dynamically based on the system's load. But instead of updated bias by some small coefficient like aux-free lb, QB directly computes the next bias from the distribution of router scores relative to routing cutoff threshold. Bias updates become small naturally when the router balances load evenly.
QB tries to find the bias that would have approximately balanced under the current cutoffs and routing on the current batch, solving constraint optimization problems and applying these updates for the next batch. The first constraint is that each token is routed to exactly k experts. The second constraint is a batch of m tokens each picks k experts, gives (mk) assignments in total, to spread load evenly across n experts each expert should process _q=mk/n_ tokens.
Each token finds the cutoff threshold as the (k+1)-th highest biased router score and uses it to calculate the bias update needed to balance load for each expert. For each expert, QB sorts the margins between its router score and every token's cutoff. It sets negative bias to q+1 the largest margin, leaving exactly q margin above the threshold. Since q/m=k/n, this is (1-k/n) quantile of the margin, which is why it's called Quantile Balancing.
## Inference performance
We are actively tracking Kimi K3's inference performance on [InferenceX](https://inferencex.semianalysis.com/).
As of 30th July, all providers on OpenRouter have a floor of $3 per million tokens input and $15 per million tokens output. Both Nvidia and AMD had Day 0 recipes on vLLM, boasting DRAM offload and DSpark speculative decoding.
On InferenceX, we benchmark Kimi K3 serving performance directly on recorded internal claude code traces. We replay an hour of these traces as they reach a steady state. There is a median of 142k input tokens and a median of 444 output tokens per turn with a median of 65 turns per session. The short output tokens per turn is typical for workloads on agentic harnesses, where the agent calls tools frequently, even edits are tool uses.
This benchmark is a big step up from our previous 8k1k/1k1k benchmark, as it truly reflects real-world agentic use cases. From a systems perspective, it is also realistic and closest to production systems. It can reflect KV cache behavior, including prefix cache and KV offloading to DRAM.
For Kimi K3, Day 0 bringup was easier than DSv4 due to better documentation and preparation ahead of weights release. Appropriate images and a speculative decoder model were released at the same time as the weights.
_Related: [DeepSeekV4 1.6T Day 0 to Day 43 Performance Over Time — Huawei, GB300 NVL72, MI355X, B200](/blog/deepseekv4-16t-day-0-to-day-43-performance)_
For Nvidia, bringup was simple. But due to the models' sheer size, it doesn't fit on a single B200 node. We had to use PP to get it working. DSpark also didn't work with PP.
For B300, the model fits on 1 node and serves well. After accounting for the weights, GPU HBM can only hold 3.25M tok. In the graph below, throughput goes up as batch sizes increase until concurrency increases above 8. This roughly correlates to the 3.25M tok KV cache budget, and cache starts to thrash, resulting in hit rates falling to `<` 10% when theoretical hit rate is 95%.
Click to see the full InferenceX dashboard →
_The article continues with the B300 concurrency sweep, the AMD MI355X and MI455X bringup, and the full cross-hardware serving comparison for Kimi K3, in the [subscriber edition on the SemiAnalysis newsletter](https://newsletter.semianalysis.com/p/kimi-k3-the-manos-the-mythos-the)._
{`{
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [
{
"@type": "Question",
"name": "What is Kimi Delta Attention (KDA)?",
"acceptedAnswer": {
"@type": "Answer",
"text": "KDA is the linear attention layer in Kimi K3's hybrid attention mechanism. It descends from linear attention and DeltaNet: linear attention removes the softmax so all past keys and values compress into a single hidden state S, DeltaNet regularizes the growth of S by minimizing the L2 norm of the value retrieval, Gated DeltaNet adds an LSTM-style scalar forget gate alpha, and KDA expands alpha into a diagonal matrix for fine-grained per-channel memory decay and positional awareness. KDA also replaces RoPE as the position-aware operator in the full attention layers."
}
},
{
"@type": "Question",
"name": "What is the KDA to MLA ratio in Kimi K3?",
"acceptedAnswer": {
"@type": "Answer",
"text": "3:1, the same ratio Kimi Linear showed balances performance and efficiency. Kimi K3 interleaves three KDA layers with one full-attention Gated MLA layer. Keeping MLA as the full attention mechanism is unusual: GLM 5.2, DeepSeek V4, MiniMax M3, and MiMo V3 all use GQA-based sparse attention instead, because MLA's absorption trick trades extra prefill computation for cheaper decode, which suits decode-dominant reasoning but not prefill-dominant agentic workloads."
}
},
{
"@type": "Question",
"name": "What is the computational complexity of FlashKDA?",
"acceptedAnswer": {
"@type": "Answer",
"text": "For decode, both computation and memory traffic are constant with respect to sequence length: roughly 7*D^2 FLOPs and 8*D^2 bytes per head, dominated by reading and writing the FP32 recurrent state. For prefill, FlashKDA runs two kernels (K1 prepares chunk-level tensors, K2 does the chunk-level recurrence) performing 12*C^3 + 8*C^2*D + 6*C*D^2 FLOPs per chunk of size C, so overall FLOPs is O(T*D^2) and memory traffic is O(TC + TD + D^2) — linear in sequence length T."
}
},
{
"@type": "Question",
"name": "Does linear attention actually give Kimi K3 a constant-size KV cache during serving?",
"acceptedAnswer": {
"@type": "Answer",
"text": "No. KDA's recurrent state is fixed size at any single token position, but prefix caching requires storing state at positions a future request might resume from. Caching every position would regress memory usage to growing with sequence length, so Moonshot saves recurrent states at coarse granularity — vLLM caches every 32K tokens, plus at prompt boundaries because agentic turns typically start at the end of a prompt. Realistically, KDA greatly reduces KV cache memory but does not consume a constant amount of it."
}
},
{
"@type": "Question",
"name": "What are Attention Residuals and Block Attention Residuals?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Attention Residuals apply softmax attention across the depth dimension instead of the sequence dimension: each layer attends over the representations produced by previous layers, using a learned per-layer query vector rather than one generated from the current token. This gives every layer direct, selective access to earlier representations instead of relying on the residual stream alone. Block Attention Residuals group the L layers into N blocks and attend over completed block outputs plus the current block's evolving partial sum, cutting communication from O(Ld) to O(Nd) while staying competitive on quality — about 1.25x compute efficiency over standard residual connections."
}
},
{
"@type": "Question",
"name": "What is LatentMoE and why does expert intermediate dimension matter?",
"acceptedAnswer": {
"@type": "Answer",
"text": "LatentMoE compresses routed tokens before dispatch and decompresses them after aggregation; Kimi K3's Stable LatentMoE adds an RMSNorm before the up-projection. Halving the expert input dimension from 7168 to 3584 lets the active expert count double from 8 to 16 at the same communication volume. But the ratio of communication to computation time, which sets how much communication a MoE kernel can hide, works out to (P*F) / (6*m*B) * (1-1/E) — expert intermediate dimension m is the only model configuration in it. That is why recent open weight models, Kimi K3 included, raised the expert intermediate dimension to 3072."
}
},
{
"@type": "Question",
"name": "How does InferenceX benchmark Kimi K3?",
"acceptedAnswer": {
"@type": "Answer",
"text": "On recorded internal Claude Code traces rather than fixed 8k1k/1k1k synthetic shapes. An hour of traces is replayed at steady state, with a median of 142k input tokens and 444 output tokens per turn across a median of 65 turns per session. Short outputs per turn are typical of agentic harnesses where the agent calls tools frequently. Replaying real traces exercises production KV cache behavior including prefix cache hits and KV offloading to DRAM."
}
},
{
"@type": "Question",
"name": "How does Kimi K3 serve on B200 and B300?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Both Nvidia and AMD shipped Day 0 vLLM recipes with DRAM offload and DSpark speculative decoding, and Day 0 bringup was easier than DeepSeek V4 because images and a speculative decoder model landed alongside the weights. Kimi K3 does not fit on a single B200 node, so it needs pipeline parallelism, and DSpark does not work with PP. On B300 the model fits on one node; after weights, HBM holds about 3.25M tokens of KV cache, and throughput improves with concurrency only up to 8, past which the cache thrashes and hit rates fall below 10% against a theoretical 95%."
}
}
]
}`}
---
# Vera Rubin NVL72 vs GB200 NVL72? Inference TCO & Architecture Analysis
> Rubin LUT Based Tensor Core, Feynman, Rack Scale, Perf Per MegaWatt, Perf Per Dollar, Software Improvements, Public Rubin Software, PyTorch, vLLM, OpenAI Triton
- **Author**: SemiAnalysis
- **Date**: 2026-07-23
- **URL**: https://inferencex.semianalysis.com/blog/vera-rubin-nvl72-vs-gb200-nvl72-inference
- **Tags**: benchmark, gpu, inference, nvidia, rubin, gb200, gb300, deepseek, trtllm, dynamo
- **Reading time**: 20 min
_Originally published on the [SemiAnalysis newsletter](https://newsletter.semianalysis.com/p/vera-rubin-nvl72-vs-gb200-nvl72-inference) on July 23, 2026._
[Vera Rubin NVL72 is the second generation of Nvidia’s rack-scale Oberon architecture, and its gains on inference come from extreme co-design](https://newsletter.semianalysis.com/p/vera-rubin-extreme-co-design-an-evolution). Early results from engineering samples are encouraging. Vera Rubin NVL72 running DeepSeek R1 delivers 5.4x performance per MW and 5x performance per dollar over GB200 NVL72 today, and the gap is even wider against GB200 NVL72 during its early bringup in 2025. Vera Rubin is still in the early bringup stage now, so we expect the gap to continue to widen. Rubin’s inference performance will keep improving as software matures, the same pattern we demonstrated for Blackwell in our [InferenceX benchmarks](https://github.com/SemiAnalysisAI/InferenceX), and Rubin still has a long runway ahead.
[Nvidia has also recently made available their first public release of the Rubin (SM_107) software stack with CUDA 13.4](https://docs.nvidia.com/cuda/developer-preview/13.4/cuda-toolkit-release-notes/index.html) and has upstreamed Rubin PRs to PyTorch, vLLM and OpenAI Triton Compiler. Blackwell was not able to reuse Hopper WGMMA kernels, but Rubin is able to reuse Blackwell’s kernels, which makes the software bring up process much smoother. For speed of light (SOL) performance, engineers will still need to tune and rewrite kernels but for those that are focused on time to market, Blackwell kernels can be reused. We will also explain Rubin’s new 3-bit programmable LUT tensor core.
NVIDIA has also released on GitHub that Feynman is SM_140. [Unlike Blackwell to Rubin, Rubin to Feynman will be a much more complex transition on the kernel front.](https://semianalysis.com/accelerator-hbm-model/)
_Related: [Vera Rubin – Extreme Co-Design: An Evolution from Grace Blackwell Oberon](https://newsletter.semianalysis.com/p/vera-rubin-extreme-co-design-an-evolution)_
The early metrics gathered on VR NVL72 come from CoreWeave. We have not independently verified them. Nvidia has committed to submitting verifiable numbers to InferenceX by Q3 CY2026. Google should submit TPUv7 results in the next couple of months, and AMD has committed to MI455X UALoE72. Once those land, the ecosystem gets an objective comparison across systems.
In this article we break down Nvidia’s Rubin claims against several baselines, showing where Rubin clearly leads Blackwell and where the lead is thinner. We will also analyze Rubin’s performance per total cost of ownership using our already existing estimates for Rubin’s total cost of ownership (TCO). The TCO for Rubin and many other systems is sourced from our [AI TCO model, which tracks the total cost of ownership of different AI chips, factoring in capex, opex and different other expenses.](https://semianalysis.com/ai-cloud-tco-model/) We also consider performance per watt using our [All-in Utility Provisioned Power Estimates from our Datacenter Model](https://semianalysis.com/datacenter-industry-model/).
Finally, we will present [a component by component build up of the Bill of Materials (BoM) for the VR NVL72. This is available in our upcoming SemiAnalysis Bill of Materials (BoM) Model.](https://semianalysis.com/vr-nvl72-model/)
Another area where Rubin Oberon NVL72 will fare better than Blackwell Oberon NVL72 is in a much faster production ramp period. This is thanks to Rubin’s simpler cableless compute tray design and learnings from Nvidia’s experience with deploying a rack-scale copper backplane, having invested much effort into ironing out issues with Blackwell’s copper backplane. [Our Accelerator Model tracks quarter by quarter shipments of Rubin at both the package level and the rack level.](https://semianalysis.com/accelerator-hbm-model/)
## A Brief Breakdown of Rubin Chip-Level Microarchitecture Features
Going through a complete breakdown of Rubin microarchitecture will have to wait until we obtain ssh access to Rubin systems, allowing us to run [benchmarks similar to those we carried out when first analyzing Blackwell.](https://newsletter.semianalysis.com/p/dissecting-nvidia-blackwell-tensor) However, there are still a few interesting points we can still make.
We expect that Rubin bringup will be much more seamless compared to the transition from Hopper to Blackwell, where engineers expended much effort just to port kernels to Blackwell. This simplicity comes from the fact that Rubin is able to run Blackwell SM100-family kernels across all the important kernel libraries in DeepGEMM, FlashMLA, CUTLASS, among others. Moving from Hopper to Blackwell meant rewriting kernels from scratch. Hopper’s kernels don’t run on Blackwell at all.
Reusing Blackwell SM100 kernels means a clear time to market advantage, but for speed of light (SOL) performance, engineers will still need to tune and rewrite kernels specifically for the Rubin architecture, though kernel reuse buys them time to focus much more on this kernel tuning.
Turning to architectural details, Rubin’s SMEM increased to 328 KiB compared to Blackwell’s 228 KiB. While the default SMEM capacity is 228 KiB, [Rubin comes with an oversized shared memory mode](https://github.com/triton-lang/triton/blob/24fcd59d53e42c7fe7b696c235d12ce039af1015/third_party/nvidia/backend/driver.c#L984-L993) that allows an increase to 328 KiB. Furthermore, TMEM has been increased to 288 KiB up from 256 KiB in Blackwell as the number of columns increased from 512 to 576. The additional columns will allow stashing block scale factors, while keeping the TMEM region for accumulators disjointed from it. [This greatly simplifies block-scaled kernel logic](https://x.com/ReubenConducts/status/2078514481261400109): it saves the kernel writers from carefully pipelining and overlapping MMA matrix and block scaling factor loads.
[Source](https://github.com/triton-lang/triton/pull/10936)
Rubin’s TMA now supports inline descriptor updates. There are tons of use cases for this. For example, in an MoE layer, each expert is a separate weight matrix at its own address in HBM, so the TMA descriptor has to point somewhere new on every expert switch. On Blackwell, that meant rewriting the descriptor in memory and synchronizing before the next load. Now, with Rubin, the per-expert offset is passed inline to the TMA instruction so that one descriptor covers all experts, with no in-memory rewrite between them. This removes overhead during token dispatch and improves decode speed at low batch sizes.
[Source](https://developer.nvidia.com/blog/inside-nvidia-rubin-gpu-architecture-powering-the-era-of-agentic-ai/)
Inline TMA descriptor update corresponds to the [ISA feature `.override` qualifiers](https://docs.nvidia.com/cuda/developer-preview/13.4/parallel-thread-execution/index.html#data-movement-and-conversion-instructions-overriding-tensor-property-value). TMA instructions require a `tensorMap` object that specifies layout and format metadata. By using the `.override` qualifier, bulk asynchronous copy instructions can reuse the `tensorMap` object as a template, but replacing certain metadata fields, such as strides. In the case of MoE, expert weights have identical shapes, data types, and properties. By overriding the global address, kernel writers can avoid duplicating or replacing `tensorMap` objects when loading different experts.
Rubin doubles BF16/FP16 exponential throughput per clock per SM again, which helps overlap Tensor Core work with softmax during attention. FP32 throughput is unchanged from Blackwell Ultra.
Compared to Blackwell NVFP4/MXFP4 Tensor Cores which could only accept UE4M3/UE8M0 block scale factor format, Rubin Tensor Cores will now be able to accept the UE5M3 8-bit block scale factor too. This additional block scale format will allow for more flexibility and less quantization error in certain cases due to its wider range.
It is also important to note that latency has improved for SM-driven NVLink communications through the use of counted writes, which reduces the number of back and forth messages required to send data between GPUs over the copper backplane. This is a huge deal because Blackwell NVLink latency is multiple times higher than that of TPU and Trainium.
Rubin’s Tensor core delivers twice the throughput for FP8 and FP4 as compared to Blackwell. A key change driving this is doubling the k dimension as this means in theory, a GEMM takes half the number of clock cycles to execute. Additionally, the awkward K=96/3xFP4 instructions from Blackwell Ultra are still present, but alongside a new K=128 variant.
In Blackwell, PDL allowed for overlap at the grid level, where the dependent grid needs to wait for all threadblocks in the previous kernel to complete before starting. This allowed for some overlap and hiding of the ramp-down and ramp-up time between kernels, but didn’t come close to the extremely fine-grained overlap that trendy megakernel authors look to achieve. In Rubin, finer-grained overlap is enabled, where the dependent kernel can synchronize with the previous kernel at the threadblock level instead.
Rubin has 2.8x higher global memory bandwidth than Blackwell Ultra through the use of 3D-stacked HBM4 memory. It is unlikely Rubin delivers any improvement versus Blackwell in memory system latency. [Our Accelerator & HBM Model has a complete breakdown of the memory volumes estimates & vendor used in Rubin.](https://semianalysis.com/accelerator-hbm-model/)
Rubin adds 2:4 sparsity support for activations. In every group of four values, two are kept and two are zeroed. The pattern is regular, so the Tensor Core knows where the survivors are, skips the rest, and runs the MMA at twice the rate. A small metadata field tracks which slots were kept.
Nvidia shipped 2:4 on weights back in Ampere and nobody used it, because it meant pruning the model and retraining. Rubin applies it to activations at runtime, so no retraining is needed. In attention, QK^T runs dense, then the scores get compressed on the way out of Tensor Memory. Softmax processes only the survivors, and the following GEMM against V runs sparse. The output stays dense, so nothing else in the model changes. It works on MLP activations too.
Nvidia has published no accuracy data, and throwing out half the attention scores before softmax is not obviously free. CoreWeave’s DeepSeek R1 results do not appear to use it either, which makes it another Rubin feature with silicon today and no tuned kernels behind it yet.
### Lookup Table Weight Decompression in Rubin SM107 Tensor Core
Rubin adds LUT B, a Tensor Core MMA mode that decompresses the weight operand from a lookup table. In this mode, the B operand is a compressed matrix of indices. In a standard inference GEMM, the B operand holds the weights. The weight values live in a lookup table in Tensor Memory. The Tensor Core reads each index and reconstructs the weight value inside the MMA. There is no separate dequantization pass. After lookup, the multiply runs at FP8.
In LUT B, every weight position stores a 3-bit index rather than a complete numerical value. The index selects one of eight E4M3 values in the lookup table shared by that weight’s 8×64 block. For example, if the stored index is 5, the Tensor Core uses entry 5 from that block’s lookup table as the weight. The lookup happens inside the MMA, so the kernel never has to construct a separate decompressed weight matrix.
[Source](https://docs.nvidia.com/cuda/developer-preview/13.4/pdf/ptx_isa_9.4.pdf)
The lookup table (LUT) does not have to follow the spacing of a conventional uniform or floating-point grid. A quantization algorithm can therefore place more values around dense clusters of weights, use uneven spacing for long tails, or choose an asymmetric codebook when positive and negative weights have different distributions.
This flexibility creates the possibility of better accuracy per stored bit. Rubin LUT B has fewer individual codes than FP4, but it can place those codes where a particular weight group needs them rather than accepting the fixed ratios of E2M1. It is not automatically more accurate than MXFP4 or NVFP4, however. One codebook is shared across 512 weights, whereas NVFP4 adapts its scale over much smaller groups of 16. The result will depend on the codebook-fitting algorithm, calibration data, quantization-aware training and whether sensitive layers remain at higher precision.
Each index is 3 bits while the lookup table has 8 entries. Each entry is one byte, an E4M3 8-bit float in the reference kernel. This results in 3.125 bits per weight: 3 bits for the index, plus 64 bits of codebook spread across 512 weights. The codebook sits in HBM with the indices, so 3.125 bits per weight is the full stored footprint.
The instruction loads the compressed weights into the collector buffer. The Tensor Core can hold them there and reuse them across a run of activation tiles. This is a weight stationary pattern. The mode also has limits as it does not support transpose of the B matrix.
The block-scaled formats, NVFP4 and MXFP, also decompress inside the MMA. But they apply one uniform scale per block, not a codebook. Software methods like AWQ reach low bit counts by running a separate dequantization step before the matmul, Rubin is the first NVIDIA Tensor Core input format that reconstructs a non-uniform codebook inside the MMA.
A lower bit rate cuts the HBM capacity that the weights need. It also cuts the bytes that the GPU reads for each weight. At low batch size, weight bandwidth limits the decode step. Fewer bytes per weight then raise decode throughput. A non-uniform codebook also holds accuracy better than uniform rounding at the same bit count. This feature should also have an impact on power efficiency, as fewer bits will need to move through the memory system for each flop.
Using Kimi K3 2.8T as an example, at about 4.25 bits per weight, MXFP4 stores 2.8e12 x 4.25 / 8 = about 1,487.5 GB, where GB = 1e9 bytes. At 3.125 bits per weight, the Rubin lookup-table format stores 2.8e12 x 3.125 / 8 = about 1,094 GB (about 1.09 TB). The difference is about 393.5 GB. These figures cover the raw weight payload only, and exclude the KV cache, activations, and any parallelism replication. At 288 GB of HBM4 per Rubin package, the weights alone need about 6 packages in NVFP4 and about 4 packages in the new Rubin format.
## Feynman Architecture Sneak Peek
From Blackwell (SM100)/Blackwell Ultra to Rubin (SM107), the jump is relatively small in terms of the microarchitecture, so Rubin can be thought of as a Blackwell kicker architecture. In comparison, Feynman (sm_140) is a completely new architecture family. This will require rewriting lots of kernels from Rubin to Feynman, which is similar to what happened from Hopper WGMMA to Blackwell tcgen05. [Our Accelerator & HBM Model provides a full breakdown of Feynman quarter by quarter volume estimates.](https://semianalysis.com/accelerator-hbm-model/)
Feynman’s 3D stacking will be similar to what AMD has been doing with 3D stacking since their MI300X with CDNA3.
One of the new features of the Feynman architecture is that it will contain sparsity aware data movement ops. These can be used in sparse GEMMs to improve performance by avoiding pointless loads, stores and FMAs.
## Nuances of CoreWeave VR NVL72 Results
Yesterday, [CoreWeave published their benchmarked Vera Rubin NVL72 Inference results](https://www.coreweave.com/blog/nvidia-vera-rubin-nvl72-on-coreweave-10x-more-tokens-per-megawatt-than-blackwell) expressed in units of performance (tokens/sec) per power used (MW). We will break down the nuances of their data and compare their results against Blackwell’s performance using our own InferenceX July 2026 results as a baseline.
Click to see the full InferenceX dashboard →
The first notable claim on the CoreWeave-Nvidia chart is that VR NVL72 achieves 10x better token throughput per megawatt than GB200 NVL72 at the iso-interactivity of ~150 tok/s/user. This is about 50% faster than today’s “fast mode” on frontier models.
Three things about their chart. The benchmark is single-turn, 8k in and 1k out. The y-axis is output token throughput per megawatt, not total throughput. And their power number covers **both prefill and decode GPUs**, even though only output tokens are counted. InferenceX measures output throughput against **decode GPU watts only**, so we renormalized our data to match theirs for this comparison.
It is important to point out that CoreWeave claims to have enabled all of the following inference optimizations on both their baseline GB200 NVL72 and Rubin NVL72 performance results, including but not limited to:
- NVFP4 Precision
- Speculative Decoding (Using MTP)
- Disaggregated Serving (Using Dynamo)
- Wide Expert Parallelism
- via TensorRT-LLM
The above results seem to suggest that Rubin comes to market with a strong performance gain vs Blackwell out of the gate. However, there are a few nuances that are worth unpacking.
First, attentive readers will note that CoreWeave is comparing Rubin against a **GB200 NVL72 2025 baseline**. In some ways, comparing performance at the early stages of GB200 NVL72’s lifecycle is fair, since Rubin performance is expected to massively improve from this early stage in its own lifecycle. Our analysis will also use the GB200 NVL72 early performance results from 2025, but we also compare how GB200 NVL72 did by 2026 as well as the most current GPU worth comparing to: **GB300 NVL72**. We will directly compare GB300 NVL72 performance from early in 2026 with Rubin’s comparable early lifecycle performance.
The second nuance in CoreWeave’s performance results is that they are using DeepSeek R1 671B, a model that is not widely used anymore. One would perhaps wish that CoreWeave used a more modern model like GLM5.2, Kimi K2.5, Qwen3.5, or DeepSeek V4. Even better would be Kimi K3 or Qwen3.8, both of which are [coming soon to InferenceX](https://inferencemax.ai/)! At least CoreWeave is [not using GPTOSS 120B in Summer 2026 like AMD is for MI455X UALoE72](https://github.com/ROCm/aiter/pull/3676) performance metrics. We expect that the fog of war created by benchmarking old models will be cleared up once Nvidia starts benchmarking Rubin on more modern model architectures with InferenceX in Q3 CY2026.
Oddly enough, CoreWeave’s choice of using DeepSeek R1 671B is theoretically more favourable towards the Blackwell baseline, and not Rubin. Rubin’s main advantages lie in a higher HBM capacity, higher CPU DRAM capacity, and greater HBM bandwidth, meaning that Rubin is more optimized for multi-trillion parameter models like Fable 5, Gemini Pro, Kimi K3, and Qwen3.8 2.4T.
The third noteworthy item is that CoreWeave uses only single turn 8k/1k input/output tokens. Theoretically, multi-turn long context workloads like Agentic Coding should do better on Rubin, due to Rubin’s higher HBM capacity and bandwidth, but this would not be captured on a simple single-turn benchmark. [Our upcoming AgentX benchmark scenario created in collaboration with Weka, LMCache, the vLLM/SGLang community, Nvidia, AMD, and many others in the community will provide a realistic agentic workload to benchmark inference performance.](https://inferencex.semianalysis.com/datasets/cc-traces-weka-062126) We encourage everyone to adopt this inference benchmark!
Finally, we note that CoreWeave’s testing was done on a pre-production rack without a scale-out fabric. Specifically, CoreWeave used a Dell Engineering Sample (ES) rack. We do believe these results are valuable as they use wide EP and PD disagg, which uses the NVL72 scale-up backplane and proves that it is working well. This backplane faced many reliability challenges during the ramp of GB200 NVL72 Oberon, [as we have noted in our Accelerator model.](https://semianalysis.com/accelerator-hbm-model/)
[Source](https://x.com/CoreWeave/status/2061146723200962763/photo/2)
### Rubin Versus Blackwell Performance per MegaWatt
The metric Nvidia chose to lead with was “output tokens per second per all-in utility megawatt”, counting every GPU in the system. To compare apples-to-apples, we renormalize our own InferenceX benchmark data onto the same total-GPU basis. Below, we put VR NVL72 up against our official GB200 and GB300 July 2026 benchmarks, as well as CoreWeave’s 2025 GB200 baseline.
The eye-catching multiples in Nvidia’s charts all come from the 2025 baseline. When comparing benchmark data, we believe we should use figures from the same time period, so the July 2026 GB200 and GB300 benchmarks are the more useful comparison.
In theory, datacenter PUE can be lower for Vera Rubin [since Vera Rubin can operate with 45 degrees Celsius coolant temperatures in custom datacenters without chillers](https://blogs.nvidia.com/blog/liquid-cooling-ai-factories/). However, for our comparisons, since most datacenters are designed to accommodate a wide variety of systems, we use the same PUE across the DLC cooled chips.
The following pareto curves plot output throughput per total-GPU megawatt against interactivity. Each line stops where its recipe’s frontier ends.
Next, we provide the same data in table form. When a cell says "impossible," we mean that the interactivity is past that recipe's frontier, simply not allowing the configuration to serve that workload at that speed.
Here is the same frontier as bars, across the 100 to 300 tok/s/user band. All four recipes have data through 250 tok/s/user, and only Rubin and GB300 make it to 300 tok/s/user.
Let’s first compare Rubin against the July 2026 GB300 NVL72 baseline. Rubin’s lead is smallest at low interactivity and continues growing through the middle of the interactivity curve. Rubin sits at near 2x the throughput of Blackwell up through 100 tok/s/user, then widens to roughly 4x around 200 tok/s/user, where the gap peaks. Then, the gap begins to narrow again. The headline 5.4x performance gain over GB300 at 300 tok/s/user isn’t Rubin pulling further ahead. Rather, it is GB300 running the last, barely viable point on its frontier, which causes the ratio to balloon. GB200 can’t reach 300 tok/s/user at all. Blackwell’s per-GPU throughput drops off fast as the batch shrinks at high interactivity, while Rubin is still on a flatter part of its frontier.
Comparing Rubin against the 2025 GB200 NVL72 baseline is different, showing the biggest lead in the middle of the curve. The gap starts at under 3x at low speeds, but increases to about 10x at 150 tok/s/user (the point Nvidia highlights in their chart), before falling back to 6x at around 200 tok/s/user. The data from that line is accurate, but as we have mentioned it uses a software stack that is a year old, not the GB200 you would run today.
At the very top of the interactivity range, the Blackwell curves drop off. By 350 tok/s/user, neither GB200 nor GB300 can serve the workloads at all, leaving only Rubin with an actual curve, delivering 96,446 tok/s/MW at 300 tok/s/user and 70,703 at 350 tok/s/user.
Clearly, Rubin is going to give us a lot more “fast mode” than Blackwell.
### Rubin Versus Blackwell Performance per TCO
Per-megawatt performance only counts performance against power. Cost per million output tokens folds in the hardware’s total cost of ownership (TCO) including IT capital costs as well as electricity and datacenter costs. [Our TCO model breaks this down comprehensively, providing capital costs and operating costs across server generations.](https://semianalysis.com/ai-cloud-tco-model/) Here, we divide each SKU's all-in TCO by that same renormalized output throughput, so lower is better. Rubin carries a higher TCO per GPU than Blackwell, $3.57 per GPU-hour against $1.84 for GB200 and $2.36 for GB300 in the operator ownership scenario (not rental prices). The charts and tables below will show how Rubin’s $ per token lead comes out a little smaller than its per-megawatt lead.
As with the per-MW analysis, the 2025 GB200 baseline produces the largest gains in performance for Rubin, but the July 2026 GB200 and GB300 numbers are the more relevant baseline for comparison for anyone buying capacity today.
The following pareto curves plot cost per million output tokens against interactivity. Each line stops where its recipe’s frontier ends.
Next, we provide the same data in table form, with the ratio showing how many times cheaper Rubin is at each interactivity. Again, a cell marked "impossible" is a speed that the recipe's frontier can't reach.
The chart below plots the frontier as bars across the 100 to 300 tok/s/user band. All four recipes have data through 250 tok/s/user, and only Rubin and GB300 reach 300 tok/s/user.
Against July 2026 GB200 & GB300, Rubin is cheaper at every interactivity, and the gap widens as you climb. The gap starts at about 1.5x cheaper than GB200 through 100 tok/s/user, and improves to 3x by 200 tok/s/user through to 250 tok/s/user. The 5x edge over GB300 at 300 tok/s/user is the same as the per-MW view, where GB300 can barely serve tokens and GB200 can’t serve at this interactivity level at all.
The 2025 GB200 NVL72 baseline is once again the more dramatic one, cresting in the middle of the curve. Rubin is a little over 2x cheaper at low speeds, peaks near 8x at 150 tok/s/user, and then moves back to 5x by 200 tok/s/user. Same comment as on the per-MW version: the 2025 GB200 baseline measures a year-old software stack, not the GB200 you would run today.
At the very top of the range, things are the same. GB200 has no operating point past 250 tok/s/user and GB300 has none past 300 tok/s/user, so by 350 tok/s/user only Rubin can serve at all, delivering a cost of $4.18 per million output tokens.
Click to see the full InferenceX dashboard →
_The article continues with Rubin's performance compared against the best-known publicly available MI355X distributed inference performance, plus a brief analysis of how the Triton Compiler, PyTorch, vLLM, and Dynamo software will function on Rubin, in the [subscriber edition on the SemiAnalysis newsletter](https://newsletter.semianalysis.com/p/vera-rubin-nvl72-vs-gb200-nvl72-inference)._
{`{
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [
{
"@type": "Question",
"name": "How much faster is Vera Rubin NVL72 than GB200 NVL72 on inference?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Running DeepSeek R1 on a single-turn 8k input / 1k output workload, Vera Rubin NVL72 engineering-sample results deliver 5.4x performance per megawatt and 5x performance per dollar over GB200 NVL72 measured on the July 2026 software stack. Against CoreWeave's 2025 GB200 NVL72 baseline the per-megawatt gap peaks near 10x at 150 tok/s/user, but that baseline measures a year-old software stack. Rubin is still in early bringup, so the gap is expected to keep widening as its software matures."
}
},
{
"@type": "Question",
"name": "What is the Rubin LUT-based Tensor Core weight decompression format?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Rubin SM107 adds LUT B, a Tensor Core MMA mode where the weight operand is a compressed matrix of 3-bit indices. Each index selects one of eight E4M3 entries in a lookup table shared by an 8x64 weight block, and the reconstruction happens inside the MMA with the multiply running at FP8, with no separate dequantization pass. The stored footprint is 3.125 bits per weight: 3 bits of index plus 64 bits of codebook spread across 512 weights. For a 2.8T-parameter model like Kimi K3, that is about 1,094 GB of weights versus about 1,487.5 GB in MXFP4, saving roughly 2 of the 6 288 GB HBM4 packages the weights would otherwise need."
}
},
{
"@type": "Question",
"name": "What are the caveats in CoreWeave's 10x tokens-per-megawatt Vera Rubin claim?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Four nuances. First, the 10x compares Rubin against a 2025 GB200 NVL72 baseline running a year-old software stack; against July 2026 GB200 and GB300 InferenceX baselines the per-megawatt lead is roughly 2x through 100 tok/s/user, peaking around 4x versus GB300 near 200 tok/s/user. Second, the benchmark uses DeepSeek R1 671B, an older model that theoretically favors the Blackwell baseline since Rubin's advantages are HBM capacity and bandwidth suited to multi-trillion parameter models. Third, it is a single-turn 8k in / 1k out workload, which does not capture multi-turn agentic serving where Rubin should do better. Fourth, testing ran on a pre-production Dell engineering sample rack without a scale-out fabric."
}
},
{
"@type": "Question",
"name": "Can Rubin GPUs run existing Blackwell CUDA kernels?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Yes. Rubin (SM107) runs Blackwell SM100-family kernels across the important kernel libraries including DeepGEMM, FlashMLA, and CUTLASS, which makes bringup much smoother than the Hopper-to-Blackwell transition, where kernels had to be rewritten from scratch. Engineers still need to tune and rewrite kernels for speed-of-light performance on Rubin. Feynman (SM140) is a completely new architecture family, so the Rubin-to-Feynman transition will again require rewriting many kernels."
}
},
{
"@type": "Question",
"name": "How does Vera Rubin NVL72 compare to Blackwell on cost per million tokens?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Rubin carries a higher TCO at $3.57 per GPU-hour against $1.84 for GB200 and $2.36 for GB300 in the operator ownership scenario, per the SemiAnalysis AI Cloud TCO Model. Even so, against July 2026 GB200 and GB300 baselines on DeepSeek R1, Rubin is cheaper per million output tokens at every interactivity: about 1.5x cheaper than GB200 through 100 tok/s/user, improving to 3x by 200 through 250 tok/s/user, and about 5x cheaper than GB300 at 300 tok/s/user. GB200 has no operating point past 250 tok/s/user and GB300 none past 300, so by 350 tok/s/user only Rubin can serve at all, at $4.18 per million output tokens."
}
}
]
}`}
---
# DeepSeekV4 1.6T Day 0 to Day 43 Performance Over Time — Huawei, GB300 NVL72, MI355X, B200
> Day 0 Inference Performance, InferenceX, 100x performance improvement in 26 Days, Cost per Million Tokens, Huawei 950DT Inference Trace Analysis
- **Author**: SemiAnalysis
- **Date**: 2026-06-09
- **URL**: https://inferencex.semianalysis.com/blog/deepseekv4-16t-day-0-to-day-43-performance
- **Tags**: benchmark, gpu, inference, deepseek, nvidia, amd, huawei, gb300, b300, b200, mi355x, h200, sglang, vllm, trtllm, cann
- **Reading time**: 29 min
_Originally published on the [SemiAnalysis newsletter](https://newsletter.semianalysis.com/p/deepseekv4-16t-day-0-to-day-43-performance) on June 9, 2026._
The release of DeepSeek v4 marks another step forward for the open model community - unsurprisingly, it is the product of a Chinese lab. The evolution of its performance over time is of paramount importance to the AI Ecosystem. [The open-source InferenceX engineering team has pulled multiple all-nighters to measure performance results for this model on Day 0, Day 1, Day 2, and beyond and bring these results to the world.](https://inferencex.semianalysis.com/) In this article, we will highlight DeepSeek v4’s Day 0 performance and explain the significant improvements made in the subsequent weeks following the model’s release. We will also explain core components of DeepSeek v4’s model architecture and discuss how it was co-designed in part for Huawei Ascend inference.
In section 2 of our blog post, we do a comprehensive analysis of DeepSeekv4’s inference on Day 0 Huawei Ascend 950DT. This article serves as the first analysis of Ascend 950DT DeepSeekv4 inference and we break down the compute ↔ communication overlap & the different compute streams that Huawei did to optimize performance.
A key goal of InferenceX, especially during a model’s Day 0 release window, is to record each SKU’s performance using open-sourced images and recipes across as many frameworks as possible, regardless of how well these images and recipes perform. This enables us to track improvements over time, which we believe best reflects the real, deployable performance of each chip. The video below shows iterative improvements for non-MTP configs from Day 0 onward for vLLM/SGLang, respectively. [visit inference.com to see the MTP configs from day 0 onwards too](https://inferencemax.ai/).
_vLLM non-MTP DeepSeek V4 Pro configs improving from Day 0 onward. Source: SemiAnalysis InferenceX_
The graphics reflect the thousands of engineering hours that went into tuning DeepSeek v4 inference performance and most of the optimizations are merged into the master branch of SGLang/vLLM. One of the north star goals of InferenceX is to highlight the iterative improvements to performance _over time_, instead of just snapshots of performance, after all when it comes to engineering, the things you learn along the way are often just as important as the end result.
_SGLang non-MTP DeepSeek V4 Pro configs improving from Day 0 onward. Source: SemiAnalysis InferenceX_
In the early days of DeepSeek v4 Pro, CUDA vLLM and CUDA SGLang and CUDA vLLM disaggregated prefill worked great out of the box, proving the strength of the vLLM and SGLang open ecosystems. These inference engines are so fundamental to the global ML ecosystem that both teams have started their own company, Inferact and RadixArk, with each raising hundreds of millions of dollars to continue to fuel the growth of their open-source inference engines.
Huawei Ascend has also described and demonstrated Day 0 inference performance support for DeepSeekV4 in their documentation. China currently dominates the open model landscape, with [Kimi K2.6 still beating Jensen’s Nemotron Committee Coalition’s Nemotron 3 Ultra on coding](https://x.com/SemiAnalysis_/status/2062942704296743164). Furthermore, [Nvidia’s in house TensorRT-LLM did not work well for DeepSeek v4, and we at SemiAnalysis had to fix their open source mHC kernel launch code](https://github.com/NVIDIA/TensorRT-LLM/pull/13710). [Thank you for NVIDIA engineers for rebasing and merging our patch](https://github.com/NVIDIA/TensorRT-LLM/pull/13771)!
ROCm did not work well either in the first couple of days of DeepSeek v4’s launch. That said, the AMD SGLang engineering team, under the technical leadership of HaiShaw, massively improved performance in the first month - achieving a more than 100x performance by Day 26. We will talk more about the good, & the bad, of AMD software progress in our upcoming, comprehensive State of AMD 2026 article.
All performance tracking is documented in our open-source GitHub repo. Feel free to give us a star if you find the repo useful: [https://github.com/SemiAnalysisAI/InferenceX](https://github.com/SemiAnalysisAI/InferenceX).
Click to see the full DeepSeekV4 InferenceX dashboard →
The SemiAnalysis InferenceX inference initiative is supported by many in the ML community, including OpenAI, Oracle, Microsoft, Weka, PyTorch Foundation, vLLM, SGLang, and CoreWeave, among others.
[See all InferenceX supporters](https://inferencex.semianalysis.com/quotes)
The InferenceX team is hugely thankful for the ongoing engineering efforts carried out by the vLLM community maintainers, Inferact, as well as all of the SGLang maintainers around the world at RadixArk, Meta, and elsewhere. We would also like to shout out to and thank Nvidia engineers Kedar Potdar, Ankur Singh, Xin Li, Alec Flowers and many other Nvidia engineers for their Day 0 support for this project. We would also like to extend our appreciation to the AMD engineering team for their Day X support of DeepSeek v4 Pro on the ROCm stack.
Unfortunately, our GB300 cluster happened to be down when DeepSeek v4 was released. Luckily, [CoreWeave came through and contributed compute to the open source community and maintainers, scrambling to find two spare dev GB300 NVL72 racks.](https://x.com/SemiAnalysis_/status/2048082151711641829) Our GB300 results were only achievable because of their support, and we are using it around the clock to drive further improvements to results.
If you want to work on low-level benchmarking, InferenceX, or other interesting technical work, then send us your resume to [letsgo@semianalysis.com](mailto:letsgo@semianalysis.com) with three bullet points demonstrating your engineering abilities. If available, please attach GitHub repo links, websites, or blogs to show off your projects, work, and knowledge.
## Section 1: DeepSeekV4 Pro Day 0 Performance
In this section, we will start by discussing DeepSeek v4 Pro’s out of the box performance on Day 0. We will reference throughput-interactivity curves, how different parallelisms favor throughput versus interactivity, and other inference optimizations such as MTP and disaggregated inference, which were explained in the [InferenceX V2 article](https://newsletter.semianalysis.com/p/inferencex-v2-nvidia-blackwell-vs).
> Note that to avert a potential Inference World War 3 and prevent [another round of vLLM vs SGLang twitter drama/rap battle,](https://x.com/EmbeddedLLM/status/1913854116545307094) for this article, we will not be showing results for both vLLM and SGLang for same hardware SKU on the same graph.
The following two graphs shows all the Day 0 recipes we managed to record, with most recipes using the native model checkpoint utilizing mixed FP4 MoE-FP8 Attention quantized weights (except for the H200 and MI355X SKUs). Because the native FP4+FP8 checkpoint for DeepSeekV4 Pro was not usable on Day 0 for the MI355X, we were only left with the option of using a full FP8 non-native checkpoint.
Unfortunately, AMD SGLang and AMD vLLM distributed inference still does not work on DeepSeekV4 Pro.
Turning to [SGLang](https://github.com/sgl-project/sglang/pull/23600) and [vLLM](https://github.com/vllm-project/vllm/pull/40760), both supported native DeepSeek v4 Pro on the CUDA platform the moment the model was released publicly. Most advertised recipes, especially for newer SKUs such as B200/B300, worked out of the box without any major issues.
[Live chart](https://inferencex.semianalysis.com/inference?g_model=DeepSeek-V4-Pro&g_rundate=2026-04-27&g_runid=25016676395&i_hc=1&i_prec=fp4%2Cfp8&i_active=b200_vllm%2Cb300_vllm%2Cgb200_dynamo-vllm%2Ch200_vllm%2Cmi355x_atom%2Cmi355x_sglang)
The below graph shows SGLang Day 0 performance:
[Live chart](https://inferencex.semianalysis.com/inference?i_hc=1&g_model=DeepSeek-V4-Pro&g_rundate=2026-04-25&i_prec=fp4%2Cfp8&g_runid=24943464864&i_active=b200_sglang%2Cb300_sglang%2Cmi355x_sglang)
Let’s now dive deeper into each group of Day 0 results.
### Day 0 Multi-Node Disaggregated Prefill on GB200 NVL72
[Live chart](https://inferencex.semianalysis.com/inference?g_model=DeepSeek-V4-Pro&g_rundate=2026-04-27&g_runid=25016676395&i_prec=fp4%2Cfp8&i_hc=1&i_legend=0&i_active=b200_vllm%2Cgb200_dynamo-vllm)
vLLM and Nvidia were very fast in delivering their GB200 distributed inference Dynamo vLLM recipe in [srt-slurm](https://github.com/NVIDIA/srt-slurm/pull/71). Disaggregated inferencing and wide expert parallelism (WideEP) are inference optimization techniques that can considerably improve performance per dollar - readers can learn more about these techniques in our [InferenceX V2 article](https://newsletter.semianalysis.com/p/inferencex-v2-nvidia-blackwell-vs). The recipe itself was rudimentary: eager on prefill, using NIXL for KV cache transfer. We independently replicated the recipe achieving up to 5x better results than for a B200 run using lower interactivity configs.
This is a great example of the CUDA moat at work: With CUDA, distributed inferencing tends to be supported near Day 0 for the latest open models.
### Day 3 Multi-Token Prediction (MTP) Speculative Decoding
[Live chart](https://inferencex.semianalysis.com/inference?g_model=DeepSeek-V4-Pro&g_rundate=2026-04-27&g_runid=25016676395&i_prec=fp4%2Cfp8&i_hc=1&i_legend=0&i_active=b300_sglang%2Cb300_sglang_mtp)
The first MTP support delivered for DeepSeek v4 came on Day 3 from SGLang. Using MTP led to a substantial improvement in throughput at higher interactivities. An explanation of MTP and how it benefits memory-bound small batch size decode can be found in our [InferenceX V2 article](https://newsletter.semianalysis.com/p/inferencex-v2-nvidia-blackwell-vs).
### Day 0 ROCm AMD MI355X Disappointment
Turning to ROCm on AMD MI355X, our Day 0 results for DeepSeek v4 were confusing. Most AMD users in the open-source ecosystem were also mired in confusion. The MI355x could only run FP8 on Day 0, and delivered results on the bottom left of the chart below in the overall Day 0 plot. Inference was technically working, but it was an unusable experience given extremely low interactivity levels of only 1-2 tokens per user per second, far below average user reading speeds.
We used the Day 0 WIP recipe provided by an [SGLang PR](https://github.com/sgl-project/sglang/pull/23608#issuecomment-4311952977), courtesy of HaiShaw et al at AMD. This was the only working recipe we could find on Day 0. Unfortunately, its performance was disappointing and native FP4+FP8 checkpointing didn’t work - this was likely due to the less mature ROCm ecosystem. However, as we will talk about later in the article, HaiShaw’s team eventually came through, doing an amazing job by improving performance by over 100x from Day 0 through Day 26 through some classic first principles driven engineering work.
[Live chart](https://inferencex.semianalysis.com/inference?g_model=DeepSeek-V4-Pro&g_rundate=2026-04-25&i_hc=1&i_legend=0&g_runid=24943464864&i_prec=fp4%2Cfp8&i_gpus=mi355x_atom%2Cmi355x_sglang&i_dstart=2026-04-25&i_dend=2026-04-26&i_active=mi355x_sglang)
### AMD ATOM Inference Engine Disappointment
ATOM did somewhat better on interactivity, but it still falls short for a concurrency of greater than 1. We used [ATOM #650](https://github.com/ROCm/ATOM/pull/650) during the early days of DeepSeek v4 hardcoded `kv_cache[:1,...]`, and this meant that the KV cache was pinned to a single sequence slot. With only one slot available, a second concurrent request has nowhere to store its KV state. This was the case because the infrastructure that enables batching possible was not yet in place, so we could only run batch size of one user.
ATOM also ran with almost every hot path on a fallback: the FP4 MoE was forced onto Triton because AITER’s `fused_moe` was broken on GFX950, and the mHC pre-projection patched to Torch because AITER’s kernel crashed, forcing eager execution.
### NVIDIA TensorRT-LLM Bugs and Lack of Day 0 DeepSeekV4 Pro Support
TensorRT did not support DeepSeek v4 out of the box because `mhcFusedHcKernel.cu` had a single hardcoded `FHC_HIDDEN = 4096` constant. This is a problem because SHAPE_K, residual/x TMA descriptors, and the MMA kernel template instantiations were all tied to that hidden size. All previous DeepSeek models and DeepSeek v4 flash have a hidden size of 4096, so this worked for the meantime. But attempting to run inference for DeepSeek v4 Pro resulted in a `“mhcFusedHcLaunch: hidden_size=7168 not supported (only 4096)”` guard error.
Nvidia engineers also encountered this guard error and instead of adding code to support DeepSeek v4 Pro’s 7168 hidden size, they simply [removed the guard](https://github.com/NVIDIA/TensorRT-LLM/commit/b3f45bb608aecca666a451ca5138b81470487f05). To nobody’s surprise, the error then disappeared.
Because of this “fix”, there was a period of over a week where, unless the env var `TRTLLM_MHC_ENABLE_FUSED_HC=0` was used, the kernel would compile exclusively for 4096, with nothing rejecting a 7,168 call. Using default settings (fused HC on by default; B300 = SM10x → MMA path), a stock trtllm-serve of DeepSeek v4 Pro feeds 7,168 tensors into the 4,096-wired kernel. Running inference with these settings results in an inference [run without triggering an immediate crash, but there are hidden consequences: the engine ends up corrupting hidden states and producing invalid generations](https://github.com/SemiAnalysisAI/InferenceX/actions/runs/25231354124/job/73987414247). This was fixed in [a PR authored by us](https://github.com/NVIDIA/TensorRT-LLM/pull/13710), and it was surprising that such a simple problem took a week to be noticed and that it took another few days for the PR to be approved.
In the time it took to diagnose the issue and narrow the problem down to the fused HC hidden size mismatch, we had already reached Day 9 post DeepSeek v4 Pro launch. This episode is a good case study that proves the strength of the open native SGLang and native vLLM engine ecosystems. Thanks to these robust ecosystems, Day 0 support will always come to native SGLang and native vLLM first before it comes to TensorRT-LLM or AMD’s ATOM engine (ATOM, by the way, currently has zero production customers).
In the graphs below, we can see how as of today, TRT-LLM’s performance is superior at higher batch sizes, but it tends to fall behind at higher interactivity levels.
## Section 1.5: Performance Over Time
As mentioned earlier in the article, we capture a snapshot of Day 0 performance across the inference engines and recipes as it acts as the baseline against which improvements in performance can be measured over time. With this baseline performance - we are able to measure and present the following data analyzing performance improvements over time.
### DeepSeek v4 Pro on MI355X - 100x Improvement in less than 1 Month
On Day 0, DeepSeek v4 Pro was technically working on the MI355X, but it was clearly not deployable into any production workflow. However, the improvements since then have been phenomenal - with the AMD team led by HaiShaw delivering an over 100x improvement in throughput in less than a month post DeepSeek v4 release.
_MI355X DeepSeek V4 Pro performance improving from Day 0 onward. Source: SemiAnalysis InferenceX_
[Live chart](https://inferencex.semianalysis.com/inference?g_model=DeepSeek-V4-Pro&g_rundate=2026-04-25&i_legend=0&g_runid=24943464864&i_prec=fp4%2Cfp8&i_gpus=mi355x_sglang%2Ch200_sglang&i_dstart=2026-04-25&i_dend=2026-05-27&i_dates=2026-05-02%2C2026-05-03%2C2026-05-04%2C2026-05-08%2C2026-05-10%2C2026-05-19%2C2026-05-21&i_active=mi355x_sglang)
The chart above shows how the throughput pareto-optimal frontier climbed when comparing results from the FP8 build on Day 0 released on 25th April to results from the FP4 build released on the 27th of May. The gain came almost entirely from AMD replacing PyTorch-native fallback paths with real AITER, Triton, TileLang, and FlyDSL kernels.
There are two steps that drive the lion’s share of the gains. The largest percentage improvement actually came from the first commit after the baseline Day 0 submission - the team managed to mop up a ton of low hanging fruit and significantly improve the first iteration from the FP8 baseline. The next largest improvement came a few days later as the AMD team finally got FP4 weight MoE working, allowing us to switch MoE experts from FP8 to native FP4 (MXFP4), improving expert-weight bandwidth. This also moved FlashMLA and the sparse-attention indexer off the torch fallback onto TileLang kernels and enabled HIP graphs.
The next big improvement we saw came from the introduction of AITER mHC kernels, which are used at every layer. This improvement boosted performance such that we were able to see MI355X exceed H200 performance for DeepSeek v4 Pro at lower interactivity levels for the first time.
Before the windowed-attention kernel can run, it needs to know which KV-cache slots each query’s window covers. This is done by SWA-prepare, and its implementation in Triton also helped with the improvement.
The next big jump came on May 19th as the team retired the remaining fallbacks: FlashMLA moved from TileLang to Triton, and as the AITER FlyDSL FP4 MoE kernel landed. The team also enabled fused hash-topk, DSv4 radix attention, fused store-cache, fused WQA/WKV projection, and fused paged-compress, further boosting performance. The concurrency sweep was also increased to 1024, drawing the high-throughput, low-interactivity end of the frontier that did not exist before.
[Live chart](https://inferencex.semianalysis.com/inference?g_rundate=2026-05-31&g_runid=26696268345&g_model=DeepSeek-V4-Pro&i_gpus=mi355x_atom%2Ch200_sglang&i_dstart=2026-04-26&i_dend=2026-05-14&i_prec=fp4%2Cfp8&i_active=mi355x_atom&i_dates=2026-05-02)
ATOM also improved drastically, expanding from a single conc=1 point to delivering decent throughput along the whole pareto frontier, with some points beating H200. The first gain came from [AITER fix #2916](https://github.com/ROCm/aiter/pull/2916), which corrected the device-allocation bug behind the mHC crash and let ATOM restore that AITER kernel. Next, FP4 experts moved onto AITER’s fused MoE kernel (Triton override removed), the sparse-attention OOM was cleared so eager mode and the single-sequence caps could be dropped. Batching support was also implemented, expanding the sweep from conc=1 to conc 1–512 with much better performance.
#### MI355X MTP
By Week 4, MTP was working for AMD on all frameworks, delivering multiple-fold iso-interactivity throughput improvement. One consistent characteristic we noticed however, is that MTP tends to deliver worse results at higher throughput. This is because MTP exploits the compute slack in memory-bound decode, so compute-bound large batch size decode jobs have an MTP cost that outweighs the benefit that draft tokens would provide.
### B300
[Live chart](https://inferencex.semianalysis.com/inference?g_rundate=2026-05-29&g_model=DeepSeek-V4-Pro&g_runid=26649066318&i_gpus=b300_sglang%2Cb300_trt%2Cb300_vllm&i_active=b300_sglang%2Cb300_trt&i_dstart=2026-04-24&i_dend=2026-05-18&i_dates=2026-04-25%2C2026-04-26%2C2026-04-27%2C2026-04-28%2C2026-04-29%2C2026-05-03%2C2026-05-05)
For B300 on SGLang, DeepGEMM MegaMoE, our results showed a 3x improvement over less than a week thanks to the use of a grouped FP4 MoE GEMM that keeps experts resident and does one mega-dispatch instead of per-expert kernels, as well as from tuning to use EP4 instead of EP8.
### B200
Performance for the B200 was relatively similar to that of the B300, with TRT being superior at lower interactivity for the B200. But TRTLLM does not work out of the box, compared to CUDA vLLM & SGLang vLLM which works out of the box.
### GB300 NVL72
_GB300 NVL72 DeepSeek V4 Pro performance improving over time. Source: SemiAnalysis InferenceX_
[Live chart](https://inferencex.semianalysis.com/inference?i_hc=1&g_model=DeepSeek-V4-Pro&g_rundate=2026-06-08&g_runid=27099659001&i_prec=fp4%2Cfp8&i_gpus=gb300_dynamo-sglang%2Cgb300_dynamo-sglang_mtp&i_active=gb300_dynamo-sglang&i_dates=2026-04-30%2C2026-05-07%2C2026-05-11%2C2026-05-20%2C2026-05-22%2C2026-05-28%2C2026-06-02%2C2026-06-03%2C2026-06-08&i_dstart=2026-04-30&i_dend=2026-06-08)
The most dramatic improvements for GB300 SGLang MTP came on June 2nd from the implementation of W4A4 (MXFP4) MegaMoE. Compared to the non-MTP implementation that was in use on May 7th, the main improvements in the June 2nd version came entirely from a rewrite of the GB300 decode topology rather than touching kernels or precision. While the Day 0 recipe ran at most points with narrow EP=8 fed by one or two prefill workers and capped concurrency at 16,384; the May 20th run widened decode to EP=16, scaled prefill to four–twelve workers per decode worker, and pushed concurrency to 21,504.
Based on the graph and analysis above, we can see that, as expected for a larger world size inference system, Wide EP is the main lever for GB300’s excellent performance which is delivered by amortized weight loading across more GPUs. Read the [InferenceX V2](https://newsletter.semianalysis.com/p/inferencex-v2-nvidia-blackwell-vs) article to find out more about Wide EP.
These results for GB300 were only possible due to CoreWeave’s support.
## B200 Tokens Per Megawatt (MW) Improvements
For the B200 with the vLLM engine, token throughput per all-in provisioned utility megawatt reached 300,000 tokens per second per MW for 50 tok/s/user interactivity on Day 0, improving to nearly 500,000 tokens per second per MW by June 5th.
[Live chart](https://inferencex.semianalysis.com/inference?g_model=DeepSeek-V4-Pro&g_rundate=2026-06-05&g_runid=27002889438&i_metric=y_tpPerMw&i_gpus=b200_vllm&i_dates=2026-04-28&i_dstart=2026-04-27&i_dend=2026-06-05&i_hc=1&i_linelabel=1)
Tokens per all-in provisioned-utility MW is the best figure of merit for considering return on investment at the fleet scale: It adds more information to raw per-GPU token throughput because it reflects PUE and datacenter overhead. Because a B200's all-in utility power envelope is fixed near 2.17 kW/GPU, that ~1.7x jump from ~300k to ~500k tok/s/MW reflects a pure software gain.
The same class of optimizations that pushed the throughput frontier (MegaMoE grouped-FP4 GEMMs, wider EP, the FP4 weight path, scheduler tuning) drop straight through to power efficiency because the all-in utility power in MW is unchanged.
Many organizations approach inference fleets from a perspective of maximizing a scarce quantity of utility power. The question is how one can convert provisioned MW into as many billed tokens as possible at a given utilization and price. This analysis is best informed by metrics like revenue per MW, tokens per all-in utility power, capex per MW among others. This is a business case that our [Tokenomics model](https://semianalysis.com/tokenomics-model/) is built to address.
## Current Performance As of June 6, 2026
Let’s round out this section on performance improvements by quickly reviewing the best performance across systems and inference engines. When using SGLang, the GB300 continues to dominate and mogs all other inference systems, demonstrating the advantage of the GB300 NVL72’s rack-scale world size.
[Live chart](https://inferencex.semianalysis.com/inference?g_model=DeepSeek-V4-Pro&g_rundate=2026-06-05&g_runid=27002889438&i_active=b300_sglang_mtp%2Cgb300_dynamo-sglang%2Cgb300_dynamo-sglang_mtp%2Cmi355x_sglang_mtp&i_linelabel=1)
When we switch on MTP, serving with the GB300 is unbeatable across all interactivity levels we analyzed. The cost per million output tokens for the GB300 reaches $0.156 at 50 tok/s/user assuming 8k tokens input, 1k tokens output. Find out more about how we calculate Total Cost of Ownership (TCO) in our [TCO model](https://semianalysis.com/ai-cloud-tco-model/).
[Live TCO calculator view](https://inferencex.semianalysis.com/calculator?g_rundate=2026-06-08&g_model=DeepSeek-V4-Pro&g_runid=27099659001)
The rack-scale advantage is fundamentally a scale-up domain story. NVL72 puts 72 GPUs in a single NVLink domain, which lets the serving stack run expert parallelism wide enough to keep DeepSeek V4's MoE dispatch/combine all-to-all entirely on NVLink instead of spilling onto the slower scale-out fabric, all while amortizing expert-weight loads across far more ranks.
B200 and B300 in 8-GPU NVLink islands scaled out over InfiniBand hits that wall much earlier, and the MI355X sits further back on both scale-up domain size and collective-stack maturity. Turning these per-rack throughput wins into deployed serving capacity is a separate question that comes down to how many of each SKU are actually online: shipments and ASPs by SKU, plus installed base and effective FLOPS by customer, quarter by quarter, which we track in our [Accelerator & HBM model](https://semianalysis.com/accelerator-hbm-model/).
### ROCm vLLM DeepSeek v4 Pro Disappointment
When it comes to ROCm, progress has been much slower for native vLLM vs native SGLang. Performance of ROCm vLLM is lagging far behind its CUDA vLLM counterpart. Part of the issue is that AMD is re-focusing on ATOM (an inference engine that serves 0 production tokens) instead of focusing on native vLLM (an inference engine that lots of their major customers uses). We will talk more about in our upcoming State of AMD 2026 article (covering the good, the bad, and the ugly when it comes to AMD inference). One of the positive developments we will be covering is that the functional enablement of distributed inferencing on open source out of the box upstream AMD vLLM has finally happened for non-DeepSeekv4 models. It took many months to get there, and there is still much ground for the AMD vLLM team to cover.
[Live chart](https://inferencex.semianalysis.com/inference?i_hc=1&g_model=DeepSeek-V4-Pro&g_rundate=2026-06-05&i_prec=fp4%2Cfp8&i_active=b200_vllm%2Cmi355x_vllm&g_runid=27002889438)
## What’s next for DeepSeek v4
### vLLM
vLLM’s plan is tracked in [the DeepSeek V4 roadmap issue (#40902),](https://github.com/vllm-project/vllm/issues/40902) with landed code in implementation PR #40860 and a description of benchmarking against SemiAnalysis’s InferenceX dashboard. The FP4 Indexer and initial MegaMoE support has already been implemented, and Hopper is now supported. The remaining work for vLLM for DeepSeek v4 spans five areas:
- **Core model support**: continued MegaMoE work (PR #40833) and NVFP4 support.
- **Runtime and parallelism**: Model Runner V2 integration, MTP optimizations, prefill/decode (PD) optimizations, and pipeline parallelism support.
- **Kernel integration**: a paged prefill kernel, a fast top-k kernel, more horizontal fusion, DeepEP V2, and integration with DeepSeek’s own TileKernels.
- **KV cache**: KV cache offloading, covering PD + CPU offloading (PR #39654) and distributed KV offloading.
- **Hardware support**: beyond the completed Hopper support, SM120 and AMD support remains as key to-do items.
The focal themes here are on the surrounding systems: a new model runner, pipeline parallelism, KV offloading, and wider hardware coverage.
Upcoming updates to InferenceX, SemiAnalysis’s open source & public’s EcosystemX dashboard will visualize the software evolution & CI coverage & queue times across all major ML open libraries across all major AI chips: NVIDIA, AMD, TPU, Trainium, Huawei, and more.
### SGLang
SGLang’s plan lives in [performance optimization tracker (#23666](https://github.com/sgl-project/sglang/issues/23666)) that Nvidia structured around DeepSeek v4’s network diagram, walking it block by block; some items may already be partially covered by the initial support PR (#23600), and community contributions are welcomed.
There are three high-level goals reflected here: CUDA graph support for decode, piecewise CUDA graph support for prefill, and no at-runtime weight processing. In addition, weight prep should happen once rather than per step. Within these three high level goals, the checklist is grouped by V4’s components:
- **mHC**: trying TF32/BF16 for the `fc_hc_fn` GEMM (which has a small N dimension and may need a special kernel), a 1/RMS + multiply fusion, single-kernel `hc_split_sinkhorn` and `hc_post`, and fusing MulSum + RMSNorm (+ FP8/MXFP8 quant) in the attention and MoE blocks.
- **HCA (with Compressor)**: horizontal fusion of `fc_qa` + `fc_kv` into one FP8 GEMM, q-norm/k-norm and RMSNorm+RoPE fusions, a non-sparse MQA path that drops `topk_idx`, MQA reading directly from the compressed and SWA KV-caches with no copy/concat, single-kernel InvRoPE, a fused Compressor state update (kv-update + ape-Add + score-update), and making HCA, especially the Compressor, CUDA-graph-compatible for decode.
- **CSA (Indexer + Compressor)**: similar direct cache reads for the sparse path, optional (P1) fusions of fc_compressor + fc_idx_compressor and fc_qb + fc_idx_qb, a (RoPE +) Hadamard + MXFP4-quant fusion, an efficient MXFP4 BMM+ReLU kernel (potentially fused with MulSum and even Top-1024), and CUDA-graph compatibility for the Indexer and Compressor.
- **MoE**: checking TF32/BF16 for the router GEMM, collapsing the routing path (softplus + sqrt + bias-add + Top-6 + gather + norm + multiply) into as few kernels as possible, fusing block-wise FP8 and MXFP8 activation quant, ensuring both shared-expert and routed-expert FC13 are single kernels, and auditing the tiny sorting kernels before the routed experts.
SGLang’s focus is replacing chains of small ops with single fused kernels, making the new attention variants read caches in place, and pulling the decode path fully into CUDA graphs.
## Section 2: Huawei 950DT Day 0 DeepSeek v4 Analysis
DeepSeek v4 was the first major open model with first class Day 0 support on the Huawei Ascend, and indeed, part of the DeepSeek official API has been served on Huawei since Day 0. We have Huawei performance numbers on DeepSeek v4 and plan to release a follow up article deep diving into an apples to apples comparison of inference on Huawei vs on the H200 and B200, measuring comparative performance using the same benchmark harness.
Our upcoming public open source SemiAnalysis EcosystemX dashboard will visualize the software evolution and CI coverage across all major ML open libraries, for all major AI chips, including the Ascend stack.
### CANN
CANN (Compute Architecture for Neural Networks) is Huawei’s software toolkit for running AI workloads on its own Ascend chips. Starting August 2025, they’ve open-sourced CANN to attract more developers and to “chip” away at Nvidia’s dominance, especially within China given that the US government heavily restricts CUDA chip shipments into China.
[Source](https://gitcode.com/cann/community/blob/master/events/meetup/slides/DeepSeek-V4/20260424/DeepSeek-V4%E6%98%87%E8%85%BE%E9%A6%96%E5%8F%91_%E5%9F%BA%E4%BA%8ECANN%E7%9A%84%E9%AB%98%E6%80%A7%E8%83%BD%E6%8E%A8%E7%90%86%E4%BC%98%E5%8C%96%E5%AE%9E%E8%B7%B5.pdf)
On Day 0, CANN released an optimization guide and benchmark figures for Ascend chips. Through it, we can see Huawei’s CANN strategy: To make Ascend competitive through full-stack inference optimization that is aimed at Chinese domestic model releases. Huawei is trying to show the Chinese ecosystem that if DeepSeek releases a new architecture, CANN can ship the kernels, graph path, quantization, serving integration, and deployment recipe.
One interesting methodology of the CANN team that we observed while benchmarking MTP and can’t help but mention was how they dealt with MTP draft token AR (acceptance rate) or AL (acceptance length). Benchmarking MTP is not trivial as the AR/AL of the benchmark may differ from the user’s use case. For example, a benchmark may on average accept two draft token out of three but with deployed use cases being extremely varied, it may end up only accepting 1.5 tokens out of three on average.
This means that the user may see lower performance compared to the benchmark, and thus wrongly conclude their setup is flawed. We addressed this in our [InferenceX v2 article](https://newsletter.semianalysis.com/i/188090866/multi-token-prediction-mtp) by comparing ARs with MTBench. Future iterations of our benchmark will comprehensively address this gap by using real traces.
To address this quirk, Huawei instead times the full decode step to coincide with the last MTP module, thus [recording time per decode step instead of time per token](https://gitcode.com/cann/cann-recipes-infer/blob/052e0ba122043bf46a2b5d17e16488e53e7b0b60/executor/core/engine/execution_engine.py#L451). The final benchmark result published then requires the user to multiply by their usecase’s MTP AL to derive comparable performance metrics, which is a very elegant way to compare performance.
### Hey NVIDIA Goliath, There’s a New David in Town - The Ascend 950
Huawei’s internal codename for Ascend 950 chips is “David”, and this codename is referenced multiple times in the CANN codebase. No doubt it is because they believe they are the David to Nvidia’s Goliath.
The SIMT/SIMD 950 chips come in two flavors: 950PR, and 950DT. PR stands for Prefill and Recommendation and are lower cost chips with better cost-performance. DT stands for Decode and Training, and this variant features higher memory bandwidth and higher performance. Both are based on the same Ascend 950 Die, which uses a dual-die UMA architecture, but they are each packaged with different memory. The Huawei roadmap estimates and volumes per quarter of each Huawei chip is available in the [SemiAnalysis Accelerator model.](https://semianalysis.com/accelerator-hbm-model/)
[Source](https://cann.csdn.net/69d8a96e54b52172bc684f2e.html)
Two major components of the chip architecture that are important to discuss are the AIC(AI Cube) and AIV(AI Vector). AIC is the **matrix/tensor core** side of Ascend’s AI Core. It is used for dense matrix math: GEMM, matmul, convolution-like tensor ops, attention projections, FFN linear layers, etc. Huawei documentation describes AIC as the **matrix-compute** core in split AI Core architectures. AIV is the **vector core** side. It handles elementwise/vector work: activation functions, normalization pieces, masking, reductions, type conversion, layout transforms, post-processing around matmuls, etc.
[Source](https://cann.csdn.net/69d8a96e54b52172bc684f2e.html)
This is similar to TPU’s MXU. However, Ascend exposes the split between the two functions more directly as separated independent cores, with each able to load its own code segment, and also feature a “dual-master mode,” where AIC and AIV independently run code rather than having the AIV driving the AIC through messages.
The AI CPU is a device-side ARM64 execution unit with direct access to device memory. It is used as a complement to AI Core for the work that maps poorly onto the SIMD/SIMT cores: branch-heavy control flow, scalar logic, dynamic-shape handling, and the value-dependent scheduling/tiling metadata that kernels need before they run. Because the AI CPU lives on the device, Ascend can keep this irregular control-style work local instead of round-tripping work to the host CPU, which is a primary source of latency and pipeline bubbles. The AI CPU is also the unit that historically sat on the older AICore → AICPU → SDMA path for communication orchestration, before the dedicated CCU offloaded that work.
Like the TPU and Trainium, Ascend 950 adds a dedicated CCU communication engine. This engine sits alongside the compute die and handles collective-communication work without consuming AI Core compute capacity by supporting remote-read + reduce + local-write, and local-read + remote-write. The benefit is in lower communication latency, less HBM traffic, fewer user-buffer copies, and freeing compute cores from comm orchestration, avoiding the older AICore -> AICPU -> SDMA path.
### Huawei DeepSeekV4 Pro 950DT Profile
The above shows a three step profile of DeepSeek flash v4 on Ascend 950DT, running using a config with a 16-rank DP/EP deployment. It shows 16-rank collective participation plus active MoE dispatch/combine traffic.
As is now standard across most stacks, CANN also uses independent compute and communication operators that can run on multiple streams - performance improves by controlling Cube and Vector core allocation to avoid resource contention. Operations like Prolog, Compressor, and LightningIndexer can be overlapped, C4A Compressor can be completely hidden, and shared expert computation can be hidden under routed expert execution without degrading routed expert performance.
Zooming into a given decode step, we can see how different components are split into streams. Operations on different streams may run concurrently when the device has free, suitable resources. Models use multiple streams because a layer may not be a single serial chain, and instead can contain branches that only need to synchronize when their results are combined, for instance a shared-expert compute overlapping 100% with routed-expert compute.
Streams 145-148 in the above diagram correspond to metadata streams. These operators fire once per decode pass and precompute value-dependent scheduler/tiling metadata that later kernels reuse. They are the only AI CPU ops in the decode step, they make up a tiny fraction of total time, and are fully overlapped with AI Core compute. The impact is likely larger on longer-context benchmarks, where there is more sequence-length and mask-dependent partitioning to resolve up front.
In DeepSeek v4, Huawei moves the value-dependent scheduler stage for sparse attention and the LightningIndexer onto the AI CPU rather than bouncing it back to the host. These metadata ops build reusable per-core partitioning tensors from runtime sequence-length, mask, and paged-KV information; `SparseAttnSharedkv` and `QuantLightningIndexer` then consume them to decide which Batch/Head/Q-block/K-block work each cube core handles, along with the corresponding vector-core reduction tasks. Conceptually, this mirrors FlashInfer’s planning phase on host for paged attention: a cheap, dynamic-shape-aware setup step that runs once and is thus amortized over layers, with the only caveat being that Huawei pushes that same planning work onto the on-device AI CPU instead of the host.
Stream 152 in the diagram above contains the LM head, the last layer, and the second last layer’s `o_proj` and MoE. This is a decision of the `npugraph_ex` graph compiler, likely to allow the `npugraph_ex` runtime to consider the main graph “complete” on stream 144 while the tail work continues asynchronously.
CANN also introduced MC² (merged compute-communication) back in 2024. This is a class of fused operators that are not ordinary kernels nor HCCL collectives. They embed communication and compute into one kernel. In DeepSeek v4 decode, we can see `MoeDistributeDispatchV2` and `MoeDistributeCombineV2` MC² EP operators being used.
The main takeaway here is that Ascend delivers working, optimized inference infrastructure for DeepSeek v4 on Day 0. The Huawei CANN stack is one of only two stacks with Day 0 Support for DeepSeekV4, the other being Nvidia’s CUDA. As we explained earlier in the article, AMD’s stack unfortunately did not work well on Day 0. This is in stark contrast to last year when DeepSeek v3/R1 released. Back then, only one stack worked on Day 0: the Nvidia CUDA stack.
[Source](https://x.com/deepseek_ai/status/2057854261699195173)
The biblical story that gave the Ascend 950 its internal codename ends with the giant face-down. But the Goliath in that story stood still and let David sling stones at him, whereas Nvidia’s Goliath is constantly in motion, ships a new architecture every year and improves existing architectures. Huawei has proven it can sling a stone on Day 0; whether it can fell a moving giant is yet to be seen.
## DeepSeek V4 Architecture Deep Dive and Co-Design
### Inference Optimizations for 1M Context Length
DeepSeek v4 features Compressed Sparse Attention (CSA) and Heavily Compressed Attention (HCA), walking away from Multi-head Latent Attention (MLA). The design is heavily motivated by KV cache size reduction.
In essence, HCA’s KV cache consists of a sliding window of the KV embeddings and a set of compressed KV entries, where each entry compresses key / value into one and across m′ tokens (m′ = 128 for DeepSeek V4 Pro).
CSA uses the same KV cache compression technique as HCA, but with a lower compression rate (m=4). CSA also applies sparse attention on the compressed KV entries by using a lightning indexer to select tokens to attend to. The sparse attention inherits DeepSeek Sparse Attention in DeepSeek v3.2.
By interleaving CSA and HCA, DeepSeek v4 aggressively compressed KV cache size, resulting in 50x KV cache reduction at 1M context length.
However, the novelty of CSA and HCA creates KV cache management challenges for serving frameworks. For example, vLLM’s KV cache memory allocator implements complex strategies to ensure efficient memory loading patterns and support serving features like prefix caching. This includes setting a logical block size that divides the KV compression rates of both CSA and HCA, and a page size bucketing strategy to avoid memory fragmentation due to storing the KV cache, compressor states, indexer KV, each having a different size per entry.
### Determinism
To ensure RL training stability, DeepSeek went all in on making computation deterministic. This effort shows when looking into GPU kernels and their rollout infrastructure. DeepSeek wrote custom kernels for all operations to achieve batch invariance by enforcing a specific reduction order regardless of batch size. This includes batch-invariant split KV attention forward, GEMMs, and MoE backward kernels. Batch-invariant kernels come at a performance loss because using them prohibits many popular algorithmic techniques that don’t guarantee deterministic reduction order. DeepSeek mitigates the performance loss by writing kernels that are tailored for their workload, for instance specializing kernels for matrix shapes. On the rollout infrastructure side, DeepSeek focused on fault tolerance to make all rollouts reproducible. DeepSeek built a token-granular write-ahead log for each generation request, so any request preempted during either prefill or decode can be resumed without recomputation.
## MegaMoE
The DeepSeek V4 release also included a new fused MoE kernel that achieves better overlap of all of the operations in the MoE layer. MoE with expert parallelism consists first of a token dispatch all-to-all followed by Linear1, Activation, Linear 2, and finally a token combine all-to-all. Linear 1 and Linear 2 are grouped GEMM operations where each expert in a given rank has its weights applied to its routed tokens. The authors mention in the DeepSeek V4 paper that other implementations overlap/interleave the token dispatch with Linear 1 and the Combine with Linear 2, but there is still a sync across all experts at the operation boundaries, between Linear 1, Activation, and Linear 2. MegaMoE instead splits experts into waves and schedules each wave separately, allowing for finer-grained overlapping of each of the operations and resulting in more of the communication latency being hidden. This is reminiscent of compute-comms fusions such as distributed GEMM, where a compute kernel and a dependent communication kernel are overlapped by breaking the workload into smaller pieces and pipelining to hide communication latency.
The paper claims a theoretical speedup of 1.92x over the naive kernel in the DeepSeek v4 Flash configuration, which means that the naive kernel must spend close to 50% of its time on Dispatch and Combine communication!
Now that we have discussed performance benchmarks in detail, let’s discuss total cost of ownership and cost per token when running DeepSeek v4 on H200 and the GB200 NVL72.
Click to see the full DeepSeekV4 InferenceX dashboard →
_The article continues with the full total cost of ownership and cost-per-token analysis for H200 and GB200 NVL72 in the [subscriber edition on the SemiAnalysis newsletter](https://newsletter.semianalysis.com/p/deepseekv4-16t-day-0-to-day-43-performance)._
{`{
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [
{
"@type": "Question",
"name": "How much did MI355X SGLang DeepSeek V4 Pro performance improve in the first 26 days?",
"acceptedAnswer": {
"@type": "Answer",
"text": "AMD MI355X SGLang DeepSeek V4 Pro throughput improved by more than 100x in the first 26 days after launch. The Day 0 FP8 build on 2026-04-25 was technically working but pinned at 1-2 tok/s/user interactivity, far below usable serving levels. The gains came almost entirely from replacing PyTorch-native fallback paths with real AITER, Triton, TileLang, and FlyDSL kernels, with major step changes from enabling native FP4 (MXFP4) weight MoE, introducing AITER mHC kernels at every layer, and retiring remaining fallbacks (FlashMLA from TileLang to Triton, AITER FlyDSL FP4 MoE, fused hash-topk, DSv4 radix attention, fused store-cache, fused WQA/WKV projection, and fused paged-compress). Measured on InferenceX."
}
},
{
"@type": "Question",
"name": "What is the cost per million output tokens for DeepSeek V4 Pro on GB300 NVL72 with MTP?",
"acceptedAnswer": {
"@type": "Answer",
"text": "On GB300 NVL72 SGLang with MTP enabled, DeepSeek V4 Pro reaches $0.156 per million output tokens at 50 tok/s/user on the 8K input / 1K output workload, per the InferenceX TCO calculator. The rack-scale advantage comes from NVLink scale-up to 72 GPUs, which lets DeepSeek V4's MoE dispatch/combine all-to-all run entirely on NVLink instead of spilling onto the slower scale-out fabric, while amortizing expert-weight loads across far more ranks. 8-GPU NVLink islands like B200 and B300 hit that wall much earlier when scaled out over InfiniBand."
}
},
{
"@type": "Question",
"name": "What is the DeepSeek V4 attention architecture and how does CSA / HCA reduce KV cache?",
"acceptedAnswer": {
"@type": "Answer",
"text": "DeepSeek V4 replaces Multi-head Latent Attention (MLA) with Compressed Sparse Attention (CSA) and Heavily Compressed Attention (HCA). HCA's KV cache combines a sliding window of KV embeddings with compressed KV entries, each entry compressing key and value across 128 tokens (m'=128) for DeepSeek V4 Pro. CSA uses the same compression mechanism at a lower rate (m=4) and applies sparse attention on the compressed entries via a lightning indexer that inherits the sparse-attention pattern from DeepSeek V3.2. Interleaving CSA and HCA delivers a roughly 50x reduction in KV cache size at 1M context length."
}
},
{
"@type": "Question",
"name": "How did B200 vLLM tokens per provisioned megawatt improve for DeepSeek V4 Pro?",
"acceptedAnswer": {
"@type": "Answer",
"text": "B200 vLLM tokens per second per all-in provisioned utility megawatt improved from about 300,000 on Day 0 to nearly 500,000 by 2026-06-05 at 50 tok/s/user interactivity on DeepSeek V4 Pro. Because B200's all-in utility power envelope is fixed near 2.17 kW per GPU, this roughly 1.7x jump is a pure software gain from MegaMoE grouped-FP4 GEMMs, wider expert parallelism, the FP4 weight path, and scheduler tuning. Tokens per all-in provisioned-utility MW is the best figure of merit for fleet-scale ROI because it reflects PUE and datacenter overhead alongside raw per-GPU throughput."
}
},
{
"@type": "Question",
"name": "What is MegaMoE in DeepSeek V4 and how much does it speed up MoE layers?",
"acceptedAnswer": {
"@type": "Answer",
"text": "MegaMoE is a fused MoE kernel introduced with DeepSeek V4 that splits experts into waves and schedules each wave separately, achieving finer-grained overlap between the dispatch all-to-all, Linear 1, Activation, Linear 2, and combine all-to-all than prior implementations that synced at every operation boundary. The DeepSeek V4 paper reports a theoretical 1.92x speedup over the naive kernel in the DeepSeek V4 Flash configuration, which implies the naive kernel spends close to 50% of its time on dispatch and combine communication."
}
},
{
"@type": "Question",
"name": "Which inference stacks shipped Day 0 support for DeepSeek V4 Pro?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Only NVIDIA CUDA (via native SGLang and native vLLM) and Huawei CANN on Ascend 950DT shipped working Day 0 support for DeepSeek V4 Pro. AMD ROCm on MI355X worked technically but was pinned at 1-2 tok/s/user interactivity, well below usable serving levels. NVIDIA TensorRT-LLM was broken out of the box because mhcFusedHcKernel.cu had a hardcoded FHC_HIDDEN=4096 constant that silently corrupted hidden states for DeepSeek V4 Pro's 7168 hidden size; a SemiAnalysis-authored patch was merged days later. This is a sharp contrast to the DeepSeek V3 / R1 launch where only NVIDIA CUDA worked on Day 0."
}
}
]
}`}
---
# GB300 NVL72 vs GB200 NVL72 Inference Performance & Perf per Dollar - on DeepSeek-V4-Pro 1.6T: Up to 2.83x Throughput
> DSv4-Pro FP4 8K/1K, Dynamo+vLLM, disaggregated on both racks. GB300's 50% extra HBM (288 vs 192 GB/GPU) unlocks a wider prefill+decode recipe GB200 can't fit — lifting middle-of-curve perf/$ by 2.31x despite a 20% per-GPU TCO premium.
- **Author**: SemiAnalysis
- **Date**: 2026-05-27
- **URL**: https://inferencex.semianalysis.com/blog/gb300-nvl72-vs-gb200-nvl72-dsv4-pro-vllm-fp4
- **Tags**: benchmark, gpu, inference, deepseek, nvidia, gb300, gb200, nvl72, vllm, dynamo, wide-ep, disagg
- **Reading time**: 11 min
On DeepSeek-V4-Pro FP4 at 8K/1K with Dynamo vLLM and disaggregated prefill/decode on both racks, GB300 NVL72 delivers **up to 2.83x throughput per GPU vs GB200 NVL72 at iso-interactivity**, peaking at 27 tok/s/user (6,182 tok/s/GPU on GB300 vs 2,189 tok/s/GPU on GB200). On paper the silicon delta looks modest — same memory bandwidth, same NVLink fabric, same scale-up world size, only 1.5x more HBM capacity and 1.5x more FP4 — but the middle-of-curve gap blows past every static ratio because GB300's extra HBM removes a software constraint GB200 has to pay for.
The mechanism is **HBM headroom**. At 1.6T params, DSv4-Pro's FP4 weights alone are about 800 GB, and on GB200 the available HBM at narrow prefill shapes is tight enough that the recipe has to compromise on batch size to fit. GB300's 1.5x HBM capacity (288 vs 192 GB/GPU) holds the same model on the same shape with hundreds of GB of headroom to spare, so prefill can run a wider batch that keeps the wider decode pool saturated. After a 20% per-GPU TCO premium ($2.65 vs $2.21/GPU/hr per the [SemiAnalysis AI Cloud TCO Model](https://semianalysis.com/ai-cloud-tco-model/)), GB300 still lands **2.31x cheaper per million tokens at 27 tok/s/user**. More HBM, more save.
Click to see the full InferenceX dashboard →
## DeepSeek-V4-Pro Model Architecture
DeepSeek-V4-Pro is DeepSeek's flagship MoE: **1.6T total parameters with 49B activated per token** (per the [DeepSeek V4 preview announcement](https://api-docs.deepseek.com/news/news260424)). The architecture pairs **token-wise compression** with **DSA (DeepSeek Sparse Attention)** — the sparse-attention pattern DeepSeek introduced in V3.2, extended to longer context (the official services run DSv4 at 1M default). The open-weights checkpoint is [`deepseek-ai/DeepSeek-V4-Pro`](https://huggingface.co/deepseek-ai/DeepSeek-V4-Pro).
## On-Paper Specs
GB300 NVL72 (Blackwell Ultra) and GB200 NVL72 (Blackwell) share the same NVLink 5 scale-up fabric, the same 72-GPU world size, the same NVSwitch generation, and the same 8 TB/s HBM bandwidth per GPU. The deltas are HBM capacity and dense FP4. Values pulled directly from [/gpu-specs](/gpu-specs):
| Spec | GB200 NVL72 | GB300 NVL72 | GB300 / GB200 |
| ---------------------------------- | ------------------- | ------------------- | ------------- |
| HBM capacity | 192 GB | 288 GB | **1.50x** |
| HBM bandwidth | 8 TB/s | 8 TB/s | 1.00x |
| Dense FP4 (TFLOP/s) | 10,000 | 15,000 | **1.50x** |
| Dense FP8 (TFLOP/s) | 5,000 | 5,000 | 1.00x |
| Dense BF16 (TFLOP/s) | 2,500 | 2,500 | 1.00x |
| Scale-up BW per GPU (uni-di) | 900 GB/s (NVLink 5) | 900 GB/s (NVLink 5) | 1.00x |
| Scale-up world size | 72 | 72 | 1.00x |
| Scale-up domain HBM capacity | 13.5 TB | 20.25 TB | **1.50x** |
| Scale-up domain HBM BW (aggregate) | 576 TB/s | 576 TB/s | 1.00x |
| TCO (SemiAnalysis AI Cloud Model) | $2.21/GPU/hr | $2.65/GPU/hr | 1.20x |
If decode were purely HBM-bandwidth-bound and prefill were purely FP4-compute-bound, the on-paper perf/$ ceiling would be `1.50 / 1.20 = 1.25x` on either bottleneck. The measured **2.31x perf/$ peak is 1.85x higher than that ceiling** — which is the entire point of the post. The lift comes from a regime where the **silicon ratio understates the system gain**: HBM capacity is a discrete unlock for what recipe even fits, not a continuous knob, and a wider prefill+decode shape that one rack can run and the other can't is worth a factor that doesn't appear on any spec sheet.
## What Disagg + Wide EP Actually Buy You
Inference on a sparse MoE has two phases with opposite resource profiles. **Prefill** is compute-bound: every token in a request is processed in parallel through the entire model, so DSv4-Pro's 384-routed-expert MoE lights up every expert at every layer for every prompt. **Decode** is memory-bandwidth-bound: each generated token only activates 6 of 384 routed experts (plus 1 shared expert) per layer, and the per-step cost is dominated by streaming whichever experts got routed through HBM. Running both on the same GPUs means prefill bursts constantly disrupt steady-state decode, and you end up underutilizing both.
**Disaggregation** splits them onto separate GPU pools that get tuned independently. Prefill instances run wide enough to amortize the all-experts-active compute step; decode instances run with whatever (TP, EP, DP) shape gives the best tokens-per-step under steady-state load. The two pools talk over the NVLink fabric (KV transfer from prefill → decode), and you can scale each independently.
**Wide expert parallelism (EP)** then takes the decode side and shards the routed experts across many ranks. At EP=4 each GPU holds 96 of DSv4-Pro's 384 routed experts, all of which must be resident in HBM and ready to stream for any token that routes to them. At EP=8 each GPU holds 48. At EP=16 each GPU holds 24 — the per-rank routed-expert weight footprint shrinks roughly linearly, and the rest of HBM goes to KV cache and activations. The wider you shard, the more thinly each GPU's HBM bandwidth has to spread when servicing requests routed to its experts, and the more efficient per-GPU decode becomes. Every additional rank in the EP group is doing useful work for every other rank — _that's_ the "more you buy, the more you save" lever, applied not to bulk-rate hardware discounts but to actual silicon utilization.
The catch is that wide EP fires a routed **all-to-all dispatch** before each MoE layer's expert GEMMs and an **all-to-all combine** after. Across DSv4-Pro's MoE layers that is hundreds of collectives per token. They have to overlap behind the GEMM compute or they expose themselves as raw latency. On NVLink 5 (900 GB/s per GPU uni-di, 1.8 TB/s bi-di), the dispatch fits inside the GEMM time budget for EP=8 through EP=16 medium-batch decode, and the runtime hides it. On the scale-out side (ConnectX-7 RoCEv2 Ethernet or InfiniBand at 50 GB/s per GPU uni-di, **18x slower**), the same collective takes 18x longer and exposes itself — which is why wide EP requires the rack-scale NVLink island, and why both GB200 NVL72 and GB300 NVL72 win against any 8-GPU HGX node on this workload regardless of who shipped first.
## The Numbers
All rows are DeepSeek-V4-Pro FP4 at **ISL 8192 / OSL 1024** on NVL72, Dynamo vLLM, disaggregated prefill/decode, no speculative decoding, measured on InferenceX on 2026-05-22 ([GHA run 26306422380](https://github.com/SemiAnalysisAI/InferenceX/actions/runs/26306422380)). Cost per million total tokens is `TCO_$/GPU/hr × 1e6 / (3600 × tput_per_gpu)`, with GB200 NVL72 at $2.21/GPU/hr and GB300 NVL72 at $2.65/GPU/hr per the [SemiAnalysis AI Cloud TCO Model](https://semianalysis.com/ai-cloud-tco-model/).
**GB200 NVL72 (Dynamo vLLM), DSv4-Pro FP4 8K/1K disagg:**
| Conc | Prefill | Decode | tok/s/GPU | tok/s/user | TPOT (ms) | $/M tok |
| ---- | ------------ | ------------ | ----------- | ---------- | --------- | --------- |
| 1 | 8 GPU, TP=8 | 8 GPU, EP=1 | 32.8 | 74.13 | 13.26 | $18.72 |
| 256 | 8 GPU, TP=8 | 32 GPU, EP=1 | 1,613.8 | 32.69 | 30.83 | $0.38 |
| 512 | 8 GPU, TP=8 | 32 GPU, EP=1 | 2,004.5 | 28.31 | 35.46 | $0.31 |
| 256 | 8 GPU, TP=8 | 8 GPU, EP=8 | 3,148.0 | 24.42 | 41.23 | $0.20 |
| 512 | 8 GPU, TP=8 | 8 GPU, EP=8 | 5,336.2 | 21.26 | 47.43 | $0.10 |
| 1024 | 8 GPU, TP=8 | 8 GPU, EP=8 | 6,036.2 | 21.60 | 46.42 | $0.10 |
| 4096 | 16 GPU, TP=8 | 8 GPU, EP=8 | 8,153.1 | 18.51 | 54.34 | $0.08 |
| 4096 | 24 GPU, TP=8 | 8 GPU, EP=8 | **8,933.0** | **15.26** | **66.26** | **$0.07** |
**GB300 NVL72 (Dynamo vLLM), DSv4-Pro FP4 8K/1K disagg:**
| Conc | Prefill | Decode | tok/s/GPU | tok/s/user | TPOT (ms) | $/M tok |
| ---- | ------------ | ------------- | ------------ | ---------- | --------- | --------- |
| 18 | 4 GPU, TP=4 | 68 GPU, EP=1 | 138.8 | 73.43 | 13.58 | $5.31 |
| 192 | 4 GPU, TP=4 | 24 GPU, EP=1 | 1,920.0 | 36.78 | 27.44 | $0.38 |
| 3072 | 28 GPU, TP=8 | 32 GPU, EP=16 | 6,812.0 | 25.91 | 38.77 | $0.11 |
| 4096 | 16 GPU, TP=8 | 8 GPU, EP=8 | 10,214.0 | 17.58 | 57.12 | $0.07 |
| 4096 | 20 GPU, TP=8 | 8 GPU, EP=8 | 10,853.1 | 14.74 | 69.17 | $0.07 |
| 4096 | 24 GPU, TP=8 | 8 GPU, EP=8 | **11,055.6** | **13.12** | **77.83** | **$0.07** |
GB200's peak throughput per GPU is 8,933 at 15.3 tok/s/user. GB300's peak is 11,056 at 13.1 tok/s/user — **1.24x more tok/s/GPU at a lower interactivity floor**, close to the 1.5x silicon ratio after software overhead. The throughput-per-dollar at peak is essentially tied ($0.069 vs $0.067) because GB300's 20% TCO premium eats most of the 1.24x throughput lift. The headline ratio shows up not at peak but in the middle of the curve, where GB300's HBM headroom buys a recipe GB200 doesn't have.
## Iso-Interactivity Comparison
Throughput per GPU and cost per million tokens at matched interactivity, interpolated along each SKU's Pareto frontier. Cells outside a frontier's measured range render as `_unreachable_`.
| Interactivity (tok/s/user) | GB200 tok/s/GPU | GB300 tok/s/GPU | GB300 / GB200 | GB200 $/M tok | GB300 $/M tok | GB200 / GB300 |
| -------------------------- | --------------- | --------------- | ------------- | ------------- | ------------- | ------------- |
| 16 | 8,835 | 10,608 | 1.20x | $0.07 | $0.07 | 1.00x |
| 18 | 8,366 | 10,094 | 1.21x | $0.07 | $0.07 | 1.01x |
| 20 | 7,283 | 9,401 | 1.29x | $0.08 | $0.08 | 1.07x |
| 22 | 5,650 | 8,562 | 1.52x | $0.11 | $0.08 | 1.31x |
| 25 | 2,846 | 7,208 | 2.53x | $0.21 | $0.10 | 2.11x |
| **27** | **2,189** | **6,182** | **2.83x** | **$0.28** | **$0.12** | **2.31x** |
| 28 | 2,058 | 5,789 | 2.81x | $0.30 | $0.13 | 2.30x |
| 32 | 1,661 | 3,570 | 2.15x | $0.36 | $0.21 | 1.76x |
| 36 | 1,376 | 2,036 | 1.48x | $0.65 | $0.35 | 1.88x |
| 50 | 649 | 941 | 1.45x | $4.78 | $1.58 | 3.03x |
The headline **2.83x throughput per GPU peak at 27 tok/s/user (2.31x perf/$) sits in the middle of the curve**, not at peak throughput. Below 20 tok/s/user both racks run wide enough prefill batches that the HBM-headroom advantage rounds away; above 36 tok/s/user both run narrow batches where neither rack has a recipe that wide-EP can fully exploit. The 22–32 tok/s/user band is where GB300's 1.5x HBM capacity lets it sit on a higher Pareto knot (`conc=3072, 28 GPU prefill, 32 GPU decode EP=16, 6,812 tok/s/GPU at 25.9 tok/s/user`) that GB200 has no equivalent for — its closest recipes at the same interactivity are conc=256 / 512 on a 32-GPU decode pool that delivers only 1,614–2,005 tok/s/GPU.
The 50 tok/s/user row shows the cost ratio (3.03x) widening again as both curves enter their steep right-side decay. The interpretation here is more cautious — both racks have very thin Pareto coverage out there (one knot each at ~33 tok/s/user for GB200 / ~37 tok/s/user for GB300, then the long tail out to ~73 tok/s/user), so the interpolated values are reading a wide gap between two measured knots. The 22–32 tok/s/user band is the honest sweet spot for the GB300 advantage; treat the 50 tok/s/user row as directional.
[Live chart](https://inferencex.semianalysis.com/inference?g_rundate=2026-05-22&g_runid=26306422380&i_active=gb200_dynamo-vllm%2Cgb300_dynamo-vllm&g_model=DeepSeek-V4-Pro&i_linelabel=1), pre-filtered to GB200 NVL72 and GB300 NVL72 Dynamo vLLM on DSv4-Pro FP4 8K/1K for the 2026-05-22 run.
## Acknowledgments
Thanks to NVIDIA's Dynamo and vLLM teams — including Jatin Gangani, Kedar Potdar, Sridhar Ramaswamy, Ishan Dhanani, and Sahithi Chigurupati — and the vLLM team for shipping the GB200 and GB300 DSv4-Pro recipes that made the rack-to-rack comparison possible. Companion piece: [GB200 NVL72 vs B200 on DeepSeek R1](https://inferencex.semianalysis.com/blog/gb200-nvl72-vs-b200-disagg-deepseek-r1-fp4-dynamo-trt) covers the scale-up fabric advantage one step down the SKU ladder.
Click to see the full InferenceX dashboard →
{`{
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [
{
"@type": "Question",
"name": "How much faster is GB300 NVL72 than GB200 NVL72 on DeepSeek-V4-Pro with Dynamo vLLM?",
"acceptedAnswer": {
"@type": "Answer",
"text": "On DSv4-Pro FP4 at 8K/1K with Dynamo vLLM and disaggregated prefill/decode on both racks, GB300 NVL72 delivers up to 2.83x throughput per GPU vs GB200 NVL72 at iso-interactivity, peaking at 27 tok/s/user (6,182 vs 2,189 tok/s/GPU on the dashboard's Pareto interpolation). The peak cost-per-million-tokens advantage is 2.31x at the same interactivity after factoring in GB300's 20 percent TCO premium ($2.65 vs $2.21 per GPU per hour). Below 20 tok/s/user the gap shrinks to about 1.2x because both racks run wide prefill batches; above 36 tok/s/user both run narrow batches where neither has a recipe wide EP can exploit. Measured on InferenceX, GHA run 26306422380, 2026-05-22."
}
},
{
"@type": "Question",
"name": "Why does GB300 NVL72 win in the middle of the throughput-interactivity curve despite identical NVLink bandwidth?",
"acceptedAnswer": {
"@type": "Answer",
"text": "The gap is HBM capacity, not NVLink. DSv4-Pro is 1.6T parameters with about 800 GB of FP4 weights. GB300's 1.5x HBM capacity (288 vs 192 GB per GPU) gives the prefill side enough headroom to run a meaningfully wider batch on the same TP shape, which is what keeps a wider decode pool saturated and lifts per-GPU throughput. In the 22–32 tok/s/user band GB300 sits on a Pareto knot (conc=3072, 28 GPU prefill, 32 GPU decode EP=16) that GB200 has no equivalent for at the same interactivity — its closest recipes deliver only 1,614–2,005 tok/s/GPU vs GB300's 6,812 at 25.9 tok/s/user."
}
},
{
"@type": "Question",
"name": "Is GB300 NVL72 cheaper per million tokens than GB200 NVL72 in this comparison?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Yes in the 22–32 tok/s/user band, essentially tied at peak throughput. GB300's TCO is about 20 percent higher per GPU-hour ($2.65 vs $2.21 per the SemiAnalysis AI Cloud TCO Model), which dilutes the throughput advantage in cost terms. At peak throughput (13–18 tok/s/user) cost is essentially tied: 1.00x to 1.07x in favor of GB300. At 27 tok/s/user the cost gap is 2.31x (GB200 $0.28 per million tokens vs GB300 $0.12). At 50 tok/s/user the interpolated cost gap widens to 3.03x but with thin Pareto coverage on both sides, so treat the very-high-interactivity rows as directional rather than definitive."
}
},
{
"@type": "Question",
"name": "Does the GB300 advantage scale to other workloads and other models?",
"acceptedAnswer": {
"@type": "Answer",
"text": "The mechanism (HBM-headroom-driven wide-EP recipe unlock) generalizes to any sparse MoE large enough that the FP4 weight footprint approaches a single-GPU HBM capacity at narrow prefill shapes. DeepSeek-R1 0528 at 671B / 37B active is half the weight footprint of DSv4-Pro and fits more comfortably on GB200, so the GB300 lift on R1 is smaller. Kimi K2.5 / K2.6 at 1T / 32B active sits in between. Models with much smaller weight footprints (Qwen3.5, GLM-5, MiniMax-M2.5, gpt-oss-120b) won't show this gap because the model fits comfortably on either rack — for those, the relevant lever is dense FP4 compute (1.5x on GB300) and the gap stays closer to the silicon ratio. Workloads with longer context than 8K compound the GB300 advantage because KV cache scales linearly with sequence length, and the 1.5x HBM headroom translates directly into 1.5x more in-flight tokens at the same TP shape — but no InferenceX recipe at 1M-context DSv4-Pro has shipped yet."
}
}
]
}`}
---
# B200 NVFP4 vs H200 FP8 on GLM-5: Up to 3.65x Better Performance per Dollar with SGLang MTP
> Both SKUs run SGLang EAGLE MTP; the Blackwell generation lifts perf/$ by ~1.2x at the peak and the NVIDIA GLM-5-NVFP4 checkpoint on FlashInfer TRT-LLM sparse MLA stacks another ~2.4–3.0x on 8K/1K
- **Author**: SemiAnalysis
- **Date**: 2026-05-26
- **URL**: https://inferencex.semianalysis.com/blog/b200-glm5-nvfp4-vs-h200-fp8-3-6x-perf-per-dollar
- **Tags**: benchmark, gpu, inference, glm5, nvidia, b200, h200, sglang, fp4
- **Reading time**: 12 min
On GLM-5 8K/1K with both H200 and B200 running SGLang, NVIDIA's GLM-5-NVFP4 checkpoint on B200 delivers **up to 3.65x better performance per dollar than H200 SGLang FP8 at iso-interactivity** — H200 at $1.06/M tokens vs B200 NVFP4 at $0.29/M tokens at 80 tok/s/user. The lift stays in a 3.24x–3.65x band across H200's full 25–84 tok/s/user operating range. Measured on InferenceX as of 2026-05-25 on SGLang v0.5.12.
The 3.65x factors cleanly at the peak. At 80 tok/s/user, **B200 SGLang FP8 + MTP delivers 1.22x better performance per dollar than H200 SGLang FP8 + MTP** — the Blackwell generation + software step alone, with the same precision and the same EAGLE recipe on both sides. **Swapping the B200 weights from `zai-org/GLM-5-FP8` to `nvidia/GLM-5-NVFP4` stacks another 2.98x** — the precision step alone, riding on FlashInfer's TRT-LLM sparse MLA kernels that landed as the default on sm100/sm103 in [sgl-project/sglang #21783](https://github.com/sgl-project/sglang/pull/21783). 1.22 × 2.98 ≈ 3.65. The two steps trade places across the band — generation contributes more at low interactivity (1.36x at 50 tok/s/user) and precision contributes more at high (3.07x at 84 tok/s/user) — but the combined lift is steady.
Click to see the full InferenceX dashboard →
GLM-5 is ZAI's (Zhipu) MoE flagship, released 2026-02-11 — roughly 14 weeks before this run. It's a **744B-parameter sparse MoE with ~40B activated per token**: 256 experts with top-8 routing (~5.9% sparsity) plus shared experts, **DeepSeek Sparse Attention (DSA)** on decode paired with Multi-head Latent Attention (MLA) for KV-cache compression, and a 200K context window. The published architecture name is `glm_moe_dsa` — the same sparse-attention pattern DeepSeek introduced in V3.2 and that SGLang's TRT-LLM sparse MLA backend on Blackwell was tuned around.
NVIDIA additionally published a quantized weights release at [`nvidia/GLM-5-NVFP4`](https://huggingface.co/nvidia/GLM-5-NVFP4) — the same model architecture as `zai-org/GLM-5-FP8`, with all MoE GEMM weights re-cast from FP8 to NVFP4 (16-element blocks, FP8 per-block scales, FP32 per-tensor scale). The KV cache stays FP8. This is the checkpoint the B200 line in the chart loads; the H200 line loads `zai-org/GLM-5-FP8` because Hopper has no FP4 tensor cores.
## On-Paper Specs
Before the recipes, the hardware. H200 SXM (Hopper) and B200 SXM (Blackwell) sit one generation apart. The radar below normalizes each axis to the maximum across every NVIDIA + AMD SKU in [`/gpu-specs`](/gpu-specs) — so the visible H200 and B200 polygons compress against axes where GB200/GB300 NVL72 set the ceiling (notably scale-up domain memory and scale-up domain memory bandwidth, which scale with the rack-scale 72-GPU NVLink domain).
Absolute values for the two SKUs in this benchmark:
| Spec | H200 SXM | B200 SXM | B200 / H200 |
| ---------------------------------- | ------------------- | ------------------- | ----------- |
| HBM capacity | 141 GB (HBM3e) | 180 GB (HBM3e) | 1.28x |
| HBM bandwidth | 4.8 TB/s | 8.0 TB/s | 1.67x |
| Dense FP4 (TFLOP/s) | — | 9,000 | — |
| Dense FP8 (TFLOP/s) | 1,979 | 4,500 | 2.27x |
| Dense BF16 (TFLOP/s) | 989 | 2,250 | 2.28x |
| Scale-up BW per GPU (uni-di) | 450 GB/s (NVLink 4) | 900 GB/s (NVLink 5) | 2.00x |
| Scale-up world size | 8 | 8 | 1.00x |
| Scale-up domain HBM capacity | 1,128 GB | 1,440 GB | 1.28x |
| Scale-up domain HBM BW (aggregate) | 38.4 TB/s | 64.0 TB/s | 1.67x |
| TCO (SemiAnalysis AI Cloud Model) | $1.41/GPU/hr | $1.95/GPU/hr | 1.38x |
The implication for an FP8-vs-FP8 comparison: with the same precision and the same recipe, B200's perf/$ ceiling vs H200 is bounded by `2.27 / 1.38 ≈ 1.64x` on a fully compute-bound workload and by `1.67 / 1.38 ≈ 1.21x` on a fully memory-bandwidth-bound workload (using HBM as the bandwidth axis; NVLink BW would push the bound up to `2.00 / 1.38 ≈ 1.45x`). The measured 1.22x at 80 tok/s/user lands inside the memory-bandwidth bracket — GLM-5 decode at this concurrency is dominated by HBM reads of MoE weights and KV-cache, not FP8 GEMM throughput, so the dense compute headroom on Blackwell mostly stays on the table. NVFP4 is the lever that breaks the GEMM ceiling: H200 has zero FP4 tensor cores, B200 has 9 PFLOP/s, and the resulting precision step compounds 2.41x–3.07x on top of the generation step.
## What Shipped to Make This Happen
**Upstream stack.** SGLang [v0.5.10](https://github.com/sgl-project/sglang/releases/tag/v0.5.10) (2026-04-07) was the first stable release where GLM-5 ran end-to-end on Blackwell across all four precision/MTP/disagg variants — the [tracking issue #19380](https://github.com/sgl-project/sglang/issues/19380) flipped every Functional and Baseline Perf row to DONE the same day. The benchmark in this post runs [v0.5.12](https://github.com/sgl-project/sglang/releases/tag/v0.5.12) (released 2026-05-16), which inherits the same Blackwell defaults plus the round-1 perf optimizations on top. The kernel changes that matter:
- [sgl-project/sglang #21783](https://github.com/sgl-project/sglang/pull/21783) sets **FlashInfer TRT-LLM sparse MLA kernels as the default attention backend on sm100/sm103** (B200/B300). DSA prefill and decode now run on the kernels GLM-5/V3.2 were tuned against, rather than the older `flashmla_kv` path that hit a [GLM-5 accuracy regression](https://github.com/sgl-project/sglang/issues/21291) on B200.
- [sgl-project/sglang #21405](https://github.com/sgl-project/sglang/pull/21405) enables **IndexCache** for sparse MLA, reusing index tensors across consecutive decode steps for a >10% decode throughput lift on the same kernel call sequence.
- [flashinfer-ai/flashinfer #2726](https://github.com/flashinfer-ai/flashinfer/pull/2726) (in FlashInfer v0.6.6.post1) fixed an intermittent NVFP4 illegal-memory-access bug that had been [blocking](https://github.com/sgl-project/sglang/issues/19081) the NVFP4 functional sign-off; [flashinfer-ai/flashinfer #2836](https://github.com/flashinfer-ai/flashinfer/pull/2836) (in v0.6.7) lifted the trtllm-gen sparse MLA perf ceiling.
**MTP.** GLM-5 reuses the EAGLE speculative-decoding plumbing SGLang built for DeepSeek V3.2 (`--speculative-algorithm EAGLE --speculative-num-steps 3 --speculative-eagle-topk 1 --speculative-num-draft-tokens 4`), with the overlap scheduler enabled via `SGLANG_ENABLE_SPEC_V2=1`. The same flag set runs on H200 and B200 — the only thing that differs across the two SKUs in the recipes below is the model checkpoint and the attention backend choice.
## The Numbers
All rows are GLM-5 at **ISL 8192 / OSL 1024** on a single non-disaggregated node, measured on InferenceX as of 2026-05-25 on **SGLang v0.5.12** with EAGLE-based MTP enabled on every recipe. Cost per million total tokens is computed as `TCO_$/GPU/hr / (3600 × tput_per_gpu / 1e6)`, with H200 at $1.41/GPU/hr and B200 at $1.95/GPU/hr per the [SemiAnalysis AI Cloud TCO Model](https://newsletter.semianalysis.com/p/ai-cloud-economics).
Container image: `lmsysorg/sglang:v0.5.12-cu130` on both SKUs.
**H200 SGLang FP8 + MTP, TP=8 on 8 GPUs** (model `zai-org/GLM-5-FP8`):
| Conc | tok/s/GPU | tok/s/user | TPOT (ms) | $/M tokens |
| ---- | --------- | ---------- | --------- | ---------- |
| 4 | 347.9 | 84.49 | 11.84 | $1.13 |
| 8 | 489.7 | 59.82 | 16.72 | $0.80 |
| 16 | 675.9 | 39.64 | 25.22 | $0.58 |
| 32 | 851.9 | 24.90 | 40.16 | $0.46 |
| 64 | 847.2 | 20.80 | 48.08 | $0.46 |
Concurrency 64 falls back slightly on tok/s/GPU as TTFT begins to dominate the request budget — conc 32 sets the H200 throughput ceiling and the cost floor on this recipe. The Pareto frontier drops conc 64 because conc 32 dominates it in both axes.
**B200 SGLang FP8 + MTP, TP=8 on 8 GPUs** (model `zai-org/GLM-5-FP8`):
| Conc | tok/s/GPU | tok/s/user | TPOT (ms) | $/M tokens |
| ---- | --------- | ---------- | --------- | ---------- |
| 4 | 417.0 | 100.85 | 9.92 | $1.30 |
| 8 | 650.1 | 77.82 | 12.85 | $0.83 |
| 16 | 952.7 | 56.93 | 17.57 | $0.57 |
| 32 | 1,296.8 | 38.16 | 26.21 | $0.42 |
| 64 | 1,619.3 | 23.56 | 42.45 | $0.33 |
| 128 | 1,929.5 | 13.78 | 72.59 | $0.28 |
| 256 | 1,947.3 | 11.88 | 84.15 | $0.28 |
**B200 SGLang NVFP4 + MTP, TP=4 on 4 GPUs** (model `nvidia/GLM-5-NVFP4`) — the cost-frontier anchor:
| Conc | tok/s/GPU | tok/s/user | TPOT (ms) | $/M tokens |
| ---- | --------- | ---------- | --------- | ---------- |
| 4 | 1,038.7 | 121.22 | 8.25 | $0.52 |
| 8 | 1,523.5 | 94.53 | 10.58 | $0.36 |
| 16 | 2,228.1 | 66.27 | 15.09 | $0.24 |
| 32 | 3,037.3 | 43.99 | 22.73 | $0.18 |
| 64 | 3,739.7 | 26.78 | 37.33 | $0.14 |
| 128 | 4,115.5 | 17.63 | 56.73 | $0.13 |
| 256 | 4,090.7 | 17.37 | 57.57 | $0.13 |
**B200 SGLang NVFP4 + MTP, TP=8 on 8 GPUs** — single high-interactivity datapoint, extends the FP4 frontier right:
| Conc | tok/s/GPU | tok/s/user | TPOT (ms) | $/M tokens |
| ---- | --------- | ---------- | --------- | ---------- |
| 4 | 579.2 | 140.08 | 7.14 | $0.94 |
The TP=8 / 8 GPU configuration trades half the per-GPU throughput for a 16% interactivity lift over TP=4 at the same conc — the additional GPUs cut TPOT from 8.25 ms to 7.14 ms. The combined FP4 Pareto frontier walks from $0.13/M at 18 tok/s/user (TP=4, conc=128) up to $0.94/M at 140 tok/s/user (TP=8, conc=4).
## Iso-Interactivity Performance per Dollar
Throughput per GPU and cost per million tokens at matched interactivity, interpolated along each SKU's Pareto frontier. Performance-per-dollar lift in the last column is the inverse of the $/M ratio — B200 NVFP4 perf/$ relative to H200. Cells outside a frontier's measured range render as _unreachable_.
| Interactivity (tok/s/user) | H200 FP8 MTP $/M | B200 FP8 MTP $/M | B200 NVFP4 MTP $/M | B200 NVFP4 perf/$ vs H200 |
| -------------------------- | ---------------- | ---------------- | ------------------ | ------------------------- |
| 25 | $0.46 | $0.34 | $0.14 | 3.24x |
| 30 | $0.50 | $0.37 | $0.15 | 3.32x |
| 40 | $0.58 | $0.43 | $0.17 | 3.44x |
| 50 | $0.69 | $0.51 | $0.19 | 3.54x |
| 60 | $0.80 | $0.60 | $0.22 | 3.60x |
| 70 | $0.93 | $0.72 | $0.26 | 3.63x |
| **80** | **$1.06** | **$0.87** | **$0.29** | **3.65x** |
| 84 | $1.12 | $0.94 | $0.31 | 3.64x |
| 100 | _unreachable_ | $1.28 | $0.38 | _∞_ |
| 120 | _unreachable_ | _unreachable_ | $0.51 | _∞_ |
| 140 | _unreachable_ | _unreachable_ | $0.93 | _∞_ |
B200 NVFP4's performance-per-dollar lift over H200 peaks at **3.65x at 80 tok/s/user** and stays in the 3.24x–3.65x band across the entire H200 operating range — there is no interactivity at which H200 FP8 + MTP is even within 3x of B200 NVFP4 + MTP on this workload. The precision-only lift (B200 FP8 → B200 NVFP4) widens monotonically with interactivity, from **2.41x at 25 tok/s/user to 3.07x at 84 tok/s/user**, because B200 FP8's perf/$ drops faster than B200 NVFP4 as batch shrinks. Above 84 tok/s/user the comparison stops being a comparison: H200 has no recipe that delivers another tok/s/user, while B200 NVFP4 extends another 60 tok/s/user of operating regime out to 140 tok/s/user on TP=8.
[Live chart](https://inferencex.semianalysis.com/inference?g_rundate=2026-05-25&g_model=GLM-5&g_runid=26381101926&i_prec=fp4%2Cfp8&i_active=b200_sglang_mtp%2Ch200_sglang_mtp&i_linelabel=1), pre-filtered to GLM-5 SGLang MTP on H200 + B200 for the 2026-05-25 run. [Live cost view](https://inferencex.semianalysis.com/inference?g_rundate=2026-05-25&g_model=GLM-5&g_runid=26381101926&i_prec=fp4%2Cfp8&i_active=b200_sglang_mtp%2Ch200_sglang_mtp&i_metric=y_costh&i_linelabel=1) of the same comparison.
## What's Next for Blackwell on GLM-5
Three gaps still narrow the headline number from here, all upstream-tracked:
- **Disaggregated serving on NVL72.** The numbers above are single-node aggregated. The [tracking issue](https://github.com/sgl-project/sglang/issues/19380) is actively closing FP8 B200 disaggregated 8K/1K and GB300 disaggregated MTP. Wide EP on NVL72 has already demonstrated a [~3x throughput-per-GPU advantage on Kimi K2.5](/blog/gb200-nvl72-kimi-k2-5-vllm-wide-ep-3x-vs-b200) — the same lever should lift GLM-5's perf/$ further at the low-interactivity / high-throughput end where the FP4 frontier plateaus.
For chat-style GLM-5 serving in the 25–84 tok/s/user band on SGLang today, B200 NVFP4 + MTP delivers 3.2x–3.65x better performance per dollar than H200 FP8 + MTP across every measurable operating point.
## Acknowledgments
This recipe loop moved fast because the [SGLang NVIDIA collaboration](https://github.com/sgl-project/sglang/issues/19380) closed every Functional and Baseline Perf row across no-MTP/MTP and Agg/Disagg on Blackwell in roughly a quarter — NVFP4 IMA fixes in FlashInfer, sparse MLA defaults on sm100/sm103, IndexCache, EAGLE-based MTP for GLM-5 — and the InferenceX recipe loop wired the H200 MTP sibling in one week after upstream stabilized. Thanks to the SGLang maintainers, the FlashInfer team, the NVIDIA SGLang collaboration thread, and everyone landing PRs on the [tracking issue](https://github.com/sgl-project/sglang/issues/19380). Speed of the upstream-to-benchmark loop is the moat.
Click to see the full InferenceX dashboard →
{`{
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [
{
"@type": "Question",
"name": "How much better performance per dollar does NVIDIA B200 NVFP4 deliver vs H200 FP8 on GLM-5 SGLang serving with MTP?",
"acceptedAnswer": {
"@type": "Answer",
"text": "On GLM-5 at 8K/1K sequence length with SGLang v0.5.12 and EAGLE-based MTP enabled on both SKUs, B200 NVFP4 (model nvidia/GLM-5-NVFP4) delivers up to 3.65x better performance per dollar than H200 FP8 (model zai-org/GLM-5-FP8) at iso-interactivity. The peak lift is at 80 tok/s/user: H200 at $1.06 per million tokens vs B200 NVFP4 at $0.29 per million. The lift stays in the 3.24x to 3.65x band across the full H200 operating range from 25 to 84 tok/s/user. TCO inputs are $1.41 per GPU per hour for H200 and $1.95 per GPU per hour for B200 from the SemiAnalysis AI Cloud TCO Model. Measured on InferenceX as of 2026-05-25 (GHA run 26381101926)."
}
},
{
"@type": "Question",
"name": "How much of the 3.65x B200 NVFP4 vs H200 FP8 performance-per-dollar lift comes from generation vs precision?",
"acceptedAnswer": {
"@type": "Answer",
"text": "The lift factors cleanly at the peak. Holding precision and MTP fixed, B200 SGLang FP8 + MTP delivers about 1.22x better performance per dollar than H200 SGLang FP8 + MTP at 80 tok/s/user — the Blackwell generation plus software step alone, with the same EAGLE recipe and the same zai-org/GLM-5-FP8 checkpoint on both SKUs. Swapping the B200 weights from zai-org/GLM-5-FP8 to nvidia/GLM-5-NVFP4 stacks another 2.98x — the precision step alone. 1.22 multiplied by 2.98 is about 3.65. Across the H200 operating band, generation contributes between 1.19x (at 84 tok/s/user) and 1.36x (at 50 tok/s/user), and precision contributes between 2.41x (at 25 tok/s/user) and 3.07x (at 84 tok/s/user); the two steps trade places but the combined lift stays in 3.24x to 3.65x."
}
},
{
"@type": "Question",
"name": "What changed in SGLang v0.5.10 / v0.5.12 that enables GLM-5 NVFP4 with MTP on Blackwell?",
"acceptedAnswer": {
"@type": "Answer",
"text": "SGLang v0.5.10 (released 2026-04-07) was the first stable release where every Functional and Baseline Perf row of the GLM-5 (G)B200 tracking issue (sgl-project/sglang #19380) flipped to DONE across no-MTP/MTP and Agg/Disagg, at both FP8 and NVFP4. v0.5.12 (released 2026-05-16) is what shipped in the InferenceX benchmark run. Key kernel changes: sgl-project/sglang #21783 sets FlashInfer TRT-LLM sparse MLA kernels as default on sm100/sm103 (B200/B300); sgl-project/sglang #21405 enables IndexCache for >10% decode throughput; flashinfer-ai/flashinfer #2726 fixed an intermittent NVFP4 illegal-memory-access bug that had been blocking NVFP4 functional sign-off; flashinfer-ai/flashinfer #2836 lifted the trtllm-gen sparse MLA perf ceiling. MTP uses EAGLE with --speculative-num-steps 3 --speculative-eagle-topk 1 --speculative-num-draft-tokens 4 plus SGLANG_ENABLE_SPEC_V2=1 for the overlap scheduler."
}
},
{
"@type": "Question",
"name": "Why does the FP4 vs FP8 precision gap on B200 grow from 2.41x at 25 tok/s/user to 3.07x at 84 tok/s/user?",
"acceptedAnswer": {
"@type": "Answer",
"text": "At low interactivity (high concurrency), both B200 FP8 + MTP and B200 NVFP4 + MTP saturate weight-loading bandwidth, so the cost ratio is closer to the raw 2x FP4-vs-FP8 GEMM throughput advantage — 2.26x at 18 tok/s/user, 2.41x at 25 tok/s/user. As interactivity rises and concurrency falls, each decode step amortizes weight loading across fewer tokens. The GEMM time per token grows, and the FP4 tensor cores' compute advantage compounds with the smaller per-rank weight footprint on the TP=4 NVFP4 recipe (4 GPUs vs 8 GPUs on the FP8 line). At 84 tok/s/user, B200 FP8 interpolates to $0.94 per million tokens against B200 NVFP4 at $0.31 — a 3.07x gap, with the precision delta now setting the recipe's cost floor."
}
},
{
"@type": "Question",
"name": "What's not covered by this B200 NVFP4 vs H200 FP8 GLM-5 comparison?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Three gaps remain. (1) Disaggregated serving on NVL72: the comparison here is single-node aggregated; SGLang's tracking issue #19380 is actively closing FP8 B200 disagg 8K/1K and GB300 disagg MTP work, and wide expert parallelism on NVL72 has already shown a ~3x throughput-per-GPU lift on Kimi K2.5. (2) Piecewise CUDA graph for B200 FP8 Agg prefill (sgl-project/sglang #23351 in review, #24276 follow-up) is expected to lift the B200 FP8 curve more than the B200 NVFP4 curve, narrowing the precision-only ratio at high interactivity. (3) The H200 SGLang MTP recipe (InferenceX PR #1480) landed one week before this run; H200 disagg, trtllm-mha attention, or KV FP8 on H200 would each push the H200 curve up before declaring the generation step closed."
}
}
]
}`}
---
# B200 NVFP4 vs H100 FP8 on MiniMax-M2.5: Up to 8.2x Better Performance per Dollar with vLLM
> vLLM PR #36307 unlocks the trtllm-gen FP8 MoE kernel for MiniMax on B200; combined with NVFP4, perf/$ scales from 4.0x at 22 tok/s/user to 8.2x at 110 on 8K/1K
- **Author**: SemiAnalysis
- **Date**: 2026-05-26
- **URL**: https://inferencex.semianalysis.com/blog/b200-minimax-m2-5-vllm-nvfp4-vs-h100-fp8-perf-per-dollar
- **Tags**: benchmark, gpu, inference, minimax, nvidia, b200, h100, vllm, fp4
- **Reading time**: 14 min
On MiniMax-M2.5 8K/1K with vLLM, NVIDIA's NVFP4 checkpoint of MiniMax-M2.5 on B200 delivers **up to 8.2x better performance per dollar than H100 vLLM FP8 at iso-interactivity** — H100 at $0.74/M tokens vs B200 NVFP4 at $0.09/M tokens at 110 tok/s/user. The lift grows monotonically across H100's 21–111 tok/s/user operating range, from 4.0x at the low end (22 tok/s/user, $0.12 vs $0.031) to 8.2x at the high end. Measured on InferenceX on 2026-05-22.
The 8.2x factors cleanly at the peak. At 110 tok/s/user, **B200 vLLM FP8 delivers 2.94x better performance per dollar than H100 vLLM FP8** — the Blackwell generation step alone, riding on the same `MiniMaxAI/MiniMax-M2.5` checkpoint and the same vLLM build on both SKUs. **Swapping the B200 weights to `nvidia/MiniMax-M2.5-NVFP4` stacks another 2.77x** — the precision step alone, unlocked by [vllm-project/vllm #36307](https://github.com/vllm-project/vllm/pull/36307) which added a **modular variant** of the trtllm-gen FP8 MoE kernel so MiniMax's non-standard routing method can finally use it. 2.94 × 2.77 ≈ 8.14. The precision step widens with interactivity (1.65x at 22 → 2.77x at 110) because the trtllm-gen kernel's headroom over the older triton path opens up as the GEMM ceiling becomes the binding constraint.
Click to see the full InferenceX dashboard →
MiniMax-M2.5 is MiniMax AI's MoE flagship: **230B total parameters with 10B activated per token** across 256 small experts (different architecture from the older MiniMax-Text-01's 32 large experts). The published checkpoint is [`MiniMaxAI/MiniMax-M2.5`](https://huggingface.co/MiniMaxAI/MiniMax-M2.5) and NVIDIA shipped a quantized [`nvidia/MiniMax-M2.5-NVFP4`](https://huggingface.co/nvidia/MiniMax-M2.5-NVFP4) variant with all MoE GEMM weights re-cast from BF16/FP8 to NVFP4 (16-element blocks, FP8 per-block scales, FP32 per-tensor scale). The KV cache stays FP8. The B200 NVFP4 line in the chart loads the NVIDIA quantized weights; the B200 FP8 and H100 FP8 lines load the original MiniMaxAI checkpoint.
The relevant architectural detail for this post is the **routing method**. MiniMax M2's expert-routing layer emits routing logits in a dtype the original ("monolithic") trtllm-gen FP8 MoE kernel doesn't accept — which is why MiniMax was stuck on the slower triton MoE path on B200 until vLLM PR #36307 added the modular kernel variant that handles routing externally. We come back to this in "What Shipped".
## Why MiniMax-M2.5 Is Worth Optimizing For
MiniMax-M2.5 is the open-weights coding-and-agent model in the M2 series. The 256-small-expert routing layer was tuned for software-engineering workloads (SWE-Bench family, Terminal Bench, agentic tool-use eval), and on the headline coding-quality evals it lands **within 1–4 points of Claude Opus 4.5/4.6 on every benchmark** and **leads Gemini 3 Pro** on Multi-SWE-Bench (51.3 vs 42.7) and VIBE-Pro (54.2 vs 36.9). Multi-SWE-Bench specifically — which scores Opus 4.5 at 50.0 and Opus 4.6 at 50.3 — has M2.5 in front at 51.3.
The quality context is what makes the serving cost-per-token story matter. A **10B-active** open-weights MoE that holds within striking distance of frontier proprietary coding models — served at **$0.031/M tokens** at the throughput-anchor point on B200 NVFP4 — is a different cost-of-deployment proposition than routing the same workload to a closed-API frontier model. The vLLM PR + NVFP4 + B200 stack laid out below is what compresses the inference price-tag for that kind of agent / SWE-loop workload from "expensive to run continuously" into the range where you can keep an autonomous coding agent looping on tasks for hours without the bill writing the architecture itself.
## On-Paper H100 vs B200 Specs
Before the recipes, the hardware. H100 SXM (Hopper, 2023) and B200 SXM (Blackwell, 2025) sit two generations apart. The radar below normalizes each axis to the maximum across every NVIDIA + AMD SKU in [`/gpu-specs`](/gpu-specs) — so the visible H100 and B200 polygons compress against axes where GB200/GB300 NVL72 set the ceiling (notably scale-up domain memory and scale-up domain memory bandwidth, which scale with the rack-scale 72-GPU NVLink domain).
Absolute values for the two SKUs in this benchmark:
| Spec | H100 SXM | B200 SXM | B200 / H100 |
| ---------------------------------- | ------------------- | ------------------- | ----------- |
| HBM capacity | 80 GB (HBM3) | 180 GB (HBM3e) | 2.25x |
| HBM bandwidth | 3.35 TB/s | 8.0 TB/s | 2.39x |
| Dense FP4 (TFLOP/s) | — | 9,000 | — |
| Dense FP8 (TFLOP/s) | 1,979 | 4,500 | 2.27x |
| Dense BF16 (TFLOP/s) | 989 | 2,250 | 2.28x |
| Scale-up BW per GPU (uni-di) | 450 GB/s (NVLink 4) | 900 GB/s (NVLink 5) | 2.00x |
| Scale-up world size | 8 | 8 | 1.00x |
| Scale-up domain HBM capacity | 640 GB | 1,440 GB | 2.25x |
| Scale-up domain HBM BW (aggregate) | 26.8 TB/s | 64.0 TB/s | 2.39x |
| TCO (SemiAnalysis AI Cloud Model) | $1.30/GPU/hr | $1.95/GPU/hr | 1.50x |
What does the silicon buy on its own? **B200 has 2.27x more FP8 compute than H100** (4,500 vs 1,979 TFLOP/s), **4.55x more FP4 compute than H100 has FP8 compute** (9,000 vs 1,979 TFLOP/s — Hopper has zero FP4 tensor cores, so the precision step is a cross-precision compute lift, not an apples-to-apples one), and **2.39x more HBM bandwidth** (8.0 vs 3.35 TB/s), all at 1.50x the TCO. Those raw ratios bound the perf/$ ceiling: **1.51x for FP8 vs FP8** on a compute-bound workload (`2.27 / 1.50`), **1.59x** if HBM bandwidth is the constraint (`2.39 / 1.50`), or **3.03x for B200 NVFP4 vs H100 FP8** on the cross-precision compute axis (`4.55 / 1.50`).
The measured numbers go further. The 2.94x FP8 generation step is **almost 2x the FP8 silicon ceiling**, and the 8.16x combined lift is **~2.7x the cross-precision FP4 silicon ceiling** — the gap above the silicon ceiling is the trtllm-gen modular FP8 MoE kernel (vLLM PR #36307) doing what the older triton MoE path can't. The H100 vLLM stack on MiniMax-M2.5 is leaving substantial headroom on the table compared to what the trtllm-gen kernel path delivers on B200. NVFP4 stacks the precision-step lift on top because the B200 has 9 PFLOP/s of FP4 compute and H100 has none.
## TensorRT-LLM MoE Kernel Integration into vLLM
**Upstream: vLLM PR #36307 — TRTLLM FP8 MoE Modular Kernel.** [vllm-project/vllm #36307](https://github.com/vllm-project/vllm/pull/36307) by [Wei Zhao](https://github.com/wzhao18), merged 2026-03-12, adds a **modular** variant of the trtllm-gen FP8 MoE kernel for Blackwell. The previous "monolithic" trtllm-gen kernel only accepted routing-logits in a specific dtype, which excluded models like MiniMax M2 whose routing layer emits a different dtype. The modular kernel does routing externally, so the dtype constraint goes away — MiniMax M2 (and a broader set of MoE models) can now use the same fast attention + MoE kernel path that DeepSeek/Kimi/GLM-5 already used on B200. The PR's test plan ran on `MiniMaxAI/MiniMax-M2.5` with TP=2 + expert parallelism enabled, the same recipe shape the B200 frontier uses below.
The kernel matters. Below is a per-kernel comparison on MiniMax-M2.5 (1K/1K — _not_ 8K/1K, but the kernel ordering carries) showing what each MoE backend produces in vLLM:
## The Numbers
All rows are MiniMax-M2.5 at **ISL 8192 / OSL 1024** on a single non-disaggregated node, measured on InferenceX on 2026-05-22 on vLLM. Cost per million total tokens is computed as `TCO_$/GPU/hr / (3600 × tput_per_gpu / 1e6)`, with H100 at $1.30/GPU/hr and B200 at $1.95/GPU/hr per the [SemiAnalysis AI Cloud TCO Model](https://newsletter.semianalysis.com/p/ai-cloud-economics).
**H100 vLLM FP8, TP=8 on 8 GPUs** (model `MiniMaxAI/MiniMax-M2.5`):
| Conc | tok/s/GPU | tok/s/user | TPOT (ms) | $/M tokens |
| ---- | --------- | ---------- | --------- | ---------- |
| 4 | 476.5 | 110.93 | 9.01 | $0.76 |
| 8 | 771.4 | 89.71 | 11.15 | $0.47 |
| 16 | 1,193.7 | 69.09 | 14.47 | $0.30 |
| 32 | 1,707.6 | 49.70 | 20.12 | $0.21 |
| 64 | 2,317.0 | 33.00 | 30.31 | $0.16 |
| 128 | 2,985.6 | 21.19 | 47.19 | $0.12 |
**B200 vLLM FP8, TP=2 on 2 GPUs** (the throughput anchor across most of the curve):
| Conc | tok/s/GPU | tok/s/user | TPOT (ms) | $/M tokens |
| ---- | --------- | ---------- | --------- | ---------- |
| 4 | 1,926.8 | 112.30 | 8.90 | $0.28 |
| 8 | 3,143.5 | 92.25 | 10.84 | $0.17 |
| 16 | 4,684.8 | 68.04 | 14.70 | $0.12 |
| 32 | 6,514.0 | 47.40 | 21.10 | $0.08 |
| 64 | 9,079.0 | 32.35 | 30.91 | $0.06 |
| 128 | 10,053.9 | 23.91 | 41.82 | $0.05 |
| 256 | 10,134.1 | 23.92 | 41.81 | $0.05 |
| 512 | 10,112.2 | 23.85 | 41.93 | $0.05 |
**B200 vLLM FP8, TP=4 on 4 GPUs** (extends the low-interactivity arm):
| Conc | tok/s/GPU | tok/s/user | TPOT (ms) | $/M tokens |
| ---- | --------- | ---------- | --------- | ---------- |
| 256 | 11,035.8 | 19.67 | 50.85 | $0.05 |
| 512 | 11,827.1 | 12.71 | 78.68 | $0.05 |
**B200 vLLM NVFP4, TP=2 on 2 GPUs** (the cost-frontier anchor on the left, model `nvidia/MiniMax-M2.5-NVFP4`):
| Conc | tok/s/GPU | tok/s/user | TPOT (ms) | $/M tokens |
| ---- | --------- | ---------- | --------- | ---------- |
| 128 | 16,256.5 | 28.82 | 34.70 | $0.03 |
| 256 | 17,407.3 | 20.61 | 48.51 | $0.03 |
| 512 | 17,577.0 | 20.63 | 48.47 | $0.03 |
**B200 vLLM NVFP4, TP=1 on 1 GPU** (the mid/high-interactivity arm):
| Conc | tok/s/GPU | tok/s/user | TPOT (ms) | $/M tokens |
| ---- | --------- | ---------- | --------- | ---------- |
| 4 | 4,488.8 | 131.18 | 7.62 | $0.12 |
| 8 | 6,683.0 | 97.87 | 10.22 | $0.08 |
| 16 | 9,546.6 | 68.76 | 14.54 | $0.06 |
| 32 | 11,698.0 | 44.16 | 22.65 | $0.05 |
| 256 | 11,962.0 | 44.29 | 22.58 | $0.05 |
**B200 vLLM NVFP4, TP=4 and TP=8 on 4 and 8 GPUs** (extend the high-interactivity arm at conc=4):
| Recipe | Conc | tok/s/GPU | tok/s/user | TPOT (ms) | $/M tokens |
| ------------- | ---- | --------- | ---------- | --------- | ---------- |
| TP=4 / 4 GPUs | 4 | 1,423.3 | 165.92 | 6.03 | $0.38 |
| TP=4 / 4 GPUs | 8 | 2,468.9 | 144.91 | 6.90 | $0.22 |
| TP=8 / 8 GPUs | 4 | 768.6 | 180.26 | 5.55 | $0.70 |
The combined NVFP4 Pareto frontier walks from $0.031/M at 21 tok/s/user (TP=2, conc=512) up to $0.70/M at 180 tok/s/user (TP=8, conc=4).
## Iso-Interactivity Performance per Dollar
Throughput per GPU and cost per million tokens at matched interactivity, interpolated along each SKU's Pareto frontier. Performance-per-dollar lift in the last column is the inverse of the $/M ratio — B200 NVFP4 perf/$ relative to H100. Cells outside a frontier's measured range render as _unreachable_.
| Interactivity (tok/s/user) | H100 FP8 $/M | B200 FP8 $/M | B200 NVFP4 $/M | B200 NVFP4 perf/$ vs H100 |
| -------------------------- | ------------- | ------------- | -------------- | ------------------------- |
| 22 | $0.12 | $0.05 | $0.031 | 3.96x |
| 30 | $0.15 | $0.06 | $0.034 | 4.32x |
| 40 | $0.18 | $0.07 | $0.042 | 4.23x |
| 50 | $0.21 | $0.08 | $0.048 | 4.39x |
| 60 | $0.25 | $0.10 | $0.052 | 4.85x |
| 70 | $0.31 | $0.12 | $0.058 | 5.36x |
| 80 | $0.38 | $0.14 | $0.065 | 5.84x |
| 90 | $0.47 | $0.16 | $0.073 | 6.41x |
| 100 | $0.60 | $0.20 | $0.083 | 7.19x |
| **110** | **$0.74** | **$0.25** | **$0.091** | **8.16x** |
| 130 | _unreachable_ | $0.44 | $0.118 | _∞_ |
| 150 | _unreachable_ | _unreachable_ | $0.250 | _∞_ |
| 175 | _unreachable_ | _unreachable_ | $0.569 | _∞_ |
B200 NVFP4's perf/$ lift over H100 climbs **monotonically from 3.96x at 22 tok/s/user to 8.16x at 110 tok/s/user**, with the peak at 8.23x at 110.8 tok/s/user — the right edge of H100's measurable range. Unlike a same-generation comparison where the lift is roughly flat across the band, this one grows fast: H100's frontier falls off steeply on the right (its conc=4 point sits at only 476 tok/s/GPU at $0.76/M), while B200 NVFP4 still has 4–5x that throughput at the same interactivity. The precision-only lift (B200 FP8 → B200 NVFP4) widens from 1.65x at 22 tok/s/user to 2.77x at 110 — the trtllm-gen kernel's GEMM headroom over the triton path becomes the binding constraint as batch shrinks. Above 110 tok/s/user the comparison stops being a comparison: H100 has no recipe that delivers another tok/s/user, while B200 NVFP4 extends the regime out to 180 tok/s/user on TP=8.
[Live chart](https://inferencex.semianalysis.com/inference?g_rundate=2026-05-22&g_runid=26306422380&g_model=MiniMax-M2.5&i_prec=fp4%2Cfp8&i_active=b200_vllm%2Ch100_vllm&i_linelabel=1&i_advlabel=1), pre-filtered to MiniMax-M2.5 vLLM on H100 + B200 for the 2026-05-22 run. [Live cost view](https://inferencex.semianalysis.com/inference?g_rundate=2026-05-22&g_runid=26306422380&g_model=MiniMax-M2.5&i_prec=fp4%2Cfp8&i_active=b200_vllm%2Ch100_vllm&i_metric=y_costh&i_linelabel=1&i_advlabel=1) of the same comparison.
## What's Next for Blackwell on MiniMax-M2.5
Three gaps still expand or sharpen the headline number from here:
- **NVL72 disagg (without wide EP).** **Wider expert parallelism isn't the right lever for this model** — at 10B active params on 256 small experts, each rank in a TP=2 / 8-GPU configuration already holds only a handful of experts, so widening EP across a 72-GPU NVLink domain doesn't shrink the per-rank weight footprint enough to matter (unlike DeepSeek R1 or Kimi K2.5, where wide EP compounds via compute-comm overlap on the EP collectives). **Disaggregated prefill + decode is still on the table** though: today's single-node aggregated recipe puts both stages on the same TP=2 island and contends for HBM bandwidth at the conc 256+ saturation knee; a disagg recipe on GB200/GB300 NVL72 would move KV between dedicated prefill and decode pools over NVLink 5 and let the decode pool absorb more concurrency before saturating. No InferenceX disagg recipe for MiniMax on NVL72 has shipped yet.
For MiniMax-M2.5 serving on vLLM today, B200 NVFP4 is the cheaper choice by 4x–8.2x across every interactivity point H100 can reach.
## Acknowledgments
[Wei Zhao](https://github.com/wzhao18) at NVIDIA merged the [trtllm FP8 MoE modular kernel](https://github.com/vllm-project/vllm/pull/36307) in vLLM on 2026-03-12. Thanks to Wei Zhao and the vLLM TRT-LLM kernel collaborators, the InferenceX recipe maintainers, and the MiniMax AI team for the open-weights releases.
Click to see the full InferenceX dashboard →
{`{
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [
{
"@type": "Question",
"name": "How much better performance per dollar does NVIDIA B200 NVFP4 deliver vs H100 FP8 on MiniMax-M2.5 vLLM?",
"acceptedAnswer": {
"@type": "Answer",
"text": "On MiniMax-M2.5 at 8K/1K sequence length with vLLM, B200 NVFP4 (model nvidia/MiniMax-M2.5-NVFP4) delivers up to 8.2x better performance per dollar than H100 FP8 (model MiniMaxAI/MiniMax-M2.5) at iso-interactivity. The peak lift is at 110 tok/s/user: H100 at $0.74 per million tokens vs B200 NVFP4 at $0.091 per million. The lift grows monotonically from 3.96x at 22 tok/s/user to 8.16x at 110. TCO inputs are $1.30 per GPU per hour for H100 and $1.95 per GPU per hour for B200 from the SemiAnalysis AI Cloud TCO Model. Measured on InferenceX as of 2026-05-22 (GHA run 26306422380)."
}
},
{
"@type": "Question",
"name": "What does vLLM PR #36307 do and why does it matter for MiniMax-M2.5 on B200?",
"acceptedAnswer": {
"@type": "Answer",
"text": "vllm-project/vllm PR #36307 by Wei Zhao (merged 2026-03-12) adds a modular variant of the trtllm-gen FP8 MoE kernel for Blackwell. The previous monolithic trtllm-gen kernel had a routing-logits dtype constraint that excluded models like MiniMax M2 whose router emits a different dtype. The modular kernel does routing externally so the constraint goes away. With #36307, MiniMax M2 on B200 vLLM can finally use the same fast attention plus MoE kernel path that DeepSeek, Kimi, and GLM-5 already used. On the supplementary per-kernel comparison at 1K/1K, the trtllm-gen modular kernel delivers roughly 1.4x higher Generation TPS than the triton MoE fallback at low interactivity and roughly 2x higher Total TPS; deep_gemm is not competitive on this routing method."
}
},
{
"@type": "Question",
"name": "How much of the 8.2x B200 NVFP4 vs H100 FP8 perf-per-dollar lift comes from generation vs precision?",
"acceptedAnswer": {
"@type": "Answer",
"text": "The lift factors cleanly at the peak. Holding precision fixed, B200 vLLM FP8 delivers about 2.94x better performance per dollar than H100 vLLM FP8 at 110 tok/s/user — the Blackwell generation plus software step, with the same MiniMaxAI/MiniMax-M2.5 checkpoint and the same vLLM build on both SKUs. Swapping the B200 weights to nvidia/MiniMax-M2.5-NVFP4 stacks another 2.77x at 110 — the precision step alone, riding on the trtllm-gen FP8 MoE modular kernel unlocked by vLLM PR #36307. 2.94 multiplied by 2.77 is about 8.14. Across H100's operating band, generation contributes between 2.40x (at 22 tok/s/user) and 2.99x (at 103), and precision contributes between 1.65x (at 22) and 2.81x (at 110); both steps widen at higher interactivity, which is why the combined lift grows from 3.96x to 8.16x rather than staying flat."
}
},
{
"@type": "Question",
"name": "Why is the B200 vs H100 generation lift (2.94x) almost 2x the on-paper FP8 ceiling (1.51x)?",
"acceptedAnswer": {
"@type": "Answer",
"text": "On raw silicon B200 has 2.27x the dense FP8 throughput of H100 at 1.50x the TCO, putting the on-paper FP8 perf-per-dollar ceiling at 1.51x in a compute-bound regime or 1.59x in a memory-bandwidth-bound regime. The measured 2.94x at 110 tok/s/user is almost 2x that ceiling, which means the comparison is not silicon-bound — the H100 vLLM stack is leaving substantial headroom on the table on MiniMax-M2.5 compared to the trtllm-gen kernel path that B200 vLLM gets via PR #36307. An H100 stack with FP8 KV cache, FlashInfer attention upgrades, or a similar fast-MoE kernel would narrow the generation step toward its on-paper ceiling."
}
},
{
"@type": "Question",
"name": "What's not covered by this B200 NVFP4 vs H100 FP8 MiniMax-M2.5 comparison?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Three gaps remain. (1) Speculative decoding: neither recipe runs MTP or EAGLE on MiniMax-M2.5, because vLLM MTP support for the MiniMax M2 routing layer has lagged DeepSeek/Kimi/GLM-5; once it lands the precision step at high interactivity should narrow and the absolute floor at low interactivity should drop further. (2) Disaggregated serving on NVL72: this comparison is single-node aggregated; wide expert parallelism on NVL72 has shown a roughly 3x throughput-per-GPU lift on Kimi K2.5 and would lift MiniMax-M2.5's perf-per-dollar further. (3) The H100 vLLM stack still has room: it runs vllm/vllm-openai v0.18.0; FlashInfer attention upgrades and an FP8 KV path on H100 would each push the H100 curve up before declaring the generation step closed."
}
}
]
}`}
---
# B200 NVFP4 vs H200 INT4 on Kimi K2.5/K2.6: Up to 2.95x Better Performance per Dollar
> On vLLM 8K/1K the NVFP4 path on B200 is 2.71x–2.95x cheaper per million tokens than H200 INT4 across the entire 30–90 tok/s/user serving band, and 2.45x–2.74x cheaper than B200 INT4 on the same silicon. Both factors decompose cleanly into B200's HBM bandwidth, HBM capacity, and NVFP4 tensor cores
- **Author**: SemiAnalysis
- **Date**: 2026-05-26
- **URL**: https://inferencex.semianalysis.com/blog/b200-nvfp4-vs-h200-int4-kimi-k2-vllm-perf-per-dollar
- **Tags**: benchmark, gpu, inference, kimi, nvidia, b200, h200, vllm, nvfp4
- **Reading time**: 13 min
Kimi K2.5 and K2.6 are the open-weights models behind xAI's Cursor Composer 2 and Composer 2.5 — 1M+ daily active users from the Cursor IDE, and the current leader on SWE-Bench Pro at 58.6%. On the 8K/1K workload, vLLM on NVIDIA B200 in NVFP4 serves K2.5/K2.6 cheaper than H200 in INT4 across the entire single-node Pareto frontier. **B200 NVFP4 is 2.71x–2.95x cheaper per million tokens than H200 INT4 in the 30–90 tok/s/user serving band**, peaking at **2.95x at 32 tok/s/user** ($0.140/M on B200 NVFP4 vs $0.413/M on H200 INT4 — a 66% reduction). On the same B200 silicon, swapping INT4 for NVFP4 is worth another **2.45x–2.74x at iso-interactivity** ($0.397/M → $0.154/M at 40 tok/s/user). Measured on SemiAnalysis InferenceX, 2026-05-19, [GHA run 26118912054](https://github.com/SemiAnalysisAI/InferenceX/actions/runs/26118912054).
Both SKUs run the same `vllm/vllm-openai:v0.21.0` container. The spread comes from the silicon and the precision. B200 has 2.27x H200's FP8 dense throughput (4,500 vs 1,979 TFLOP/s), 1.67x its HBM bandwidth (8 vs 4.8 TB/s), and 2.00x its NVLink scale-up bandwidth (900 vs 450 GB/s uni-di). On the FP4 axis H200 has nothing — Hopper SM90 has no FP4 tensor cores, and the [official datasheet](https://resources.nvidia.com/en-us-data-center-overview/gtc24-h200-datasheet) stops at FP8. B200's NVFP4 cores deliver 9,000 TFLOP/s. The measured 3x cost-per-token gap is what those silicon ratios look like once you fold in B200's 1.38x TCO penalty ($1.95 vs $1.41 per GPU/hr per the [SemiAnalysis AI Cloud TCO Model](https://newsletter.semianalysis.com/p/ai-cloud-economics)).
Click to see the full InferenceX dashboard →
## Kimi K2.5 / K2.6 Model Architecture & DownStream Cursor Composer 2.5 Model
[Kimi K2.5](https://huggingface.co/moonshotai/Kimi-K2.5) (released 2026-01-27) and [Kimi K2.6](https://huggingface.co/moonshotai/Kimi-K2.6) (released 2026-04-20) share the original Kimi K2 backbone: a **1.0T-parameter MoE with 32B activated per token**, **DeepSeek-style top-8-of-385 expert routing across 61 transformer layers (1 dense block + 60 MoE blocks)**, **Multi-head Latent Attention (MLA)**, SwiGLU, **YaRN RoPE**, a 163,840-token vocabulary, and a **256K context window** (262,144 tokens). The HF checkpoints are [`moonshotai/Kimi-K2.5`](https://huggingface.co/moonshotai/Kimi-K2.5) and [`moonshotai/Kimi-K2.6`](https://huggingface.co/moonshotai/Kimi-K2.6) — the two are post-training refinements on the same pre-trained architecture, so **every serving result in this post applies one-to-one to both**.
**K2.5 and K2.6 are the open-weights models powering xAI's Cursor Composer 2 and Composer 2.5**, serving 1M+ daily active users from the Cursor IDE. **K2.6 also leads frontier models on the public agentic-coding benchmarks**: 58.6% on SWE-Bench Pro — ahead of GPT-5.4 (57.7%), Claude Opus 4.6 (53.4%), and Gemini 3.1 Pro (54.2%) — and 80.2% on SWE-Bench Verified ([Moonshot K2.6 model card](https://huggingface.co/moonshotai/Kimi-K2.6)). Cline's [production deployment data](https://cline.bot/blog/moonshots-kimi-k2-for-coding-our-first-impressions-in-cline) puts it at 3.3% failure rate on complex diff-editing tasks, matching Claude 4 Sonnet. K2.6's Agent Swarm primitive fans out to **300 parallel sub-agents across 4,000 coordinated steps**, up from K2.5's 100 / 1,500. If you're hosting an OSS agentic coding stack today, K2.5 or K2.6 is the model you're serving.
A note on quantization: Moonshot ships K2.5/K2.6 with **native INT4 weights** as the default open-weights checkpoint, which is what the H200 INT4 and B200 INT4 curves in this post use directly. The **B200 NVFP4 curve uses a NVFP4 requantization of the same weights** so B200's FP4 tensor cores can do the MoE GEMMs at full rate. H200 cannot run this path — Hopper SM90 has no FP4 tensor cores.
## On-Paper Specs
NVIDIA B200 SXM (Blackwell, 2025) vs NVIDIA H200 SXM (Hopper, 2024) — both are NVIDIA, both run vLLM, both ship in 8-GPU NVLink islands. The radar below normalizes each axis to the cross-vendor maximum in [`/gpu-specs`](/gpu-specs), so the visible polygons compress against axes where GB200 NVL72 / GB300 NVL72 set the ceiling (Scale Up Domain Memory + BW at world-size 72), and the FP4 axis is dominated by GB300 NVL72 at 15,000 TFLOP/s — B200's 9,000 TFLOP/s reads ~60% on that axis.
| Spec | H200 SXM | B200 SXM | B200 / H200 |
| ---------------------------------- | ------------------- | ------------------- | ----------- |
| HBM capacity | 141 GB | 180 GB | 1.28x |
| HBM bandwidth | 4.8 TB/s | 8 TB/s | **1.67x** |
| Dense FP4 (TFLOP/s) | — (no FP4 cores) | 9,000 | **∞** |
| Dense FP8 (TFLOP/s) | 1,979 | 4,500 | **2.27x** |
| Dense BF16 (TFLOP/s) | 989 | 2,250 | 2.27x |
| Scale-up BW per GPU (uni-di) | 450 GB/s (NVLink 4) | 900 GB/s (NVLink 5) | **2.00x** |
| Scale-up world size | 8 | 8 | 1.00x |
| Scale-up domain HBM capacity | 1.13 TB | 1.44 TB | 1.28x |
| Scale-up domain HBM BW (aggregate) | 38.4 TB/s | 64 TB/s | 1.67x |
| TCO (SemiAnalysis AI Cloud Model) | $1.41/GPU/hr | $1.95/GPU/hr | 1.38x |
**Mapping silicon to measured perf.** When both SKUs run vLLM INT4 on the same model, the workload is bounded by **HBM bandwidth on the decode path** — each step streams the active expert weights through HBM, batched across in-flight users. B200's 1.67x HBM BW advantage shows up directly in the throughput: at iv = 26 tok/s/user, **B200 INT4 hits 1,791 tok/s/GPU vs H200 INT4's interpolated 1,055 — a 1.70x ratio, sitting right at the silicon limit**. After the 1.38x TCO penalty, B200 INT4 lands a 1.22x cost-per-token advantage over H200 INT4.
**HBM capacity buys a second silicon win that doesn't show up in the radar: lower TP, less collective overhead per token.** Kimi K2.5/K2.6 in INT4 weighs roughly **500 GB of live model state** (1T total params at ~4 bits each, plus activations, KV cache, paged attention scratch). On B200's **180 GB per GPU**, that fits in **4 GPUs (720 GB aggregate, ~30% headroom for KV cache and activations) → TP=4 is viable**. On H200's **141 GB per GPU**, the same model needs **at least 8 GPUs (1,128 GB aggregate) to leave meaningful KV cache headroom → TP=8 is required**. Every Pareto-winning B200 NVFP4 point in this post is **TP=4**; every measured H200 INT4 point is **TP=8**.
Halving the tensor-parallel world size halves the collective traffic per decode step — one fewer log₂N AllReduce hop on the attention output projection, on the MoE gather, and on the post-MLP reduce. Amdahl's law on the serial-collectives bottleneck pulls the per-step latency floor down. The B200 NVFP4 curve doesn't just sit above B200 INT4 by the precision ratio; it also pulls left on the interactivity axis because each decode step finishes sooner.
**The precision unlock sits on top of both.** Switching B200's path from INT4 to NVFP4 doubles its dense-tensor-core throughput — the path that does the bulk of MoE GEMMs in K2 — without re-paying for HBM. B200 NVFP4 hits **3,879 tok/s/GPU at 32 tok/s/user, 2.17x B200 INT4's peak at 26 tok/s/user**. Compose the three factors — **1.67x HBM BW (decode-bound throughput floor) × ~2x NVFP4 (the precision unlock) × the TP=4-vs-TP=8 collectives win** — and divide by the 1.38x TCO penalty. That lands at the measured **2.95x cost-per-million-tokens advantage** at the headline interactivity point.
## The Numbers
All rows are Kimi K2.5 / K2.6 at **ISL 8192 / OSL 1024** on a single 8-GPU node, measured on InferenceX on 2026-05-19, [GHA run 26118912054](https://github.com/SemiAnalysisAI/InferenceX/actions/runs/26118912054). Throughput is per-GPU. Cost per million tokens uses the SemiAnalysis AI Cloud TCO model: H200 at $1.41/GPU/hr, B200 at $1.95/GPU/hr. Formula: `$/M tok = TCO\_$/GPU/hr × 1e6 / (3600 × tput_per_gpu)`.
**H200 vLLM INT4 (TP=8)** — the reference point:
| Conc | tok/s/GPU | tok/s/user | TPOT (ms) | $/M tokens |
| ---- | --------- | ---------- | --------- | ---------- |
| 4 | 384.4 | 91.18 | 10.97 | $1.019 |
| 8 | 590.2 | 70.28 | 14.23 | $0.664 |
| 16 | 797.9 | 46.64 | 21.44 | $0.491 |
| 32 | 990.9 | 28.86 | 34.65 | $0.395 |
| 64 | 1,174.5 | 16.67 | 59.98 | $0.334 |
**B200 vLLM INT4 (TP=8)** — the same precision on Blackwell silicon, isolating the silicon-only delta:
| Conc | tok/s/GPU | tok/s/user | TPOT (ms) | $/M tokens |
| ---- | --------- | ---------- | --------- | ---------- |
| 4 | 446.7 | 104.36 | 9.58 | $1.213 |
| 8 | 692.8 | 81.12 | 12.33 | $0.782 |
| 16 | 969.4 | 59.21 | 16.89 | $0.559 |
| 32 | 1,351.4 | 40.48 | 24.70 | $0.401 |
| 64 | 1,790.7 | 26.01 | 38.45 | $0.303 |
**B200 vLLM NVFP4 (TP=4 + TP=8)** — the headline-winning recipe; the dense Pareto-winning arm is TP=4 across all concurrencies, with one TP=8 conc=4 point extending the high-interactivity end:
| Conc | tok/s/GPU | tok/s/user | TPOT (ms) | $/M tokens | TP |
| ---- | --------- | ---------- | --------- | ---------- | ---- |
| 4 | 532.0 | 125.51 | 7.97 | $1.018 | TP=8 |
| 4 | 947.4 | 111.08 | 9.00 | $0.572 | TP=4 |
| 8 | 1,537.2 | 90.66 | 11.03 | $0.352 | TP=4 |
| 16 | 2,318.7 | 67.40 | 14.84 | $0.234 | TP=4 |
| 32 | 3,202.7 | 46.83 | 21.35 | $0.169 | TP=4 |
| 64 | 3,879.3 | 32.19 | 31.07 | **$0.140** | TP=4 |
The bolded row is the headline: **$0.140 per million tokens on B200 NVFP4 at 32 tok/s/user**, the lowest serving cost on the chart.
## Iso-Interactivity Cost Comparison
Cost per million tokens at matched interactivity, interpolated along each SKU's Pareto frontier. Cells outside a frontier's measured range render as `_unreachable_` (and the ratio column as `_∞_`). The overlap range across all three curves is **30–90 tok/s/user** — that's where the meaningful three-way comparison lives.
| Interactivity (tok/s/user) | H200 INT4 $/M | B200 INT4 $/M | B200 NVFP4 $/M | H200 / B200 NVFP4 | H200 / B200 INT4 | B200 INT4 / B200 NVFP4 |
| -------------------------- | ------------- | ------------- | -------------- | ----------------- | ---------------- | ---------------------- |
| **32** | **$0.413** | **$0.343** | **$0.140** | **2.95x** | **1.20x** | **2.45x** |
| 35 | $0.427 | $0.362 | $0.145 | 2.95x | 1.18x | 2.50x |
| 40 | $0.453 | $0.397 | $0.154 | 2.94x | 1.14x | 2.58x |
| 50 | $0.511 | $0.477 | $0.177 | 2.88x | 1.07x | 2.69x |
| 60 | $0.569 | $0.566 | $0.206 | 2.75x | 1.00x | **2.74x** |
| 70 | $0.660 | $0.655 | $0.244 | 2.71x | 1.01x | 2.69x |
| 80 | $0.811 | $0.766 | $0.286 | 2.84x | 1.06x | 2.68x |
| 90 | $0.996 | $0.927 | $0.347 | 2.87x | 1.07x | 2.67x |
| 100 | _unreachable_ | $1.123 | $0.421 | _∞_ | _unreachable_ | 2.67x |
| 110 | _unreachable_ | _unreachable_ | $0.550 | _∞_ | _∞_ | _∞_ |
| 125 | _unreachable_ | _unreachable_ | $1.000 | _∞_ | _∞_ | _∞_ |
**The B200 NVFP4 vs H200 INT4 gap is flat across the overlap: 2.71x–2.95x from 30 to 90 tok/s/user.** Both ends of the curve get the same advantage. At the low-interactivity / high-batch end, the workload is decode-bound and B200's HBM bandwidth + NVFP4 tensor cores both stay saturated. At the high-interactivity / low-batch end, NVFP4 keeps reducing per-token compute as the batch shrinks. The same-precision row (H200 INT4 vs B200 INT4) tells a different story: it narrows to **1.00x–1.07x at 60–80 tok/s/user**, where B200's silicon advantage just about pays for its TCO premium. The precision unlock is what carries the headline.
Above 100 tok/s/user, only B200 NVFP4 has a recipe at all. H200 INT4's frontier ends at 91 tok/s/user (conc=4 saturates per-step compute); B200 INT4 ends at 104. **B200 NVFP4 still serves out to 125 tok/s/user at $1.00/M** — a regime neither Hopper recipe reaches.
[Live chart](https://inferencex.semianalysis.com/inference?g_rundate=2026-05-19&g_runid=26118912054&g_model=Kimi-K2.5&i_prec=fp4%2Cint4&i_active=b200_vllm%2Ch200_vllm), pre-filtered to B200 + H200 vLLM Kimi K2.5/K2.6 across FP4 and INT4 on the same 2026-05-19 run.
## Acknowledgments
Kimi K2.5 and K2.6 are the work of [Moonshot AI](https://www.moonshot.ai/), with weights at [`moonshotai/Kimi-K2.5`](https://huggingface.co/moonshotai/Kimi-K2.5) and [`moonshotai/Kimi-K2.6`](https://huggingface.co/moonshotai/Kimi-K2.6). The vLLM NVFP4 path on Blackwell is the work of the [vLLM project](https://github.com/vllm-project/vllm) and NVIDIA's TensorRT-LLM / AITER kernel teams whose FP4 MoE kernels vLLM links against. Continuous benchmarking by SemiAnalysis on InferenceX. Speed is the moat.
Click to see the full InferenceX dashboard →
{`{
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [
{
"@type": "Question",
"name": "How much cheaper is NVIDIA B200 NVFP4 than H200 INT4 on Kimi K2.5 and K2.6?",
"acceptedAnswer": {
"@type": "Answer",
"text": "On the 8K/1K workload with vLLM, B200 NVFP4 is 2.71x to 2.95x cheaper per million tokens than H200 INT4 across the entire 30 to 90 tok/s/user serving band. The peak gap is 2.95x at 32 tok/s/user, where B200 NVFP4 serves at $0.140 per million tokens vs H200 INT4 at $0.413 per million tokens — a 65 percent cost reduction. Above 100 tok/s/user, H200 INT4 has no recipe at all, while B200 NVFP4 still serves out to 125 tok/s/user at $1.00 per million tokens. Costs use the SemiAnalysis AI Cloud TCO Model: H200 at $1.41 per GPU per hour and B200 at $1.95 per GPU per hour. Measured on InferenceX, GHA run 26118912054, 2026-05-19."
}
},
{
"@type": "Question",
"name": "How much of the gap is silicon vs how much is the precision unlock?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Three factors compose. (1) HBM bandwidth: B200 has 1.67x H200's HBM BW (8 vs 4.8 TB/s) and the workload is decode-bound, so at iv = 26 tok/s/user B200 INT4 hits 1,791 tok/s/GPU vs an interpolated 1,055 for H200 INT4 — 1.70x, sitting right at the silicon ratio. (2) HBM capacity unlocks lower tensor parallelism: Kimi K2.5/K2.6 INT4 weighs about 500 GB of live model state, which fits in 4 B200 GPUs (180 GB each, 720 GB aggregate) but needs 8 H200 GPUs (141 GB each, 1,128 GB) to leave meaningful KV cache headroom. Every Pareto-winning B200 NVFP4 recipe in this post is TP=4; every H200 INT4 point is TP=8. Halving the tensor-parallel world size halves the collective traffic per decode step (one fewer log-base-2-N AllReduce hop) and pulls the per-step latency floor down by Amdahl's law on the serial-collectives bottleneck. (3) Precision unlock: switching B200 from INT4 to NVFP4 doubles dense tensor-core throughput, lifting B200 NVFP4 peak to 3,879 tok/s/GPU (2.17x B200 INT4 peak). The three multiply and then get divided by the 1.38x TCO penalty for B200 ($1.95 vs $1.41 per GPU per hour), landing at the measured 2.71x-2.95x cost-per-million-tokens advantage. NVFP4 is the precision lever; HBM bandwidth is the throughput floor; HBM capacity is the TP-reduction lever; H200 has none of the three (Hopper has no FP4 tensor-core support, lower HBM BW, and lower HBM capacity forces TP=8)."
}
},
{
"@type": "Question",
"name": "Is the NVFP4 vs INT4 gap on the same B200 silicon worth the swap?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Yes. On the same B200 hardware, switching the vLLM precision from native INT4 to NVFP4 is worth 2.45x to 2.74x at iso-interactivity in the 30 to 90 tok/s/user serving band, peaking at 2.74x at 60 tok/s/user ($0.566 INT4 vs $0.206 NVFP4 per million tokens). Mechanism: NVFP4 lights up B200's 9,000 TFLOP/s FP4 tensor cores, which the INT4 path does not use. NVFP4 also extends the reachable interactivity range — B200 INT4 caps at 104 tok/s/user, B200 NVFP4 serves out to 125 tok/s/user. No silicon change, no TCO change, just precision."
}
},
{
"@type": "Question",
"name": "Why is Kimi K2.5 / K2.6 the model that matters here?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Kimi K2.5 and K2.6 are the open-weights models powering xAI's Cursor Composer 2 and Composer 2.5 backends, serving over one million daily active users from the Cursor IDE. K2.6 also leads frontier models on the public agentic-coding benchmarks: 58.6 percent on SWE-Bench Pro, ahead of GPT-5.4 (57.7), Claude Opus 4.6 (53.4), and Gemini 3.1 Pro (54.2), and 80.2 percent on SWE-Bench Verified. Cline's production deployment data shows it hitting 3.3 percent failure rate on complex diff-editing tasks, matching Claude 4 Sonnet. The architecture is 1T total parameters with 32B active per token, 384 experts (8 selected plus 1 shared), 61 transformer layers, Multi-head Latent Attention, and a 256K context window. K2.5 (released 2026-01-27) and K2.6 (released 2026-04-20) share the same pre-trained backbone, so every serving result in this post applies one-to-one to both — they are post-training refinements, not new architectures. For anyone hosting an OSS agentic coding stack today, K2.5 or K2.6 is the model they are serving."
}
},
{
"@type": "Question",
"name": "What's not yet covered for Kimi K2.5 / K2.6 serving?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Four gaps. First, AMD MI355X has no InferenceX recipe for K2.5 / K2.6 yet; the same precision unlock argument should apply once kernel coverage lands (MI355X has 10,066 TFLOP/s FP4 tensor cores, slightly above B200). Second, PD-disaggregated serving (mori-sglang on AMD, NVIDIA Dynamo) is the next ~1.5x lever and has no K2 recipe in the InferenceX loop yet. Third, the GB200 NVL72 and GB300 NVL72 rack-scale wide expert parallelism path has not been wired in for K2.5 / K2.6, despite the 384-expert architecture being a natural fit. Fourth, this post measures 8K / 1K; the 32K / 2K and 128K / 2K agentic tool-call workloads would re-rank the curves once KV cache pressure starts mattering for a model with a 256K context window."
}
}
]
}`}
---
# MI355X DeepSeek-V4-Pro on SGLang: 110.5x Throughput per GPU in 26 Days
> The amd/deepseek_v4 side branch shipped TileLang attention indexer, Triton sparse MLA, fused RoPE/Hadamard, FlyDSL MoE, and FP4 weights across 31 performance optimizations PRs — lifting first-light 20 tok/s/GPU at 2.4 tok/s/user into 2,256 tok/s/GPU at 9.4 tok/s/user on 8K/1K, with both throughput and interactivity climbing together
- **Author**: SemiAnalysis
- **Date**: 2026-05-26
- **URL**: https://inferencex.semianalysis.com/blog/mi355x-deepseek-v4-pro-sglang-110x-in-26-days
- **Tags**: benchmark, gpu, inference, deepseek, amd, mi355x, sglang, rocm, fp4
- **Reading time**: 15 min
26 days after DeepSeek-V4-Pro's release on [2026-04-24](https://api-docs.deepseek.com/news/news260424), AMD MI355X SGLang on the [sgl-project/sglang `amd/deepseek_v4` side branch](https://github.com/sgl-project/sglang/compare/main...amd/deepseek_v4) hits **2,256 tok/s/GPU at 9.4 tok/s/user** on the 8K/1K workload — **110.5x the 20.4 tok/s/GPU at 2.4 tok/s/user first-light point** from 2026-04-25, and the rare result where both axes climb together: throughput per GPU up 110.5x _and_ interactivity up 3.85x at the same time. SemiAnalysis [called the 14-day stretch ~75x at the kernel level](https://x.com/SemiAnalysis_/status/2053520440589451720); the dashboard now captures another 12 days of optimization on top.
**31 performance optimization PRs** on the AMD side branch did the heavy lifting in a tight relay: FP4 weight enablement ([#24031](https://github.com/sgl-project/sglang/pull/24031)), TileLang attention indexer for DeepSeek Sparse Attention ([#24033](https://github.com/sgl-project/sglang/pull/24033), [#24050](https://github.com/sgl-project/sglang/pull/24050)), Triton sparse MLA kernel and its later fused-dispatch optimization ([#24930](https://github.com/sgl-project/sglang/pull/24930), [#25878](https://github.com/sgl-project/sglang/pull/25878), [#25977](https://github.com/sgl-project/sglang/pull/25977)), fused multi-head compress / RoPE / Hadamard ([#24355](https://github.com/sgl-project/sglang/pull/24355), [#24727](https://github.com/sgl-project/sglang/pull/24727), [#26014](https://github.com/sgl-project/sglang/pull/26014)), FlyDSL MoE ([#24971](https://github.com/sgl-project/sglang/pull/24971)), fused hash topk ([#24728](https://github.com/sgl-project/sglang/pull/24728)), AITER MHC pre/post, and a half-dozen compressor element-wise kernel fusions. Speed is the moat.
Click to see the full InferenceX dashboard →
## DeepSeek-V4-Pro Model Architecture
DeepSeek-V4-Pro is DeepSeek's flagship MoE: **1.6T total parameters with 49B activated per token** (per the [DeepSeek V4 preview announcement](https://api-docs.deepseek.com/news/news260424)). The architecture pairs a novel **token-wise compression** path with **DSA (DeepSeek Sparse Attention)** — the same sparse-attention pattern DeepSeek introduced in V3.2 but extended to a longer context (the official services run DSv4 at **1M context** by default). The vendor framing for V4-Pro is "peak efficiency: world-leading long context with drastically reduced compute & memory costs"; the open-weights checkpoint is [`deepseek-ai/DeepSeek-V4-Pro`](https://huggingface.co/deepseek-ai/DeepSeek-V4-Pro).
The attention mechanism is the central reason the SGLang AMD fork has so many kernels to write. Token-wise compression introduces a **multi-head compress (mHC) pre/post pair** around the attention block — runtime fuses these with RoPE and Hadamard transforms below — and DSA on the decode path needs a separate **attention indexer** plus a **sparse MLA kernel** that walks only the routed positions. The whole stack is new enough that the upstream `main` branch couldn't run DeepSeek-V4-Pro on Blackwell or ROCm at launch; the AMD fork is what closes that gap on MI355X.
**FP4 weight support on MI355X wasn't there at launch either.** The 2026-04-25 first-light measurement is FP8 — and required `SGLANG_HACK_FLASHMLA_BACKEND=torch` plus a `--time=300` SLURM bump just to get past the ~30 min MoE JIT compile without hitting the 3 h CI cap — because [PR #24031](https://github.com/sgl-project/sglang/pull/24031) (kk, 2026-04-29) hadn't yet enabled the FP4 model path on ROCm. Once that landed (plus the matching InferenceX recipe on 2026-05-02 that flipped `SGLANG_DSV4_FP4_EXPERTS=True` and pulled the FP4 weights of `deepseek-ai/DeepSeek-V4-Pro`), the curve moved into a measurable serving regime. Every date in this post from 2026-05-02 onward is FP4; only 2026-04-25 is FP8.
## DeepSeek-V4-Pro vs Claude Opus 4.6 vs GPT-5.4 vs Gemini 3.1 Pro
DeepSeek published the V4-Pro-Max evaluation at preview against Claude Opus 4.6, GPT-5.4-xHigh, and Gemini 3.1-Pro-High across knowledge/reasoning and agentic benchmarks. Quality-wise this is an **open-source frontier coding model**:
That quality bar is the reason the AMD SGLang team under the leadership of HaiShaw treated MI355X serving as a 14-day sprint: a frontier open-weights coding model is worth the engineering investment, and once a usable curve exists on AMD silicon every percentage point of perf/$ on the serving stack moves real workloads.
## What Shipped to Make This Happen
**Upstream stack: the `amd/deepseek_v4` SGLang side branch.** [sgl-project/sglang `amd/deepseek_v4`](https://github.com/sgl-project/sglang/compare/main...amd/deepseek_v4) is an actively rebased side branch landing AMD-specific DeepSeek-V4-Pro kernels in numbered performance optimization PRs. 31 PRs through 2026-05-22, four primary contributors. Every measurement in this post was taken against side-branch images, not SGLang main (see [What's Next](#whats-next-for-mi355x-deepseek-v4-pro) for the upstreaming story). The optimizations that moved the curve, grouped by mechanism:
- **DSA attention (TileLang indexer + Triton sparse MLA).** [#24033](https://github.com/sgl-project/sglang/pull/24033) (Thomas Wang, 04-29) ports the TileLang attention path to ROCm; [#24050](https://github.com/sgl-project/sglang/pull/24050) (Thomas Wang, 04-29) adds the **attention indexer** in TileLang; [#24930](https://github.com/sgl-project/sglang/pull/24930) (amd-danli103, 05-11) introduces the **Triton sparse MLA kernel**; [#25878](https://github.com/sgl-project/sglang/pull/25878) (05-20) and [#25977](https://github.com/sgl-project/sglang/pull/25977) (jacky.cheng, 05-22) fuse the gather + attention path into single dispatches for prefill and extend respectively.
- **mHC fusion (multi-head compress, token-wise compression path).** [#24355](https://github.com/sgl-project/sglang/pull/24355) (kk, 05-04) "optimize mhc performance"; [#24424](https://github.com/sgl-project/sglang/pull/24424) (Thomas Wang, 05-05) **compressor element-wise kernel fusion**; [#25020](https://github.com/sgl-project/sglang/pull/25020) (Xinyi Song, 05-12) compressor optimization; [#25245](https://github.com/sgl-project/sglang/pull/25245) (jacky.cheng, 05-15) **fused softmax pool Triton kernel for compressor**; [#25353](https://github.com/sgl-project/sglang/pull/25353) (Xinyi Song, 05-15) "enable new compressor path"; [#26014](https://github.com/sgl-project/sglang/pull/26014) (Xinyi Song, 05-22) **Triton fused mhc_post_pre for low concurrency**.
- **RoPE + Hadamard fusion.** [#24727](https://github.com/sgl-project/sglang/pull/24727) (Xinyi Song, 05-09) **fuses RoPE Hadamard using `rope_rotate_activation`** — eliminates a CPU-side launch and improves HBM utilization on the per-step decode loop. [#24249](https://github.com/sgl-project/sglang/pull/24249) (Xinyi Song, 05-02) does the analogous **fused compress-decode** kernel.
- **MoE: FlyDSL + FP4 + fused hash topk.** [#24031](https://github.com/sgl-project/sglang/pull/24031) (kk, 04-29) enables the **FP4 model path**; [#24728](https://github.com/sgl-project/sglang/pull/24728) (Xinyi Song, 05-09) **fuses the hash topk** routing step; [#24971](https://github.com/sgl-project/sglang/pull/24971) (Thomas Wang, 05-11) lands the **FlyDSL MoE backend** for ROCm; [#25070](https://github.com/sgl-project/sglang/pull/25070) (Thomas Wang, 05-12) adds the swiglu-limit dense MoE / shared expert path.
- **AITER kernels + misc fusions.** Cherry-picked AITER MHC pre/post fix on 05-07 ([commit b639cb6](https://github.com/sgl-project/sglang/commit/b639cb6)); [#25043](https://github.com/sgl-project/sglang/pull/25043) (jacky.cheng, 05-12) **fuses input_layernorm with FP8 per-128 group quant** on the attention path; [#25251](https://github.com/sgl-project/sglang/pull/25251) (jacky.cheng, 05-19) uses **AITER `greedy_sample`** for all-greedy sampling; [#25097](https://github.com/sgl-project/sglang/pull/25097) (Raiden Makoto, 05-13) **Triton fused store cache for ROCm**; [#25375](https://github.com/sgl-project/sglang/pull/25375) (Thomas Wang, 05-18) **rmsnorm_quant fusion** for the wqb input.
**InferenceX recipe loop.** The InferenceX benchmark recipe absorbed each upstream wave with image bumps roughly every 2–3 days through the optimization phase: container images progressed from `rocm/sgl-dev:v0.5.10rc0-rocm720-mi35x-20260414` (04-25, FP8 only, recipe needed `SGLANG_HACK_FLASHMLA_BACKEND=torch` to even compile) → `rocm/sgl-dev:rocm720-mi35x-583b1b6-20260501-DSv4` (05-02, FP4 enabled via `SGLANG_DSV4_FP4_EXPERTS=True`) → `a8410de6-20260502` (05-03, fused-compress-decode) → `bfd32b6-20260507` (05-08, AITER MHC pre/post + Triton SWA prepare) → `0363e6c-20260509` → `b19052c-20260518` (05-19, stable `lmsysorg/sglang:v0.5.12-rocm720-mi35x` repo with Triton attention backend, FlyDSL MoE, fused hash topk) → `8c3b5aa-20260521` (05-21 final). Recipe tuning between image bumps tightened `--num-continuous-decode-steps` (4 → 8, +4.7%), drove `--max-running-requests` and `--cuda-graph-max-bs` from the matrix concurrency value, and enabled `--enable-prefill-delayer` on the DP-attention configurations.
## The Numbers
All rows are DeepSeek-V4-Pro at **ISL 8192 / OSL 1024** on a single MI355X 8-GPU node, measured on InferenceX between 2026-04-25 and 2026-05-21. Throughput is per-GPU. Precision: 2026-04-25 is FP8 (the only path that worked at launch); 2026-05-02 onward is FP4 on `deepseek-ai/DeepSeek-V4-Pro` with `SGLANG_DSV4_FP4_EXPERTS=True`. DP attention engaged at high concurrency in the later runs.
**2026-04-25 (FP8, baseline first-light):**
| Conc | tok/s/GPU | tok/s/user | TPOT (ms) |
| ---- | --------- | ---------- | --------- |
| 8 | 20.4 | 2.43 | 411 |
| 32 | 42.0 | 1.19 | 843 |
| 64 | 67.4 | 0.93 | 1,074 |
**2026-05-02 (FP4 first light, +TileLang attention, FP4 enablement):**
| Conc | tok/s/GPU | tok/s/user | TPOT (ms) |
| ---- | --------- | ---------- | --------- |
| 1 | 25.2 | 23.89 | 41.86 |
| 2 | 45.4 | 21.65 | 46.41 |
| 4 | 76.5 | 18.38 | 54.87 |
| 8 | 115.8 | 13.87 | 72.92 |
| 16 | 167.2 | 10.07 | 97.87 |
| 32 | 247.0 | 7.33 | 138.64 |
| 64 | 359.9 | 5.23 | 199.14 |
| 128 | 500.2 | 3.61 | 288.50 |
**2026-05-04 (+fused compress-decode, +TileLang MHC post, dropped Torch fallback):**
| Conc | tok/s/GPU | tok/s/user | TPOT (ms) |
| ---- | --------- | ---------- | --------- |
| 1 | 33.3 | 31.82 | 31.43 |
| 4 | 102.1 | 24.65 | 40.86 |
| 8 | 153.0 | 18.43 | 54.82 |
| 16 | 218.9 | 13.04 | 77.62 |
| 32 | 324.2 | 10.10 | 100.26 |
| 64 | 455.7 | 6.86 | 151.33 |
| 128 | 614.6 | 4.54 | 227.59 |
**2026-05-10 (+AITER MHC pre/post, +Triton SWA prepare, +FlyDSL MoE preview):**
| Conc | tok/s/GPU | tok/s/user | TPOT (ms) |
| ---- | --------- | ---------- | --------- |
| 1 | 43.9 | 42.44 | 23.56 |
| 4 | 136.0 | 33.11 | 30.45 |
| 8 | 233.4 | 28.63 | 35.44 |
| 16 | 336.1 | 20.33 | 49.86 |
| 32 | 488.3 | 16.80 | 60.58 |
| 64 | 802.9 | 14.81 | 66.43 |
| 128 | 1,194.3 | 10.17 | 98.80 |
| 256 | 1,503.2 | 6.14 | 164.86 |
**2026-05-21 (latest: SGLang v0.5.12 + Triton attention backend + fused hash topk + FlyDSL MoE):**
| Conc | tok/s/GPU | tok/s/user | TPOT (ms) |
| ------- | ----------- | ---------- | ---------- |
| 1 | 59.2 | 57.06 | 17.52 |
| 4 | 198.5 | 47.71 | 20.96 |
| 8 | 348.2 | 41.78 | 23.94 |
| 16 | 561.3 | 33.37 | 29.97 |
| 32 | 811.7 | 23.99 | 41.68 |
| 64 | 959.6 | 16.79 | 59.56 |
| 128 | 1,556.0 | 13.76 | 72.69 |
| **256** | **2,256.1** | **9.37** | **106.75** |
| 512 | 1,814.4 | 5.59 | 178.90 |
The bolded row is the headline: **2,256 tok/s/GPU at 9.4 tok/s/user on conc 256 with DP attention** — **110.5x the 20.4 tok/s/GPU at 2.4 tok/s/user first-light point** on 04-25 (and 33.5x even the 67.4 tok/s/GPU 04-25 peak at 0.9 tok/s/user, which wasn't a serving operating point). New ceiling for MI355X DSv4-Pro single-node aggregated serving.
## Iso-Interactivity Throughput Comparison
Throughput per GPU at matched interactivity, interpolated along each date's Pareto frontier. 2026-04-25 doesn't reach any interactivity above 2.5 tok/s/user, so every row reads `_unreachable_` for that date — the model wasn't yet operating in a serving regime. Cells outside a frontier's measured range render as `_unreachable_`.
| Interactivity (tok/s/user) | 04-25 | 05-02 | 05-04 | 05-10 | 05-21 | 05-02 → 05-21 |
| -------------------------- | ------------- | ------------- | ------------- | ------------- | ------------- | ------------- |
| 8 | _unreachable_ | 221 | 401 | 1,363 | _unreachable_ | _∞_ |
| 10 | _unreachable_ | 169 | 328 | 1,208 | 2,162 | **12.8x** |
| 12 | _unreachable_ | 136 | 247 | 1,065 | 1,855 | **13.6x** |
| **15** | _unreachable_ | **104** | **194** | **775** | **1,272** | **12.2x** |
| 17 | _unreachable_ | 88 | 169 | 473 | 951 | 10.8x |
| 20 | _unreachable_ | 61 | 139 | 361 | 876 | **14.3x** |
| 25 | _unreachable_ | _unreachable_ | 99 | 266 | 788 | _∞_ |
| 30 | _unreachable_ | _unreachable_ | 50 | 205 | 653 | _∞_ |
| 40 | _unreachable_ | _unreachable_ | _unreachable_ | 89 | 393 | _∞_ |
| 50 | _unreachable_ | _unreachable_ | _unreachable_ | _unreachable_ | 140 | _∞_ |
The headline is **12–14x throughput-per-GPU at iso-interactivity from 2026-05-02 to 2026-05-21** in the 10–20 tok/s/user serving band. The lift cascades date-over-date — every image bump moved the curve another 1.6–4.4x. The high-interactivity arm (25+ tok/s/user) opened up entirely after 05-04, and 50 tok/s/user only became measurable on 05-21 with the latest FlyDSL MoE + fused hash topk kernels in `lmsysorg/sglang:v0.5.12-rocm720-mi35x`.
[Live chart](https://inferencex.semianalysis.com/inference?g_rundate=2026-05-22&g_runid=26306422380&g_model=DeepSeek-V4-Pro&i_gpus=mi355x_sglang&i_dates=2026-05-03%2C2026-05-04%2C2026-05-08%2C2026-05-19%2C2026-05-21%2C2026-04-25&i_prec=fp4%2Cfp8&i_dstart=2026-04-25&i_dend=2026-05-21&i_linelabel=1), pre-filtered to MI355X SGLang DSv4-Pro across the 5 measured dates.
## What's Next for MI355X DeepSeek-V4-Pro
**The remaining gap to NVIDIA on DSv4-Pro is not silicon — it is software.** On paper, the MI355X die has more HBM (288 GB vs B200's 180 GB — **1.60x capacity**), the same 8 TB/s HBM bandwidth, and slightly more dense per-GPU compute across the board (FP4 / FP8 / BF16 all at **1.12x** B200). The one silicon axis where B200 leads is intra-node scale-up bandwidth — NVLink 5 at 900 GB/s uni-directional vs 5th Gen Infinity Fabric at 576 GB/s, a 1.56x edge — and at single-node TP=8 on a 1.6T-active-49B MoE that delta is a smaller lever than the kernel-stack maturity gap the AMD fork is still closing.
| Spec | MI355X | B200 SXM | MI355X / B200 |
| ---------------------------------- | -------------------------- | ------------------- | ------------- |
| HBM capacity | 288 GB | 180 GB | **1.60x** |
| HBM bandwidth | 8 TB/s | 8 TB/s | 1.00x |
| Dense FP4 (TFLOP/s) | 10,066 | 9,000 | 1.12x |
| Dense FP8 (TFLOP/s) | 5,033 | 4,500 | 1.12x |
| Dense BF16 (TFLOP/s) | 2,516 | 2,250 | 1.12x |
| Scale-up BW per GPU (uni-di) | 576 GB/s (Infinity Fabric) | 900 GB/s (NVLink 5) | 0.64x |
| Scale-up world size | 8 | 8 | 1.00x |
| Scale-up domain HBM capacity | 2.30 TB | 1.44 TB | **1.60x** |
| Scale-up domain HBM BW (aggregate) | 64 TB/s | 64 TB/s | 1.00x |
So when the measured B200 SGLang DSv4-Pro curve sits ~5x above MI355X SGLang in the 15–30 tok/s/user serving band on the exact same FP4 / 8K / 1K workload, that gap is not flops, not HBM capacity, not HBM bandwidth, and barely scale-up bandwidth. It is **upstream kernel coverage, fusion completeness, and scheduler tuning** — exactly the surface the `amd/deepseek_v4` fork is rebasing against, exactly the gap that shrank 110.5x in 26 days:
Per the [SemiAnalysis assessment](https://x.com/SemiAnalysis_/status/2053520440589451720), the closing steps:
- **~5x more throughput needed to catch single-node aggregated B200.** The B200 SGLang stack on DSv4-Pro already reaches the multi-thousand tok/s/GPU range out to 70+ tok/s/user that MI355X SGLang only touches at the low-interactivity left edge. Closing it is realistic for AMD within the next couple of weeks at the current PR cadence on the `amd/deepseek_v4` fork — the silicon supports it, the kernels just need to catch up.
- **Another ~1.5x for PD-disaggregated B200.** No InferenceX disagg recipe for MI355X DSv4-Pro has shipped yet. The `mori-sglang` AMD disagg fork has the prefill/decode separation primitives, but they haven't been wired into the DSv4-Pro recipe in the InferenceX loop.
- **Sustained kernel cadence on the AMD fork.** The 31-PR pace is what produced the 110.5x lift; the [open compare view](https://github.com/sgl-project/sglang/compare/main...amd/deepseek_v4) is still adding performance optimization PRs every 2–3 days, so the curve in this post will already be stale by next week. The new compressor path ([#25353](https://github.com/sgl-project/sglang/pull/25353)) and the fused nosplitk attention dispatch for extend ([#25977](https://github.com/sgl-project/sglang/pull/25977)) shipped after the 2026-05-21 dataset and are not yet reflected.
- **Side branch → SGLang main upstream migration.** The first chunk landed in [PR #24933](https://github.com/sgl-project/sglang/pull/24933) (kk, merged 2026-05-18, +3,678 / -70 across 17 files) — enough to run DSv4-Pro on ROCm in **eager mode** on SGLang main via `is_hip` / `use_aiter` gating, Triton replacements for the JIT-fused kernels that don't compile on ROCm, and a new HIP attention backend for the DSv4 attention path. The PR description explicitly flags the follow-on work: "subsequent PRs to merge remaining DSv4 optimizations from `amd/deepseek_v4` branch" — compression flow fusion, multi-stream enablement, the TileLang attention indexer, FlyDSL MoE, and the perf-critical SGLANG*OPT*\* toggles all remain side-branch-only as of 2026-05-22. Until those migrate, MI355X DSv4-Pro serving on SGLang `main` will under-perform what this post measured by an order of magnitude — the side-branch images (`lmsysorg/sglang:v0.5.12-rocm720-mi35x-*`) remain the only way to reproduce the curves above.
For MI355X DSv4-Pro serving today, the 2026-05-21 recipe on `lmsysorg/sglang:v0.5.12-rocm720-mi35x-20260517` is the production frontier — anything earlier than 05-10 should not be benchmarked against.
## Acknowledgments
The 31 performance optimization PRs are the work of [Thomas Wang](https://github.com/thomawan) (TileLang attention indexer, FlyDSL MoE, compressor element-wise fusion, attn early-exit with CUDA graph, rmsnorm-quant fusion), [Xinyi Song](https://github.com/xinyiisme) (fused compress-decode, fused RoPE Hadamard, fused hash topk, compressor optimization), [HaiShaw](https://github.com/HaiShaw) (integration coordination + ENV setup), [amd-danli103](https://github.com/amd-danli103) (Triton sparse MLA + fused dispatch), [jacky.cheng](https://github.com/jackylee99) (input_layernorm + FP8 per-group quant fusion, softmax pool, AITER greedy_sample), [kk](https://github.com/kkHuang-amd) (FP4 enablement, MHC perf, fuse_wqkv), [Raiden Makoto](https://github.com/raidenmakoto) (Triton fused store cache), [Xinyu Jiang](https://github.com/xinyujiang) (radix opt), and the broader AMD AI team. Speed of the upstream-to-benchmark loop is the moat.
Click to see the full InferenceX dashboard →
{`{
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [
{
"@type": "Question",
"name": "How much has AMD MI355X SGLang DeepSeek-V4-Pro performance improved since launch?",
"acceptedAnswer": {
"@type": "Answer",
"text": "On the 8K/1K workload, throughput per GPU on MI355X SGLang DeepSeek-V4-Pro grew from 20.4 tok/s/GPU at 2.4 tok/s/user on 2026-04-25 (FP8 first-light, conc 8) to 2,256 tok/s/GPU at 9.4 tok/s/user on 2026-05-21 (FP4, conc 256, DP attention enabled) — 110.5x throughput-per-GPU in 26 days, with interactivity also climbing 3.85x at the same time. In the 10 to 20 tok/s/user serving band the cumulative lift from the first FP4 measurement on 2026-05-02 to 2026-05-21 is 12 to 14x at iso-interactivity (104 to 1,272 tok/s/GPU at 15 tok/s/user; 61 to 876 at 20). SemiAnalysis previously called the 14-day stretch about 75x at the kernel level. Measured on InferenceX, GHA run 26306422380."
}
},
{
"@type": "Question",
"name": "What's on the SGLang amd/deepseek_v4 fork that made this happen?",
"acceptedAnswer": {
"@type": "Answer",
"text": "31 numbered performance optimization PRs through 2026-05-22 on the sgl-project/sglang amd/deepseek_v4 fork. Key kernel changes: TileLang attention path with attention indexer (PRs 24033 and 24050 by Thomas Wang); Triton sparse MLA kernel and later fused gather+attention dispatch (PRs 24930, 25878, 25977 by amd-danli103 and jacky.cheng); fused multi-head compress (mHC) operations (PR 24355 by kk, PR 24424 by Thomas Wang, PR 25353 by Xinyi Song, PR 26014 by Xinyi Song); fused RoPE and Hadamard (PR 24727 by Xinyi Song); FlyDSL MoE backend (PR 24971 by Thomas Wang); fused hash topk routing (PR 24728 by Xinyi Song); FP4 model path enablement (PR 24031 by kk); AITER MHC pre/post pickup; input_layernorm with FP8 per-128 group quant fusion (PR 25043 by jacky.cheng); rmsnorm-quant fusion for the wqb input (PR 25375 by Thomas Wang). The InferenceX recipe pulled each upstream wave in via container image bumps roughly every 2 to 3 days, progressing from rocm/sgl-dev:v0.5.10rc0-rocm720-mi35x-20260414 to lmsysorg/sglang:v0.5.12-rocm720-mi35x-20260517."
}
},
{
"@type": "Question",
"name": "Why was the 2026-04-25 first-light measurement so slow?",
"acceptedAnswer": {
"@type": "Answer",
"text": "DeepSeek-V4-Pro shipped 2026-04-24 with a novel attention path (token-wise compression plus DSA, DeepSeek Sparse Attention) that the upstream SGLang main branch could not run on Blackwell or ROCm at launch. The 04-25 InferenceX recipe forced SGLANG_HACK_FLASHMLA_BACKEND=torch as a fallback and only the FP8 path even compiled, so the measured kernel time was dominated by torch fallback paths rather than the production attention indexer or compressor kernels that landed over the following two weeks. The result was peak 67 tok/s/GPU at 0.93 tok/s/user, which is not a serving operating point. The first FP4 measurement on 2026-05-02 with the proper TileLang attention path was the first time the curve hit a usable interactivity range."
}
},
{
"@type": "Question",
"name": "How does this compare to NVIDIA B200 on DeepSeek-V4-Pro?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Per the SemiAnalysis assessment, MI355X DSv4-Pro still needs roughly another 5x throughput at iso-interactivity to catch single-node aggregated B200 on the same workload, and another 1.5x on top of that to catch PD-disaggregated B200. At the current PR cadence on the amd/deepseek_v4 SGLang fork (31 performance optimization PRs in 26 days), closing the single-node gap is realistic within the next couple of weeks. No InferenceX disaggregated recipe for MI355X DSv4-Pro has shipped yet."
}
},
{
"@type": "Question",
"name": "What's not yet covered for MI355X DeepSeek-V4-Pro on SGLang?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Three gaps remain. First, the dashboard chart in this post is the 2026-05-21 snapshot; the new compressor path (PR 25353), fused nosplitk attention dispatch for extend (PR 25977), and Triton fused mhc_post_pre for low concurrency (PR 26014) shipped on the amd/deepseek_v4 fork after the 05-21 dataset and are not yet reflected. Second, MI355X has no disaggregated prefill+decode recipe for DSv4-Pro in InferenceX yet; the mori-sglang AMD disagg fork has the primitives but they have not been wired into the DSv4-Pro recipe. Third, the 8K/1K workload here is single-node TP=8 with DP attention engaged at high concurrency; longer-context (1M default for DSv4) and disaggregated recipes are still upstream-pending."
}
}
]
}`}
---
# AMD MI355X GLM-5 Inference: Up to 40% Cheaper per Million Tokens than B200 on SGLang FP8
> 14 weeks after GLM-5 launched, AMD landed both MTP and non-MTP SGLang FP8 recipes on MI355X — fused MLA + FP8 KV cache via TileLang flips the single-node FP8 cost curve in AMD favor across most of the performance Pareto
- **Author**: SemiAnalysis
- **Date**: 2026-05-25
- **URL**: https://inferencex.semianalysis.com/blog/mi355x-glm5-fp8-sglang-40-cheaper-than-b200
- **Tags**: benchmark, gpu, inference, glm5, amd, nvidia, mi355x, b200, sglang, rocm
- **Reading time**: 8 min
14 weeks after GLM-5's release, AMD MI355X SGLang FP8 undercuts NVIDIA B200 SGLang FP8 on cost per million tokens across most of the single-node Pareto frontier on the 8k/1k workload (from ~10 to ~77 tok/s/user; B200 noses back ahead above ~90 tok/s/user). The peak gap is **1.41x at 18 tok/s/user with MTP** ($0.30/M on B200 vs $0.22/M on MI355X — a 40% reduction) and **1.36x at 10 tok/s/user without MTP** ($0.31/M vs $0.23/M). Both runs are on **SGLang v0.12**, where the MI355X ROCm stack is now feature-matched with the CUDA stack on B200: both MTP and non-MTP recipes, both with FP8 KV cache, both on SGLang's latest TileLang-backed MLA path.
This is the cadence that matters. GLM-5 dropped, and within a quarter AMD shipped an upstream SGLang kernel ([sgl-project/sglang PR #21511](https://github.com/sgl-project/sglang/pull/21511)) along with other optimizations plus the matching InferenceX recipes ([InferenceX PR #1440](https://github.com/SemiAnalysisAI/InferenceX/pull/1440)) that flipped the FP8 single-node cost curve on the model. Speed is the moat.
Click to see the full InferenceX dashboard →
GLM-5 is ZAI's (Zhipu) MoE flagship, released 2026-02-11 — exactly 14 weeks before the InferenceX run in this post. It's a **744B-parameter sparse MoE with ~40B activated per token**: 256 experts with top-8 routing (~5.9% sparsity) plus shared experts. The published architecture name is `glm_moe_dsa` — the model integrates **DeepSeek Sparse Attention (DSA)** on the decode path, the same sparse-attention pattern DeepSeek introduced in V3.2 and that SGLang's TileLang backend was built around, paired with Multi-head Latent Attention (MLA) for KV-cache compression to support its 200K context window.
On MI355X, the equivalent capability landed via SGLang's TileLang backend in mid-April, and the resulting decode throughput moved enough that MI355X's lower per-GPU TCO ($1.48/GPU/hr vs B200 at $1.95/GPU/hr per the [SemiAnalysis AI Cloud TCO Model](https://newsletter.semianalysis.com/p/ai-cloud-economics)) now compounds into a real cost-per-token advantage instead of being swamped by software gaps.
## What Shipped to Make This Happen
One of the headline performance optimizations on the AMD side is [sgl-project/sglang PR #21511](https://github.com/sgl-project/sglang/pull/21511) by [HaiShaw](https://github.com/HaiShaw), merged 2026-04-03. The PR enables FP8 KV cache and an FP8 attention kernel on MI300/MI355 using SGLang's TileLang backend (tested on both DeepSeek-V3.2 and GLM-5), with a different fusion strategy per generation:
- **On MI355**, the PR **reuses the existing `fused_qk_rope_cat_and_cache_mla` kernel for both Q and KV FP8 quantization**. The QK rope concat, MLA cache write, and FP8 quant for both Q and KV all collapse into one kernel pass per decode step — no extra HBM round-trips, no separate quantization launches.
The TileLang dependency was bumped to enable FP8 GEMM on AMD, and a new `sparse_mla_fwd_decode_partial_fp8` kernel was added for the partial-decode reduction path. The PR reports throughput gains of greater than 5% on MI355 (greater than 10% on MI300), no accuracy regression on gsm8k (DeepSeek-V3.2 0.945 → 0.946; GLM-5 0.946 → 0.950), and activates with `--kv-cache-dtype fp8_e4m3` alongside the TileLang prefill/decode backends.
## The Numbers
All rows are GLM-5 FP8 at **ISL 8192 / OSL 1024** on a single non-disaggregated node, measured on InferenceX on 2026-05-20 on **SGLang v0.12** for both CUDA (B200) and ROCm (MI355X). Cost per million total tokens is computed as `TCO_$/GPU/hr / (3600 × tput_per_gpu / 1e6)`, with B200 at $1.95/GPU/hr and MI355X at $1.48/GPU/hr.
Container images used:
- **B200:** `lmsysorg/sglang:v0.5.12-cu130`
- **MI355X:** `lmsysorg/sglang-rocm:v0.5.12-rocm720-mi35x-20260517`
**B200 SGLang FP8 MTP, TP=8 on 8 GPUs:**
| Conc | tok/s/GPU | tok/s/user | TPOT (ms) | $/M tokens |
| ---- | --------- | ---------- | --------- | ---------- |
| 4 | 417.0 | 100.85 | 9.92 | $1.30 |
| 8 | 650.1 | 77.82 | 12.85 | $0.83 |
| 16 | 952.7 | 56.93 | 17.57 | $0.57 |
| 32 | 1,296.8 | 38.16 | 26.21 | $0.42 |
| 64 | 1,619.3 | 23.56 | 42.45 | $0.34 |
| 128 | 1,929.5 | 13.78 | 72.59 | $0.28 |
| 256 | 1,947.3 | 11.88 | 84.15 | $0.28 |
**MI355X SGLang FP8 MTP, TP=4 on 4 GPUs** (the Pareto-anchor recipe):
| Conc | tok/s/GPU | tok/s/user | TPOT (ms) | $/M tokens |
| ---- | --------- | ---------- | --------- | ---------- |
| 4 | 625.5 | 76.80 | 13.02 | $0.66 |
| 8 | 911.7 | 54.59 | 18.32 | $0.45 |
| 16 | 1,208.1 | 35.82 | 27.92 | $0.34 |
| 32 | 1,707.4 | 24.83 | 40.27 | $0.24 |
| 64 | 1,895.0 | 18.19 | 54.99 | $0.22 |
| 128 | 1,911.7 | 18.05 | 55.40 | $0.22 |
**MI355X SGLang FP8 MTP, TP=8 on 8 GPUs** (the high-interactivity arm):
| Conc | tok/s/GPU | tok/s/user | TPOT (ms) | $/M tokens |
| ---- | --------- | ---------- | --------- | ---------- |
| 4 | 373.4 | 90.43 | 11.06 | $1.10 |
| 8 | 534.2 | 65.05 | 15.37 | $0.77 |
**B200 SGLang FP8 non-MTP, TP=8 on 8 GPUs:**
| Conc | tok/s/GPU | tok/s/user | TPOT (ms) | $/M tokens |
| ---- | --------- | ---------- | --------- | ---------- |
| 4 | 231.3 | 54.25 | 18.43 | $2.34 |
| 8 | 382.4 | 46.07 | 21.71 | $1.42 |
| 16 | 613.2 | 36.65 | 27.28 | $0.88 |
| 32 | 933.7 | 27.47 | 36.40 | $0.58 |
| 64 | 1,291.8 | 18.42 | 54.28 | $0.42 |
| 128 | 1,669.1 | 11.87 | 84.23 | $0.32 |
| 256 | 1,746.1 | 10.72 | 93.27 | $0.31 |
**MI355X SGLang FP8 non-MTP, TP=4 on 4 GPUs:**
| Conc | tok/s/GPU | tok/s/user | TPOT (ms) | $/M tokens |
| ---- | --------- | ---------- | --------- | ---------- |
| 4 | 358.8 | 42.03 | 23.79 | $1.15 |
| 8 | 579.6 | 34.68 | 28.83 | $0.71 |
| 16 | 870.8 | 25.86 | 38.67 | $0.47 |
| 32 | 1,274.0 | 18.57 | 53.86 | $0.32 |
| 64 | 1,660.1 | 11.83 | 84.56 | $0.25 |
| 128 | 2,071.4 | 7.33 | 136.36 | $0.20 |
| 256 | 2,189.4 | 6.69 | 149.45 | $0.19 |
## Iso-Interactivity Cost Comparison
Interpolating both Pareto frontiers at matched interactivity. For MI355X MTP the Pareto frontier is the lower of TP=4 and TP=8 at each interactivity — TP=4 dominates up to ~77 tok/s/user, with TP=8 conc 4 taking over at the high-interactivity end (~90 tok/s/user) where TP=4 can't reach.
**MTP:**
| Interactivity (tok/s/user) | B200 SGLang MTP $/M tok | MI355X SGLang MTP $/M tok | B200 / MI355X |
| -------------------------- | ----------------------- | ------------------------- | ------------- |
| **18** | **$0.30** | **$0.22** | **1.41x** |
| 24 | $0.34 | $0.24 | 1.40x |
| 35 | $0.40 | $0.34 | 1.17x |
| 55 | $0.55 | $0.45 | 1.22x |
| 77 | $0.82 | $0.66 | 1.25x |
| 90 | $1.08 | $1.10 | 0.98x |
**Non-MTP:**
| Interactivity (tok/s/user) | B200 SGLang $/M tok | MI355X SGLang $/M tok | B200 / MI355X |
| -------------------------- | ------------------- | --------------------- | ------------- |
| 15 | $0.37 | $0.28 | 1.31x |
| 20 | $0.45 | $0.35 | 1.27x |
| 30 | $0.66 | $0.58 | 1.14x |
| 40 | $1.07 | $1.03 | 1.05x |
[Live chart](https://inferencex.semianalysis.com/inference?g_model=GLM-5&i_prec=fp8&g_rundate=2026-05-20&g_runid=26187777287&i_active=b200_sglang%2Cb200_sglang_mtp%2Cmi355x_sglang%2Cmi355x_sglang_mtp&i_metric=y_costh&i_linelabel=1), pre-filtered to GLM-5 FP8 on B200 and MI355X SGLang for the 2026-05-20 run.
## What's Next for MI355X on GLM-5
This result is single-node, aggregated, FP8 only. Two gaps still need closing:
- **FP4 composability.** B200 in this comparison is FP8 on a CUDA nightly. B200 NVFP4 SGLang for GLM-5 is now shipping and will further compress B200's cost curve. MI355X MXFP4 GLM-5.1 SGLang shipped via [InferenceX PR #1098](https://github.com/SemiAnalysisAI/InferenceX/pull/1098) on 2026-04-21, but the FP4 + MTP composition on MI355X is not yet at parity with the FP8 + MTP recipe shown here.
- **Disaggregation and wide expert parallelism.** MI355X GLM-5 has no disagg or wide-EP recipe yet. NVIDIA's GB200 NVL72 Dynamo TRT-LLM and Dynamo vLLM recipes on Kimi K2.5 already demonstrated a [~3x throughput-per-GPU advantage from rack-scale wide EP](https://inferencex.semianalysis.com/blog/gb200-nvl72-kimi-k2-5-vllm-wide-ep-3x-vs-b200). AMD has still not shipped disagg for GLM-5 yet.
## Acknowledgments
This recipe loop moved fast because [Anush Elangovan](https://x.com/AnushElangovan), [HaiShaw](https://github.com/HaiShaw), and the broader AMD AI team landed both the upstream SGLang TileLang fused MLA + FP8 KV kernel in a 14-week window after GLM-5 dropped. The SGLang maintainers reviewed and shipped the kernel within days of submission. Speed of the upstream-to-benchmark loop is the moat.
Click to see the full InferenceX dashboard →
{`{
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [
{
"@type": "Question",
"name": "How much cheaper is AMD MI355X than NVIDIA B200 on GLM-5 FP8 single-node serving?",
"acceptedAnswer": {
"@type": "Answer",
"text": "On GLM-5 FP8 at 8k/1k sequence length with SGLang MTP, MI355X serves at up to 1.41x lower cost per million tokens than B200 — a 40% reduction. The peak gap is at 18 tok/s/user, where B200 costs $0.30 per million tokens and MI355X costs $0.22. Without MTP, the peak gap is 1.36x at 10 tok/s/user ($0.31 vs $0.23). The MI355X cost advantage holds across the entire MTP curve from ~12 to ~77 tok/s/user. The headline configuration is a 4-GPU TP=4 MTP recipe on MI355X with TCO at $1.48/GPU/hr vs B200 at $1.95/GPU/hr. Measured on InferenceX as of 2026-05-20."
}
},
{
"@type": "Question",
"name": "What is SGLang PR #21511 and how does it help MI355X on GLM-5?",
"acceptedAnswer": {
"@type": "Answer",
"text": "sgl-project/sglang PR #21511 (merged 2026-04-03 by HaiShaw) enables FP8 KV cache and an FP8 attention kernel on AMD MI300 and MI355 using SGLang's TileLang backend, tested on both DeepSeek-V3.2 and GLM-5. On MI355, it reuses the existing fused_qk_rope_cat_and_cache_mla kernel for both Q and KV FP8 quantization, collapsing the QK rope concat, MLA cache write, and FP8 quantization into a single kernel pass per decode step. On MI300, a separate Triton kernel set_mla_kv_buffer_fp8_quant handles the KV cache quantization. The PR reports throughput gains greater than 5% on MI355 (greater than 10% on MI300), no accuracy regression on gsm8k (GLM-5 0.946 to 0.950, DeepSeek-V3.2 0.945 to 0.946), and activates with --kv-cache-dtype fp8_e4m3 alongside the TileLang prefill/decode backends."
}
},
{
"@type": "Question",
"name": "Why is the MI355X cost gap biggest at 18 tok/s/user?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Two effects compound. First, the MI355X SGLang MTP recipe ships in a 4-GPU TP=4 variant that has no direct 4-GPU B200 equivalent at FP8, so MI355X spreads the same throughput across fewer GPUs at lower per-GPU TCO ($1.48 vs $1.95/GPU/hr). Second, the MI355X TP=4 throughput curve plateaus at $0.22 per million tokens across concurrency 64 and 128, both delivering ~18 tok/s/user, while B200 at the same interactivity is interpolating between conc 128 ($0.28 at 13.8 tok/s/user) and conc 64 ($0.34 at 23.6 tok/s/user). The compounded effect peaks at 18 tok/s/user (B200 $0.30 vs MI355X $0.22, 1.41x or 40% cheaper). Above 90 tok/s/user the comparison flips marginally back to B200 because there is no MI355X recipe matching B200's TP=8 conc 4 at 100+ tok/s/user."
}
},
{
"@type": "Question",
"name": "Is MI355X also cheaper than B200 on GLM-5 FP8 without MTP?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Yes, but the gap narrows at higher interactivity. Without MTP, MI355X SGLang FP8 (TP=4) is 1.36x cheaper than B200 SGLang FP8 (TP=8) at 10 tok/s/user ($0.23 vs $0.31 per million tokens), 1.27x cheaper at 20 tok/s/user ($0.35 vs $0.45), and 1.05x cheaper at 40 tok/s/user ($1.03 vs $1.07). MTP widens the cheap-end gap because the speculative decoding pass lifts effective per-step throughput on MI355X TP=4 by ~1.34x: at concurrency 32, TPOT drops from 53.9 ms (non-MTP) to 40.3 ms (MTP) and tok/s/GPU rises from 1,274 to 1,707."
}
},
{
"@type": "Question",
"name": "What are the remaining gaps for AMD MI355X on GLM-5?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Two main gaps remain. FP4 composability: B200 NVFP4 SGLang for GLM-5 is shipping and is materially faster than MI355X MXFP4. MI355X MXFP4 GLM-5.1 SGLang exists via InferenceX PR #1098 but FP4 + MTP composition on MI355X is not yet at parity with the FP8 + MTP recipe in this comparison. Disaggregation and wide expert parallelism: MI355X GLM-5 has no disagg or wide-EP recipe yet. NVIDIA GB200 NVL72 Dynamo recipes on Kimi K2.5 already demonstrate around 3x throughput per GPU advantage from rack-scale wide EP. AMD has still not shipped disagg for GLM-5 yet."
}
}
]
}`}
---
# AMD MI355X Qwen3.5 397B-A17B Inference: Up to 19x Throughput per GPU in 3 Months on SGLang FP8
> From v0.5.8 (Feb) → v0.5.10rc0 (Apr) → v0.5.12 (May), three AITER kernel landings on MI355X plus a TP=8 → TP=2/TP=4 retune push Qwen3.5 8k/1k peak from 1.3k to 6.4k tok/s/GPU and extend the curve out to 75 tok/s/user
- **Author**: SemiAnalysis
- **Date**: 2026-05-25
- **URL**: https://inferencex.semianalysis.com/blog/mi355x-qwen3-5-sglang-v0-5-12-up-to-17x
- **Tags**: benchmark, gpu, inference, qwen, amd, mi355x, sglang, rocm
- **Reading time**: 7 min
13 weeks after Alibaba's [Qwen3.5-397B-A17B release on 2026-02-16](https://www.alibabacloud.com/blog/602894), AMD MI355X SGLang FP8 throughput per GPU on the 8k/1k workload has moved up to **19.0x at iso-interactivity at 40 tok/s/user** (192 → 3,660 tok/s/GPU between the 2026-02-20 v0.5.8.post1 baseline and the 2026-05-19 v0.5.12 run, on the dashboard's monotone-cubic-Hermite Pareto interpolation). The gains compound across three SGLang releases plus three AITER MoE kernel landings drove most of the move, with another **~1.5x** from the May v0.5.10rc0 → v0.5.12 image bump on top.
The story is software-only — same MI355X CDNA4 silicon at $1.48/GPU/hr the whole time. The receipts: [sgl-project/sglang#20736](https://github.com/sgl-project/sglang/pull/20736), [sgl-project/sglang#21188](https://github.com/sgl-project/sglang/pull/21188), and [sgl-project/sglang#21421](https://github.com/sgl-project/sglang/pull/21421), all merged Mar–Apr and all gated on `SGLANG_USE_AITER=1`. Speed of the upstream-to-benchmark loop is the moat.
Click to see the full InferenceX dashboard →
Qwen3.5-397B-A17B is Alibaba's MoE flagship, released 2026-02-16 is an 397B total parameters with 17B activated per token across **512 experts** (top-K routing), with a hybrid attention stack interleaving Gated DeltaNet and Gated Attention layers. The first InferenceX benchmark ran on MI355X four days after the release.
## What Shipped to Make This Happen
Some of the performance optimizations that lead to these massive gains are:
- **[sgl-project/sglang PR #20736](https://github.com/sgl-project/sglang/pull/20736)** by [zhentaocc](https://github.com/zhentaocc) (with co-author [yichiche](https://github.com/yichiche)), merged 2026-04-15 — **fuses the shared expert with routed experts in Qwen2 MoE and Qwen3.5 MoE**. When `shared_expert_intermediate_size == moe_intermediate_size`, the shared expert is treated as an additional expert (top-K + 1) inside a single AITER MoE dispatch. One fewer kernel launch per MoE layer, fewer HBM round-trips for the shared-expert weights. Reported +4.6% total throughput, −4% TPOT on Qwen3.5 at concurrency 16; FP8 accuracy initially required an AITER split-K fix before being enabled.
- **[sgl-project/sglang PR #21188](https://github.com/sgl-project/sglang/pull/21188)** by [yichiche](https://github.com/yichiche), merged 2026-03-23 — **adds a `forward_hip` path to `GemmaRMSNorm` so AMD GPUs use fused RMSNorm kernels (AITER `fused_add_rms_norm` / `rms_norm`) instead of the native fallback**. The native path was scalar-bound on MI355X; the fused path absorbs the Gemma-style `weight + 1.0` offset into the kernel. Reported on 8x MI355X at conc 1, 8k/1k: **−23.1% median E2E latency, +30.0% total throughput, −17.0% median TTFT**, with GSM8K accuracy rising from 0.943 to 0.955.
- **[sgl-project/sglang PR #21421](https://github.com/sgl-project/sglang/pull/21421)** by [zhentaocc](https://github.com/zhentaocc), merged 2026-03-26 — **integrates AITER's `fused_topk` kernel into SGLang's `fused_topk` for softmax-scored MoE top-K selection**. Auto-dispatches to `aiter.fused_moe.fused_topk` when AITER is enabled. Kernel microbenchmarks: ~1.31x to **6.29x** faster than the sgl-kernel baseline on Qwen3.5 shapes (E=512, top-K=10), with the largest gains at high token counts. End-to-end bs=64 1k/1k: +1.9% total throughput, GSM8K within ±0.001 of baseline.
## The Numbers
All rows are Qwen3.5-397B-A17B FP8 at **ISL 8192 / OSL 1024** on a single non-disaggregated MI355X node, measured on InferenceX. Cost per million total tokens is computed as `TCO_$/GPU/hr / (3600 × tput_per_gpu / 1e6)` with MI355X TCO at $1.48/GPU/hr per the [SemiAnalysis AI Cloud TCO Model](https://newsletter.semianalysis.com/p/ai-cloud-economics).
Container images per date:
- **2026-02-20:** `rocm/sgl-dev:v0.5.8.post1-rocm720-mi35x-20260218`
- **2026-04-16:** `lmsysorg/sglang-rocm:v0.5.10rc0-rocm720-mi35x-20260414`
- **2026-05-19:** `lmsysorg/sglang-rocm:v0.5.12-rocm720-mi35x-20260517`
**2026-02-20, MI355X SGLang FP8, TP=8 on 8 GPUs** (baseline):
| Conc | tok/s/GPU | tok/s/user | TPOT (ms) | $/M tokens |
| ---- | --------- | ---------- | --------- | ---------- |
| 4 | 171.9 | 40.86 | 24.47 | $2.39 |
| 8 | 312.1 | 37.66 | 26.55 | $1.32 |
| 16 | 568.0 | 35.47 | 28.19 | $0.72 |
| 32 | 917.8 | 28.48 | 35.11 | $0.45 |
| 64 | 1,288.0 | 19.22 | 52.03 | $0.32 |
**2026-04-16, MI355X SGLang FP8, TP=2 on 2 GPUs** (post-retune + AITER PRs):
| Conc | tok/s/GPU | tok/s/user | TPOT (ms) | $/M tokens |
| ---- | --------- | ---------- | --------- | ---------- |
| 4 | 1,074.3 | 63.89 | 15.65 | $0.38 |
| 8 | 1,704.6 | 50.98 | 19.61 | $0.24 |
| 16 | 2,571.9 | 38.50 | 26.51 | $0.16 |
| 32 | 3,567.8 | 26.22 | 38.15 | $0.12 |
**2026-04-16, MI355X SGLang FP8, TP=4 on 4 GPUs** (high-throughput arm):
| Conc | tok/s/GPU | tok/s/user | TPOT (ms) | $/M tokens |
| ---- | --------- | ---------- | --------- | ---------- |
| 32 | 2,584.9 | 38.56 | 25.94 | $0.16 |
| 64 | 3,426.6 | 24.84 | 40.25 | $0.12 |
| 128 | 4,263.2 | 15.38 | 65.01 | $0.10 |
| 256 | 5,099.3 | 9.20 | 108.64 | $0.08 |
**2026-05-19, MI355X SGLang FP8, TP=2 on 2 GPUs** (v0.5.12 bump):
| Conc | tok/s/GPU | tok/s/user | TPOT (ms) | $/M tokens |
| ---- | --------- | ---------- | --------- | ---------- |
| 4 | 1,267.5 | 75.22 | 13.29 | $0.32 |
| 8 | 2,008.1 | 59.67 | 16.76 | $0.20 |
| 16 | 3,175.6 | 46.73 | 21.40 | $0.13 |
| 32 | 4,346.8 | 31.91 | 31.34 | $0.09 |
**2026-05-19, MI355X SGLang FP8, TP=4 on 4 GPUs** (v0.5.12 bump):
| Conc | tok/s/GPU | tok/s/user | TPOT (ms) | $/M tokens |
| ---- | --------- | ---------- | --------- | ---------- |
| 32 | 3,171.8 | 46.82 | 21.36 | $0.13 |
| 64 | 4,113.4 | 29.83 | 33.53 | $0.10 |
| 128 | 5,019.6 | 18.09 | 55.27 | $0.08 |
| 256 | 6,409.1 | 11.56 | 86.53 | $0.06 |
## Iso-Interactivity Throughput Comparison
Each date is interpolated on its Pareto frontier (the higher of TP=2 and TP=4 throughput at each interactivity for the April and May runs; TP=8 only for the Feb baseline). Ratios are throughput-per-GPU at matched tok/s/user:
| Interactivity (tok/s/user) | Feb v0.5.8 tok/s/GPU | Apr v0.5.10rc0 tok/s/GPU | May v0.5.12 tok/s/GPU | May / Feb | May / Apr |
| -------------------------- | -------------------- | ------------------------ | --------------------- | --------- | --------- |
| 20 | 1,259 | 3,906 | 4,861 | 3.86x | 1.24x |
| 30 | 859 | 3,278 | 4,449 | 5.18x | 1.36x |
| 35 | 612 | 2,867 | 4,114 | 6.72x | 1.44x |
| **40** | **192** | **2,476** | **3,660** | **19.0x** | **1.48x** |
| 50 | _unreachable_ | 1,765 | 2,959 | _∞_ | 1.68x |
| 60 | _unreachable_ | 1,244 | 1,985 | _∞_ | 1.60x |
The 19x peak at 40 tok/s/user is partly a regime extension — the Feb TP=8 recipe had a 24.5 ms TPOT floor at conc 4 (40.86 tok/s/user) and couldn't run cheaper than that on this workload, so the comparison band tops out where the old recipe was already in collapse. By 50 tok/s/user the v0.5.8 curve doesn't exist at all; by 75 tok/s/user only the v0.5.12 curve still has a point. The May v0.5.12 image alone adds 1.44x to 1.68x on top of the April baseline across the entire shared band — a clean version-bump win.
[Live chart](https://inferencex.semianalysis.com/inference?g_model=Qwen-3.5-397B-A17B&g_rundate=2026-05-19&i_gpus=mi355x_sglang&i_dstart=2026-02-20&i_dend=2026-05-19&i_prec=fp8), pre-filtered to MI355X SGLang Qwen3.5 FP8 across all three runs.
## What's Next for MI355X on Qwen3.5
- **Disaggregated Serving.** Qwen3.5's 512-expert pool is exactly the regime where a disaggregated prefill/decode split should shine. There is no MI355X Qwen3.5 disagg recipe yet, and AMD has still not shipped disagg for Qwen3.5.
## Acknowledgments
This 3-month curve move is the work of [zhentaocc](https://github.com/zhentaocc) (Todd Chen) and [yichiche](https://github.com/yichiche) (Jacky Cheng) at AMD, who authored all three upstream SGLang PRs, with [HaiShaw](https://github.com/HaiShaw) reviewing and merging. Speed of the upstream-to-benchmark loop is the moat.
Click to see the full InferenceX dashboard →
{`{
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [
{
"@type": "Question",
"name": "How much faster is MI355X SGLang on Qwen3.5 FP8 compared to 3 months ago?",
"acceptedAnswer": {
"@type": "Answer",
"text": "On Qwen3.5-397B-A17B FP8 at 8k/1k on MI355X SGLang, throughput per GPU at iso-interactivity has improved by up to 19.0x between the 2026-02-20 v0.5.8.post1 baseline and the 2026-05-19 v0.5.12 run, peaking at 40 tok/s/user (192 to 3,660 tok/s/GPU on the dashboard's monotone-cubic-Hermite Pareto interpolation). Peak per-GPU throughput rose from 1,288 to 6,409 tok/s/GPU (5.0x). The Feb baseline was on TP=8; the April and May runs use TP=2 and TP=4. Single MI355X node throughout, no hardware change."
}
},
{
"@type": "Question",
"name": "Which SGLang PRs drove the MI355X Qwen3.5 speedup?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Three AMD-authored upstream PRs gated on SGLANG_USE_AITER=1 landed in the v0.5.10rc0 image. PR #20736 (zhentaocc, merged 2026-04-15) fuses the shared expert with routed experts in Qwen2/Qwen3.5 MoE as topk+1 in a single AITER dispatch. PR #21188 (yichiche, merged 2026-03-23) adds a forward_hip path to GemmaRMSNorm so AMD GPUs use fused RMSNorm kernels (AITER fused_add_rms_norm / rms_norm) instead of the native fallback, reported as -23.1% E2E latency and +30.0% throughput at concurrency 1 on 8k/1k. PR #21421 (zhentaocc, merged 2026-03-26) integrates AITER's fused_topk kernel into SGLang's fused_topk for softmax MoE top-K selection, with kernel microbenchmarks 1.31x to 6.29x faster than the sgl-kernel baseline on Qwen3.5 shapes."
}
},
{
"@type": "Question",
"name": "How much of the gain came from switching TP=8 to TP=2/TP=4?",
"acceptedAnswer": {
"@type": "Answer",
"text": "The April 2026 InferenceX recipe update bundled the TP retune with the v0.5.10rc0 image bump and the AITER PRs in a single change, so they cannot be cleanly separated from the public InferenceX dataset. What is clear: TP=8 was leaving most MI355X tensor-core capacity idle on Qwen3.5's 512-expert MoE dispatch path, and TP=2 / TP=4 spreads decode batches across fewer ranks to keep the AITER fused-MoE dispatch hot. The TP retune is a necessary condition for the AITER kernel gains to materialize end-to-end."
}
},
{
"@type": "Question",
"name": "How much speedup came from just the May v0.5.12 image bump?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Holding the TP=2/TP=4 recipes constant, the 2026-05-19 SGLang v0.5.12 image delivers 1.44x to 1.68x throughput per GPU over the 2026-04-16 v0.5.10rc0 image at iso-interactivity in the 30 to 60 tok/s/user band, and pushes the Pareto frontier out to 75 tok/s/user where the April recipe topped out at 64. Peak throughput at concurrency 256 rises from 5,099 to 6,409 tok/s/GPU on TP=4."
}
},
{
"@type": "Question",
"name": "What's not covered by this MI355X-only Qwen3.5 result?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Disaggregated serving. Qwen3.5's 512-expert pool is exactly the regime where a disaggregated prefill/decode split should shine, but no MI355X Qwen3.5 disagg recipe exists yet and AMD has still not shipped disagg for Qwen3.5."
}
}
]
}`}
---
# GB200 NVL72 vs B200 on DeepSeek R1 670B: Up to 4.4x Throughput per GPU at 125 tok/s/user
> DeepSeek R1 FP4 1k/1k. NVL72's 72-GPU NVLink scale-up fabric lets decode run wide EP up to EP=32, where B200's 8-GPU NVLink island caps out at EP=8 over RoCEv2
- **Author**: SemiAnalysis
- **Date**: 2026-05-23
- **URL**: https://inferencex.semianalysis.com/blog/gb200-nvl72-vs-b200-disagg-deepseek-r1-fp4-dynamo-trt
- **Tags**: benchmark, gpu, inference, deepseek, nvidia, gb200, b200, nvl72, trtllm, dynamo, wide-ep, disagg
- **Reading time**: 10 min
On DeepSeek R1 0528 FP4 1k/1k with Dynamo TRT-LLM + MTP and disaggregated prefill/decode on both SKUs, GB200 NVL72 delivers **up to 4.39x throughput per GPU vs B200 at iso-interactivity** — peaking at 125 tok/s/user (4,130 tok/s/GPU on GB200 NVL72 vs 941 tok/s/GPU on B200).
NVIDIA [GB200 NVL72](https://inferencex.semianalysis.com/gpu-specs) connects all 72 GPUs over NVLink 5 at **900 GB/s per GPU uni-directional** (1.8 TB/s jensen math bidi rx + tx). A [B200](https://inferencex.semianalysis.com/gpu-specs) server connects only 8 GPUs over NVLink; once decode EP needs more than 8 ranks, the all-to-all has to leave the NVLink island and cross **ConnectX-7 RoCEv2 Ethernet at 400 Gbit/s per GPU**. So per-GPU bandwidth available to any wider-than-8 EP collective drops from 900 GB/s to 50 GB/s, 18x. DeepSeek R1's 256 routed experts amortize beautifully when the all-to-all stays on NVLink end-to-end across 16 or 32 ranks.
Click to see the full InferenceX dashboard →
DeepSeek R1 0528 is the 671B-parameter MoE that DeepSeek released in May 2025 — Multi-head Latent Attention (MLA) for KV-cache compression, 256 routed experts with 8 active per token plus 1 shared expert, and 61 transformer layers. Every MoE layer fires a routed all-to-all dispatch followed by an all-to-all combine on each forward pass: roughly 120 all-to-alls per token. That collective volume is exactly what NVLink-class scale-up bandwidth is for.
## Why GB200 NVL72 Wins in the Middle of the Curve
In the middle of the curve — roughly 75–175 tok/s/user on this workload — decode becomes **network-bound on the EP dispatch and combine collectives**. Each MoE layer fires two all-to-all collectives per token: a **dispatch** that routes each token to the 8 of 256 experts it was assigned to (which generally live on remote ranks under wide EP), and a **combine** that gathers the expert outputs back to each token's home rank. Across DeepSeek R1's ~60 MoE layers that is roughly 120 collectives per forward pass.
When the network is fast enough, the runtime **overlaps each dispatch and combine with the matmul compute it is serving**: issue the dispatch, start the expert GEMM on tokens that have already arrived, finish the GEMM in roughly the time it takes for the remaining bytes to land, then issue the combine. The collective latency mostly disappears from the critical path because the GPU was busy doing useful compute throughout.
On ConnectX-7 RoCEv2 Ethernet at 50 GB/s per GPU — 18x less per-rank bandwidth than NVLink — that overlap collapses. The same collective takes up to 18x longer per byte moved, no longer fits inside the GEMM time budget, and **exposes itself as raw communication time**.
## The Numbers
All rows are DeepSeek R1 0528 FP4 at **ISL 1024 / OSL 1024**, Dynamo TRT-LLM with MTP enabled, disaggregated prefill/decode on both SKUs, multinode in both cases, measured on InferenceX on 2026-05-22 (run 26306422380). Cost per million total tokens is computed as `TCO_$/GPU/hr / (3600 × tput_per_gpu / 1e6)`, with B200 at $1.95/GPU/hr and GB200 NVL72 at $2.21/GPU/hr per the [SemiAnalysis AI Cloud TCO Model](https://newsletter.semianalysis.com/p/ai-cloud-economics).
**GB200 NVL72 (Dynamo TRT, MTP), DeepSeek R1 FP4 1k/1k disagg:**
| Conc | Prefill | Decode | tok/s/GPU | tok/s/user | TPOT (ms) | $/M tok |
| ------ | ------------- | ------------- | ------------ | ---------- | --------- | --------- |
| 4 | 4 GPU, TP=4 | 32 GPU, EP=8 | 60.7 | 286.40 | 3.49 | $10.12 |
| 8 | 4 GPU, TP=4 | 32 GPU, EP=8 | 111.8 | 272.64 | 3.67 | $5.49 |
| 12 | 4 GPU, TP=4 | 32 GPU, EP=8 | 165.2 | 257.11 | 3.89 | $3.72 |
| 24 | 4 GPU, TP=4 | 32 GPU, EP=8 | 274.8 | 222.28 | 4.50 | $2.23 |
| 48 | 4 GPU, TP=4 | 32 GPU, EP=8 | 363.3 | 207.30 | 4.82 | $1.69 |
| 180 | 4 GPU, TP=4 | 32 GPU, EP=32 | 1,149.1 | 164.37 | 6.08 | $0.53 |
| 2,253 | 12 GPU, TP=12 | 32 GPU, EP=32 | 7,698.0 | 90.99 | 10.99 | $0.08 |
| 4,301 | 8 GPU, TP=8 | 16 GPU, EP=16 | 12,659.7 | 43.29 | 23.10 | $0.05 |
| 16,130 | 12 GPU, TP=12 | 20 GPU, EP=4 | **14,659.4** | **17.82** | **56.11** | **$0.04** |
**B200 (Dynamo TRT, MTP), DeepSeek R1 FP4 1k/1k disagg multinode:**
| Conc | Prefill | Decode | tok/s/GPU | tok/s/user | TPOT (ms) | $/M tok |
| ------ | ------------- | ------------ | ------------ | ---------- | --------- | --------- |
| 6 | 4 GPU, TP=4 | 40 GPU, EP=8 | 49.3 | 309.17 | 3.23 | $10.99 |
| 10 | 4 GPU, TP=4 | 40 GPU, EP=8 | 118.7 | 277.39 | 3.61 | $4.56 |
| 15 | 4 GPU, TP=4 | 40 GPU, EP=8 | 168.9 | 261.09 | 3.83 | $3.21 |
| 25 | 4 GPU, TP=4 | 40 GPU, EP=8 | 242.4 | 224.59 | 4.45 | $2.23 |
| 45 | 4 GPU, TP=4 | 40 GPU, EP=8 | 369.9 | 191.18 | 5.23 | $1.46 |
| 90 | 4 GPU, TP=4 | 40 GPU, EP=8 | 577.3 | 150.56 | 6.64 | $0.94 |
| 180 | 4 GPU, TP=4 | 40 GPU, EP=8 | 897.9 | 126.42 | 7.91 | $0.60 |
| 875 | 4 GPU, TP=4 | 40 GPU, EP=8 | 2,832.9 | 101.79 | 9.82 | $0.19 |
| 1,214 | 4 GPU, TP=4 | 16 GPU, EP=8 | 7,111.4 | 74.04 | 13.51 | $0.08 |
| 4,968 | 12 GPU, TP=12 | 32 GPU, EP=8 | 9,660.7 | 56.35 | 17.75 | $0.06 |
| 10,860 | 12 GPU, TP=12 | 20 GPU, EP=4 | **12,515.7** | **21.34** | **46.86** | **$0.04** |
## Iso-Interactivity Throughput Comparison
| Interactivity (tok/s/user) | GB200 NVL72 tok/s/GPU | B200 tok/s/GPU | GB200 NVL72 / B200 |
| -------------------------- | --------------------- | -------------- | ------------------ |
| 25 | 14,125 | 12,292 | 1.15x |
| 45 | 12,508 | 10,853 | 1.15x |
| 60 | 11,017 | 9,185 | 1.20x |
| 75 | 9,379 | 6,968 | 1.35x |
| 90 | 7,796 | 4,512 | 1.73x |
| 100 | 6,781 | 3,047 | 2.23x |
| **125** | **4,130** | **941** | **4.39x** |
| 150 | 1,922 | 583 | 3.30x |
| 175 | 826 | 429 | 1.93x |
| 200 | 432 | 332 | 1.30x |
| 225 | 262 | 241 | 1.09x |
| 250 | 186 | 193 | 0.97x |
| 275 | 103 | 126 | 0.82x |
| 300 | _unreachable_ | 67 | _∞_ (B200 wins) |
And the same comparison normalized to cost per million tokens, which dilutes the GB200 NVL72 advantage by its 13% per-GPU TCO premium ($2.21 vs $1.95 per GPU-hour):
| Interactivity (tok/s/user) | GB200 NVL72 $/M tok | B200 $/M tok | B200 / GB200 NVL72 |
| -------------------------- | ------------------- | ------------ | ------------------ |
| 25 | $0.0435 | $0.0441 | 1.01x |
| 45 | $0.0491 | $0.0499 | 1.02x |
| 60 | $0.0557 | $0.0590 | 1.06x |
| 75 | $0.0655 | $0.0777 | 1.19x |
| 100 | $0.0905 | $0.1778 | 1.96x |
| **125** | **$0.1486** | **$0.5755** | **3.87x** |
| 150 | $0.3194 | $0.9292 | 2.91x |
| 175 | $0.7430 | $1.2638 | 1.70x |
| 200 | $1.4215 | $1.6314 | 1.15x |
| 225 | $2.3450 | $2.2454 | 0.96x |
| 250 | $3.2962 | $2.8067 | 0.85x (B200 wins) |
The 4.39x throughput peak (3.87x cost gap) at 125 tok/s/user is where wide EP across the NVLink fabric is doing the most work.
[Live chart](https://inferencex.semianalysis.com/inference?g_rundate=2026-05-22&g_runid=26306422380&i_seq=1k%2F1k&i_active=b200_dynamo-trt_mtp%2Cgb200_dynamo-trt_mtp), pre-filtered to B200 and GB200 NVL72 Dynamo TRT MTP on DeepSeek R1 FP4 1k/1k for the 2026-05-22 run.
## When Each SKU Wins
- **GB200 NVL72 Dynamo TRT** is the right choice for everything in the 75 to 200 tok/s/user band where wide EP across the 72-GPU NVLink fabric is the dominant factor. The cost gap peaks at 3.87x in favor of GB200 NVL72 at 125 tok/s/user — chat-style and reasoning serving at production interactivity targets land squarely inside this band.
NVIDIA's [SGLang GB200 NVL72 results](https://lmsys.org/blog/2025-09-25-gb200-part-2/) show the same scale-up fabric advantage on the SGLang stack. AMD's MI300/MI355X have no rack-scale UALoE72 equivalent shipping until [H2 2026 engineering samples](https://newsletter.semianalysis.com/p/ai-cloud-economics) per the inferencex-v2 launch piece, so there is no rack scale comparator on the AMD side yet for this workload.
## Acknowledgments
Thanks to NVIDIA's Dynamo and TensorRT-LLM teams — including Jatin Gangani, Kedar Potdar, Sridhar Ramaswamy, Ishan Dhanani, and Sahithi Chigurupati — for shipping the disagg recipes on both B200 multinode RoCEv2 and GB200 NVL72. Checkout our other blog post on [GB200 NVL72 vs B200 Kimi K2.5 post](https://inferencex.semianalysis.com/blog/gb200-nvl72-kimi-k2-5-vllm-wide-ep-3x-vs-b200).
Click to see the full InferenceX dashboard →
{`{
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [
{
"@type": "Question",
"name": "How much faster is GB200 NVL72 than B200 on DeepSeek R1 FP4 with Dynamo TRT-LLM and MTP?",
"acceptedAnswer": {
"@type": "Answer",
"text": "On DeepSeek R1 0528 FP4 at 1k/1k with Dynamo TRT-LLM + MTP and disaggregated prefill/decode on both SKUs, GB200 NVL72 delivers up to 4.39x throughput per GPU vs B200 at iso-interactivity, peaking at 125 tok/s/user (4,130 vs 941 tok/s/GPU on the dashboard's monotone-cubic-Hermite Pareto interpolation). At peak throughput (sub-25 tok/s/user) the gap shrinks to 1.15x because both SKUs run narrow EP=4 with DP attention on the same TP=32 disagg shape and the workload is decode-memory-bandwidth bound. Above 250 tok/s/user the curves cross and B200 wins by about 1.2x because at small batch sizes the workload fits inside an 8-GPU NVLink island and the cross-rack hop is pure overhead. Measured on InferenceX 2026-05-22, run 26306422380."
}
},
{
"@type": "Question",
"name": "Why does GB200 NVL72 win so big in the middle of the throughput-interactivity curve?",
"acceptedAnswer": {
"@type": "Answer",
"text": "The 75–175 tok/s/user band is where decode becomes network-bound on the EP dispatch and combine collectives. Each MoE layer fires an all-to-all dispatch and an all-to-all combine; across about 60 MoE layers that is roughly 120 collectives per token. On NVLink 5 at 900 GB/s per GPU uni-directional (1.8 TB/s bi-di), each dispatch/combine pair fits inside the matmul time budget for that layer's expert GEMMs, so the runtime overlaps the collective behind compute and the latency disappears from the critical path. On ConnectX-7 RoCEv2 Ethernet at 50 GB/s per GPU — 18x slower — the same collective takes 18x longer per byte moved, no longer fits inside the GEMM, and exposes itself as raw latency with the GPU sitting idle waiting on the network. So NVL72 can run EP=16 and EP=32 without paying TPOT cost; B200 multinode cannot overlap the cross-node all-to-all with compute, so it has to drop back to single-node EP=8 where the collective stays on NVLink at the cost of a much smaller wide-EP throughput win."
}
},
{
"@type": "Question",
"name": "Is GB200 NVL72 also cheaper per million tokens than B200 in this comparison?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Yes in the 75–175 tok/s/user band, marginally tied at the extremes. GB200 NVL72 TCO is about 13% higher per GPU-hour ($2.21 vs $1.95 per the SemiAnalysis AI Cloud TCO Model), which dilutes the throughput advantage in cost terms. At peak throughput (25 to 60 tok/s/user) cost is essentially tied: 1.01x to 1.06x in favor of GB200 NVL72. At 125 tok/s/user the cost gap is 3.87x (B200 $0.58 per million tokens vs GB200 NVL72 $0.15). Above 225 tok/s/user the cost gap inverts: B200 is 5% cheaper at 225 tok/s/user, 15% cheaper at 250 tok/s/user, and 27% cheaper at 275 tok/s/user."
}
},
{
"@type": "Question",
"name": "Where does B200 still beat GB200 NVL72 on DeepSeek R1 FP4?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Above roughly 250 tok/s/user. At that interactivity the workload runs at very small batch sizes (4 to 25 concurrent users on a 40-GPU decode pool in the B200 recipe), the per-token decode work is small enough that all-to-all bandwidth isn't the bottleneck, and the workload comfortably fits inside an 8-GPU NVLink island. B200 saves the cross-rack hop and wins by about 1.2x at 275 tok/s/user. NVL72 in this dataset has no recipe that runs below 286 tok/s/user, so above that point only B200 is reachable. The very-low-batch regime is also where rack-scale NVL72's advantage is structurally smallest because there are few tokens in flight for the wide NVLink bandwidth to carry."
}
},
{
"@type": "Question",
"name": "Do these results extend to other models or only DeepSeek R1?",
"acceptedAnswer": {
"@type": "Answer",
"text": "The pattern is general for sparse MoE models with many routed experts and a high per-layer all-to-all volume. Our prior post on Kimi K2.5 NVFP4 8k/1k showed GB200 NVL72 Dynamo vLLM at 12,587 tok/s/GPU vs B200 at 4,021 tok/s/GPU on peak throughput, a 3.13x advantage from wide EP up to EP=16 on the NVL72 fabric. DeepSeek R1 here is a different model (671B vs 1T parameters, 256 vs 384 experts, MLA vs the K2.5 attention) but the per-MoE-layer all-to-all behavior is similar enough that the headline structure repeats: peak throughput parity-ish, big middle-of-curve gap driven by wide EP on NVLink, and high-interactivity inversion when batches fit on one NVLink island. Dense models or MoE models with fewer routed experts will show much smaller gaps because the all-to-all collective is a smaller fraction of per-step cost."
}
}
]
}`}
---
# SGLang 0.5.6 on B200 DeepSeek R1 FP4: Up to 1.8x at Low Concurrency
> Piecewise CUDA graphs for DeepSeek V3, a unified event loop, and JIT kernels push 8k/1k throughput from 508 to 907 tok/s/GPU on the same 16 GPU B200 pool
- **Author**: SemiAnalysis
- **Date**: 2026-05-02
- **URL**: https://inferencex.semianalysis.com/blog/sglang-0-5-6-b200-deepseek-r1-fp4-up-to-1-8x
- **Tags**: benchmark, inference, gpu, nvidia, b200, deepseek, sglang, fp4
- **Reading time**: 5 min
B200 running SGLang 0.5.6 on DeepSeek R1 NVFP4 reaches 907 tok/s/GPU at concurrency 4 on the 8k/1k workload, up 1.79x from 508 tok/s/GPU on 0.5.5. Both runs use the same 16 GPU pool at TP 4 / EP 4. The only change was the Docker image being updated from lmsysorg/sglang:v0.5.5-cu129-amd64 to lmsysorg/sglang:v0.5.6-cu129-amd64.
SGLang 0.5.6 shipped on 2025-12-03 and the InferenceX benchmark caught the full effect 28 days later, on 2025-12-31, the same day the image bump landed. This is the reason we built InferenceX's automated benchmark loop, to catch software-driven performance changes on the same hardware as soon as they land.
Click to see the full InferenceX dashboard →
The performance gain is largest at low concurrency. At concurrency 4 and 8 the decode loop spends a meaningful fraction of each step in Python scheduler and kernel dispatch code rather than in matmuls, so the 0.5.6 scheduler and graph changes apply most directly. At high concurrency the tensor cores are near saturation and the smaller throughput gain (1.03x at conc 64, 1.16x at conc 128) comes from the refactored attention kernel path.
## What Shipped in SGLang 0.5.6
[SGLang 0.5.6](https://github.com/sgl-project/sglang/releases/tag/v0.5.6) shipped on 2025-12-03. Three release items apply to the low-concurrency throughput gains. Piecewise CUDA graph support was extended to DeepSeek V3 and the MLA attention path, reducing the per-step Python cost of constructing and replaying graphs. The event loop was unified across PD-disaggregated, overlap, and DP-attention serving modes, reducing inner-loop overhead. JIT kernels were introduced, reducing startup cost and allowing kernel compilation to specialize for shapes seen at run time.
Three other 0.5.6 changes affect the attention kernel path. MHA and MLA KV caches were refactored to support FP4. The FlashInfer TRTLLM GEN MHA path was re-enabled. FlashInfer bumped to 0.5.2. These matter at high concurrency where the KV cache is large and attention is the dominant cost. The 1.16x at concurrency 128 comes from this path.
## The Numbers
All rows are DeepSeek R1 NVFP4 at ISL 8192 / OSL 1024 on InferenceX. 0.5.5 data is from the 2025-12-15 run on the image set by [InferenceX PR #204](https://github.com/SemiAnalysisAI/InferenceX/pull/204), which moved the B200 SGLang configs from v0.5.3rc1-cu129-b200 to v0.5.5-cu129-amd64 on 2025-11-10. 0.5.6 data is from the 2025-12-31 run, triggered by [InferenceX PR #276](https://github.com/SemiAnalysisAI/InferenceX/pull/276) which bumped the Docker image to v0.5.6-cu129-amd64 with no other configuration change.
B200 SGLang, DeepSeek R1 NVFP4, TP 4 / EP 4 decode, 16 GPU non-disaggregated pool. The recipe follows the [SGLang DeepSeek V3/R1 deployment guide](https://docs.sglang.io/basic_usage/deepseek_v3.html).
| Version | Conc | tok/s/GPU | TPOT (ms) | tok/s/user | Gain |
| --------- | ----- | --------- | --------- | ---------- | --------- |
| 0.5.5 | 4 | 508 | 9.2 | 108.4 | baseline |
| 0.5.5 | 8 | 903 | 11.6 | 86.5 | baseline |
| 0.5.5 | 16 | 1,471 | 15.7 | 63.8 | baseline |
| 0.5.5 | 32 | 2,302 | 22.2 | 45.1 | baseline |
| 0.5.5 | 64 | 3,323 | 33.7 | 29.6 | baseline |
| 0.5.5 | 128 | 4,430 | 54.9 | 18.2 | baseline |
| **0.5.6** | **4** | **907** | **9.2** | **108.5** | **1.79x** |
| 0.5.6 | 8 | 1,437 | 11.6 | 86.0 | 1.59x |
| 0.5.6 | 16 | 1,500 | 15.5 | 64.6 | 1.02x |
| 0.5.6 | 32 | 3,063 | 22.0 | 45.6 | 1.33x |
| 0.5.6 | 64 | 3,419 | 32.9 | 30.4 | 1.03x |
| 0.5.6 | 128 | 5,145 | 53.7 | 18.6 | 1.16x |
The bolded row is the headline: 907 tok/s/GPU on 0.5.6 at concurrency 4 vs 508 on 0.5.5, a 1.79x lift on identical hardware and recipe. Interactivity at matched concurrency is almost identical across versions. TPOT at each concurrency is unchanged within rounding. 0.5.6 serves more users per GPU at the same per-user token rate.
[Live chart](https://inferencex.semianalysis.com/inference?g_rundate=2025-12-31&g_runid=20621824084&i_prec=fp4%2Cfp8&i_gpus=b200_sglang&i_dstart=2025-12-15&i_dend=2025-12-31), pre-filtered to B200 SGLang DeepSeek R1 across the 0.5.5 and 0.5.6 runs.
## Where Each Improvement Lands on the Curve
Decode on a TP 4 / EP 4 DeepSeek R1 NVFP4 deployment has a fixed per-step cost. Kernel launches, Python scheduler work, and graph construction are the main contributors alongside attention and MoE GEMMs. At concurrency 4 the GEMMs are small enough that fixed cost is a meaningful slice of the step. Reducing fixed cost speeds up the step directly, which is why the biggest ratios (1.79x at conc 4, 1.59x at conc 8) appear at low concurrency. Piecewise CUDA graphs and JIT kernels are the relevant release items.
At concurrency 128 the KV cache is large and attention is the dominant cost per step. The refactored MHA and MLA KV caches for FP4 and the re-enabled FlashInfer TRTLLM GEN MHA path produce a 1.16x ratio at conc 128 even though the scheduler-overhead reduction has flattened at that point. At middle concurrencies (16, 32, 64) neither effect is dominant and the throughput gain is smaller and less stable (1.02x, 1.33x, 1.03x).
Click to see the full InferenceX dashboard →
{`{
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [
{
"@type": "Question",
"name": "How much faster is SGLang 0.5.6 than 0.5.5 on B200 DeepSeek R1 FP4?",
"acceptedAnswer": {
"@type": "Answer",
"text": "On B200 at TP 4 / EP 4 non-disaggregated, DeepSeek R1 NVFP4, 8k/1k sequence length, SGLang 0.5.6 delivers 1.79x the tok/s/GPU of 0.5.5 at concurrency 4 (508 to 907) and 1.59x at concurrency 8 (903 to 1,437). Mid and high concurrency see smaller throughput gains: 1.02x at conc 16, 1.33x at conc 32, 1.03x at conc 64, and 1.16x at conc 128. Interactivity (tok/s/user) at matched concurrency is almost unchanged between versions. Measured on InferenceX with 0.5.5 data from the 2025-12-15 run and 0.5.6 data from the 2025-12-31 run."
}
},
{
"@type": "Question",
"name": "What changed in SGLang 0.5.6 that explains the speedup?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Three release items do most of the work at low concurrency. Piecewise CUDA graph support was extended to DeepSeek V3 and the MLA attention path, reducing per-step Python and kernel-launch cost. The event loop was unified across PD-disaggregated, overlap, and DP-attention serving modes, tightening the inner decode loop. JIT kernels were introduced, cutting startup cost and letting kernel compilation specialize for observed shapes. MHA and MLA KV caches were refactored for FP4 support and FlashInfer bumped to 0.5.2, which raise the attention kernel ceiling but contribute less to the low-concurrency throughput gain."
}
},
{
"@type": "Question",
"name": "Why is the 0.5.6 speedup biggest at low concurrency?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Scheduler and kernel-launch overhead is a larger fraction of each decode step at small batch sizes. At concurrency 4 on 8k/1k, MoE GEMM shapes are small enough that fixed per-step cost is a meaningful slice of the decode step, so the piecewise CUDA graph and JIT kernel changes produce a visible 1.79x. At mid concurrency (16 to 64) the scheduler wins fade and the attention kernel is not yet dominant, giving smaller and less stable ratios. At concurrency 128 the KV cache is large, attention time sets the pace, and the refactored MHA and MLA KV caches plus the re-enabled FlashInfer TRTLLM GEN MHA path pick up a 1.16x lift."
}
},
{
"@type": "Question",
"name": "How quickly did InferenceX catch the SGLang 0.5.6 improvement?",
"acceptedAnswer": {
"@type": "Answer",
"text": "SGLang 0.5.6 shipped on 2025-12-03. InferenceX PR #276 bumped the NVIDIA DeepSeek SGLang Docker image from v0.5.5-cu129-amd64 to v0.5.6-cu129-amd64 on 2025-12-31, 28 days later, and the first 0.5.6 run on the DeepSeek R1 FP4 B200 configuration ran the same day. No hardware or parallelism change, just a Docker image bump."
}
}
]
}`}
---
# GB200 NVL72 vs B200 on Kimi K2.5: 3.1x from Wide EP vLLM
> Rack scale NVLink on NVL72 lets Dynamo vLLM run Kimi K2.5 wide EP up to Decode EP 16, taking peak throughput from 4,021 to 12,587 tok/s/GPU on 8k/1k NVFP4
- **Author**: SemiAnalysis
- **Date**: 2026-04-23
- **URL**: https://inferencex.semianalysis.com/blog/gb200-nvl72-kimi-k2-5-vllm-wide-ep-3x-vs-b200
- **Tags**: benchmark, gpu, inference, kimi, nvidia, gb200, b200, vllm, nvl72, wide-ep
- **Reading time**: 7 min
NVIDIA's GB200 NVL72 running Dynamo vLLM peaks at 12,587 tok/s/GPU on Kimi K2.5 NVFP4 8k/1k, while the best B200 single node vLLM recipe peaks at 4,021 tok/s/GPU on the same workload. That is a 3.13x advantage in peak throughput per GPU. NVL72's rack scale NVLink fabric lets decode run with wide expert parallelism up to Decode EP 16 on the tested recipes, with the peak at Decode EP 8 on an 8 GPU decode pool. B200 tops out at Decode EP 4 on the best measured recipe. Past that, the expert all to all starts hitting scale out fabric latencies.
Click to see the full InferenceX dashboard →
Kimi K2.5 is a 1T parameter MoE with 384 routed experts plus 1 shared expert, 8 experts active per token, and 60 MoE layers. Every MoE layer does a routed all to all dispatch followed by an all to all combine, so a single forward pass runs roughly 120 all to alls across 60 layers. On NVL72 that traffic stays on NVLink 5 at 1.8 TB/s per GPU inside a 130 TB/s aggregate fabric. On B200, wide EP past 8 GPUs leaves the NVLink island. It falls back to ConnectX 7 InfiniBand at 400 Gb/s per GPU, roughly 36x below NVL72's NVLink bandwidth. Sparsity 48 MoEs like K2.5 do not tolerate that gap at scale.
## Why Wide EP Matters for Kimi K2.5
At EP 4, each GPU holds 96 of Kimi K2.5's 384 experts. Decode is bound by the HBM bandwidth required to reload those expert weights every step. Widening EP to 16 drops the per GPU expert footprint to 24. Each expert weight read is now amortized across a larger effective batch of peer GPUs dispatching tokens through that rank. This shifts decode from weight bandwidth bound toward compute and communication bound. That is a regime where Blackwell's FP4 tensor cores and NVLink bandwidth both work in your favor.
The cost of widening EP is an all to all collective at every MoE layer. If that collective hits scale out fabric the interactivity budget collapses before the throughput gains pay back. NVL72's scale up domain is what makes wide EP practical at EP 8 through EP 16 for K2.5 decode pools. B200's 8 GPU NVLink island makes Decode EP 4 across two nodes the ceiling before scale out takes over.
## Peak Throughput and the Concurrency Curve
All numbers are Kimi K2.5 NVFP4 at ISL 8192 / OSL 1024 on InferenceX. B200 data is from the 2026-03-27 run, triggered by [InferenceX PR #926](https://github.com/SemiAnalysisAI/InferenceX/pull/926) which disabled prefix caching for Kimi K2.5 vLLM benchmarks on random datasets. GB200 NVL72 data is from the 2026-04-07 run, triggered by [InferenceX PR #1008](https://github.com/SemiAnalysisAI/InferenceX/pull/1008) which added the GB200 Dynamo vLLM disaggregated multinode recipe (vLLM 0.18.0, nvidia/Kimi-K2.5-NVFP4, NixlConnector KV transfer, FLASHINFER_MLA attention). The two runs are 11 days apart. Both are the latest available for the peak-throughput recipe on each hardware.
B200 vLLM, 2026-03-27 run, non disaggregated, 16 GPU pool:
| Prefill | Decode | Conc | tok/s/GPU | TPOT (ms) | tok/s/user |
| ---------- | ---------- | ---- | --------- | --------- | ---------- |
| TP 4, EP 4 | TP 4, EP 4 | 4 | 878 | 9.8 | 101.8 |
| TP 4, EP 4 | TP 4, EP 4 | 8 | 1,529 | 11.2 | 89.5 |
| TP 4, EP 4 | TP 4, EP 4 | 16 | 2,286 | 15.1 | 66.3 |
| TP 4, EP 4 | TP 4, EP 4 | 32 | 3,108 | 22.2 | 45.0 |
| TP 4, EP 4 | TP 4, EP 4 | 64 | **4,021** | **34.1** | **29.3** |
GB200 NVL72 Dynamo vLLM, 2026-04-07 run, disaggregated:
| Prefill | Decode | Conc | tok/s/GPU | TPOT (ms) | tok/s/user |
| ---------- | ------------ | ----- | ---------- | --------- | ---------- |
| TP 4, EP 4 | TP 4, EP 4 | 4 | 231 | 7.1 | 140.8 |
| TP 4, EP 4 | TP 4, EP 4 | 8 | 421 | 7.7 | 129.1 |
| TP 4, EP 4 | TP 4, EP 4 | 16 | 744 | 8.7 | 114.7 |
| TP 4, EP 4 | TP 4, EP 4 | 32 | 1,230 | 10.3 | 96.9 |
| TP 4, EP 4 | TP 4, EP 4 | 128 | 2,173 | 12.8 | 77.9 |
| TP 4, EP 4 | TP 16, EP 16 | 512 | 6,885 | 20.5 | 48.8 |
| TP 4, EP 4 | TP 16, EP 16 | 1,024 | 7,565 | 21.6 | 46.2 |
| TP 4, EP 4 | TP 8, EP 8 | 2,048 | **12,587** | 43.1 | 23.2 |
| TP 4, EP 4 | TP 16, EP 16 | 4,096 | 12,576 | 27.5 | 36.3 |
B200 saturates per GPU throughput at 4,021 tok/s by concurrency 64, where the 16 GPU pool is fully loaded. NVL72 keeps absorbing concurrency out to 2,048 and beyond. The decode pool is 8 to 16 GPUs of wide EP sitting on a scale up fabric. Adding users keeps the MoE all to all bandwidth bound instead of latency bound.
## Iso Interactivity Comparison
At B200's peak throughput operating point (concurrency 64, 29.3 tok/s/user, 4,021 tok/s/GPU), the closest GB200 NVL72 points are:
| Interactivity (tok/s/user) | GB200 NVL72 tok/s/GPU | Config |
| -------------------------- | --------------------- | --------------------------------- |
| 36.3 | 12,576 | Decode TP 16, EP 16 at conc 4,096 |
| 23.2 | 12,587 | Decode TP 8, EP 8 at conc 2,048 |
GB200 NVL72 sits on a roughly flat ~12,580 tok/s/GPU plateau across the 23 to 36 tok/s/user band, giving a 3.13x throughput ratio at iso interactivity near B200's peak.
[Live chart](https://inferencex.semianalysis.com/inference?g_model=Kimi-K2.5&g_rundate=2026-04-07&g_runid=24100518225), pre-filtered to Kimi K2.5 on April 7th.
## vLLM Wide EP on NVL72
vLLM shipped its PPLX all to all backend in v0.9 and added DeepEP shortly after. v0.11 completed the V1 engine migration and extended the dual batch overlap (DBO) path via PR [#24845](https://github.com/vllm-project/vllm/pull/24845), which adds DeepEP high throughput kernels and prefill support to DBO so all to all communication can be hidden behind compute. The benchmarks above run v0.18.0 without speculative decoding.
The GB200 NVL72 setup runs vLLM as worker runtime inside NVIDIA Dynamo, tagged dynamo-vllm in the InferenceX dataset. Dynamo splits prefill (4 GPUs at TP 4, EP 4) from decode (8 to 16 GPUs with TP and EP both scaled up to 16) and routes requests between them across the NVL72 fabric. SGLang and TRT-LLM have analogous disagg + wide EP paths on NVL72, with SGLang's public GB200 results currently the most mature.
## When Each SKU Wins
B200 delivers around 4k tok/s/GPU at 30 tok/s/user on a 16 GPU pool. The TP 4, EP 4 recipe saturates around concurrency 64. Past that, the latency floor collapses.
GB200 NVL72 delivers 12.5k tok/s/GPU at 23 to 36 tok/s/user across concurrency 2,048 to 4,096. The tested single node B200 recipes have no comparable operating point.
Click to see the full InferenceX dashboard →
{`{
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [
{
"@type": "Question",
"name": "How much faster is GB200 NVL72 than B200 on Kimi K2.5 inference in vLLM?",
"acceptedAnswer": {
"@type": "Answer",
"text": "On Kimi K2.5 NVFP4 at 8k/1k sequence length, GB200 NVL72 running Dynamo vLLM peaks at 12,587 tok/s/GPU, while the best B200 vLLM recipe peaks at 4,021 tok/s/GPU. That is a 3.13x advantage in peak throughput per GPU. At B200's peak throughput operating point (29.3 tok/s/user interactivity), GB200 NVL72 delivers around 12,580 tok/s/GPU at 23 to 36 tok/s/user, 3.13x the throughput at iso interactivity. Measured on InferenceX, B200 data from 2026-03-27 and GB200 NVL72 data from 2026-04-07."
}
},
{
"@type": "Question",
"name": "Why does GB200 NVL72 scale wider expert parallelism than B200 on MoE models?",
"acceptedAnswer": {
"@type": "Answer",
"text": "NVL72 is a 72 GPU NVLink scale up domain. Every GPU can reach every other GPU at 1.8 TB/s inside a 130 TB/s aggregate fabric. B200 tops out at 8 GPUs per NVLink island. Any wider expert parallelism has to cross InfiniBand at 400 Gb/s per GPU, roughly 36x below NVL72's NVLink bandwidth. Kimi K2.5 has 384 routed experts and 60 MoE layers, so every MoE layer does an all to all dispatch plus combine, around 120 all to alls per forward pass. That collective is only practical at EP 16 or higher when the fabric is NVLink end to end. On NVL72 that traffic stays inside scale up. On B200 past 8 GPUs it does not."
}
},
{
"@type": "Question",
"name": "What vLLM version and recipe is needed for Kimi K2.5 wide EP on GB200 NVL72?",
"acceptedAnswer": {
"@type": "Answer",
"text": "vLLM 0.18 or later is required for the Kimi K2.5 recipe, which depends on Eagle3 speculative decoding support. The PPLX all to all backend shipped in vLLM 0.9, DeepEP followed, and v0.11 completed the V1 engine migration and extended the dual batch overlap (DBO) path via PR #24845 (adding DeepEP high throughput kernels and prefill support to DBO). The InferenceX GB200 benchmark runs TP 4 on the prefill pool and scales decode TP and EP to 16 across the NVL72 decode pool. The upstream vLLM recipe uses a DP 4 / DP 16 shape with TP 1 and expert parallel on both sides."
}
},
{
"@type": "Question",
"name": "Is B200 still a viable option for serving Kimi K2.5?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Yes, for workloads that sit at moderate concurrency. B200 vLLM at Decode TP 4, EP 4 delivers around 4,021 tok/s/GPU at 29 tok/s/user on a 16 GPU pool. The B200 Pareto frontier tops out around concurrency 64 on a 16 GPU pool. Workloads that need to pack thousands of concurrent users onto a single serving domain without losing per GPU efficiency are where GB200 NVL72 pulls ahead, by a factor of around 3x, because the NVL72 scale up fabric is what makes Decode EP 16 practical on a 384 expert MoE."
}
}
]
}`}
---
# AMD MI355X Kimi K2.5 Inference: 7.7x Throughput, Up To 15x Interactivity in 25 Days on vLLM
> vLLM PR #35850 Fixed AITER MLA Dispatch on MI355X CDNA4, Unlocking Kimi K2.5 Inference Performance at TP=8, Shipped in vLLM 0.18
- **Author**: SemiAnalysis
- **Date**: 2026-04-22
- **URL**: https://inferencex.semianalysis.com/blog/mi355x-kimi-k2-5-vllm-aiter-7x-speedup
- **Tags**: benchmark, gpu, inference, kimi, amd, vllm, rocm, mi355x
- **Reading time**: 7 min
It took a single vLLM PR to move AMD MI355X Kimi K2.5 MXFP4's performance from 6.6 to 78.9 tok/s/user at matched concurrency on the 8k/1k workload. That same PR also provided other incredible performance gains including 12.0x interactivity at low batch, 7.7x peak throughput, and up to 15x at iso-throughput.
However, their most impressive achievement was how fast they were able to move the curve. [vLLM PR #35850](https://github.com/vllm-project/vllm/pull/35850) merged on March 6 and shipped in vLLM 0.18, and by March 26 the InferenceX benchmark loop had caught the full effect via [InferenceX PR #936](https://github.com/SemiAnalysisAI/InferenceX/pull/936) (which enabled AITER, expert parallel, and the vLLM 0.18.0 upgrade on the [MI355X Kimi K2.5 recipe](https://recipes.vllm.ai/moonshotai/Kimi-K2.5?hardware=mi355x&features=tool_calling%2Creasoning%2Cencoder_parallel)), 25 days after our vLLM 0.16.0 Mar 1 baseline. Every operating point on MI355X Kimi K2.5 MXFP4 was rewritten from a barely usable option with a single-point latency floor to a proper Pareto frontier reaching 78.9 tok/s/user at low batch and 2,687 tok/s/GPU at peak throughput. This is the exact reason we built the [InferenceX](https://github.com/SemiAnalysisAI/InferenceX) automated benchmark. To efficiently catch and report on changes like this as soon as they land.
One of the most consistent criticisms we've leveled at AMD Kimi K2.5 inference through [InferenceXv2](https://inferencex.semianalysis.com/blog/inferencex-v2-nvidia-blackwell-vs-amd-vs-hopper) is composability. MI355X silicon on CDNA4 is competitive with B200 at the tensor-core level, but AMD's ROCm and vLLM path does not always expose that capability. This is particularly visible on newer frontier MoE models where the inference performance recipes are still maturing.
Click to see the full InferenceX dashboard →
## What PR #35850 Fixed
Kimi K2.5 is a 1T-parameter MoE that uses Multi-head Latent Attention (MLA), the attention variant DeepSeek introduced in V2. MLA reduces KV-cache memory by projecting keys and values into a shared latent space. The resulting attention heads-per-rank depends on tensor-parallel rank: at TP=4, Kimi K2.5 hits 16 heads/rank, and at TP=8 it hits 8 heads/rank.
AITER, AMD's hand-tuned AI Tensor Engine for ROCm, has an optimized MLA kernel path on CDNA4, but the vLLM integration was not dispatching to it at TP=8. AITER's MLA decode kernel is built around a `gqa_ratio=16` ASM path that natively accepts 16 heads/rank (TP=4) and 128 heads/rank, and rejects intermediate values. At TP=8 on Kimi K2.5 with 8 heads/rank, the dispatch failed the head-count assertion and fell through to vLLM's reference TritonMLA path, which on MXFP4 runs materially slower than AITER.
PR #35850 landed three changes in a single commit: AITER MLA support for `num_heads < 16` via a head-repeat trick (padding 8 heads to 16 so the existing `gqa_ratio=16` ASM kernel works, which unlocks TP=8 on Kimi K2.5 and Kimi-Linear at TP=16), a relaxed head-count assertion accepting 4, 8, or any multiple of 16 in [16, 128], and auto-fallback from TritonMLA to AITER MLA when FP8 KV cache is used (TritonMLA raises `NotImplementedError` on FP8 KV). All three shipped in vLLM 0.18. Separately, AMD's ongoing MXFP4 GEMM autotuning on the MoE expert shapes contributed alongside this PR to the observed throughput delta.
## Reading the Curve
The InferenceX's benchmark results caught the change as soon as it landed:
| Date | Conc | Decode TP | tok/s/GPU | TPOT | tok/s/user | Gain at matched conc |
| ---------- | ----- | --------- | --------- | --------- | ---------- | -------------------- |
| Mar 1 | 4 | 8 | 28.7 | 152 ms | 6.6 | (baseline) |
| Mar 1 | 8 | 8 | 55.0 | 158 ms | 6.3 | (baseline) |
| Mar 1 | 16 | 8 | 104.8 | 164 ms | 6.1 | (baseline) |
| Mar 1 | 32 | 8 | 191.2 | 179 ms | 5.6 | (baseline) |
| Mar 1 | 64 | 8 | 348.5 | 199 ms | 5.0 | (baseline) |
| **Mar 26** | **4** | **8** | **337** | **13 ms** | **78.9** | **12.0x** |
| Mar 26 | 8 | 8 | 521 | 16 ms | 60.8 | 9.7x |
| Mar 26 | 16 | 8 | 870 | 20 ms | 50.5 | 8.3x |
| Mar 26 | 32 | 8 | 1,255 | 27 ms | 36.4 | 6.5x |
| Mar 26 | 64 | 8 | 1,647 | 43 ms | 23.3 | 4.7x |
TP=8 at both dates for the apples-to-apples comparison. The latency floor collapsed from 152-199 ms to 13-43 ms across the batch curve.
For peak throughput, the winning post-fix recipe shifted to TP=4, which trades a small amount of low-batch interactivity for much higher tokens per GPU numbers:
| Date | Conc | TP | tok/s/GPU | TPOT | tok/s/user |
| ------ | ---- | --- | --------- | ----- | ---------- |
| Mar 26 | 4 | 4 | 650 | 13 ms | 76.2 |
| Mar 26 | 64 | 4 | **2,687** | 53 ms | 19.0 |
### Iso-Throughput: Where the 15x Lives
The 12.0x gain in the table above compares both versions at the same batch size. The more useful comparison holds throughput per GPU fixed instead, and asks how much faster each user's response comes back. Interpolating both TP=8 curves on 8k/1k at matched tok/s/GPU levels:
| Iso-throughput (tok/s/GPU) | v0.16 interactivity (tok/s/user) | v0.18 interactivity (tok/s/user) | Interactivity gain |
| -------------------------- | -------------------------------- | -------------------------------- | ------------------ |
| 337 | 5.1 (interp, conc ~62) | **78.9** (measured, conc 4) | **15.6x** |
| 380 | 4.9 (extrap) | 74.7 (interp, conc ~5) | 15.2x |
The "up to 15x" headline sits at 337 tok/s/GPU, where v0.16's broken latency floor (152-199 ms TPOT regardless of batch) meets v0.18's proper floor of 13 ms at conc 4. At this operating point vLLM v0.18 is now able to run at near real-time speech latency on Kimi K2.5 inference.
You can find the live version of this chart [here](https://inferencex.semianalysis.com/inference?g_rundate=2026-04-20&g_runid=24695468813&g_model=Kimi-K2.5&i_gpus=mi355x_vllm&i_dstart=2026-03-01&i_dend=2026-03-26) pre-filtered to Kimi K2.5 on MI355X vLLM across Mar 1 to Mar 26.
## Speed Is the Moat
Post-fix, MI355X Kimi K2.5 inference peaks at 2,687 tok/s/GPU on 8k/1k MXFP4, roughly 67% of B200 single-node vLLM FP4 at 4,021 tok/s/GPU. At the lower per-GPU TCO that hyperscalers and neoclouds are renting Instinct MI355X at, there are real operating points where MI355X is the cheaper choice per million tokens. However, the gap that has still not closed for rack-scale disagg: MI355X is 4.7x–5.3x behind GB200 NVL72 Dynamo vLLM and TRT-LLM on this workload. Most MI355X configs are single-node, bounded to 4 or 8 GPUs, no disaggregated prefill/decode split, no wide expert parallelism across a rack-scale fabric.
AMD has already shown it can ship production disagg on its own stack. The MI355X DeepSeek R1 results use `mori-sglang` with disaggregated prefill/decode, MXFP4 and MXFP8, both with and without MTP speculative decoding. We hope to see the same for Kimi K2.5 soon.
And this is why update cadence showcased by our benchmarks matter so much. A point-in-time MI355X vs B200 comparison run on March 1 would have said MI355X was 10x behind and roughly unusable. However, data from a mere 25 days later proves that MI355X is within striking distance of B200 single-node.
Click to see the full InferenceX dashboard →
{`{
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [
{
"@type": "Question",
"name": "What did vLLM PR #35850 fix for Kimi K2.5 on MI355X?",
"acceptedAnswer": {
"@type": "Answer",
"text": "vLLM PR #35850 (merged March 6 2026) added AITER MLA support for num_heads < 16 on MI355X CDNA4 via a head-repeat trick that pads 8 heads to 16 before calling the optimized gqa_ratio=16 ASM kernel. This unlocks TP=8 on Kimi K2.5 (8 heads/rank) and Kimi-Linear at TP=16 (4 heads/rank). The PR also relaxes the head-count assertion to accept 4, 8, or any multiple of 16 in [16, 128], and adds auto-fallback from TritonMLA to AITER MLA when FP8 KV cache is used. Pre-fix, TP=8 Kimi K2.5 was falling back to the reference Triton MLA path, which on MXFP4 ran materially slower than AITER. The fix shipped in vLLM 0.18."
}
},
{
"@type": "Question",
"name": "How much faster is MI355X on Kimi K2.5 after vLLM 0.18?",
"acceptedAnswer": {
"@type": "Answer",
"text": "On Kimi K2.5 MXFP4 8k/1k, MI355X v0.18 delivers up to 15.6x more interactivity than v0.16 at iso-throughput, measured at 337 tok/s/GPU (the lowest measured point on the v0.18 TP=8 curve, where v0.18 serves 78.9 tok/s/user vs v0.16's interpolated 5.1 tok/s/user). At matched concurrency on TP=8, interactivity went from 6.6 to 78.9 tok/s/user, a 12.0x gain. Peak throughput improved 7.7x, from 348.5 tok/s/GPU (TP=8, v0.16) to 2,687 tok/s/GPU (TP=4, v0.18, the new winning-throughput recipe). Total elapsed: 25 days, Mar 1 to Mar 26."
}
},
{
"@type": "Question",
"name": "Is MI355X competitive with NVIDIA B200 on Kimi K2.5 after the fix?",
"acceptedAnswer": {
"@type": "Answer",
"text": "On single-node throughput, yes. Post-fix MI355X MXFP4 hits 2,687 tok/s/GPU vs B200 single-node vLLM FP4 at 4,021 tok/s/GPU, roughly 67% of B200 throughput with a lower per-GPU TCO on CDNA4 Instinct deployments. The remaining 4.7x to 5.3x gap to GB200 NVL72 (12,586 tok/s/GPU on Dynamo vLLM, 14,187 on Dynamo TRT-LLM) is composability. MI355X has no disaggregated serving or wide expert parallelism for Kimi K2.5 yet. AMD has shipped disagg for DeepSeek R1 via mori-sglang, so the playbook exists."
}
},
{
"@type": "Question",
"name": "Should I upgrade to vLLM 0.18 for MI355X Kimi K2.5 serving?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Yes. The AITER MLA dispatch fix and MXFP4 GEMM autotuning in PR #35850 are both required to reach the 2,687 tok/s/GPU peak on Kimi K2.5 8k/1k and the sub-15 ms TPOT latency floor at low batch. Pre-0.18 vLLM on MI355X falls back to the reference attention implementation, which leaves more than an order of magnitude of performance on the table on this model."
}
}
]
}`}
---
# InferenceX v2: NVIDIA Blackwell Vs AMD vs Hopper - Formerly InferenceMAX
> GB300 NVL72, MI355X, B200, H100, Disaggregated Serving, Wide Expert Parallelism, Large Mixture of Experts, SGLang, vLLM, TRTLLM
- **Author**: SemiAnalysis
- **Date**: 2026-02-16
- **URL**: https://inferencex.semianalysis.com/blog/inferencex-v2-nvidia-blackwell-vs-amd-vs-hopper
- **Tags**: benchmark, gpu, inference, announcement
- **Reading time**: 47 min
## Introduction
InferenceXv2 (formerly InferenceMAX) builds on the foundation established by InferenceMAXv1, [our open-source, continuously updated inference benchmark](https://github.com/SemiAnalysisAI/InferenceX) that has set a new standard for AI inference performance and economics. InferenceMAXv1 moved beyond static, point-in-time benchmarks by running continuous tests across hundreds of chips and popular open-source frameworks. [Free dashboard available here.](https://inferencemax.ai/)
[Our benchmark has been widely reproduced, validated and/or supported by almost every major buyer](https://inferencemax.semianalysis.com/quotes) of compute from [Google Cloud](https://cloud.google.com/blog/products/compute/scaling-moe-inference-with-nvidia-dynamo-on-google-cloud-a4x) to [Microsoft Azure](https://blog.aks.azure.com/2025/10/24/dynamo-on-aks#enterprise-scale-inference-experiments--dynamo-with-gb200-running-on-aks) to [Oracle, OpenAI](https://inferencemax.semianalysis.com/quotes), and many more.
InferenceXv2 builds on this foundation. It expands coverage to include large scale DeepSeek MoE disaggregated inference (disagg prefill, or simply “disagg”) with wide expert parallelism (wideEP) optimization to **all 6 NVIDIA western GPU SKUs from the past 4 years **as well as to every single AMD western GPU SKU released in the past 3 years – in total InferenceXv2 utilizes close to 1000 frontier GPUs for a full benchmark run across all SKUs.
With today’s release, InferenceXv2 is now the first suite to benchmark the Blackwell Ultra GB300 NVL72 and B300 across the whole pareto frontier curve, and it is the first third party benchmark to test disagg+wideEP multi-node FP4 and FP8 MI355X performance. In future iterations of InferenceX, we will continue to focus heavily on disaggregated serving with wide expert parallelism as that is what is deployed in production at Frontier AI Labs like OpenAI, Anthropic, xAI, Google Deepmind, DeepSeek as well as advanced API providers like TogetherAI, Baseten, and Fireworks. In this article, we will also break down the system engineering principles and economics in play around the [latest Claude Code Fast mode feature](https://code.claude.com/docs/en/fast-mode).
Our benchmark is completely open-source under Apache 2.0 – this means that we are able to move at the same rapid speed at which the AI software ecosystem is advancing. If you like our work and would like to show us some support, [please drop a star on our GitHub](https://github.com/SemiAnalysisAI/InferenceX)! We also provide a free data visualizer at [https://inferencex.com](https://inferencex.semianalysis.com/) for everyone in the ML community to explore the complete dataset themselves.
We will add DeepSeekv4 and other popular Chinese frontier models with day 0 support as over the past 6 months, we now have cleaned up a lot of tech debt and are able to [move fast with stable infrastructure](https://www.cnet.com/tech/mobile/zuckerberg-move-fast-and-break-things-isnt-how-we-operate-anymore/). We will also be adding TPUv7 Ironwood and Trainium3 to InferenceX later this year! If you want to contribute to our impactful mission while earning a competitive compensation, [consider applying here](https://app.dover.com/apply/semianalysis/2a9c8da5-6d59-4ac8-8302-3877345dbce1).
## Key Observations and Results to Highlight
We see competitive perf per TCO results on FP8 MI355X disagg+wideEP SGLang on AMD compared to FP8 B200 disagg+wideEP SGLang, but when compared to widely used Dynamo TRTLLM B200 FP8, TRT continues to framemog. This is amazing news that AMD SGLang Disagg prefill+wideEP for FP8 is able to match NVIDIA’s SGLang performance.
We also see that for single node aggregated serving, AMD’s SGLang delivers better perf per TCO than NVIDIA’s SGLang for FP8. [It is also great to see that AMD has deprecated their second class fork of vllm to move further upstream and closer to delivering first class experience.](https://x.com/vllm_project/status/2013928644302033208) Stay tuned for our “State of AMD” article where we talk about the many areas where AMD’s pace of improvement has been rapid & also the areas where the pace of improvement has been lackluster. We recommend that NVIDIA focus even more on SGLang & vLLM ecosystem in addition their TRTLLM engine. [Jensen needs to staff more resources & engineers towards contributing open ecosystems like SGLang & vLLM](https://www.linkedin.com/in/akbarnurlybayev?trk=feed-detail_main-feed-card_feed-actor-image).
When it comes to the latest inference techniques that are used by the most prominent frontier large-scale inference services (such as disagg prefill+wideEP+FP4), Nvidia absolutely frame mogs with the B200, B300 and ASU frat leader, rack scale GB200/GB300 NVL72 across both SGLang and TRTLLM. Nvidia GPUs also dominate when it comes to energy efficiency, with much lower all-in provisioned picoJoules of energy per token across all workloads.
Turning to AMD, we find that the biggest issue with inference on their systems and using their software is _[composability](https://en.wikipedia.org/wiki/Composability)_. That is, many of AMDs inference optimization implementations work well in isolation, but when combined with other optimizations, the result is not as competitive as one would expect. Specifically, the composability of disagg prefill, wideEP and FP4 inference optimizations needs significant improvement.
While performance is competitive on AMD when enabling just a subset of the SOTA inference optimizations, enabling all three major optimizations that labs use, AMD’s performance is currently not competitive with Nvidia’s. We strongly recommend to AMD that they focus heavily on composability of different inference optimizations. We have been told that AMD will start focusing on software composability of FP4+distributed inferencing across their whole software stack. This will happen after Chinese New Year as most of their disagg prefill+wideEP 10x inference engineers are based in China
Nvidia’s GB300 NVL72 doesn’t disappoint. It achieves up to 100x on FP8 vs FP4 compared to even a strong H100 disagg+wideEP+MTP baseline and 65x on FP8 vs FP8. On H100 vs GB200 NVL72, we see up to 55x realized performance difference at 75 tok/s/user. Rack scale Blackwell NVL72 is framemogging hopper and makes hopper looks like it is jestermaxxing. As Jensen said at GTC 2025, [he is chief revenue destroyer.](https://newsletter.semianalysis.com/i/174558496/ai-total-cost-of-ownership-cost-declines)
At GTC 2024, Jensen claimed that Blackwell will deliver up to 30x perf on inference compared to H100, Jensen under promised & overdelivered on Blackwell inference performance. This should curtail the instances of analysts cracking “Jensen Math” jokes for some time.
## Acknowledgments and InferenceX™ (formerly InferenceMAX) Initiative Supporters
We would like to thank Jensen Huang and Ian Buck for supporting this open-source effort by providing access to the latest GB300 NVL72 systems along with access to servers representing all GPU SKUs that they have produced for the past four years. We would like to thank the Nvidia team for allowing us to conduct independent benchmarks across this close to 1000 GPUs. Thank you to Jatin Gangani, Kedar Potdar, Sridhar Ramaswamy, Ishan Dhanani, Sahithi Chigurupati, along with many other Nvidia inference engineers for helping to validate and optimize Blackwell & Hopper configurations.
We’re also grateful to Lisa Su and Anush Elangovan for their support of InferenceMAX and for supporting our work with the dozens of AMD engineers like Chun, Andy, Bill, Ramine, Theresa, Parth, etc that contributed to InferenceMAX & upstream vLLM/SGLang bug fixes, as well as for their responsiveness on helping debug and triage AMD exclusive bugs so as to help optimize AMD performance.
We also want to recognize the SGLang, vLLM, and TensorRT-LLM maintainers for building a world-class software stack and open sourcing it to the entire world. You can check their articles on InferenceX here:
- [SemiAnalysis InferenceMAX: vLLM maintainers & NVIDIA accelerate Blackwell Inference](https://blog.vllm.ai/2025/10/09/blackwell-inferencemax.html)
- [GPT-OSS Performance Optimizations: Pushing Pareto Frontier](https://blog.vllm.ai/2026/02/01/gpt-oss-optimizations.html)
- [SGLang & NVIDIA Accelerating SemiAnalysis InferenceMAX & GB200 Together](https://lmsys.org/blog/2025-10-14-sa-inference-max/)
The InferenceX initiative is also supported by many major buyers of compute and prominent members of the ML community including those from OpenAI, Microsoft, vLLM, Tri Dao, PyTorch Foundation, Oracle and more. [You can find the full list here](https://inferencemax.semianalysis.com/quotes).
## A Primer on Important Technical Concepts
In this section, we will give a brief primer on technical concepts that may help the reader better interpret results. Some readers may not need this and can skip directly to our analysis of results. We will take a deeper dive into some of these topics after the results analysis.
## Interactivity vs Throughput Tradeoff
The fundamental tradeoff with LLM inference is throughput versus latency. _Interactivity_ (tok/s/user) describes how fast each user of a system receives tokens – it is the inverse of time per output token (TPOT). _Throughput_ (tok/s) describes how many total tokens a system can crank out across all users. One can achieve higher total throughput by batching requests, but each request will be allocated less FLOPs and thus complete slower. This is analogous to the choice of riding a metro bus vs a race car. The metro bus serves many riders, but also makes frequent stops which takes time, but the cost of the metro bus can be amortized across many passengers. The race car can only carry one or two passengers, but it will make few if any additional stops meaning a faster travel time overall, but it is much more expensive to ride per passenger. The metro bus might make more sense for people heading to the park on a weekend, while the race car might be better for bringing a celebrity to their destination. There is no one size fits all solution.
Most benchmark results we will show in this article are InferenceX is a curve. It is important to analyze throughput at various levels of interactivity/latency instead of just looking at maximum achieved throughput (which normally can only be achieved at a single low interactivity). With inference, there is no one size fits all use case. The level of interactivity and throughput needed depends on the use case. For instance, real-time speech models require extremely low latency so that the end user can maintain a natural “conversation” with the LLM, whereas a basic QA chatbot may allow for higher latency. We leave it up to the reader to look at the curve and apply this principle to identify where their use case falls on the throughput-interactivity curve.
The Cost/Perf per TCO vs Interactivity/End-to-End Latency curve mostly follows the Throughput vs Interactivity/End-to-End Latency Curve: More tokens/hour leads to a lower cost per token as fixed $/hour costs are amortized over more tokens produced.
### Prefill and Decode Phases
Inference contains two main phases: prefill and decode. _Prefill_ occurs during the first forward pass of a request’s lifetime. It is computationally intensive since all tokens in the request are processed in parallel. This phase is responsible for “filling up” the KV cache for a sequence. After prefill, responses are generated (or _decoded_) one token at a time. Each forward pass loads the entire KV cache for a sequence from HBM, while only performing the computation for a single token, making decode memory (bandwidth) intensive.
When prefill and decode performed on the same engine, prefill constantly disrupts decode batches leading to worse overall performance.
### Disaggregated Prefill
Disaggregated prefill (aka PD disaggregation or simply “disagg”) is the practice of separating the prefill and decode phases across separate pools of GPUs or clusters. These separate prefill and decode pools can be tuned independently and scaled to match the needs of workloads.
## Tensor Parallel, Expert Parallel, Data Parallel (TP, EP, DP)
TP allows for maximize interactivity at small batch sizes, but it must carry out an all-reduce at every layer. EP shards experts, exploiting MoE sparsity, with the drawback being an all-to-all collective (which is more costly than simpler collectives like all-reduce) is carried out for MoE layers and can be imbalanced at small batches. DP replicates the entire model (or just parts of a model, like attention) on multiple groups of GPUs (ranks) and then load balances requests among ranks. It is the simplest to scale, but repeats weight loading which can be wasteful at scale.
## Tracking Improvements Over Time
One of the main goals of InferenceX is to visualize performance improvements over time. While new chips are released on an O(yearly) cadence, software releases happen on an O(weekly) cadence. Our goal is to constantly update recipes with the latest and greatest software improvements and benchmark the configurations.
## DeepSeek R1
The AMD team has significantly improved performance for all configurations of SGLang DeepSeek R1 FP4. For the same interactivity, AMD has almost doubled the amount of throughput in the span of less than 2 months. Moreover, we have pushed AMD to upstream performance enhancing changes from their forked SGLang images into the official SGLang image. From December 2025 to January 2026, AMD’s software was improved up to 2x in performance.
In order to continue becoming closer to an first class experience, AMD needs increase their support of vLLM & SGLang maintainers through compute contributions and code contributions & having more reviewers that work for AMD to speed up the review process of AMD PRs into the upstream.
On the other hand, Nvidia’s results were more consistent, with minor improvements for B200 SGLang over a similar time period.
Many of the mature SKUs had minimal improvements. For example, H200 TRT single node has not changed in performance in the span of 4 months since October, but this is because Hopper support has been excellent since day 1, and performance has close to peak theoretical for this workload all along, making it hard to deliver incremental performance gains.
MI300X and MI325X have seen some improvements, mainly from the most recent SGLang release. Note that for much of the history of InferenceX, AMD was using “private” ROCm images that were not upstreamed, so runs prior to ~Jan 2026 cannot be compared directly to those that are more recent.
GB200 Dynamo TRT-LLM disagg has seen some significant improvements as well, with a 20% increase in max throughput in the span of a little over 1 month. We also see improvements in the middle interactivities, where wide EP is deployed. This is likely due to maturing wide EP kernels on GB200.
B200 SGLang has seen steady and continuous improvement for both FP4 and FP8 scenarios since our initial launch, with throughput per GPU doubling at some interactivity levels since last October.
For MI355X Disaggregated inference serving, AMD recommends using SGLang with MoRI. [MoRI is AMD’s MoE dispatch/combine collective and KV Cache transfer library](https://github.com/ROCm/mori/tree/main) built from first principles by AMD’s cracked 10x China-based engineering team. Although MoRI needs much more open CI and testing, we are strong supporters of the direction that MoRI is taking. This is because instead of taking AMD’s historical approach, which was to fork NVIDIA’s NCCL into RCCL, MoRI is built from scratch by taking the lessons from RCCL/NCCL and building an entirely new package from first principles. The use of MoRI has also delivered good speedups in the span of more than a month, with throughput per GPU increasing by more than 20% in the 20-45 tok/s/user interactivity range.
## GPT-OSS 120B
For MI300X and MI325X, we have seen marginal improvements across the board. Some AITER optimizations helped MI300X performance across all interactivities, and switching to the upstream vLLM ROCm image led to improvements.
In the case of the MI325X, it appears that not all performance enhancements that were present in the downstream ROCm fork image (used during the October 5th, 2025 run) have made it into the official vLLM ROCm image.
Unfortunately, the MI355X literally still uses a fork of the vLLM 0.10.1 build `rocm/7.0:rocm7.0_ubuntu_22.04_vllm_0.10.1_instinct_20250927_rc1`). We would love to have seen it updated it by now, but unfortunately the current official image (0.15.1, at the time this article was written) is not yet optimized for the MI355X and runs into hard errors. We had also run into hard errors crashes on Mi355 for vLLM 0.14. Word on the street is that vLLM 0.16.0 will finally deliver all the changes needed for better MI355X performance.
Turning back to Nvidia’s systems, both Hopper and Blackwell saw a steady performance increase between vLLM 0.11.2 and 0.13.0. Soon, we will update recipes for Nvidia GPUs to use the latest vLLM version and we expect even greater performance gains after making the switch. We also observed a performance bump in the latest 1.2.0 version of TRT-LLM.
## Disaggregated Inference Frameworks
NVIDIA uses Dynamo for its disaggregated inference setup. [Dynamo](https://docs.nvidia.com/dynamo/design-docs/overall-architecture) is an inference framework designed for multi-node distributed inference, featuring techniques such as prefill-decode disaggregation, request routing, and KV cache offloading. It is inference-engine agnostic, allowing us to use SGLang and TRT LLM as backends in our benchmark. For AMD, we use SGLang with two different KV cache transfer frameworks: MoRI and Mooncake. [MoRI](https://github.com/rocm/mori) is a high-performance communication interface focusing on RDMA and GPU integration, offering applications such as network collective operations and expert parallel kernels. Mooncake, which [recently joined the PyTorch ecosystem](https://pytorch.org/blog/mooncake-joins-pytorch-ecosystem/), supports prefill-decode disaggregation and many fault tolerant multi-node features.
## DeepSeek Disagg +WideEP Results Deep Dive
At almost all interactivity levels, disagg outperform aggregated inference (grey lines) in terms of total token throughput per GPU. Multi-node disaggregrated prefill framemogs single node aggregrated serving.
Nvidia continues to push new updates for B200/GB200 FP8. The latest data on DeepSeek FP8 B200 TRT single node (both MTP enabled/disabled) vs GB200 Dynamo+TRT disagg (both MTP enabled/disabled). This indicates consistent engineering effort to improve rack-scale inference software and wideEP kernels.
When comparing MI355X disaggregated inference vs aggregated inference, we noticed a similar pattern. Disaggregated inference only overtakes aggregated inference at low interactivity, high batch sizes. This is true across FP4, and it is likely due to poorly optimized kernels.
When composing disagg prefill+wideEP with FP4 on the MI355X, we observe suffers subpar performance.
Although theoretical modeling shows that disagg inference on MI355Xs should perform way better than single node, disagg actually performs worse for higher interactivity levels due to a lack of kernel and collective optimization in the ROCm software stack when composing multiple SOTA inference optimizations together.
### Nvidia TensorRT LLM and NVL72
TensorRT LLM already serves billions of tokens per hour globally across providers like TogetherAI and other advanced providers, and it has really allowed the GB200 NVL72 and GB300 NVL72 to shine, delivering more than double the performance at high throughput. MTP boosts these results even further, making use of the chips’ full potential.
The benefits delivered from the larger world size of the NVL72 family is also evident if we look at cost graphs. At a fixed interactivity level of 60 tok/s/user, each GB200 NVL GPU produces slightly less than triple the number of tokens/s than each B200 does.
This gap shrinks as interactivity increases. At 130 tok/s/user, the GB200 NVL72 has nearly no advantage and is even more expensive on a $/Million tokens basis. At low batch sizes, the inference workload shrinks enough to fit within a single HGX node’s NVLink domain (i.e. 8 GPUs), and the GB200 NVL72’s larger scale-out advantage starts to disappear.
## Nvidia versus AMD Disagg Prefill
With today’s release of InferenceXv2, for the first time the ML community is able to see a full Pareto frontier for open-source MI355X distributed inference. We show Pareto curves for the B200 and MI355X with and without enabling MTP.
For FP8 disagg prefill, MI355X (MoRI SGLang) is quite competitive with B200 (Dynamo SGLang). Wide EP is not used for either of these configs as all prefill/decode instances run using EP8 at the most. At both ends of the throughput versus interactivity Pareto frontier, MI355X falls behind the B200 slightly. However, MI355X disagg has a slight advantage for certain levels of interactivity in the middle of the curve. Both the B200 and the MI355X benefit from employing MTP, and we observe the same relative performance improvement for both chips when using MTP.
However, if we were to only measure output (decode) token throughput, we see that output token throughput is much higher for the B200 than for the MI355X at lower interactivity levels. Note that when looking at output token only throughput for disaggregated inference configurations, we normalize throughout by the number of decode GPUs, not total GPUs. It is possible that different numbers of GPUs are used for output when running inference jobs on the B200 and MI355X, but the bottom line is that whatever configuration decode is run on, B200 gets the decode job done faster.
Despite the MI355X being competitive in FP8 disagg, its FP4 performance suffers from composability issues. AMD single node FP4 performance is decent, but when we compare AMD FP4 disagg prefill to Nvidia, performance is subpar and the MI355X gets absolutely mogged by Nvidia’s B200. In a 1k1k scenario, the MI355X (MoRI SGLang) with MTP barely manages to beat the B200 (Dynamo SGLang) without MTP.
Once we bring Dynamo TRT-LLM into the equation, the B200’s performance is boosted even more to the point that the MI355X even with MTP can’t match the B200’s performance with Dynamo TRT-LLM and MTP. The MI355X can only match the B200 (without MTP) in performance by using MTP, and only for a range of interactivities from ~60 tok/s/user through ~120 tok/s/user.
When comparing Dynamo TRTLLM B200 disagg prefill to SGLang MoRI MI355 disagg prefill, AMD gets framemogged due to the more mature implementation of disagg prefill on TRTLLM.
The diagram below shows us the various parallelism configurations that form up the MI355X (MoRI SGLang) Pareto frontier. Note that currently, wide EP is not employed for any points (i.e., configurations with EP 16, 32, etc.).
## Unpacking Inference Providers’ Unit Economics
Below is a list on OpenRouter of all inference providers that serve DeepSeek R1 0528 FP8 along with their cost per million input/output tokens and average interactivity listed on. Disregarding Chutes, the middle of the pack provider serves at an interactivity of around 35 tok/s/user.
We can then use real InferenceX data to interpolate the cost per million input/output tokens at an interactivity level of 35 tok/sec/user, which is a reasonable interactivity level given the data above.
As we mention later in the article, this is best understood as *baseline *data and not completely representative of real-world inference, mainly because InferenceX benchmarks on random data and disables prefix caching. In other words, performance/cost will be *at least *this good. It is also important to note that there are not data points for _each GPU_ at *each *interactivity level. Thus we cannot make *exact *comparisons at each degree of interactivity. We nevertheless think the bar chart comparisons presented below are (very) reasonable interpolations in lieu of using exact data points.
Comparing disagg+wideEP configs at this interactivity level, we see just how effective distributed inference techniques are when it comes to both perf/TCO and overall throughput. We also see how large scale up domains (like GB300 and GB200 NVL72) absolutely dominate in total throughput per GPU.
It is interesting to note that at this interactivity level (on an 8k1k workload type), the B200 can achieve the best perf/TCO when MTP is enabled. Below we also list the Total Cost of Ownership (TCO) (Owning – Hyperscaler) for each GPU:
Let’s use the findings above to dig deeper into the unit economics of serving LLMs at scale. From the OpenRouter data above, we see that Crusoe serves at 36 tok/sec/user at $1.35/M input tokens and $5.40/M output tokens. If we assume no cache hits and that Crusoe is using at least H200s with SOTA inference techniques like MTP, disagg, and wide EP, the data above suggests they incur a cost of *no more than *$0.226$/M input tokens and $2.955/M output tokens for a profit margin of up to 83% gross margin (depreciation counted in cost of goods sold) on input tokens and 45% gross margin on output tokens.
Of course, these assumptions may not be *exactly *correct and these calculations don’t account for downtime or underutilization, but this gives an idea of some cool math you can do with InferenceX data. More analysis on the economics of inference can be found in the [SemiAnalysis Tokenomics Model](https://semianalysis.com/tokenomics-model/).
The OpenRouter data also shows Nebius AI Studio (Fast) serving DeepSeek FP4 at 167 tok/sec/user at $2/M input, $6/M output tokens. Adjusting the interactivity level in InferenceX accordingly and we see the following data.
At this high of interactivity, it becomes necessary to employ speculative decoding techniques like MTP to achieve high enough throughput to make inference economical. Luckily, MTP can increase throughput with relatively low risk to overall model accuracy. We will go on to talk more about MTP, and how it can be applied to increase throughput / decrease cost, in later sections of this article.
Lastly, we show one more chart of an FP8 DeepSeek workload served at 125 tok/s/user. This is another low latency workload where MTP considerably improves economic viability. As with the previous example, we note that at these higher ranges of interactivity, the cheapest configs all use MTP.
### Nvidia Disagg Prefill and WideEP
EP requires all-to-all communication, where every GPU needs to send tokens to every other GPU. This is extremely bandwidth hungry. Recall that Nvidia’s servers have two separate networking domains – the scale-up NVLink domain, and the Scale-out Domain, usually using InfiniBand or Ethernet as the networking protocol.
- NVLink domain (within the NVL72 rack): 72 GPUs connected via NVLink with 900 GB/s uni-directional bandwidth per GPU. This is roughly 7-10x the bandwidth of the InfiniBand/Ethernet based scale-out network.
- InfiniBand/RoCEv2 Ethernet (outside of the NVL72 rack): Typically 400-800 Gbit/s per GPU uni-directional (50-100 GB/s). Note that all our testing for Nvidia was conducted on InfiniBand based clusters.
TP shards every layer’s weight matrices across GPUs. This means that every single token at every single layer requires up to two all-reduce communications (one after the column-parallel GEMM, one after the row-parallel GEMM). For EP, all-to-all is done only at MoE layers. Each GPU sends only the tokens routed to each expert. This means cheaper comms across all layers for EP vs TP.
Because EP’s all-to-all communication bandwidth requirements scale with the number of participants, staying within the high-bandwidth NVLink domain before having to cross the slower IB/Eth fabric is better. With NVL72, EP across 72 GPUs is possible without ever leaving NVLink, whereas previous generations (with only 8-GPU NVLink domains) could only do EP across 8 GPUs at NVLink speed before hitting the slower IB/Eth networks.
Wide EP also has a major advantage in weight loading efficiency. For a model like DeepSeek R1, decode is memory-bandwidth-bound: the bottleneck is how fast GPUs can load weights from HBM. With wide EP (e.g., DEP32), 32 GPUs collectively hold and load the 670B weights once, each loading only its shard (~21B). The total HBM bandwidth of all 32 chips is applied to loading a single copy of the model. By contrast, with narrower EP and more DP replicas (e.g., 5xDEP8), each of the 5 replicas needs its own full copy of the 670B weights, that’s 5×670B = 3.35T of redundant weight loading across the system. EP amortizes weights across chips; DP replicates them. This is why wider EP, enabled by high-bandwidth interconnects like NVLink, delivers significantly better throughput per GPU.
Generally, TP is preferred at lower concurrencies due to load balancing. At small batch sizes, EP suffers from uneven token-to-expert routing, leaving some GPUs underutilized while others are overloaded. TP avoids this since each GPU holds a slice of every expert and always gets an equal share of work. At lower concurrency, the cost of this load imbalance outweighs TP’s additional communication overhead.
At higher concurrencies, this tradeoff changes. Expert activation becomes more evenly distributed across larger batch sizes, and EP’s communication and weight-loading advantages dominate over TP’s expensive per-layer all-reduce. In the middle of the curve, hybrid TP+EP configurations balance both concerns using small TP groups within each expert for load balancing while EP is used across the wider set of GPUs to amortize weights and reduce communication.
For higher interactivity levels (low batch size), large scale-up world sizes tend not to deliver stronger performance. B300 disagg over IB has the same performance as GB300 with NVL72, since the workload is latency-bound, not bandwidth-bound. The massive NVLink bandwidth advantage of NVL72 doesn’t matter because not even the much slower IB link is saturated by the tiny batches of tokens in flight.
Prefill/decode disaggregation also plays a role. Prefill is compute-heavy and bursty; decode is memory-bandwidth-bound and steady-state. When they share the same GPUs, they interfere with each other, causing latency jitter and wasted capacity. Separating them onto dedicated GPU pools lets each run a workload matched to its characteristics, improving effective utilization. This is why disaggregated B200 configs outperform single-node B200 in the middle of the throughput-interactivity curve. PD separation combined with wider EP across more GPUs over IB amortizes weights more efficiently than cramming both phases onto a single 8-GPU node.
[Side Note: the 10x inference engineers at TogetherAI noticed an pattern for multi-turn traffic where the requirements of first turn prefill is much different from the following turns prefill’s and disaggregrated it leading to better TTFT performance.](https://www.together.ai/blog/cache-aware-disaggregated-inference)
## Jensen Under Promising and Overdelivering - Hopper vs Blackwell vs Rack Scale NVL72
At GTC 2024, Jensen was on stage promising up to 30x performance gains from H100 to GB200 NVL72, [everyone thought it was classic marketing lookmaxxing and would not be achievable in real world.](https://newsletter.semianalysis.com/p/nvidia-blackwell-perf-tco-analysis) Many looked to come up with labels for this perceived use of a reality distortion field so they could crack more Jensen Math jokes. Indeed – [we did point to the comparison of 30x performance difference between the worst case](https://newsletter.semianalysis.com/i/175661150/benchmarking-the-h200-on-its-bad-hair-day) for H200 on FP8 to a reasonable case of the GB200 on FP4.
But it turns out the joke is on them. Fast forward almost two years later, and we can now see that it wasn’t marketing hype lookmaxing after all, and Jensen was actually under promising on Blackwell performance the whole time. From our testing, Blackwell is so good at large scale MoE inferencing compared to even a strong H100 disagg+wideEP FP8 baseline that it, at 116 toks/s/user, delivers up to 98x better perf on GB200 NVL72 FP4 and up to 100x better perf on GB300 NVL72 FP4! Maybe the new Jensen Math rule is that he delivers double whatever he promises in terms of token throughput. The more you spend, the more you save indeed!
Even when factoring in the increased total cost of ownership of Blackwell and Blackwell Ultra, we see a 9.7x(40 tok/s/user) up to 65x(116 tok/s/user) improvement in tokens per dollar compared to Hopper. [You can explore Hopper vs Blackwell performance in detail on our free website](https://inferencemax.semianalysis.com/?i_seq=8k%2F1k&g_model=DeepSeek-R1-0528&g_rundate=2026-02-12&g_runid=21928999802&i_prec=fp4%2Cfp8&i_metric=y_costh&i_log=1#inference). Blackwell performance is so good compared to Hopper that we needed to an log scale to our dashboard in order to visualize it.
As mentioned earlier in the article, B300 servers only connect at most 8 GPUs using the 900GByte/s/GPU NVLink scale-up network whereas GB300 NVL72 servers connect 72 GPUs using the NVlink scale-up network. So when we need more than 8 GPUs (but less than 72 GPUs) for the inference setup, we need to bring in multiple nodes of B300 servers to form our inference system which means communications falls back to the lower InfiniBand XDR scale-out network featuring 800Gbit/s (uni-di) per GPU of bandwidth. Compare this to a rack scale GB300 NVL72 which connects 72 GPUs over NVLink delivering 900GByte/s (uni-di) per GPU of bandwidth and we can see that the rack-scale server allows the GPUs in the inference setup to talk to each other with over 9x higher bandwidth compared to the case of the multiple nodes of B300 servers.
Admittedly the GB300 NVL72 has a higher all-in cost per GPU, but this only reduces the bandwidth per TCO advantage to being 8x faster. The bandwidth advantage of the rack-scale architecture directly drives a much lower cost per token. Google TPU, AWS Trainium and Nvidia are the only AI chips to have rack scale system designs deployed today. Engineering samples and low volume production of AMD’s first rack scale MI455X UALoE72 system will be in H2 2026 while due to manufacturing delays, the mass production ramp and first production tokens will only be generated on an MI455X UALoE72 by Q2 2027.
## Blackwell vs Blackwell Ultra
On paper, the newly released Blackwell Ultra has the same memory bandwidth as Blackwell, the same FP8 performance and only 1.5x higher FP4 performance, but when measuring we actually see up to 1.5x better FP8 performance on the Blackwell Ultra, though we only see 1.1x better performance on FP4. This may be due to Blackwell Ultra being a newly released GPU, meaning software is not fully optimized yet.
## MI355X vs MI325X vs MI300X
On AMD SKUs, we see up to 10x better performance on the MI355X vs the MI300X. AMD has only gotten DeepSeek SGLang Disaggregated Inferencing to work on the MI355X so far AMD has not submitted MI300X or MI325X disaggregated inferencing results, potentially due to software issues on older SKUs that are still being solved.
Turning to cost, for DeepSeekR1 on FP8, at an interactivity of 24 tok/s/user, the MI355X delivers inferences a cost that is slightly less than 3x cheaper than for the MI325X. The throughput of each GPU is slightly less than 4 times that of MI325X.
## AMD Composability Issue on FP4, Distributed Inferencing and Wide Expert Parallelism
While AMD performs somewhat decently on single node FP4 and performs competitively to B200 SGLang on FP8 distributed inferencing, the issue with the current AMD open source inferencing stack is that, while individual inference optimizations perform well, real customers deploy with multiple optimizations composed together. Top tier AI labs are all using FP4 **with **disaggregated inferencing **with** wide expert parallelism all enabled at the same time, and this is where the issue occurs.
AMD software is still not meeting the mark, and the theoretical speed of light modelling at SemiAnalysis and at AMD show that for FP4, disaggregated inferencing with wide expert parallelism should perform better than inference on a single node of MI355X. Unfortunately, Software continues to be a massive bottleneck for AMD GPUs. AMD management needs to continue to sharpen resource allocation of their engineering talent, for instance, re-allocate their engineering resources away from pet single node projects that nobody uses like ATOM towards fixing the aforementioned issues with composability of inference optimizations between disaggregated inferencing, wide expert parallelism and FP4. The current subpar software is due to lack of focus and incorrect prioritization of where the industry already is at. All top tier labs are already using disaggregated inferencing and wide expert parallelism; AMD needs to stop focusing on single node and heavily invest focus into multi node inferencing for open source solutions.
AMD is more than six months behind on open source distributed inferencing and wide expert parallelism and FP4 composability as shown by [Nvidia and SGLang team showing off their NVFP4 performance on DeepSeek six months ago](https://lmsys.org/blog/2025-09-25-gb200-part-2/).
## AMD ATOM Engine
AMD has launched a new inference engine called ATOM. Atom can deliver slightly better single node performance, but it is completely lacking on a lot of features that makes it unusable for real workloads. One such example is that it does not support NVMe or CPU KVCache offloading, tool parsing, wide expert parallelism, or disaggregated serving. This has led to zero customers using it in production. Unlike Nvidia’s TRTLLM which generates billions of tokens per hour globally at companies like TogetherAI, etc and [does support tool parsing and other features](https://nvidia.github.io/TensorRT-LLM/commands/trtllm-serve/trtllm-serve.html#cmdoption-trtllm-serve-serve-tool_parser), there are no token factories currently using ATOM due to the lack of the aforementioned features.
Furthermore, maintainers of open-source inference engines like vLLM are disappointed in AMD due to a lack of engineering and GPU resources provided by AMD. For example, Simon Mo, lead vLLM maintainer, states in this GitHub RFC that there is still no working MI355X that he can add to vLLM CI, hence the poor user experience. There are currently zero Mi355X tests on vLLM, while NVIDIA’s B200 has many tests on vLLM. Similarly, there are still not enough MI300X CI machines on vLLM. Upstream vLLM needs at least 20 more MI300 machines, 20 more MI325 machines and 20 more MI355X machines to reach the same level of usability as CUDA.
We at SemiAnalysis have been trying to get AMD to contribute more compute to vLLM and have had some success on that within the couple weeks. vLLM will start to get a couple of MI355X machines such that they can bring their CI test parity from 0% to non-0%. We will talk more about AMD’s previous lackluster contribution towards vLLM, SGLang, PyTorch CI machine situation & how Anush started to fix it in our upcoming State of AMD article. At SemiAnalysis, we will have internal dashboard to track the # of tests & quality of tests that AMD & NVIDIA runs on vLLM, SGLang, PyTorch, & JAX.
Moreover, the vLLM maintainers say that they cannot support day 0 vLLM support for ROCm due to this issue of lack of machine resources. This huge disparity in time to market continues to lead to ROCm lagging behind and leaving a huge opening for Nvidia to continue to charge an insane 75% gross margin (4x markup on cost of goods).
Lastly, AMD has not had enough committers “who demonstrated sustained upstream engagement through feature shepherding and code ownership” and has a lack of reviewers that can review their own code. This is why the pace of development on ROCm vLLM has been much slower than for CUDA vLLM.
There are many talented 10x engineers at AMD that work on ATOM and we would encourage AMD management to think about re-deploying these 10x engineers towards working on libraries and frameworks that people actually use, such as vLLM and SGLang.
As we mentioned earlier, AMD also needs to prioritize addressing composability issues with FP4, wideEP and disaggregated serving as opposed to overly focusing on optimizing FP4 for a single node.
## Multi Token Prediction (MTP)
Speculative decoding reduces the cost of autoregressive generation by using a small, inexpensive draft model to propose several tokens ahead. The large model then checks the proposed tokens in a single forward pass that resembles a prefill computation. For a given input sequence length, a single forward pass can take roughly the same time when the input has N more tokens. Speculative decoding uses this property to run inference on a smaller model to draft multiple tokens for the main model to verify with a single forward pass, producing at most N additional tokens in a similar time budget.
This assumption regarding additional token production with the same time budget is strongest for dense models because batched verification can reuse the same weight stream across multiple positions. For Mixture-of-Experts models, different tokens may route to different experts, so verifying multiple draft tokens can activate more experts than single-token decoding and force additional expert weights to be fetched from memory. As shown in the Mixtral 8x7B Instruct model results in the EAGLE paper, this extra memory traffic erodes bandwidth savings and can make verification notably comparable to a standard decoding step.
Multi-token prediction pursues similar benefits without requiring a separate draft model. Auxiliary prediction heads are added to the model architecture, so a single model can propose several future tokens from the same underlying representation. This improves distribution alignment because the proposals come from the same model that ultimately scores them. Multi-token prediction also avoids the operational complexity of serving an additional model while still enabling multi-token generation strategies but requires the MTP heads to be pretrained alongside the main model.
Across all SKUs, enabling MTP results in performance gains. By making use of the typically unused logits to verify the extra tokens, minimal compute overhead is added, saving extra expensive weight loads during decode.
At large batch sizes, the inference regime is less memory-bandwidth bound compared to for low batch sizes. Since speculative decoding (including MTP) works by trading excess compute for fewer memory-bound decoding steps, this extra verification work from speculative tokens may not fit cleanly into slack, resulting in smaller improvements at high batch sizes.
In terms of cost, MTP can drive huge cost savings, in the below table, we see that DeepSeek-R1-0528 run on FP4 using Dynamo TRT costs $0.251 per million total tokens, but enabling MTP can push costs down dramatically to only $0.057 per million total tokens.
In all configs, when all else is held equal, using MTP with DeepSeek R1 increases interactivity with no significant impact on model accuracy. This is in line with the DeepSeek V3 tech report findings.
Regarding the validity of MTP performance numbers, one may argue that the distribution of a synthetic dataset may not resemble real data. However, comparing MTP acceptance behavior between MTBench and our 1k1k benchmark, we see a very similar distribution confirming that our InferenceX benchmark is a good proxy for real world production performance. That said, InferenceX is not perfect and we are always looking to improve. If you want to be part of the mission, [apply to join our special projects team here](https://app.dover.com/apply/semianalysis/2a9c8da5-6d59-4ac8-8302-3877345dbce1).
## Accuracy Evaluations
Throughput optimizations can sometimes quietly trade off accuracy (e.g. via aggressively relaxed acceptance rates, decoding tweaks, numerically unstable kernels, or endpoint misconfiguration). Without evals, a misconfigured server (truncation, bad decoding, wrong endpoint params) can still produce great throughput numbers but deliver garbage answers. For example, this additional layer of checks has helped us discover issues with some DP attention implementation for GPT-OSS.
Each representative throughput config now has an associated numerical accuracy check. Currently we are only using GSM8k, but being a very easy benchmark, the evaluation scores may not change much from differences in numerical calculation, and a harder benchmark may have a larger delta with respect to numerical accuracy. Thus, we plan to expand towards harder ones in the future, such as GPQA, HLE, MATH-500, SWE-Bench verified.
Another form of performance-accuracy tradeoff is quantization. Serving models at lower precision may result in worse model outputs. For DeepSeek R1, FP8 runs have very slightly higher evaluation scores than FP4. Note that GSM8k evals are saturated and often during QAT/PAT it is calibrated to common popular GSM8k, MATH-500, etc, leading to sometimes evals showing great results while real world end user evaluation being subpar. If we want to be part of the team to figure out how to properly evaluate inference engine accuracy, [apply to join the mission here](https://app.dover.com/apply/semianalysis/2a9c8da5-6d59-4ac8-8302-3877345dbce1).
## Anthropic Fast Mode Inferencing Explained
Anthropic recently released “[fast mode](https://code.claude.com/docs/en/fast-mode)” alongside Opus 4.6. The value proposition: the same model quality at roughly 2.5× the speed, for around 6–12× the price. Both figures might seem surprising, and some users have speculated that [this must require new hardware](https://x.com/Yuchenj_UW/status/2020214926133063705). It doesn’t. In fact, this is just the fundamental tradeoff at play. Any model can be served at a wide range of interactivity levels (tokens/sec per user), and the cost per million tokens (CPMT) shifts accordingly. Mercedes makes metro busses as well as race cars, to follow long with our analogy.
Bean counters may think that fast mode is more expensive, but when looking at it through a total cost of ownership lens, fast mode is actually way cheaper for some situations. For example, a GB200 NVL72 rack can cost 3.3 million dollars, and as such, if claude code agentic loops (which runs on Trainium in production) that tool use call NVL72 racks, and these racks run inference 2.5x slower, you would need 2.5x more racks to deliver inference, meaning that not enabling fast mode would cost close to 5 million dollars in extra spend.
Consider a DeepSeek R1 0528 FP4 coding workflow served on B200s with TRT-LLM. At an interactivity of 50 tok/sec/user, inference cost is approximately $0.56/M output tokens. At an interactivity of 125 tok/sec/user, this rises to around $4/M output tokens, a 2.5× speed increase for a ~7× price increase, closely mirroring what we see with Anthropic’s fast mode. Note that this assumes DeepSeek R1 is similar to Opus 4.6, which isn’t the case. Still, the general principle holds true.
This follows directly from the fundamental latency-throughput tradeoff in LLM inference. At high batch sizes, GPUs achieve better utilization and greater total token throughput, meaning more users served concurrently and lower cost per token. At low batch sizes with greater parallelism per request, each user gets faster responses, but total token throughput drops. Since the [hourly cost of the accelerators](https://semianalysis.com/ai-cloud-tco-model/) is fixed regardless of how they’re used, lower throughput means fewer tokens over which to amortize that cost, and thus a higher price per token.
In short, fast mode isn’t necessarily a hardware story, but merely the natural consequence of trading throughput for latency on the same GPUs.
Furthermore, we observe that inference optimization techniques such as speculative decoding, as explained earlier, can directly lead to cheaper inference; no new chips are required.
Take the following example, DeepSeek R1 FP4 on an 8k/1k workload. At an interactivity level of 150 tok/sec/user, the baseline GB300 Dynamo TRT cost per million tokens is approximately $2.35, whereas enabling MTP decreases the price to approximately $0.11. This is a ~21x price decrease at this interactivity level simply by employing an inference optimization technique.
Fixing an interactivity level of 50 tok/sec/user, we further see how much MTP can effectively decrease CPMT across a variety of chips.
## Wide Expert Parallelism (WideEP) and Disaggregated Prefill
In this section, we will go deeper on expert parallelism and go on to explain what *wide *expert parallelism is. We will then explain the idea of Disaggregated Prefill, how it is different from WideEP, and how WideEP and Disaggregated Prefill are used in unison to achieve SOTA performance.
## WideEP
By now, most frontier AI labs employ Mixture of Experts (MoE) model architectures as opposed to dense. In MoE architectures, only a subset of “experts” are activated for each token. For instance, DeepSeek R1 has 671B total parameters, but only 37B active parameters. Specifically, DeepSeek R1 has 256 routed experts (and 1 shared expert) with each token being routed to 8 distinct experts. This architecture lends itself naturally to expert parallelism (EP), which evenly distributes expert weights across some number of GPUs.
Consider serving DeepSeek R1 on a single 8-GPU server. At 671B parameters, some form of parallelism is required to fit the model across available HBM. The naive approach is tensor parallelism (TP), which shards every weight matrix across all GPUs. This works well for dense models but ignores the sparse activation pattern of MoE. With TP=8, each expert’s weights are sharded across all 8 GPUs, meaning every expert activation requires an all-reduce across all GPUs & the reduction dims of the GEMM is smaller leading to lower arithmetic intensity, even though only 8 of 256 experts activate per token. TP treats each expert like a dense layer, paying full cross-GPU communication cost while the model’s sparsity goes unexploited.
Expert parallelism takes a more well-suited approach, assigning whole experts to individual GPUs. With EP=8, we divide the 256 experts per layer across 8 GPUs for a total of 32 experts/layer/GPU. Each GPU holds approximately 1/8th of the expert weights plus a full replica of the non-expert weights (attention projections, embeddings, normalization, and the shared expert). Since roughly 90%+ of DeepSeek R1’s parameters are routed expert weights, EP captures most of the memory savings, and replicating the remaining less than 30B non-expert parameters across all 8 GPUs is affordable.
The forward pass proceeds in two phases per layer. During attention, each GPU acts as an independent data-parallel rank, processing its own subset of requests using its replicated non-expert weights, no inter-GPU communication is needed. During the MoE phase, a lightweight router determines which experts each token requires, and tokens are dispatched to the appropriate GPUs via all-to-all communication. Each GPU executes its local experts on only the tokens routed to it, and results are returned via a second all-to-all.
The obvious way to scale is replication: deploy N independent EP8 instances across N nodes. Each instance serves requests independently with no cross-node communication. This scales throughput linearly, but each GPU still holds 32 experts per layer, and each token activates at most 8 of those 32 local experts. 75% of expert weights sit cold in HBM.
**Wide expert parallelism** (WideEP) takes a different approach by scaling EP *across *nodes rather than replicating independent instances. On a 64-GPU cluster (8 nodes), DP64/EP64 places only 256/64 = 4 experts per layer per GPU, each still holding a full replica of the non-expert weights. During the MoE phase, tokens from all 64 DP ranks are dispatched via all-to-all to the GPUs hosting their routed experts.
This yields three compounding benefits over the single-node EP8 baseline. First, reducing expert footprint from 32 to 4 experts/GPU frees substantial HBM for KV cache, directly increasing per-GPU batch size capacity. Second, 64 DP ranks funneling tokens through fewer experts per GPU increases tokens-per-expert, raising arithmetic intensity (more FLOPs per byte of weights loaded) and improving compute utilization. The same expert weights service 8x more tokens per step. Third, aggregate HBM bandwidth scales linearly with GPU count; 64 GPUs loading expert weights simultaneously provide 8x the memory bandwidth of a single node, reducing memory bottleneck.
The above configurations use only DP+EP (also known as DEP), where each GPU holds a full replica of all non-expert weights. As GPU count grows, this replication becomes increasingly wasteful. On a 64-GPU DP64/EP64 deployment, every GPU stores an identical copy of the ~40B non-expert parameters.
Adding tensor parallelism within groups of GPUs addresses this. In an EP64/DP8/TP8 configuration, the 64 GPUs are organized into 8 DP groups of 8 GPUs each. Within each TP group, the attention projections, shared expert, normalization, and LM head are sharded 8 ways, so each GPU holds only 1/8th of the non-expert weights. Across the full cluster, the 256 experts are still distributed one-per-4-GPUs as before.
Pure DEP has a single communication pattern: all-to-all for expert routing. Adding TP introduces a second all-reduce within each TP group for the attention and non-expert computations. The key design principle is to place TP groups within a single node, where NVLink or MNNVL provides high-bandwidth interconnect, and run EP/DP across nodes, where the all-to-all communication pattern can tolerate higher latency.
As always, the tradeoff is that of throughput versus latency. TP=8 within a group means those 8 GPUs now share a batch and must synchronize every decode step, reducing effective DP degree from 64 to 8. Per-GPU batching independence on the attention side is lost. But each DP group now processes attention 8x faster per step, since the matmul is split 8 ways across the TP group. Per-token latency drops while peak concurrency also drops, sliding the configuration along the latency-throughput Pareto frontier relative to pure DEP.
## Disaggregated Prefill
Disaggregated prefill, sometimes referred to as prefill-decode (PD) disaggregation, is the process of performing prefill and decode phases of LLM inference on separate nodes. Prefill occurs when a request is first processed, and a forward pass is computed on all tokens at once, thereby “prefilling” the KV cache for this request. This is a compute-intensive operation as all tokens feed through the forward pass in parallel. Tokens are then generated or “decoded” one at a time, loading the KV cache from HBM at each decode step. This is a memory-intensive process as the growing KV cache is constantly being loaded.
In traditional single-node inference, engines interleave prefill and decode on the same GPUs. Incoming prefill requests stall in-flight decode batches, increasing both time-to-first-token and inter-token latency. Chunked prefill mitigates this by breaking long prefills into smaller pieces, but the fundamental resource contention remains. Disaggregated prefill eliminates this entirely!
Disaggregation also enables independent scaling and optimization of each phase. With separate nodes, each phase can be tuned independently: different parallelism strategies, different batch sizes, and different memory allocation ratios. The ratio of prefill to decode nodes can also be matched to the workload’s input-output length ratio. For instance, prefill-dominated workloads (long input, short output e.g., summarization, RAG, agentic coding with large context windows) allocate more prefill instances. Decode-dominated workloads (short input, long output e.g., chain-of-thought reasoning, long-form generation) allocate more decode instances. Workloads with high cache hit rates also tend toward more decode, since reused KV cache entries from shared system prompts or multi-turn conversation history skip prefill entirely.
The key cost of disaggregation is KV cache transfer. After prefill completes, the full KV cache for that request must be transmitted from the prefill node to the decode node before the first decode token can be generated. For a model like DeepSeek R1 with 61 layers and FP8 KV cache, an 8192-token prefill produces roughly 500MB of KV data that must cross the network, adding directly to TTFT. This transfer is performed over RDMA (typically RoCE or InfiniBand) using zero-copy GPU-to-GPU data movement without CPU involvement. Libraries like NIXL (NVIDIA Inference Transfer Library) abstract the data movement layer behind a unified asynchronous API with pluggable backends for UCX, GPUDirect Storage, and other transports. This decouples the inference engine from any specific transfer protocol and enables disaggregation across heterogeneous hardware where prefill and decode instances may span different device types or interconnects.
## Optimizing Inference with Wide EP + Disaggregated Serving
Wide EP and disaggregated prefill are separate techniques that are often used together to achieve Pareto optimal performance. In this section, we walk through real results from InferenceX to build intuition for which combinations of parallelism strategy, wide EP, and disaggregated prefill are appropriate at different interactivity levels.
It helps to first understand what parallelism strategies fall on what parts of the Pareto frontier for single-node configurations. Take the example of DeepSeek R1 FP4 8k/1k on a single 8-GPU B200 node with TRT-LLM. The optimal strategy shifts as you move along the frontier, driven primarily by batch size and its effect on expert activation density.
At the highest interactivity levels (batch 1-16), pure TP outperforms any configuration involving EP. At low batch sizes, only a small fraction of experts activate per step. With EP, these activations are distributed unevenly across GPUs: at batch 4, only 32 of 256 experts fire, and any given GPU has roughly a low double digit percent chance of receiving zero routed tokens in a given layer. TP avoids this by sharding every expert across all GPUs, so all 8 GPUs participate equally in every expert computation regardless of which experts the router selects. We collected expert activation ratio versus batch size data while profiling DeepSeek R1, which confirms that at batch sizes 16 and below, expert activation per layer is very low.
As we move to slightly lower interactivities, batch sizes remain small enough that expert weights are still sharded via TP rather than EP. The crossover occurs around batch 32, where approximately 50-60% of experts activate per layer. At this density, EP’s load imbalance becomes tolerable and its token-routing overhead is cheaper than the per-expert all-reduce required by TP. Configurations in this range use TEP: tensor parallelism for attention (all GPUs collaborate on each attention computation), expert parallelism for MoE layers (experts assigned to specific GPUs with all-to-all routing). In the highest throughput, lowest interactivity region of the frontier, batch sizes are large (128+) and configurations shift to full DEP: attention weights are fully replicated across all GPUs as independent data-parallel ranks, experts are distributed via EP, and batch capacity is maximized at the cost of per-token latency. (128+) and attention weights are fully replicated across all DP ranks, maximizing throughput.
We observe the same general pattern when extending to wide EP with disaggregated prefill. Prefill and decode run with separate parallelism strategies and node counts, both tuned to the workload and target interactivity level. Take an 8k/1k workload (prefill heavy) at the high-throughput, low-interactivity end of the frontier. Prefill is the bottleneck as each request requires a forward pass of 8192 input tokens, which is computationally expensive. Recipes in this region allocate more prefill nodes than decode (4P1D, 7P2D, 4P3D) to sustain high prefill throughput. These prefill nodes run DEP configurations, replicating attention weights across independent data-parallel ranks so that multiple long-context prefills can be processed simultaneously. Decode nodes are fewer but run wide DEP with large batch sizes by the same principle as with single node.
On the low interactivity end of the frontier, there are fewer concurrent requests in flight, so a single prefill instance can keep pace with incoming demand. Yet each request still requires 1024 decode steps, and at high interactivity those steps must be fast. Recipes in this region shift to more decode nodes than prefill (1P3D, 1P4D), with each decode instance running TEP at low batch size. Tensor parallelism on attention minimizes per-step latency by sharding the computation across all GPUs in the instance, while expert parallelism handles MoE routing at the moderate batch sizes where EP load balance is sufficient. Multiple small-batch decode instances, rather than fewer large-batch ones, keep per-token latency low while still providing enough concurrent serving capacity.
## Dive into DeepSeek R1 Single Node Results
On DeepSeek R1 FP8 1k1k, we see that MI355X is competitive with its counterpart B200 on single node scenarios, despite getting mogged on FP4 multi node scenarios. MI355X (SGLang) even beats B200 (SGLang) in throughput performance at lower interactivity levels. Moreover, MI355X (SGLang) beats B200 (TRT and SGLang) in most cases from a perf/TCO perspective.
Unfortunately, the year is 2026, and most frontier labs and inference providers are not running FP8 nor single node inference.
This result goes to show that AMDs chips are great and can be extremely competitive with Nvidia if only they could move faster on the software front. Speed is the moat.
To that end, we see MI355X fall well behind B200 in performance on FP4:
In comparing DeepSeek R1 FP8 perf between H200 (SGLang) and MI325X (SGLang), not much has changed since our initial release of InferenceXv1 last October. The MI325X data was captured on Feb 12th, 2026 with SGLang 0.5.8 whereas the B200 data was captured Jan 23, 2026 with SGLang 0.5.7.
One thing we note is the considerably smaller interactivity range for MI325X than H200, with H200 ranging from 30-90 tok/sec/user whereas MI325X ranges from only 13-35 tok/sec/user. This is problematic for providers who would like to serve users at a broader range of interactivity.
## GPT-OSS 120B Single Node
MI300X, MI325X, H200, and H100 group in the lower-left of the throughput vs interactivity plot, indicating broadly similar tradeoffs, with Nvidia generally holding a modest lead. The next step up is MI355X, which delivers roughly more than 2x higher token throughput per GPU at a given interactivity level, relative to that first group. Within MI355X, ATOM shifts the curve toward higher throughput at low interactivity, suggesting it prioritizes peak throughput over per-user responsiveness.
Above that tier sits NVIDIA’s B200 and GB200, which outperform MI355X across the frontier. While B200 and GB200 share the same Blackwell compute die, GB200 achieves a higher throughput–interactivity curve because the platform and serving stack reduce non-compute bottlenecks at scale (interconnect/topology, CPU-GPU coupling, and runtime scheduling), translating into effective scale-out and less overhead per token.
If we add cost into the equation, MI355x becomes more competitive: beating B200 at high throughputs. However, GB200 still takes the cake for being the cheapest choice.
Turning again to the comparison between B200 and GB200 NVL72, it is obvious the impact NVL72 has. We discussed the impact of the GB200 NVL72’s larger 72 GPU scale-up world size vs the B200’s 8 GPU scale-up world size earlier in this article. The output token throughput per GPU more than doubles in the ~100 tok/s/user interactivity range, showing the impact of the NVL72’s larger scale up domain.
## Core InferenceX Repo Updates
We have made a few core architectural changes to the InferenceX repository to make it easier to understand and reproduce benchmarks. Additionally, we have fully subscribed to AI usage to maximize productivity and increase developer velocity.
## Core Changes Since InferenceXv1
One of the main changes we have made since v1 is the cadence with which we perform sweeps. Previously, we were jestermaxing and performed a full sweep over each configuration nightly. However, as we added more chips, disaggregated prefill, wide EP, and other features, we realized that running every single night was way too time consuming and wasteful. Moreover, it’s just not necessary – benchmarks only really need to be re-run when recipes change or a new software version is released.
We now trigger sweeps based on additions to a [changelog](https://github.com/InferenceMAX/InferenceMAX/blob/main/perf-changelog.yaml)at the root of the repo. When a developer makes a performance-impacting change to a given config, they add an entry to the changelog listing the affected config along with a brief description of the change. All configs are defined in a [master configuration YAML file](https://github.com/InferenceMAX/InferenceMAX/blob/main/.github/configs/nvidia-master.yaml), which serves as the stateful representation of every data point to be swept, including core settings like ISL/OSL, EP, TP, DP, MTP, and so on. When a PR containing a changelog addition is merged, a workflow parses the referenced config keys, pulls the corresponding sweep definitions from the master config, and fans them out as individual GitHub Actions jobs. The jobs collect all data points for the full sweep and upload the results as artifacts.
Below is a high-level diagram of how InferenceX launches jobs.
## Klaud Cold AI Usage
Shortly after the release of InferenceX v1, we realized how much developer throughput was being left on the table by not utilizing AI more in our InferenceX development. So, we rolled our sleeves up and decided to embrace Claude Code and begin absorbing intelligence, one token at a time to the point that we are currently spending at a $6,000/day run rate. If you want to contribute towards our KPI of absorbing an annualized $3 million dollars’ worth of Claude intelligence, [apply here to join the mission.](https://app.dover.com/apply/semianalysis/2a9c8da5-6d59-4ac8-8302-3877345dbce1) We started our enlightenment journey when we realized the GitHub Copilot agent was free – at first we couldn’t believe this feature came at no cost! We soon realized that Copilot is terrible and it became apparent why GitHub was giving it away for free. You probably would have had to *pay us *to keep using it.
We had been using Claude Code locally ever since it was released. But recently, we have integrated Claude Code into InferenceX development, using it for the usual tasks such as reviewing PRs, but we also have given it the ability to perform sweeps on clusters. With the workflows we setup, Claude can manually initiate runs, view the results, and iterate. This has enabled us to deploy quick fixes easily on the go via the GitHub app.
Another cool use case is using Claude to find recipes for new vLLM/SGLang images. When a new image is released, recipes sometimes need to be updated to achieve optimal performance (new environment variables, modified engine arguments, etc.) With our Claude Code integration, we simply open an issue and ask Claude to search through all commits in the image changelog to find necessary changes to be added to the recipe. This works quite well, and although it’s not _perfect_, it often gives a good starting point.
## GitHub Actions
In the spirit of open source, all runs occur on GitHub Actions, so benchmark results are verifiable, transparent, and reproducible. However, GitHub outages have been a constant obstacle to our goals recently. [We have seen more unicorns lately than any other animal](https://github.com/503.html)! But maybe it’s time for us to touch some grass.
Microsoft/GitHub themselves are aware of this and have stopped updating its status page with aggregate uptime numbers and are down to a single 9: 97.36% over the past 90 days. The problem doesn’t seem to go away if you choose to ignore it...
All in all, GitHub Actions is just alright. It provides a painfully average experience for developers. It is certainly not meant for launching thousands of jobs across a fleet of hundreds of GPUs. Nevertheless, we have worked closely with some GitHub Actions engineers since our launch to better meet the needs of InferenceX, and we can confidently say they have been a pleasure to work with. Moreover, one of our direct asks was to implement lazy loading for jobs when clicking on a workflow run and, while it did take them a while, [they eventually implemented the feature.](http://github.blog/changelog/2025-12-22-improved-performance-for-github-actions-workflows-page/)
## Future of InferenceX
Since the initial release of InferenceX in early October 2025, we have worked hard to continuously improve InferenceX. After release, we spent some time refactoring the codebase to make it more scalable, such that new models and inference techniques can now be added in a “plug and play” fashion. These changes enabled us to seamlessly integrate PD-disagg benchmarks for H100, H200, B200, B300, GB200, GB300, and MI355X. We also added accuracy evaluations to our default benchmark pipeline to ensure visibility into model performance across all configurations.
Although we have made many improvements since our release, there is still much work to be done to achieve the north star goal of providing the most real-world inference benchmarks possible. To achieve this goal, we plan to benchmark on real datasets, add an agentic coding performance benchmark, include more SOTA inference optimizations, benchmark more models, and so much more.
## Migration to Multi Turn Real Multi-Turn Chat and Agentic Coding Datasets
Currently, InferenceX uses completely random tokens as input for benchmarking. We then vary the ISL/OSL uniformly subject to the distribution [ISL*0.8, ISL], similarly for OSL. Because of the random data, we disable prefix caching in all our benchmarks, as the expected value of a prefix cache hit rate on completely random data is 0%. Furthermore, all the random data is single-turn, meaning each conversation contains only one prompt and one response. While this provides a good baseline Pareto frontier, it is not a practical benchmark setup that mimics real-world production inference workloads.
In the near term, we will create a basic multi-turn benchmark with a dataset like [allenai/WildChat-4.8M](https://huggingface.co/datasets/allenai/WildChat-4.8M), which captures real users’ multi-turn conversations. In addition to enabling prefix caching on all scenarios, we will enable KV cache CPU offloading, as this is what we see being done in production workloads. This will more accurately evaluate the strengths and weaknesses of each chip. For instance, MI355X has 288GB HBM3e versus B200s 192GB. Therefore, we expect MI355X to perform better in a high concurrency multiturn scenarios as more memory can be allocated to the KV cache. On the other hand, in scenarios where the GPU KV cache is stressed and blocks are offloaded to the CPU, we expect the GBs to excel as these chips have 900GB/s bidirectional CPU-GPU bandwidth, compared to 128GB/s / 256GB/s on HGX with PCIe 5.0 and 6.0, respectively. Moreover, currently we see AMD’s software for CPU offloading is poor, which may negatively affect performance in the same scenarios.
The point is: real-world multiturn datasets test more SOTA inference engine features and can capture more nuanced and robust performance data across all chips.
With the rise of Claude Code, Codex, and Kimi, it is becoming increasingly important to benchmark performance in agentic coding scenarios. Like above, these scenarios are multi-turn but also include extremely long context conversations as well as tool use. In the next few months, we plan on creating a benchmark suite that will most accurately capture the performance of open models in these agentic coding scenarios across all chips.
## Adding TPU, Trainium and More Models
Currently, we continuously benchmark DeepSeek R1 and GPT OSS 120B (previously Llama 3.1 70B as well). To keep up with the newest model architectures, we plan on adding DeepSeek V3.2 (w/ DSA), DeepSeek V4 on Day 0, Kimi K2.5, Qwen3, GLM5, and many more over the course of the next few months. We will also eventually add multi-modal models and be using EPD & CFD (invented by TogetherAI) optimization too.
In addition to new models, we are actively working on adding both TPU and Trainium.
## Total Cost of Ownership (NVL72, Blackwell, Blackwell Ultra, MI355, Hopper, MI325, MI300)
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
---
_This article continues on our Substack. [Subscribe to SemiAnalysis](https://newsletter.semianalysis.com/subscribe) to read the complete article._
{`{
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [
{
"@type": "Question",
"name": "How much faster is NVIDIA Blackwell vs Hopper for inference?",
"acceptedAnswer": {
"@type": "Answer",
"text": "GB300 NVL72 FP4 delivers up to 100x better performance compared to a strong H100 disagg+wideEP FP8 baseline, and up to 65x on FP8 vs FP8. Even factoring in higher total cost of ownership, Blackwell achieves 9.7x to 65x improvement in tokens per dollar compared to Hopper."
}
},
{
"@type": "Question",
"name": "What is disaggregated prefill in LLM inference?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Disaggregated prefill separates the compute-intensive prefill phase and memory-intensive decode phase of LLM inference onto separate pools of GPUs. This eliminates resource contention between phases, enables independent scaling and tuning, and improves both time-to-first-token and inter-token latency compared to running both on the same GPUs."
}
},
{
"@type": "Question",
"name": "What is wide expert parallelism (WideEP)?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Wide expert parallelism scales EP across multiple nodes rather than replicating independent instances. For example, on a 64-GPU cluster running DeepSeek R1, WideEP places only 4 experts per GPU instead of 32, freeing HBM for KV cache, increasing tokens-per-expert for better compute utilization, and providing 8x aggregate memory bandwidth compared to single-node EP8."
}
},
{
"@type": "Question",
"name": "How does the NVIDIA B200 compare to AMD MI355X for inference?",
"acceptedAnswer": {
"@type": "Answer",
"text": "On FP8 disaggregated prefill, MI355X is competitive with B200 using SGLang. However, on FP4 disagg+wideEP workloads used by frontier labs, B200 significantly outperforms MI355X due to AMD's composability issues when combining multiple inference optimizations. AMD's single-node FP8 performance is strong, but multi-node FP4 distributed inference lags behind."
}
},
{
"@type": "Question",
"name": "What is the cost per million tokens for DeepSeek R1 inference?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Using B200 with Dynamo TRT-LLM FP4, DeepSeek R1 inference costs approximately $0.251 per million total tokens. Enabling MTP can push costs down to $0.057 per million total tokens. On GB300 NVL72 FP4 at 150 tok/s/user, enabling MTP reduces cost from $2.35 to approximately $0.11 per million tokens, a 21x reduction."
}
},
{
"@type": "Question",
"name": "What advantage does the GB200 NVL72 rack-scale architecture provide?",
"acceptedAnswer": {
"@type": "Answer",
"text": "The GB200 NVL72 connects 72 GPUs via NVLink at 900 GB/s per GPU, over 9x the bandwidth of InfiniBand scale-out networks used between B200 nodes. This massive bandwidth advantage directly drives lower cost per token for large MoE models like DeepSeek R1 that require wide expert parallelism with all-to-all communication across many GPUs."
}
},
{
"@type": "Question",
"name": "How does Multi-Token Prediction (MTP) improve inference performance?",
"acceptedAnswer": {
"@type": "Answer",
"text": "MTP uses auxiliary prediction heads built into the model to propose multiple future tokens from the same representation, avoiding the need for a separate draft model. Across all GPU SKUs tested, enabling MTP increases throughput with no significant impact on model accuracy, and can reduce cost per million tokens by up to 21x at high interactivity levels."
}
},
{
"@type": "Question",
"name": "How does Blackwell Ultra GB300 compare to Blackwell GB200?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Despite having the same memory bandwidth and FP8 specs on paper, Blackwell Ultra achieves up to 1.5x better FP8 performance than Blackwell in practice. However, FP4 performance is only 1.1x better, likely because software is not yet fully optimized for the newly released Blackwell Ultra GPU."
}
}
]
}`}
---
# InferenceMAX: Open Source Inference Benchmarking
> NVIDIA GB200 NVL72, AMD MI355X, Throughput Token per GPU, Latency Tok/s/user, Perf per Dollar, Cost per Million Tokens, Tokens per Provisioned Megawatt, DeepSeek R1 670B, GPTOSS 120B, Llama3 70B
- **Author**: SemiAnalysis
- **Date**: 2025-10-09
- **URL**: https://inferencex.semianalysis.com/blog/inferencemax-open-source-inference-benchmarking
- **Tags**: benchmark, gpu, inference, announcement
- **Reading time**: 38 min
LLM Inference performance is driven by two pillars, hardware and software. While hardware innovation drives step jumps in performance every year through the release of new GPUs/XPUs and new systems, software evolves every single day, delivering continuous performance gains on top of these step jumps.
AI software like SGLang, vLLM, TensorRT-LLM, CUDA, and ROCm achieve continuous improvement in performance through kernel-level optimizations, distributed inference strategies, and scheduling innovations that increase the Pareto frontier of performance in incremental releases that can be just days apart.
This pace of software advancement creates a challenge: benchmarks conducted at a fixed point in time quickly go stale and do not represent the performance that can be achieved with the latest software packages.
InferenceMAX, [an open-source automated benchmark](https://github.com/InferenceMAX/InferenceMAX) designed to move at the same rapid speed as the software ecosystem itself, is built to address this challenge.
InferenceMAX runs our suite of benchmarks every night on hundreds of chips, continually re-benchmarking the world's most popular open-source inference frameworks and models to track real performance in real-time. As these software stacks improve, InferenceMAX captures that progress in near real-time, providing a live indicator of inference performance progress. A live dashboard is available for free publicly at [https://inferencemax.ai/](https://inferencemax.ai/).
AMD and Nvidia GPUs can both deliver competitive performance for different sets of workloads, with AMD performing best for some types of workloads and Nvidia excelling at others. Indeed, both ecosystems are advancing rapidly!
There are many nuances and considerations when analyzing the results from InferenceMAX, and this is in no small part because it is designed to be a neutral benchmark, not cherry-picked to promote any specific vendor or solution. As such, there are models and interactivity (tok/s/user) levels where AMD currently does better against Nvidia GPUs of the same generation, and there are also interactivity levels where Nvidia currently does better. The goal of InferenceMAX is simple but ambitious -- to provide benchmarks that both emulate real world applications as much as possible and reflect the continuous pace of software innovation.
For the initial InferenceMAX v1 release, we are benchmarking the GB200 NVL72, B200, MI355X, H200, MI325X, H100 and MI300X. Over the next two months, we're expanding InferenceMAX to include Google TPU and AWS Trainium backends, making it the first truly multi-vendor open benchmark across AMD, NVIDIA, and custom accelerators.
InferenceMAX v1 is far from perfect, but we believe that it is a good first step in the right direction. There will be room in future releases to refine workloads, extend model coverage, and better reflect real-world workloads.
## Acknowledgements
Thank you to Lisa Su and Anush Elangovan for providing the MI355X and CDNA3 GPUs for this free and open-source project. We want to recognize Anush, Quentin Colombet, and dozens of additional AMD contributors for their responsiveness and help debugging, optimizing, and validating performance across AMD GPUs. Whenever we encounter ROCm issues (we note these issues are occurring at a far lower frequency than at the end of 2024!), they have immediately jumped in to help find temporary fixes that unblock us, following up with permanent patches into ROCm to ensure long-term stability. Quentin and his team embody the [AMD 2.0 sense of urgency](https://semianalysis.com/2025/04/23/amd-2-0-new-sense-of-urgency-mi450x-chance-to-beat-nvidia-nvidias-new-moat/) that [many customers such as xAI are very appreciative of](https://www.youtube.com/live/5dmFa9iXPWI?si=5HHNsDd7bw3lDASk&t=1073).
We're also grateful to Jensen Huang and Ian Buck for supporting this open-source effort by providing access to a GB200 NVL72 rack (through OCI) and B200 GPUs. Thank you to Kedar Pandurang Potdar, Sridhar Ramaswamy, Kyle Kranen, ptrblck, the NVIDIA inference team, NVIDIA Dynamo team, NCCL team, as well as the Nvidia firmware/driver team for helping validate and optimize Blackwell and Hopper configurations and for fixing bugs with a fast time to resolution.
We also want to recognize the SGLang, vLLM, and TensorRT-LLM maintainers for building a world-class software stack and open sourcing it to the entire world. Furthermore, we want to thank Simon Mo, Kaichao You, Michael Goin, and Robert Shaw whose help was invaluable for resolving a few critical Blackwell bugs.
Finally, we're grateful to Crusoe, CoreWeave, Nebius, TensorWave, Oracle and TogetherAI for supporting open-source innovation through compute resources, enabling this project and we are thankful to the broader community for pushing inference benchmarking forward.
## We are Hiring
We are looking for an engineer to join our special projects team. This is a unique opportunity to work on high-visibility special projects such as InferenceMAX with support from many industry leaders and CEOs. If you're passionate about performance engineering, system reliability, and want to work at the intersection of hardware and software, this is a rare chance to make industry wide impact.
**What you'll work on:**
- Building and running large-scale benchmarks across multiple vendors (AMD, NVIDIA, TPU, Trainium, etc.)
- Designing reproducible CI/CD pipelines to automate benchmarking workflows
- Ensuring reliability and scalability of systems used by industry partners
**What we're looking for:**
- Strong skills in Python
- Background in Site Reliability Engineering (SRE) or systems-level problem solving
- Experience with CI/CD pipelines and modern DevOps practices
- Curiosity about GPUs, TPUs, Trainium, multi-cloud, and performance benchmarking
Link to apply: [https://app.dover.com/apply/SemiAnalysis/2a9c8da5-6d59-4ac8-8302-3877345dbce1](https://app.dover.com/apply/SemiAnalysis/2a9c8da5-6d59-4ac8-8302-3877345dbce1)
## InferenceMAX Initiative Supporters
InferenceMAX initiative is supported by many major buyers of compute and prominent members of the ML community including those from OpenAI, Microsoft, PyTorch Foundation, etc.:
> _"As we build systems at unprecedented scale, it's critical for the ML community to have open, transparent benchmarks that reflect how inference really performs across hardware and software. InferenceMAX's head-to-head benchmarks cut through the noise and provide a living picture of token throughput, performance per dollar, and tokens per Megawatt. This kind of open source effort strengthens the entire ecosystem and helps everyone, from researchers to operators of frontier datacenters, make smarter decisions."_
>
> -- Peter Hoeschele, VP of Infrastructure and Industrial Compute, OpenAI Stargate
> _"Open collaboration is driving the next era of AI innovation. The open-source InferenceMAX benchmark gives the community transparent, nightly results that inspire trust and accelerate progress. It highlights the competitive TCO performance of our AMD Instinct MI300, MI325X, and MI355X GPUs across diverse workloads, underscoring the strength of our platform and our commitment to giving developers real-time visibility into our software progress."_
>
> -- Dr. Lisa Su, Chair and CEO, AMD
> _"Inference demand is growing exponentially, driven by long-context reasoning. NVIDIA Grace Blackwell NVL72 was invented for this new era of thinking AI. NVIDIA is meeting that demand through constant hardware and software innovation to enable what's next in AI. By benchmarking frequently, InferenceMAX gives the industry a transparent view of LLM inference performance on real-world workloads. The results are clear: Grace Blackwell NVL72 with TRT-LLM and Dynamo delivers unmatched performance per dollar and per megawatt -- powering the most productive and cost-effective AI factories in the world."_
>
> -- Jensen Huang, Founder & CEO, NVIDIA
> _"Speed is the moat. InferenceMAX's nightly benchmarks match the speed of improvement of the AMD software stack. It's fantastic to see AMD's MI300, MI325, and MI355 GPUs performing so well across diverse workloads and interactivity levels."_
>
> -- Anush Elangovan, VP GPU Software, AMD
> _"InferenceMAX highlights workloads that the ML community cares about. At NVIDIA, we welcome these comparisons because they underscore the advantage of our full-stack approach -- from GPUs hardware to NVLink networking to NVL72 Rack Scale to Dynamo disaggregated serving that consistently delivers industry-leading inference performance and ROI at scale."_
>
> -- Ian Buck, VP & GM, Hyperscale, NVIDIA & Inventor of CUDA
> _"InferenceMAX's nightly results highlight the rapid pace of progress in the AMD software stack. It's exciting to witness the birth of an open project that provides a tied feedback loop between what the software team works on here at AMD and how it affects specific ML use cases across our MI300, MI325, and MI355 GPUs. I'm looking forward to see what's next for InferenceMAX and to showcase what the AMD platform can do. AMD GPUs will continue to get faster every week."_
>
> -- Quentin Colombet, Senior Director, AMD, Ex-Brium CEO
> _"Our mission at Azure is to give customers the most performant, efficient, and cost-effective cloud for AI. SemiAnalysis InferenceMAX supports that mission by providing transparent, reproducible benchmarks that track inference performance across GPUs and software stacks under realistic workloads. This continuous data on throughput, efficiency, and cost per watt strengthens our ability to tune Azure's inference platform for scale, helping customers build with confidence on Microsoft Cloud."_
>
> -- Scott Guthrie, Executive Vice President, Microsoft Cloud & AI
> _"At Microsoft, delivering the best inference performance and economics for our customers at scale requires a deep understanding of how AI models interact with real-world hardware and software. Open-source, reproducible benchmarks, like InferenceMAX, are essential for generating transparent insights into throughput, efficiency, and cost under realistic workloads. These continuous signals help guide our platform strategy, enabling us to optimize the entire stack from silicon, to systems, to software, so that every layer works together to unlock the full potential of our infrastructure."_
>
> -- Saurabh Dighe, Corporate Vice President, Azure Strategic Planning & Architecture
> _"The gap between theoretical peak and real-world inference throughput is often determined by systems software: inference engine, distributed strategies, and low-level kernels. InferenceMAX is valuable because it benchmarks the latest software showing how optimizations like FP4, MTP, speculative decode, and wide-EP actually play out across various hardware. Open, reproducible results like these help the whole community move faster."_
>
> -- Tri Dao, Chief Scientist of Together AI & Inventor of Flash Attention
> _"The industry needs many public, reproducible benchmarks of inference performance. We're excited to collaborate with InferenceMAX from the vLLM team. More diverse workloads and scenarios that everyone can trust and reference will help the ecosystem move forward. Fair, transparent measurements drive progress across every layer of the stack, from model architectures to inference engines to hardware."_
>
> -- Simon Mo, vLLM Project Co-Lead
> _"The benchmark is good sir"_
>
> -- Michael Goin, vLLM maintainer
> _"InferenceMAX benchmark is pogchamp & W in chat"_
>
> -- Kaichao You, vLLM Project Co-lead
> _"InferenceMAX demonstrates how an open ecosystem can operate in practice. Many leading inference stacks such as vLLM, SGLang, and TensorRT-LLM are built on PyTorch, and benchmarks like this show how innovations across kernels, runtimes, and frameworks translate into measurable performance on a range of hardware platforms, including NVIDIA and AMD GPUs. By being open source and running nightly, InferenceMAX offers a transparent, community-driven approach to tracking progress and providing PyTorch users with data-driven insights."_
>
> -- Matt White, Executive Director, PyTorch Foundation
> _"Oracle Cloud Infrastructure is built to give frontier labs & enterprises flexibility and choice, with many GPU SKUs available for AI at scale. InferenceMAX strengthens that mission by delivering open source, reproducible benchmarks that reflect real-world performance, efficiency, and cost on the latest hardware and software. With this transparency, customers can confidently select the platforms that best align with their AI strategies."_
>
> -- Jay Jackson, Vice President, Oracle Cloud Infrastructure
> _"InferenceMAX raises the bar by delivering open, transparent benchmarks that track how inference really performs across the latest GPUs and software stacks. For customers, having reproducible data that measures real world tokens per dollar & tokens per watt, turns abstract marketing numbers into actionable insight. At CoreWeave, we support this effort because it brings clarity to a fast-moving space and helps the entire ecosystem build with confidence."_
>
> -- Peter Salanki, CTO, CoreWeave
> _"InferenceMAX sets a new standard by providing open, transparent benchmarks that reveal how inference performs across today's leading GPUs and software stacks. With reproducible data measuring real-world tokens per dollar and tokens per watt, customers can move beyond marketing claims to actionable insights. For us at Nebius, as a full-stack AI cloud provider, this initiative helps us build our inference platform with confidence and ensure we are aligned with the ecosystem."_
>
> -- Roman Chernin, co-founder and Chief Business Officer, Nebius
> _"At Crusoe, we believe being a great partner means empowering our customers with choice and clarity. That's why we're proud to support InferenceMAX, which provides the entire AI community with open-source, reproducible benchmarks for the latest hardware. By delivering transparent, real-world data on throughput, efficiency, and cost, InferenceMAX cuts through the hype and helps our customers confidently select the very best platform for their unique workloads."_
>
> -- Chase Lochmiller, Co-Founder & CEO, Crusoe
> _"Supermicro is excited about the launch of InferenceMAX, the SemiAnalysis benchmarking system that measures real-world throughput, performance per dollar, and energy efficiency. This open-source tool provides reproducible benchmarks running on the latest hardware and software enabling AI labs and enterprises to choose the best platforms at scale."_
>
> -- Charles Liang, Founder & CEO, Supermicro
> _"At TensorWave, we're building a next-generation cloud on AMD GPUs because we believe innovation thrives when customers have strong alternatives. InferenceMAX reinforces that vision by providing open source, reproducible benchmarks that track throughput, efficiency, and cost across the latest hardware and software. By cutting through synthetic numbers and highlighting real-world inference performance, it helps customers see the full potential of AMD platforms for AI at scale."_
>
> -- Darrick Horton, CEO, TensorWave
> _"Vultr is committed to providing an open ecosystem that gives developers freedom in how they build and scale AI -- whether on NVIDIA or AMD GPUs. With InferenceMAX, customers gain open, reproducible benchmarks that deliver clear insights into throughput, efficiency, and cost across cutting-edge hardware and software. By showcasing real-world performance, we empower teams to confidently choose the right platform for their AI workloads."_
>
> -- Nathan Goulding, SVP of Engineering, Vultr
## The Fundamental Trade-off between Throughput (tok/s/gpu) & Latency/Interactivity (tok/s/user)
The fundamental trade-off that comes with serving LLMs at scale is that of throughput versus interactivity (measured in units of tokens per second per user). Throughput is the rate at which each GPU can process tokens (tok/s/gpu), whereas interactivity describes the rate at which tokens are generated for each individual user (tokens/sec/user). Put simply, you can serve individual users fast and efficiently, usually by serving fewer users at a time, but doing so will come with the cost of lower overall GPU throughput.
This trade-off exists because LLM inference relies on matrix multiplications that benefit from batching multiple requests together -- that is, serving many more users at the same time. Large batches enable better GPU utilization and higher token throughput, but they split available resources across more requests, slowing down token processing per user. Conversely, small batches concentrate GPU resources on fewer requests -- that is, fewer users, delivering high interactivity at the expense of overall throughput. In practice, most providers aim for a balance between these extremes. The optimal point on this trade-off depends on the use case: some applications prioritize responsiveness while others prioritize throughput. However, the target interactivity level translates directly to cost of inference. Higher interactivity means higher costs.
Owning or renting a GPU system for inference typically comes with a fixed $/hour cost. Thus, as interactivity increases and overall throughput decreases, fewer tokens are processed per hour, driving up the unit cost per token (measured in cost per million tokens). To maintain profitability, providers must set their price per token above their cost to serve. This means that higher interactivity use cases will need higher prices per token to support this higher cost, while high throughput applications can be served at a lower price.
A simple analogy illustrates the entire trade-off. A metro bus and a Ferrari may have a very similar absolute dollar cost of ownership, but the bus amortizes that cost across dozens of passengers while the Ferrari serves only one or two. The Ferrari delivers superior responsiveness with immediate departure, direct routes, and a premium experience, but at a fundamentally higher cost per passenger. LLM serving operates under a similar constraint.
## Pareto Frontier Curve
There is always a trade-off between throughput and latency. To identify the Pareto Frontier Curve, we try to find every data point P such that there is no point that is better than point P in both throughput and latency. This means data point P is **Pareto optimal**, i.e. no other point improves one axis without sacrificing the other. When we connect the pareto optimal dots, we get the Pareto Frontier Curve.
## InferenceMAXv1 Benchmark Methodology
Providing benchmarks that reflect the full spectrum of possibilities across many levels of interactivity for different GPUs, inference engines and workloads is a core goal of InferenceMAX. In this section we will describe how the benchmark methodology is designed to meet this goal.
For each benchmark run, we set up an inference server and a benchmark client. An inference server listens to requests and processes them. We use vLLM, SGLang, and TRT-LLM depending on the model. For benchmark clients, we use the vLLM benchmark serving script with vLLM dependencies removed. A benchmark client sends requests, records the runtime, and saves metrics related to the inference job.
We opted for benchmarking requests that are random sequences to avoid prefix caching due to the complexity of taking prefix caching into consideration for now. Prefix caching varies significantly by workload and requires a careful survey of request patterns in order to pick representative prefix ratios. In future iterations of InferenceMAX, we will be using datasets like shareGPT instead of random data. We set the request rate to infinite and set the max number of concurrent requests, so we capture the inference server behavior when processing a specific number of requests. We also set the total number of requests to be sufficiently large so that cold start instabilities, e.g. JIT compile time, are amortized.
For input / output sequence lengths, we converged on three sets: 1024 input tokens / 1024 output tokens representing chat workloads, 1024 input tokens / 8192 output tokens representing reasoning workloads, 8192 input tokens / 1024 output tokens representing summarization workloads. To mimic real world requests having different input sequence lengths, we randomly vary each request's input length from 80% to 100% of the specified input sequence length.
The config options for a benchmark run are as follows:
- **Model**: LLaMA 70B, DeepSeek R1, gpt-oss 120B
- **Precision**: MXFP4 weights, FP8, FP4
- **GPU**: H100, H200, B200, GB200 NVL72, MI300X, MI325X, MI355X
- **Open source Frameworks**: [vLLM](https://github.com/vllm-project/vllm), [SGLang](https://github.com/sgl-project/sglang), [TRT-LLM](https://github.com/NVIDIA/TensorRT-LLM)
- **Parallelism**: 1, 2, 4, 8, etc.
- **Max concurrency**: 4, 8, 16, 32, 64, etc.
Starting with models, we picked LLaMA3 70B to represent dense enterprise model deployments.
To benchmark sparse MoE models, we decided on DeepSeekV3 670B. In terms of arithmetic intensity, approximate active, total parameter count, and memory access patterns, DeepSeekV3's model architecture is the model that best matches frontier closed models such as OpenAI's 4o/5 model architecture. Thus, DeepSeek is the best proxy model for benchmarking to what OpenAI's internal model architecture likely is.
For smaller, sparse MoE models, we decided on GPT-OSS 120B MoE because it is the closest to GPT-5 mini in terms of arithmetic intensity, approximate active, total parameter count, and memory access patterns.
We are benchmarking FP8, FP4 and MX4 weights across the models depending on whether the hardware supports it. We sweep through different max concurrency users (a concept similar to batch size) to plot the full throughput and latency curve. We also sweep through different model parallelism schemes because larger model parallelism can reduce memory loading time, which in turn increases throughput at a low latency regime to a certain extent to find the pareto frontier curve.
To prevent a [restart of the SGLang vs vLLM benchmark wars](https://x.com/dylan522p/status/1920638653677596836) and to save compute time, we decided to first pick only one of vLLM or SGLang as the default engine for each model. Back in July, we let AMD & Nvidia know that we would be using SGLang for DeepSeek 670B, vLLM for Llama3 70B as well as vLLM for Llama4. We have since replaced Llama4 with GPT-OSS 120B since nobody uses Llama4 and GPT-OSS 120B more closely matches a smaller "mini" frontier model.
We want server configs to reflect real world deployments as much as possible, thus we have asked AMD and Nvidia to submit configs that are decently close to what their documentation guides reference when they discuss how to deploy these models on their hardware:
- [https://docs.nvidia.com/llm-inference-quick-start-recipes/index.html](https://docs.nvidia.com/llm-inference-quick-start-recipes/index.html)
- [recipes.vllm.ai](https://docs.vllm.ai/projects/recipes/en/latest/)
- [https://rocm.docs.amd.com/en/docs-7.0-docker/benchmark-docker/inference-vllm-gpt-oss-120b.html](https://rocm.docs.amd.com/en/docs-7.0-docker/benchmark-docker/inference-vllm-gpt-oss-120b.html)
We hadn't clearly specified whether warmup was allowed for InferenceMAX, so Nvidia has included a warmup phase in their SGLang DeepSeek submission to handle certain JIT-compiled kernels. Towards the end of our work in developing the benchmarks, AMD noticed the above fact regarding Nvidia's submission and asked if warmup was permitted, since they hadn't realized they could do the same. After some discussion between AMD, Nvidia, and the SemiAnalysis AI Engineering team, all parties agreed that warmup would be disallowed for now, and that the DeepSeek benchmark length would instead be extended by up to 5x to ensure fairness. The confusion experienced was our fault for not being explicit from the start about warmup rules. We plan to revisit the topic after launch given that in real-world production inference, warmup often occurs before the Kubernetes control plane reports a pod as healthy.
## Discussion: Strategies for Serving DeepSeek R1
We allow providers to optionally submit disaggregated serving configs for DeepSeek R1. Disaggregated serving assigns the two stages of inference, prefill and decode, to different GPU resources. By separating the two stages, requests at different stages won't interfere with each other, enabling better SLA guarantees, especially at high concurrency scenarios.
We additionally combined disaggregated serving with large scale expert parallelism (wide EP). Wide EP is enabled by multiple techniques, most notably DeepEP. DeepEP provides two dispatch modes: normal and low latency. Normal mode specializes in improving throughput of the prefill stage, while low-latency mode is tailored for lowering the latency of decode stage.
For disaggregated serving DeepSeek R1, we also received submissions with multi-token prediction (MTP) enabled. DeepSeek R1 implements MTP, where the model is trained to predict multiple tokens every forward pass with the help of additional MTP modules. According to DeepSeek, training with MTP improves the model's planning abilities. In addition, using MTP modules during inference boosts token throughput with minimal model quality loss.
Nvidia has submitted runs for DeepSeek R1 on GB200 NVL72 with disaggregated serving, wide EP, and MTP. Nvidia has also submitted specific configs to plot out the Pareto frontier, and we plan to expand to sweep a larger config space in the future.
When serving DeepSeek R1, SGLang offers multiple parallelism strategies, including **tensor parallel (TP)**, **data parallel (DP)**, and **expert parallel (EP)**. Parallelism strategies split up work between GPUs to lower the memory usage per GPU and improve hardware utilization.
Typically, we use tensor parallel to split up work in the attention layer along the number of heads dimension, which is typically 128. However, this doesn't fit well with DeepSeek R1 because it uses Multi-Latent Attention (MLA), a special type of attention where there is only one KV head, leading to KV cache duplication. To tackle this issue, SGLang uses data parallel attention for lower interactivity and splits work along the batch dimension, removing the need to duplicate KV cache and reducing communication load.
DeepSeek R1 also has a lot of expert layers, so we apply expert parallel and assign each GPU a set of expert layers. This lowers the memory usage at the cost of higher communication load.
## Architecture of InferenceMAX
InferenceMAX uses GitHub Actions to orchestrate benchmark runs. A GitHub Action runs each benchmark config as a [job](https://docs.github.com/en/actions/get-started/understand-github-actions#jobs) and executes it on a [runner](https://docs.github.com/en/actions/get-started/understand-github-actions#runners). We hook GPU servers into GitHub Actions as runners, so they listen to requests and execute jobs. When executing a job, a runner will execute a runner launch script written for that server, which in turn uses Docker or SLURM, depending on the server setup. The launch script will then execute the benchmark script, which contains the concrete benchmark config.
We define the logic of parallelism strategies + max concurrency benchmark sweep as a parameterized [workflow](https://docs.github.com/en/actions/get-started/understand-github-actions#workflows), and we incrementally compose the workflow to execute all GPU types for all models and GPUs, as well as different input / output sequence lengths.
## Performance Results -- Throughput vs E2E Latency/Interactivity (tok/s/user)
Below is the performance snapshot for the nightly run on October 7th, 2025 at the time of writing this article. For the full set of nightly results, visit our dashboards on [http://inferencemax.ai/](http://inferencemax.ai/).
When interpreting throughput vs latency/interactivity graphs, keep in mind that most practical applications operate somewhere between the extremes. Benchmark results measuring only one or a limited level of throughput or interactivity can sometimes be misleading.
For instance, if GPU A delivers 4x the throughput of GPU B at a given interactivity level -- take 5 tokens/s/user as an example for a human facing AI chatbot application, the fact that this interactivity level is far too slow to be practical means that this performance difference has little real-world significance. Instead -- a realistic interactivity level should be chosen for the given applications.
Later in this report, we will be also be normalizing throughput of GPUs by the total cost of ownership (TCO) of those GPUs.
TCO per million tokens is the true north star that customers care about -- performance is merely a stepping stone to calculating this metric. For example, a B200 could deliver 1.5x higher throughput than an MI355X, but if it has 2x the TCO per hour -- the MI355X would be the better choice as it delivers better performance per TCO even if the MI355X delivers lower absolute performance in terms of throughput per GPU.
Let's step through a few benchmark examples to explain how to analyze the results.
In our first result, the H100 vLLM vs MI300X ROCm 7.0 vLLM comparison for Llama 3.3 70B FP8 in our reasoning scenario (1k in/ 8k out) shows a strong MI300X performance especially at low interactivity levels (20 to 30 tok/s/user) due to the MI300X's better memory bandwidth and memory capacity advantages when running at TP1.
We are seeing competitive results comparing the H200 and the MI325X on vLLM GPT-OSS 120B with MX4 weights for a summarizing workload. The MI325X has an advantage over H200 for interactivity below 110 tok/s/user and still is somewhat competitive with Nvidia for levels above 110 tok/s/user.
When it comes to LLaMA 70B FP4, B200 significantly outperforms MI355X across all three workload types in terms of throughput performance. This shows that AMD's FP4 kernels have room for improvement.
Moving on to the B200 (vLLM and TRT-LLM) vs. MI355X vLLM for GPT-OSS 120B, we can see that MI355X is competitive with B200 vLLM after normalizing by TCO. In the next section, we will see that MI355X across some interactivity ranges is better perf per TCO than Nvidia. The throughput-latency graph appears to show a tighter race, with the MI355x never more than ~15 seconds slower than the B200 for a given tok/s/gpu throughput. The most practical range of interactivity we see in the real world is approximately 150-200 tok/s/user for GPT-OSS 120B.
Moving to DeepSeek 670B MoE FP8, when comparing the MI325X on SGLang vs. the H200 on SGLang, we observe that the MI355X lags significantly in both latency and interactivity for a given level of throughput. The H200 on SGLang serves inference consistently at approximately 40% lower latency than the of MI325X for comparable throughputs. Furthermore, we also see a steady gap when comparing the Pareto frontier of their interactivities. Comparing the MI355X on SGLang and the B200 on SGLang tells a similar story to our MI325X vs H200 comparison. There appears to be lots of room for improvement for AMD when it comes to SGLang images.
We can also see that for GB200 NVL72 SGLang Dynamo FP8 rack scale inferencing, it is not yet optimized and there is still room for improvement.
Moving on FP4 DeepSeek 670B MoE, we see that GB200 NVL72 rack scale TRT-LLM inference beats single node SGLang inference by a wide margin. We look forward to benchmarking wideEP + disagg prefill on multi-node 8-way machines over the next couple of months.
Next, we compare GB200 with Multi-Token Prediction (MTP) On and Off for DeepSeek R1 in an 8K input / 1K output scenario -- an input/output ratio that is meant to reflect summarization use case. The MTP On benefit is particularly noticeable comparing throughput vs. interactivity. Between the range of 70-140 tok/s/user, we see significantly higher throughput/GPU for the MTP On scenario when compared to the MTP Off -- up to 2-3x the throughput for some iso-interactivity (tok/s/user).
## Performance Results -- TCO Per Million Tokens Versus Interactivity (tok/s/user)
However, comparing token throughput per GPU is just one of a few data points needed to get to the real bottom line, namely total cost of ownership (TCO) per token.
ML inference engineers typically measure this in units of TCO per million tokens. To get from throughput per GPU to TCO per million tokens, we must normalize by the total cost of ownership in units of USD/hr/GPU when comparing chips to chips. For example, if a B200 delivered 1.5x higher throughput than the MI355X but had 2x the TCO per hour -- the MI355X would be the better choice, even if it delivers lower absolute performance.
At our InferenceMAX portal, located at [http://inferencemax.ai/](http://inferencemax.ai/), we have estimated the TCO per million vs. latency/interactivity for various customers segments such as:
- Hyperscalers and Tier 1 Frontier Labs Buying & Owning Chips (4-year Economic Useful Life)
- Neocloud Giants and Giant Managed Inference providers that plan to own their own chips (4-year Economic Useful Life)
- Renting GPUs from Neoclouds with 3 Year contract, with 25% upfront payment
Modeling Total Cost of Ownership per Token is no mean feat and it involves multiple SemiAnalysis teams and practice areas. In the AI Token Factory Economics stack, we show all the assumptions that are used to derive this north star metric, as well as the SemiAnalysis Models used to determine these quantities.
In particular, the [SemiAnalysis AI TCO Model](https://semianalysis.com/ai-cloud-tco-model/) provides comprehensive modeling of total cost of ownership for combinations of various AI server solutions and networking architectures (i.e. InfiniBand vs SpectrumX vs Arista Ethernet vs WhiteBox Ethernet) and is the main source for the total cost of ownership per GPU as well as Neocloud rental market prices used in InferenceMAX.
The SemiAnalysis GPU Cloud Market Rental Price Report is built on surveys with over 70+ GPU Clouds and over 100+ end users that rent from GPU clouds. In the future, we will explore implementing dashboards on the InferenceMAX.ai portal for different rental pricing contracts lengths like 1 year or 1 month. We also plan on allowing custom inputs such that you can input your own $/GPU/hr quotes to determine the GPU that best matches your interactivity targets and costs.
In our analysis below, we focus on cost per million tokens for Hyperscaler tier operators that are owning chips and underwrite their business case to a 4-year economic lifespan.
We see that across all interactivity levels, the cost per million tokens on MI325X on vLLM beats the cost per million tokens on the H200 using vLLM. When we bring in Nvidia's (mostly) open source TRT-LLM, we see that the H200 current software stack wins against the MI325X using today's vLLM stack.
When we compare the B200 on vLLM vs the MI355 on ROCm 7.0 vLLM when running Llama3 70B FP4 on reasoning input/output length scenarios, the B200 currently outperforms the MI355. This also illustrates our suggestion that AMD focuses more on optimizing FP4 for Llama3.
For GPT-OSS 120B FP4 summarization tasks, we see that the MI355X on vLLM has a lower TCO per million tokens than the B200 on vLLM and can even beat B200 on TRT-LLM when interactivity is below 225 tok/s/user. For interactivity levels greater than 225 tok/s/user, we see that the B200 on TRT-LLM as well as other inference engines are more optimized and deliver lower TCO per performance than the MI355X on vLLM.
On GPT-OSS 120B with MX4 weights, we see very strong performance per TCO from the MI300X compared to the H100 across the entirely interactivity range.
For gpt-oss 120B using MX4 weights, the H200 on TRT-LLM is neck and neck with the MI325X in terms of perf per TCO for interactivity levels less than 135 tok/s/user. Above this level, the MI325X vLLM takes the lead in terms of TCO per million tokens compared to H200 TRT-LLM.
What is surprising about this result is that true open source vLLM for Hopper is faster than "mostly" open source TRT-LLM hopper. Even the MI325X on vLLM beats the H200 on TRT-LLM for interactivity levels greater than 135 tok/s/user.
Moving on to DeepSeek 670B MoE using FP8, we see that when we hold TCO per million tokens constant, the B200 on SGLang delivers 1.5x faster interactivity as compared to the MI355X on SGLang. We note that there is still lots of optimizations currently in ROCm AITER that ROCm is integrating into SGLang, and so we expect that SGLang DeepSeek 670B MoE performance per TCO will improve soon.
When holding interactivity constant at ~35 tok/s/user, the GB200 NVL72 beats everything else, delivering 4x better TCO per million tokens. We note that the Dynamo team has so far only had time to implement optimizations sufficient to lower the parallelism cost pareto frontier at the 30 tok/s/user region. There is still room for them to further optimize to push down the cost pareto frontier for interactivity levels of around 40 and above for the GB200 NVL72 using FP8.
Moving on to DeepSeek R1 using FP4 for a summarization use case, we see that below 90 tok/s/user interactivity, the GB200 NVL72 on the TRT-LLM engine using Dynamo disagg prefill decisively outperforms all single node 8-GPU severs on TCO per million tokens. Interestingly, for interactivity levels above 90 tok/s/user, the B200 on TRT-LLM beats the GB200 NVL72. However, as it stands now, a single node B200 server can drive better TCO per performance than the GB200 NVL72 for high interactivity use cases.
In the benchmark below focused on a reasoning use case, we see that the B200 on SGLang currently outperforms the MI355X on SGlang.
For the summarization scenario, the GB200 using today's TRT-LLM Dynamo software outperforms a B200 single node for interactivity levels under 80 tok/s/user. Comparing the MI355X on SGLang to the B200 on SGLang, we see that the B200 delivers better TCO per million tokens.
We also benchmarked workloads running on FP4 using Multi-Token Prediction (MTP), which is a feature implemented by the DeepSeek team during training. We see that when holding TCO per million tokens constant, MTP can deliver 2-3x greater interactivity (tok/s/user) than without MTP for that given cost level. Indeed, most frontier labs and tier 1 managed DeepSeek REST API endpoint providers have already enabled MTP for production workloads.
## Estimated Token Throughput per All In Provisioned Utility Megawatt vs Interactivity (tok/s/user)
Power is the ultimate constraint for AI infrastructure. Every datacenter operates within a finite power envelope, usually measured in Megawatts (MW). This directly determines how much useful computation, and ultimately, how many tokens can be produced by a given datacenter.
Inference economics can also be analyzed not only through a lens of GPU performance in terms of throughput/GPU vs TCO, but also in terms of throughput per power as measured in terms of tokens/s per all-in provisioned MW of total utility power. Total utility power encompasses power requirement for GPUs, CPUs, networking equipment, other related cluster IT equipment as well as facility overhead. Facility overhead includes items such as electrical distribution losses and power expended on cooling equipment such as chillers, CDUs and cooling towers, among others. The greater the number of tokens processed per MW, the greater the potential revenue and profit per unit of energy. Please note that for InferenceMAX, we use all-in provisioned utility MW, which accounts for the aforementioned facility overhead, as opposed to tokens per all-in Critical IT MW, which does not account for facility overhead. These differ across sites, but we chose a representative for the industry based on our [AI TCO model](https://semianalysis.com/ai-cloud-tco-model/) and [Datacenter model](https://semianalysis.com/datacenter-industry-model/).
Do note that colocation rent and electricity cost typically make up less than 20% of the total cost of ownership. This means that if a given GPU delivers 20% lower tokens per MW compared to another GPU, this would only translate to a delta of less than 4% of the total cost of ownership (i.e. 20% \* 20% = 4%). The lion's share of the TCO contribution is from the gross margins each GPU hardware vendor charges. Some charge up 75% gross margins (i.e. a 4x markup over cost of goods sold), while others less than 50% gross margins (i.e. less than 2x cost of goods sold).
We use rate units -- i.e. token/s per MW as opposed to an accumulated amount of energy per token such as Joules per Token. This is because datacenter capacity is commissioned in terms of Megawatts (MW), which is a rate unit and is equivalent to 1 megajoule (MJ) per second. If we integrate the rate unit over a given time period -- we get the absolute quantity of energy consumed over that period.
For now, we build up our estimate for MW needed for a given cluster by adding up Thermal Design Power (TDP) of each component in the datacenter. TDP is not the same as expected average power. Using an example to explain, for memory bandwidth bounded decode workloads, power consumption of the system should never reach TDP and will instead hover at a lower power level -- the expected average power. In the future, we will benchmark the actual power consumption of each system (and networking equipment) through ipmitool. Only then will we pivot to an accumulated quantity of energy per token.
We estimate throughput per provisioned power based on the raw InferenceMAX results combined with data on total utility power for AI clusters from our [AI Datacenter Industry Model](https://semianalysis.com/datacenter-industry-model/). This model quantifies total utility power through power-normalized estimates across vendors, architectures, and inference stacks. Full estimates and ongoing nightly benchmarks are available at [InferenceMAX.ai](https://inferencemax.semianalysis.com/).
## Performance per MW Results
We see that for gpt-oss 120B, using MX4 weights for reasoning scenarios (1K input tokens / 8K output tokens) at the 90 tok/s/user interactivity level, the MI300X is able to process 750,000 token/s per all in provisioned MW (again this is measured per utility MW, and not per MW of Critical IT Power) while the MI355X is able to process 2,550,000 token/s per all in provisioned MW. This represents a ~3x improvement in power efficiency from the CDNA3 generation to the CDNA4 generation.
We see a similar trend when comparing across generations for the Nvidia camp. Looking at the HGX H100 vs the HGX B200 for gpt-oss 120B using FP4 weights, an H100 can process 900,000 token/s per MW while a B200 can process 2.8M token/s per MW ~3x better power efficiency on a B200 vs an H100. When we look at even higher interactivity levels of around 180 tok/s/user, the B200 delivers an eye-popping 7x power efficiency gain.
Let's compare power efficiency for GPUs of the same generation across AMD and Nvidia. We will first look at tokens/s per provisioned all in utility MW for GPTOSS 120B. Based on our initial InferenceMAX result snapshot below, we see that Blackwell is 20% more energy efficient compared to the CDNA4 architecture when measured by this throughput per power metric. A large factor in this divergence is the fact that the MI355X has a much higher TDP for the GPU alone at 1.4kW/GPU vs 1kW/GPU for the B200.
In our next benchmark, we look at tokens per power at an interactivity level of 30 tok/s/user for DeepSeek R1. When comparing a single node H200 FP8 vs a GB200 NVL72 FP4 (without Multi Token Prediction), the GB200 NVL72 delivers an ~8x improvement in token/s processed per all-in provisioned MW. Note that both the H200 and B200 results are for single nodes. We will explore the potential for greater token throughput per MW for the B200 and H200 that can be unlocked by implementing disaggregated prefill and wide expert parallelism over SpectrumX as well as InfiniBand. SGLang's [GB200 NVL72 analysis](https://lmsys.org/blog/2025-09-25-gb200-part-2/) shows that 8-GPU systems can indeed achieve strong performance gains through implementing wide expert parallelism. However, the SGLang blog also shows that GB200 NVL72 still beats Hopper even when both implement disaggregated prefill and wide EP.
Staying on DeepSeek, but turning to FP8, we see that the GB200 also dominates all the single-node systems on tok/s/gpu vs tok/s/user. We note that there are some nuances here -- the B200 and the MI355X are both running single node SGLang even though for DeepSeek, vLLM could deliver better results than SGLang on MI355X. We will explore adding DeepSeek on vLLM for the MI355X and/or adding SGLang multi-node wideEP to all of the 8-GPU servers as well. Furthermore, as we called out earlier, note that the Dynamo team has only had time to implement optimizations sufficient to achieve a shift lower in the parallelism pareto frontier up to around 30 tok/s/user. Further optimization can be done to push the pareto frontier lower, and thus lift the throughput per power up on GB200 NVL72 FP8 for higher interactivity levels.
## AMD Bugs and NVIDIA Blackwell Bugs
There were a few Blackwell bugs that were quite interesting to troubleshoot. The first bug was that the Blackwell vLLM image we started using back in July 2025 would lead to the instance stalling for up to 30 minutes on our bare metal B200 machines. This was especially challenging to replicate and debug as other people tried using the exact same image on their Blackwell cluster without encountering any hanging issues.
The first tool we turned to in order to debug this hanging issue was [py-spy](https://github.com/benfred/py-spy), a python profiler, to collect a trace. We noticed is that it was stuck on [ncclCommInitRank](https://github.com/NVIDIA/nccl/blob/8d26308e6aba7f1667b24a861b5dc73f0f2e1f40/src/init.cc#L1974) which is strange - as many ML performance engineers know, this function should be run very quickly on a single node. Another to note was that vLLM was using their [own custom FFI bindings](https://github.com/vllm-project/vllm/blob/3d1f67616da88cbf0033bf5027cc0c6e5e9cacf6/vllm/distributed/device_communicators/pynccl_wrapper.py#L144) to NCCL due to [various technical reasons](https://github.com/vllm-project/vllm/blob/3d1f67616da88cbf0033bf5027cc0c6e5e9cacf6/vllm/distributed/device_communicators/pynccl_wrapper.py#L4-L23).
Reading through vLLM's NCCL bindings, we weren't convinced that the FFI binding was the root cause of issue. Running nvidia-smi, we saw that the GPU_UTIL was not at 100% but instead at 0% - indicating that no kernels were running on the GPU, leading us to conclude this was not a device side NCCL deadlock.
Next, we used linux [perf](https://perfwiki.github.io/main/) top profiler to look beneath the python layer and try to gain more insight into what specific shared library could be triggering this issue. We noted that most of the CPU cycles for this process (and sub processes) were running on "libnvidia-ptxjitcompiler.so". Reading the docs on "libnvidia-ptxjitcompiler", we came across a description that reads: _"The PTX JIT Compiler library (/usr/lib/libnvidia-ptxjitcompiler.so.575.57.08) is a JIT compiler which compiles PTX into GPU machine code and is used by the CUDA driver"._ This is extremely strange as we are not sure why this is calling the PTX compiler on init given that there are no just in time kernels to compile because typically all the NCCL kernels are prebuilt at build time.
We were too ~~lazy~~ busy to rebuild the whole container image to compile NCCL from scratch with debug symbols enabled. Thus, we next used [strace](https://man7.org/linux/man-pages/man1/strace.1.html) to figure out what syscall calls ptxjitcompiler was making in order to dive one layer deeper into which functions are being called. We see that ptxjitcompiler was creating and adding files to ~/.nv/ComputeCache/ inside the container.
Peeling back yet another layer of the onion, we read up on what ~/.nv/ComputeCache/ does. According to documentation, it is the cache to convert PTX virtual ISA to SASS machine code. This was also very puzzling to us as typically NCCL is built with the machine code already bundled in addition to the PTX virtual ISA. We started reading the [NCCL build scripts and we noticed that SM100 (Blackwell) wasn't enabled for CUDA 12](https://github.com/NVIDIA/nccl/commit/80f6bda4378b99d99e82b4d76a633791cc45fef0#diff-45a9034a0c75cbfbbb34e853a43f6513c1d4c933eccf6adca705abe234fc1113R42-R49) which was what we were using and found out that they had only enabled it for the upcoming CUDA 13. This means that SM100 SASS was not bundled in and we were JIT converting compute_90 (hopper) PTX to SM100 SASS resulting in the process taking an extremely long time. The reason why other people didn't see this bug when he ran it was that he was using an internal cluster using slurm with a setting that manually mounted his home directory. Since the SASS JIT cache is stored in the home directory, ~/.nv/ComputeCache/, the SASS was already cached!
It turns out that the vLLM July container image was based on the pytorch container image which used a version of NCCL that didn't have Blackwell SM100 prebuilt. The fix is to use a [post fix version of 2.26.2](https://pypi.org/project/nvidia-nccl-cu12/2.26.2.post1/) that has Blackwell bundled such that we don't waste 30 minutes compiling virtual ISA to machine code. This bug has since been fixed in the latest vLLM container images. Thank you to simon-mo, youkaichao, mgoin, Robert-shaw, ptrblck, and Kedar Potdar for helping implement the permanent fix and immediate action on the quick resolution.
Another Blackwell issue we ran into is that a sub-dependency of vLLM/SGLang, Flashinfer, was running into file lock race conditions. For whatever reason, Nvidia decided that instead of bundling compiled kernels into the container image, they were going to download them at server launch time. Since we have up to 8 processes per node (1 process per GPU), if the code was not process safe, we would run into race conditions while downloading these compiled kernels.
It turns out that this race condition was introduced due to [an attempt to prevent race conditions from happening](https://github.com/flashinfer-ai/flashinfer/pull/1779)! Instead of relying on the builtin FileLock python package's lock cleanup, flashinfer manually cleans it up which results in a race condition. [This has been patched in Flashinfer](https://github.com/flashinfer-ai/flashinfer/pull/1779) but has not yet been upstreamed to vLLM/SGLang Blackwell release container images yet. Huge thanks to the Flashinfer team and Kedar Potar for jumping in and helping debug and patch this in record time - all within 4 hours of getting connected with the team.
There is another Blackwell bug with respective to Flashinfer changing an build environment flag name to FLASHINFER_CUDA_ARCH_LIST but the Nvidians did not inform the vLLM/SGLang maintainers or contribute their own PR thus for a couple weeks, [vLLM](https://github.com/vllm-project/vllm/pull/25730) and [SGLang did](https://github.com/sgl-project/sglang/pull/11226) not support AOT for flashinfer.
We were seeing that every so often, our Nvidia container toolkit would completely error out and display this message:
> _"docker: Error response from daemon: failed to create task for container: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: error during container init: error running prestart hook #0: exit status 1, stdout: , stderr: Auto-detected mode as 'legacy'_
>
> _nvidia-container-cli: initialization error: driver rpc error: timed out: unknown"_
Trying to use the nvidia-smi in CLI would trigger a stall as well. This indicates that the entire Nvidia driver has actually crashed. After a detailed debug session with the Nvidia firmware/driver team and the Nvidia NCCL team, we found out that there is a slow resource leak bug around since NCCL 2.26 given that we are using CUDA graphs and launching over 500 Blackwell containers per night.
Because we are stopping and starting so many Blackwell containers, all of these starts and stops accumulate until they eventually crash the driver. The specific cause of the resource leak bug stems from that fact that when CUDA graph is enabled, NCCL will by default enable user buffers. If it wasn't for the resource leakage bug, the NCCL user buffer feature would have reduced the data movement between the application level buffer and the internal NCCL buffer by having NCCL use the application buffer enabling zero-copy. [The temporary fix is to not enable NCCL user buffer](https://docs.nvidia.com/deeplearning/nccl/user-guide/docs/env.html#nccl-graph-register) in the interim period until the bug fix can be rolled out. The ETA for the fix is around Oct 20th, and it is expected to ship as part of a minor update to NCCL 2.28. Thank you to Kedar Potar and the numerous Nvidia team members for promptly identifying the root cause and fixing the bug with incredible speed and support.
On the AMD front, we ran into fewer bugs while developing InferenceMAX, and these bugs were easier to fix. One such bug was that that AMD's CUDNN equivalent, AITER, was crashing in a helper function due to it not accounting for the fact that "/opt/rocm/llvm/bin/amdgpu-arch" not only returns the compute architecture (i.e. gfx942) but also would return gfx942 whilst including a suffix. AITER is meant to pattern match to figure out which architecture it is working with, but it did not account for a suffix being present. It was easy enough to [craft a temporary fix](https://github.com/InferenceMAX/InferenceMAX/blob/3b8879031799cac260ef00bd8911dabbe5982d49/benchmarks/70b_fp8_mi325x_slurm.sh#L39), but there will be a permanent fix coming into AITER in the next couple of weeks. Thank you to Quentin for helping patch this one!
We also encountered a bug when benchmarking MI355X, where the benchmark runs crashed and dumps 1TB of files named gpucore.XXX. After investigation, we found out the root cause was chunked prefill size in the server configs was set too high. Lowering it from 196608 to 32768 fixed the issue ([PR link](https://github.com/InferenceMAX/InferenceMAX/pull/80/files)).
AMD [recently added pyxis support](https://instinct.docs.amd.com/projects/container-toolkit/en/release-1.1.x/container-runtime/enroot-pyxis-installation.html), which has resulted in a good UX for using containers in SLURM, especially when it comes to multi-node training or multi-node offline batch inference jobs. However, we ran into one bug related to their ROCm 7.0 SGLang image _"rocm/7.0:rocm7.0_ubuntu_22.04_sgl-dev-v0.5.2-rocm7.0-mi30x-20250915"_ which caused a hard crash when trying to run this image through pyxis SLURM. The root cause of this stems from how permissions are handled with the some of the layers that make up that docker image causing permission conflicts between layers. The AMD team is looking into how to permanently fix it and prevent such errors from happening again.
Back in July, When we tried to enable AITER on SGLang for AMD GPUs, the process took 10x longer than normal (~30 minutes in total) given a slow process to finish compilation for DeepSeek V3 ([GitHub issue here](https://github.com/sgl-project/sglang/issues/7826)). This issue was eventually resolved in future releases and is currently fixed.
## GitHub Action CI/CD Bugs
GitHub Actions' [self-hosted runner](https://docs.github.com/en/actions/how-tos/manage-runners/self-hosted-runners/add-runners) support provides a straightforward solution for the benchmarks we wanted to run with InferenceMAX. The integration was quick to set up and allowed for running reproducible workflows on various GPU clusters without building custom infrastructure. However, as InferenceMAX began to scale up to include more jobs, some limitations of GitHub Actions were uncovered.
Each benchmark variation runs as an individual job. For each model, we benchmark different combinations of the following: different GPUs, input/output sequence lengths, precision, tensor parallelism, and concurrency. This creates a [combinatorial explosion](https://en.wikipedia.org/wiki/Combinatorial_explosion) in the number of jobs per workflow as more configurations are added.
To illustrate: InferenceMAX currently benchmarks 3 models across up to 7 GPU types, 3 distinct ISL/OSL pairs, 2 precision settings, and roughly 4 concurrency and tensor parallelism options. Not every model uses all possible configurations, but this worst-case estimate gives us 3 \* 7 \* 3 \* 2 \* 4 \* 4 = 2016 distinct jobs. At this scale, the GitHub Actions workflow visualization hits a limitation: the server times out after ten seconds when attempting to render the DAG, resulting in an [error message](https://github.com/503.html). This makes it extremely difficult to debug the run. Our workaround for this involved splitting up the single nightly workflow into three, splitting by ISL/OSL pairs. This reduced jobs per workflow from approximately 1500 to 500, which the server appears to handle reliably.
Another bug involved a hard limit when using the [download-artifacts@v5](https://github.com/actions/download-artifact) action. At the end of each full sweep workflow, a job runs that collects and aggregates the performance results from all jobs, which are stored as artifacts of the workflow. As part of the collection process, the download-artifacts@v5 action is called. This initializes an [artifact client](https://github.com/actions/toolkit/blob/main/packages/artifact/src/internal/client.ts), which in turn invokes a [list artifacts function](https://github.com/actions/toolkit/blob/main/packages/artifact/src/internal/find/list-artifacts.ts) (needed to list all artifacts and then pattern match to find the requested one) that enforces a hard limit of 1000 for "performance reasons." There allegedly should have been a warning printed when the client tries to list more than 1000 artifacts, but we never observed this behavior.
We would like to thank Scott Guthrie for connecting us with the right people at GitHub, and thank those team members for helping us implement temporary workarounds for these bugs. We look forward to continued use of GitHub Actions to create one of the largest GPU CI/CD fleets in the open-source world.
## Recommendations to Nvidia and AMD
Even though a great number of users and GPUs are running on SGLang and vLLM, Nvidia has been allocating most of their inference engineers towards working on TensorRT-LLM and have relatively few engineering resources dedicated towards supporting SGLang and vLLM. We recommend that Jensen allocate more inference engineering resources toward supporting and contributing to popular inference engines like vLLM and SGLang. This will allow Nvidia to better fulfill their mission of accelerating workloads no matter which inference engines users select.
Furthermore, the ML community would benefit from a surge of additional time and resources from Nvidia for QA'ing their Blackwell software to minimize the number of bugs that end users encounter as they ramp applications on these new platforms. When developing InferenceMAX, we ran into many bugs that are only encountered in Blackwell and are not present on Hopper or other platforms.
On the AMD front, we have suggested that they reduce the number of ROCm specific flags that need to be manually enabled to achieve reasonable performance. AMD has recognized this and has already commenced work on ensuring that optimized configs are set by default. In fact, many changes that act to reduce number of flags needed have already merged into master.
We recommended the same for Nvidia's Blackwell platform and also suggest that Nvidia work on reducing the number of flags needed to get reasonable performance by moving towards [enabling performance optimizations](https://github.com/vllm-project/vllm/issues/25689) [by default](https://github.com/vllm-project/vllm/pull/25924).
## InferenceMAX Next Steps
Over the next couple months, we're expanding InferenceMAX's hardware coverage by integrating Google TPU and Amazon Trainium and we plan on going live within the next two months. This will enable unified, apples-to-apples comparisons across AMD, NVIDIA, Google, and AWS accelerators. This marks an important step toward making InferenceMAX a fully cross-vendor open benchmarking platform for the entire industry.
Furthermore, another initiative we're also introducing is doing nightly evals including MATH-500 and GPQA-Diamond on FP4 models, allowing the community to measure throughput vs. quality trade-offs in a consistent, transparent way. This will help highlight how low-precision inference affects accuracy across diverse model families and deployment scenarios. In addition, we will be tracking output token throughput too to create more extensive insights.
On the NVIDIA & AMD systems front, several exciting initiatives are underway. We're working on DeepSeek's disaggregated prefill + multi node expert parallelism configurations on MI300- and MI355-series GPUs & B200 GPUs too, testing how these advanced parallelism optimization scales across inference workloads. At the same time, we are exciting to test both HGX B300 Blackwell Ultra & GB300 NVL72 Blackwell Ultra to see what is the performance gains over GB200 NVL72.
InferenceMAX is not perfect but it is our strong belief that we are heading in the right direction of having an benchmark that matches the pace of AI software progress & will continue to integrate feedback from ai chip vendors, frontier labs & major consumers of accelerators.
Next, we will deep dive into breaking down the the different components that make up the TCO of the GPUs we are currently used in InferenceMAXv1, such as, H100, H200, B200, GB200 NVL72, MI300X, MI325X, MI355X.
## Hyperscaler Total Cost Of Ownership - Hopper, Blackwell, GB200 NVL72, MI300X, MI325X, MI355X
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
---
_This article continues on our Substack. [Subscribe to SemiAnalysis](https://newsletter.semianalysis.com/subscribe) to read the complete article._
{`{
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [
{
"@type": "Question",
"name": "What is InferenceMAX?",
"acceptedAnswer": {
"@type": "Answer",
"text": "InferenceMAX is an open-source automated benchmark designed to track ML inference performance in real-time. It runs a suite of benchmarks every night on hundreds of chips, continually re-benchmarking the world's most popular open-source inference frameworks and models. A live dashboard is available for free at inferencemax.ai."
}
},
{
"@type": "Question",
"name": "What GPUs does InferenceMAX benchmark?",
"acceptedAnswer": {
"@type": "Answer",
"text": "InferenceMAX v1 benchmarks the NVIDIA GB200 NVL72, B200, H200, and H100, as well as the AMD MI355X, MI325X, and MI300X. The project is expanding to include Google TPU and AWS Trainium backends, making it the first truly multi-vendor open benchmark."
}
},
{
"@type": "Question",
"name": "How often are InferenceMAX benchmarks run?",
"acceptedAnswer": {
"@type": "Answer",
"text": "InferenceMAX runs its full suite of benchmarks every night using GitHub Actions to orchestrate benchmark runs across GPU clusters. This nightly cadence ensures the results keep pace with the rapid speed of software improvements in inference engines like vLLM, SGLang, and TensorRT-LLM."
}
},
{
"@type": "Question",
"name": "How do AMD and NVIDIA GPUs compare in InferenceMAX benchmarks?",
"acceptedAnswer": {
"@type": "Answer",
"text": "AMD and NVIDIA GPUs both deliver competitive performance for different workloads. For example, the MI300X shows strong performance against the H100 at low interactivity levels due to better memory bandwidth, and the MI355X can beat the B200 on TCO per million tokens for certain GPT-OSS 120B workloads. However, NVIDIA's B200 significantly outperforms the MI355X on Llama 70B FP4 across all workload types."
}
},
{
"@type": "Question",
"name": "Who supports the InferenceMAX initiative?",
"acceptedAnswer": {
"@type": "Answer",
"text": "InferenceMAX is supported by major industry leaders including Lisa Su (AMD), Jensen Huang (NVIDIA), Scott Guthrie (Microsoft), and Peter Hoeschele (OpenAI Stargate). Compute resources are provided by Crusoe, CoreWeave, Nebius, TensorWave, Oracle, and Together AI. The PyTorch Foundation, vLLM, and SGLang maintainers also endorse the project."
}
},
{
"@type": "Question",
"name": "What models does InferenceMAX benchmark?",
"acceptedAnswer": {
"@type": "Answer",
"text": "InferenceMAX v1 benchmarks LLaMA 3 70B to represent dense enterprise model deployments, DeepSeek V3 670B as a proxy for frontier sparse MoE model architectures like OpenAI's, and GPT-OSS 120B MoE as a smaller sparse model closest to GPT-5 mini. Benchmarks run across FP8, FP4, and MX4 precisions depending on hardware support."
}
}
]
}`}
---