|
Download benchmarks/RESULTS.md from flashrt/fp8-gemm: direct link, hf CLI and curl.
- Browser
- Download file 7.64 kB
-
https://huggingface.co/flashrt/fp8-gemm/resolve/main/benchmarks/RESULTS.md
- Command line
-
hf download hf://flashrt/fp8-gemm/benchmarks/RESULTS.md
-
curl -L -o RESULTS.md https://huggingface.co/flashrt/fp8-gemm/resolve/main/benchmarks/RESULTS.md
7.64 kB
| # Benchmark Results: fp8-gemm | |
| Validated locally on June 20, 2026. | |
| Environment: | |
| - GPU: NVIDIA GeForce RTX 5090 | |
| - PyTorch: 2.9.1+cu128 | |
| - CUDA runtime reported by PyTorch: 12.8 | |
| - Build target: `sm_120a` | |
| - Backend: source extension | |
| - Benchmark command: | |
| ```bash | |
| python fp8-gemm/benchmarks/benchmark.py \ | |
| --backend source --mode headline --warmup 20 --iterations 100 --compile-ref | |
| ``` | |
| Correctness gate: | |
| ```bash | |
| python fp8-gemm/tests/test_fp8_gemm.py --backend source --mode full | |
| ``` | |
| Result: 8/8 rows passed. Metrics recorded: max absolute error, mean absolute | |
| error, p99 absolute error, cosine similarity, dtype, and tolerance. Public v1 | |
| SM120 scope is `M=1` decode and `2 <= M <= 64` small-M rows. SM110 uses a | |
| separate full-row CUTLASS dispatcher described below. | |
| ## Headline Rows | |
| | Shape | Tile | FlashRT us | Torch eager us | Torch compile us | Speedup vs eager | Speedup vs compile | Max abs | P99 abs | Cosine | | |
| | --- | --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | | |
| | `M=1,K=4096,N=2048` | `gemv_fp8_m1_w4` | 6.188 | 32.799 | 41.714 | 5.30x | 6.74x | 0.000 | 0.000 | 1.000000 | | |
| | `M=1,K=4096,N=8192` | `gemv_fp8_m1_w8` | 10.290 | 162.342 | 156.012 | 15.78x | 15.16x | 0.000 | 0.000 | 1.000000 | | |
| | `M=16,K=4096,N=4096` | `ld_fp8_gemm_16x128x256_w4` | 14.391 | 106.215 | 96.204 | 7.38x | 6.68x | 0.000 | 0.000 | 1.000000 | | |
| | `M=32,K=4096,N=8192` | `ld_fp8_gemm_32x128x256_w4` | 22.581 | 200.997 | 189.331 | 8.90x | 8.38x | 0.000 | 0.000 | 1.000000 | | |
| | `M=64,K=512,N=1024` | `ld_fp8_gemm_64x128x256_w4` | 8.259 | 18.085 | 50.002 | 2.19x | 6.05x | 0.000 | 0.000 | 1.000000 | | |
| ## M=1 Variant Sweep | |
| The dispatcher defaults to `variant=0`. Explicit variants are retained for | |
| benchmarking and tuning; public callers should use `variant=0` unless they have | |
| measured their exact shape. | |
| | Shape | Variant | Tile | FlashRT us | Speedup vs eager | Status | | |
| | --- | ---: | --- | ---: | ---: | --- | | |
| | `M=1,K=4096,N=2048` | 0 | `gemv_fp8_m1_w4` | 6.188 | 5.30x | pass | | |
| | `M=1,K=4096,N=2048` | 4 | `gemv_fp8_m1_w4` | 6.186 | 5.30x | pass | | |
| | `M=1,K=4096,N=2048` | 8 | `gemv_fp8_m1_w8` | 6.184 | 5.30x | pass | | |
| | `M=1,K=4096,N=2048` | 16 | `gemv_fp8_m1_w16` | 6.188 | 5.30x | pass | | |
| | `M=1,K=4096,N=8192` | 0 | `gemv_fp8_m1_w8` | 10.290 | 15.78x | pass | | |
| | `M=1,K=4096,N=8192` | 4 | `gemv_fp8_m1_w4` | 10.274 | 15.81x | pass | | |
| | `M=1,K=4096,N=8192` | 8 | `gemv_fp8_m1_w8` | 10.272 | 15.82x | pass | | |
| | `M=1,K=4096,N=8192` | 16 | `gemv_fp8_m1_w16` | 10.278 | 15.80x | pass | | |
| ## Block-128 Scaled GEMM | |
| Measured on RTX 5090 against an independent binding of the original FlashRT | |
| pointer API. The wrapper and native columns execute the same production | |
| CUTLASS kernel from separate extension modules. PyTorch eager and compile | |
| dequantize the block-scaled tensors to FP32, run the GEMM, and cast to BF16. | |
| CUTLASS is already the native implementation, so there is no additional | |
| contract-equivalent library row. | |
| | Workload `(M,K,N)` | Native us | Wrapper us | Wrapper/native | Eager us | Compile us | Max abs | P99 abs | Cosine | | |
| | --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | | |
| | decode `(1,1024,1024)` | 10.287 | 10.276 | 0.999 | 36.256 | 42.242 | 0.000000 | 0.000000 | 1.0000001 | | |
| | action `(51,1536,1536)` | 14.364 | 14.360 | 1.000 | 55.595 | 51.500 | 0.000061 | 0.000000 | 1.0000001 | | |
| | GROOT `(277,2048,2048)` | 28.698 | 28.692 | 1.000 | 104.895 | 73.989 | 0.000122 | 0.000000 | 1.0000001 | | |
| | vision `(1024,1152,1152)` | 18.456 | 18.466 | 1.001 | 101.103 | 79.565 | 0.000122 | 0.000000 | 1.0000000 | | |
| | video `(2520,3072,3072)` | 114.188 | 114.696 | 1.004 | 1032.687 | 930.219 | 0.000244 | 0.000000 | 1.0000000 | | |
| | Qwen MLP `(128,4096,12288)` | 51.258 | 51.253 | 1.000 | 892.744 | 390.698 | 0.000244 | 0.000000 | 1.0000000 | | |
| All wrapper outputs were bitwise equal to the original native entry. The | |
| PyTorch-reference metrics above use production-scale ranges; the wider full | |
| correctness sweep remains the release gate. | |
| ## Release Status | |
| - Source correctness: passed. | |
| - Source benchmark/tile sweep: passed for v1 public scope. | |
| - Existing SM120 installed artifacts: published. | |
| - SM110 local installed artifact: correctness, compile, graph, and parity | |
| passed. | |
| - SM110 Hub artifact: pending clean-commit rebuild and upload. | |
| ## NVIDIA Thor SM110 Results | |
| Validated August 2, 2026 on NVIDIA Thor with PyTorch 2.11.0+cu130, CUDA 13.0, | |
| CUTLASS 4.5.2, and a locally installed | |
| `torch211-cxx11-cu130-aarch64-linux` artifact. Timings are CUDA Graph replay | |
| latencies. `Native` is the independently loaded original FlashRT pointer API; | |
| the ratio is installed artifact / native, so values above 1 are slower. | |
| | Workload `(M,K,N)` | Auto tile | Artifact us | Native us | Artifact/native | Correctness | | |
| | --- | --- | ---: | ---: | ---: | --- | | |
| | decode `(1,4096,2048)` | T1 | 17.232 | 17.344 | 0.997 | pass | | |
| | decode-wide `(1,4096,8192)` | T1 | 50.144 | 50.112 | 1.001 | pass | | |
| | small-M `(16,4096,4096)` | T1 | 23.952 | 24.304 | 0.997 | pass | | |
| | small-M `(32,4096,8192)` | T1 | 46.256 | 46.000 | 1.013 | pass | | |
| | small-M `(64,512,1024)` | T1 | 11.296 | 11.264 | 0.997 | pass | | |
| | PI0.5 QKV `(51,2048,2560)` | T1 | 14.080 | 14.048 | 1.009 | pass | | |
| | PI0.5 O `(51,2048,2048)` | T1 | 13.440 | 13.504 | 0.993 | pass | | |
| | PI0.5 gate/up `(51,2048,16384)` | Wide | 92.496 | 81.312 | 1.128 | pass | | |
| | PI0.5 down `(51,8192,2048)` | T1 | 23.392 | 23.392 | 1.003 | pass | | |
| | GROOT DiT QKV `(51,1536,4608)` | T1 | 15.232 | 15.104 | 1.004 | pass | | |
| | GROOT N1.7 O `(277,2048,2048)` | Wide | 18.704 | 18.704 | 1.002 | pass | | |
| | GROOT N1.7 gate/up `(277,2048,16384)` | Wide | 186.432 | 189.360 | 0.985 | pass | | |
| | GROOT N1.7 down `(277,8192,2048)` | Sq | 50.080 | 49.984 | 1.003 | pass | | |
| | GROOT vision O `(1024,1024,1024)` | Sq | 15.360 | 15.424 | 0.997 | pass | | |
| | Cosmos Edge action `(64,2048,9216)` | T1 | 25.264 | 25.312 | 0.999 | pass | | |
| | LingBot vision O `(1024,1280,1280)` | Wide | 17.152 | 17.216 | 0.997 | pass | | |
| | LingBot action gate/up `(105,2048,16384)` | Wide | 140.080 | 139.984 | 1.002 | pass | | |
| Each graph ratio is the median of paired, per-launch package/native samples; | |
| candidate order rotates every round to control Thor DVFS bias. Sixteen rows are | |
| within about 1.3% of the original FlashRT pointer extension. PI0.5 gate/up is a | |
| reproducible CUTLASS dependency-version outlier: the Hub-buildable package uses | |
| CUTLASS 4.5.2 while the original native extension uses 4.4.2, and the paired | |
| ratio in the final clean artifact run is 1.128. CUTLASS 4.0 was also tested but | |
| failed at runtime on SM110, so it is not a valid packaging fallback. This row | |
| is retained explicitly and is not used for a native-parity claim. | |
| The installed artifact selected the fastest validated tactic on every row; | |
| worst auto/fastest-valid-tile was 1.0028. Source-to-artifact packaging parity | |
| passed with median 0.9986, p95 1.0195, and max 1.0244. | |
| ## PI0.5 Thor Prefill and BF16 Bias Update | |
| Source gate rerun August 8, 2026 on NVIDIA Thor, PyTorch 2.13.0+cu130: | |
| - correctness: `39/39`, `fail_count=0`; | |
| - plain FP8 GEMM outputs were bitwise equal to the reference across the | |
| `M=65..1024` band; | |
| - PI0.5 prefill QKV/O/gate-up/down auto dispatch was within 2% of the fastest | |
| valid Sq/T1/Wide package tile and the original FlashRT native entry; | |
| - all 11 BF16 bias, bias+residual, and bias+GELU checks passed; | |
| - bias-only output was exact; residual p99 was at most one BF16 step; tanh-GELU | |
| p99 was at most `3.8147e-6`, with cosine at least `0.999995`. | |
| The down-projection bias family uses a CUTLASS Wide fused epilogue while other | |
| SigLIP shapes use the faster cuBLASLt path. The dispatcher preserves the | |
| public row-major `(N,K)` weight contract. | |