FuTransformer: FP8 prefill and INT4 decode for Llama-style inference on Hopper
Abstract
Transformer prefill reuses weights across tokens and is dominated by matrix multiplication and activation data movement; single-token decode has limited reuse and is dominated by weight and KV-cache reads. We present FUTRANSFORMER, a CUDA implementation of a Llama-style Transformer block for NVIDIA Hopper GPUs. It applies CODA's GEMM-plus-epilogue approach to inference, adding direct KV-cache placement, folding the fixed RMSNorm gain into weights, writing FP8 output directly with delayed scaling, and supporting prefill without padding. Decode uses INT4 projection weights and an INT4 KV-cache copy. Weights and keys follow Tensor Core fragment layouts for direct dequantization into MMA operands without full intermediate tiles. A block-diagonal Hadamard transform reduces cache quantization error from outlier channels. On one H100, prefill is up to 1.48x faster than compiled PyTorch FP8 and reaches 1.29 PFLOP/s. For gate/up projection with SwiGLU at the 8B shape, our BF16 path is 1.13x faster than CODA. Our FP8 path is 2.02-2.18x faster than the evaluated BF16 CODA path. Across 8B and 70B shapes at batches 1-32, INT4 decode is 1.3-2.4x faster than the faster of PyTorch's BF16 and INT4 blocks at each point: 2.1-3.3x faster than compiled, CUDA-graphed BF16 and 1.3-6.3x faster than the same block using PyTorch's INT4 projection kernel, which targets a single query row and loses to BF16 at batch 32. It is also 31-51% faster than our FP8 path. Complete Llama-3.1-8B decode takes 2.8 ms per step at batch one, versus 8.1 ms for the compiled transformers implementation. Decoding every WikiText-2 token through the INT4 weight path raises perplexity from 6.24 to 7.23 with round-to-nearest weights or 6.99 with GPTQ in the same format; the rotated INT4 cache adds 0.20. The kernels match a quantized reference computation within 0.001 perplexity.
Figures & tables
| Shape | Projection weights | |||||
|---|---|---|---|---|---|---|
| 1B | 2048 | 8192 | 32 | 8 | 64 | 60.82 M |
| 8B | 4096 | 14336 | 32 | 8 | 128 | 218.10 M |
| 70B | 8192 | 28672 | 64 | 8 | 128 | 855.64 M |
| 405B | 16384 | 53248 | 128 | 8 | 128 | 3187.67 M |
| Latency ( s) | Our speedup | ||||
| Shape | Compiled PyTorch | CODA | FuTransformer (ours) | vs. PyTorch | vs. CODA |
| A. Precision matched: all implementations use BF16 | |||||
| 8B | 726 | 690 | 613 | 1.18 | 1.13 |
| 405B | 10089 | 9750 | 9442 | 1.07 | 1.03 |
| B. Cross precision: baselines use BF16; FuTransformer uses E4M3 | |||||
| 8B | 726 | 690 | 316 | 2.30 | 2.18 |
| PyTorch, BF16 cache | FuTransformer INT4 weights | speedup vs. | |||||
|---|---|---|---|---|---|---|---|
| Shape, batch, context | eager | compiled | INT4 block | BF16 cache | INT4 cache | compiled | INT4 block |
| 8B, , 1024 | 1015 | 172 | 106 | 77.8 | 78.0 | 2.2 | 1.4 |
| 8B, , 1024 | 1019 | 214 | 203 | 76.5 | 74.1 | 2.9 | 2.7 |
| 8B, , 4096 | 1118 | 382 | 717 | 265.5 | 180.9 | 2.1 | 4.0 |
| 70B, , 1024 | 1399 | 591 | 270 | 205.3 | 206.1 | 2.9 | 1.3 |
| 70B, , 1024 | 1405 | 643 | 618 | 196.6 | 197.4 | 3.3 | 3.1 |
| PyTorch | |||
|---|---|---|---|
| compiled | INT4 block | FuTransformer INT4 | |
| 1 | 170 | 106 | 77.0 |
| 8 | 215 | 202 | 74.6 |
| 16 | 229 | 318 | 98.5 |
| 32 | 251 | 585 | 118.8 |
| BF16 cache | E4M3 cache | INT4 cache | |||||||
|---|---|---|---|---|---|---|---|---|---|
| Shape, batch, context | BF16 | FP8 | INT4 | BF16 | FP8 | INT4 | BF16 | FP8 | INT4 |
| 8B, , 1024 | 165.2 | 122.1 | 77.0 | 167.2 | 124.4 | 78.0 | 166.9 | 122.4 | 77.0 |
| 8B, , 1024 | 174.8 | 128.4 | 76.4 | 176.1 | 128.6 | 78.3 | 174.0 | 126.2 | 75.4 |
| 8B, , 4096 | 364.6 | 324.4 | 266.2 | 306.0 | 269.9 | 205.5 | 275.3 | 236.8 | 179.8 |
| 70B, , 1024 | 588.7 | 334.4 | 205.0 | 590.6 | 335.6 | 206.2 | 603.3 | 334.4 | 206.8 |
| 70B, , 1024 | 606.6 | 399.9 | 196.1 | 607.0 | 398.8 | 199.8 | 600.8 | 398.2 | 195.2 |
| Decode, ms per step | Decode, tokens/s | Prefill 2048 | ||||||
|---|---|---|---|---|---|---|---|---|
| Implementation | , 1024 | , 1024 | , 4096 | ms | tokens/s | |||
| PyTorch eager, BF16 | 22.77 | 22.30 | 103.74 | 44 | 359 | 309 | 67.9 | 30 147 |
| PyTorch compiled, BF16 | 8.08 | 11.08 | 59.35 | 124 | 722 | 539 | 52.1 | 39 318 |
| FuTransformer BF16 / BF16 | 5.51 | 5.77 | 11.71 | 182 | 1 386 | 2 732 | 46.4 | 44 153 |
| FuTransformer FP8 / BF16 | 4.19 | 4.33 | 10.56 | 239 | 1 849 | 3 030 | 26.6 | 77 010 |
| FuTransformer INT4 / BF16 | 2.70 | 2.66 | 8.76 | 371 | 3 004 | 3 654 | 46.5 | 44 067 |
| 8B | 70B | |||
|---|---|---|---|---|
| Variant | , 4096 | |||
| FuTransformer as described | 77.3 | 74.8 | 178.3 | 208.1 |
| K in natural order, shared-memory transpose | 77.9 | 76.5 | 207.0 | 207.5 |
| and nibbles unpacked arithmetically | 78.1 | 78.2 | 223.0 | 208.8 |
| Cache row quantized by a separate kernel | 79.4 | 76.7 | 179.4 | 209.5 |
| Weight nibbles converted by a bias MMA | 84.2 | 89.8 | 179.8 | 231.4 |
| Normal input | Outlier mixture | |||
|---|---|---|---|---|
| Configuration | 1B | 8B | 1B | 8B |
| PyTorch BF16 | 4.13 | 4.12 | 4.20 | 4.18 |
| FuTransformer BF16 | 3.46 | 3.43 | 3.54 | 3.49 |
| PyTorch FP8, row-wise scale | 39.6 | 39.5 | 39.1 | 39.1 |
| FuTransformer FP8, delayed tensor scale | 40.3 | 40.3 | 39.8 | 39.8 |
| Configuration | 8B | 1B |
|---|---|---|
| E4M3 cache | 0.9 | 0.7 |
| INT4 cache | 3.2 | 2.2 |
| INT4 cache, channel outliers, no rotation | 22.2 | 29.9 |
| INT4 cache, channel outliers, Hadamard rotation | 7.4 | 12.9 |
| E4M3 weights | 3.4–3.5 | 3.4–3.6 |
| INT4 weights, group size 128 | 9.8–10.2 | 9.9–10.5 |
| Decode-block weights | Perplexity | vs. BF16 |
|---|---|---|
| PyTorch BF16 (reference) | 6.240 | |
| FuTransformer BF16 kernels | 6.240 | +0.000 |
| FuTransformer INT4, round-to-nearest | 7.226 | +0.986 |
| FuTransformer INT4, round-to-nearest, clipped scales | 7.393 | +1.153 |
| FuTransformer INT4, GPTQ | 6.986 | +0.746 |
| INT4 cache mirror | |||
|---|---|---|---|
| Decode-block weights | BF16 cache | rotated | unrotated |
| BF16 | 6.240 | 6.387 | 6.777 |
| INT4, round-to-nearest | 7.226 | 7.458 | 8.161 |
| INT4, GPTQ | 6.986 | 7.182 | 7.762 |
| Independent | Cascaded | BF16 | |||
|---|---|---|---|---|---|
| Layer | RTN | GPTQ | RTN | GPTQ | kernels |
| 0 | 13.0 | 6.1 | 15.6 | 7.6 | 0.28 |
| 1 | 12.6 | 7.2 | 20.9 | 13.1 | 0.39 |
| 2 | – | – | 30.7 | 21.4 | – |
| 4 | – | – | 36.5 | 28.4 | – |
| 8 | – | – | 40.1 | 29.3 | – |
| Prefill / decode weights | BF16 cache | INT4 cache |
|---|---|---|
| BF16 / BF16 | 5.595 | 5.728 |
| BF16 / E4M3 | 5.616 | – |
| BF16 / INT4 round-to-nearest | 6.158 | – |
| BF16 / INT4 GPTQ | 5.986 | 6.120 |
| E4M3 / BF16 | 5.599 | 5.731 |
| E4M3 / E4M3 | 5.621 | 5.745 |
| Configuration | HellaSwag | ARC-Challenge |
|---|---|---|
| BF16 | 0.793 | 0.552 |
| INT4 GPTQ weights, BF16 cache | 0.772 | 0.503 |
| and the rotated INT4 cache | 0.768 | 0.476 |
| Length distribution | Actual tokens | Padding ratio | Speedup |
|---|---|---|---|
| All equal | 16384 | 1.00 | 1.00 |
| 14097 | 1.16 | 1.15 | |
| 10448 | 1.57 | 1.57 | |
| Lognormal, median | 8527 | 1.92 | 1.85 |
| One at , seven at | 2944 | 5.57 | 5.07 |
Efficient Transformer Inference
Efficient Transformer Inference studies methods and systems that reduce the latency, memory, and energy needed to run Transformer models.
See all 119 papers