Update FP4 GEMM Benchmark (#14449)
This commit is contained in:
@@ -1,16 +1,13 @@
|
|||||||
import argparse
|
import argparse
|
||||||
import copy
|
|
||||||
import csv
|
import csv
|
||||||
import itertools
|
|
||||||
import os
|
import os
|
||||||
|
|
||||||
import pytest
|
|
||||||
import torch
|
import torch
|
||||||
import triton
|
import triton
|
||||||
from flashinfer import mm_fp4
|
from flashinfer import mm_fp4
|
||||||
from sgl_kernel import cutlass_scaled_fp4_mm, scaled_fp4_quant
|
from sgl_kernel import cutlass_scaled_fp4_mm, scaled_fp4_quant
|
||||||
|
|
||||||
from sglang.srt.utils import get_device_capability
|
from sglang.srt.utils import get_device_capability, is_sm100_supported
|
||||||
|
|
||||||
# CI environment detection
|
# CI environment detection
|
||||||
IS_CI = (
|
IS_CI = (
|
||||||
@@ -73,9 +70,21 @@ else:
|
|||||||
# x_vals = [64],
|
# x_vals = [64],
|
||||||
x_log=False,
|
x_log=False,
|
||||||
line_arg="provider",
|
line_arg="provider",
|
||||||
line_vals=["cutlass", "cudnn", "trtllm"],
|
line_vals=["sglang_cutlass", "cutlass", "cudnn", "trtllm", "auto"],
|
||||||
line_names=["baseline cutlass fp4", "cudnn fp4", "trtllm fp4"],
|
line_names=[
|
||||||
styles=[("red", "solid"), ("blue", "solid"), ("green", "solid")],
|
"sglang cutlass fp4",
|
||||||
|
"flashinfer cutlass fp4",
|
||||||
|
"cudnn fp4",
|
||||||
|
"trtllm fp4",
|
||||||
|
"auto fp4 (cudnn/cutlass)",
|
||||||
|
],
|
||||||
|
styles=[
|
||||||
|
("red", "solid"),
|
||||||
|
("orange", "solid"),
|
||||||
|
("blue", "solid"),
|
||||||
|
("green", "solid"),
|
||||||
|
("purple", "solid"),
|
||||||
|
],
|
||||||
ylabel="latency (ms)",
|
ylabel="latency (ms)",
|
||||||
plot_name="fp4_gemm_benchmark",
|
plot_name="fp4_gemm_benchmark",
|
||||||
args={},
|
args={},
|
||||||
@@ -101,13 +110,27 @@ def benchmark(batch_size, provider, N, K, dtype, correctness, csv_file):
|
|||||||
res_fi = torch.empty((M, N), dtype=dtype, device="cuda")
|
res_fi = torch.empty((M, N), dtype=dtype, device="cuda")
|
||||||
|
|
||||||
quantiles = [0.5, 0.2, 0.8]
|
quantiles = [0.5, 0.2, 0.8]
|
||||||
if provider == "cutlass":
|
if provider == "sglang_cutlass":
|
||||||
ms, min_ms, max_ms = triton.testing.do_bench_cudagraph(
|
ms, min_ms, max_ms = triton.testing.do_bench_cudagraph(
|
||||||
lambda: cutlass_scaled_fp4_mm(
|
lambda: cutlass_scaled_fp4_mm(
|
||||||
a_fp4, b_fp4, a_scale_interleaved, b_scale_interleaved, alpha, dtype
|
a_fp4, b_fp4, a_scale_interleaved, b_scale_interleaved, alpha, dtype
|
||||||
),
|
),
|
||||||
quantiles=quantiles,
|
quantiles=quantiles,
|
||||||
)
|
)
|
||||||
|
if provider == "cutlass":
|
||||||
|
ms, min_ms, max_ms = triton.testing.do_bench_cudagraph(
|
||||||
|
lambda: mm_fp4(
|
||||||
|
a_fp4,
|
||||||
|
b_fp4.T,
|
||||||
|
a_scale_interleaved,
|
||||||
|
b_scale_interleaved.T,
|
||||||
|
alpha,
|
||||||
|
dtype,
|
||||||
|
res_fi,
|
||||||
|
backend="cutlass",
|
||||||
|
),
|
||||||
|
quantiles=quantiles,
|
||||||
|
)
|
||||||
if provider == "cudnn":
|
if provider == "cudnn":
|
||||||
ms, min_ms, max_ms = triton.testing.do_bench_cudagraph(
|
ms, min_ms, max_ms = triton.testing.do_bench_cudagraph(
|
||||||
lambda: mm_fp4(
|
lambda: mm_fp4(
|
||||||
@@ -118,6 +141,7 @@ def benchmark(batch_size, provider, N, K, dtype, correctness, csv_file):
|
|||||||
alpha,
|
alpha,
|
||||||
dtype,
|
dtype,
|
||||||
res_fi,
|
res_fi,
|
||||||
|
backend="cudnn",
|
||||||
),
|
),
|
||||||
quantiles=quantiles,
|
quantiles=quantiles,
|
||||||
)
|
)
|
||||||
@@ -137,6 +161,19 @@ def benchmark(batch_size, provider, N, K, dtype, correctness, csv_file):
|
|||||||
),
|
),
|
||||||
quantiles=quantiles,
|
quantiles=quantiles,
|
||||||
)
|
)
|
||||||
|
if provider == "auto":
|
||||||
|
ms, min_ms, max_ms = triton.testing.do_bench_cudagraph(
|
||||||
|
lambda: mm_fp4(
|
||||||
|
a_fp4,
|
||||||
|
b_fp4.T,
|
||||||
|
a_scale_interleaved,
|
||||||
|
b_scale_interleaved.T,
|
||||||
|
alpha,
|
||||||
|
dtype,
|
||||||
|
res_fi,
|
||||||
|
),
|
||||||
|
quantiles=quantiles,
|
||||||
|
)
|
||||||
if correctness:
|
if correctness:
|
||||||
res_cutlass = cutlass_scaled_fp4_mm(
|
res_cutlass = cutlass_scaled_fp4_mm(
|
||||||
a_fp4, b_fp4, a_scale_interleaved, b_scale_interleaved, alpha, dtype
|
a_fp4, b_fp4, a_scale_interleaved, b_scale_interleaved, alpha, dtype
|
||||||
@@ -213,12 +250,14 @@ if __name__ == "__main__":
|
|||||||
writer = csv.writer(f)
|
writer = csv.writer(f)
|
||||||
writer.writerow(["provider", "m", "n", "k", "time_ms"])
|
writer.writerow(["provider", "m", "n", "k", "time_ms"])
|
||||||
|
|
||||||
# Check architecture compatibility - FP4 operations require sm100a/sm103a
|
# FP4 operations require Blackwell SM100 support
|
||||||
major, minor = get_device_capability()
|
major, minor = get_device_capability()
|
||||||
if major is None or major < 10: # Requires compute capability 10.0+ (sm100a/sm103a)
|
if not is_sm100_supported():
|
||||||
print("Skipping FP4 GEMM benchmark")
|
print("Skipping FP4 GEMM benchmark")
|
||||||
if major is not None:
|
if major is not None:
|
||||||
print(f"FP4 operations require sm100a/sm103a, but found sm{major}{minor}")
|
print(
|
||||||
|
f"FP4 operations require SM100 (Blackwell), but found sm{major}{minor}"
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
print("Could not determine device capability")
|
print("Could not determine device capability")
|
||||||
else:
|
else:
|
||||||
|
|||||||
Reference in New Issue
Block a user