|
| 1 | +""" |
| 2 | +Benchmark: fused_add_rms_norm |
| 3 | +Compares: FlagGems vs torch.compile vs vLLM (if available) |
| 4 | +""" |
| 5 | + |
| 6 | +import time |
| 7 | + |
| 8 | +import torch |
| 9 | + |
| 10 | +import flag_gems |
| 11 | + |
| 12 | + |
| 13 | +# ── reference: naive torch ────────────────────────────────────────────── |
| 14 | +def torch_fused_add_rms_norm(x, residual, weight, eps=1e-5): |
| 15 | + x = x + residual |
| 16 | + variance = x.pow(2).mean(-1, keepdim=True) |
| 17 | + return x * torch.rsqrt(variance + eps) * weight, x |
| 18 | + |
| 19 | + |
| 20 | +# ── reference: torch.compile ──────────────────────────────────────────── |
| 21 | +@torch.compile |
| 22 | +def compiled_fused_add_rms_norm(x, residual, weight, eps=1e-5): |
| 23 | + x = x + residual |
| 24 | + variance = x.pow(2).mean(-1, keepdim=True) |
| 25 | + return x * torch.rsqrt(variance + eps) * weight, x |
| 26 | + |
| 27 | + |
| 28 | +# ── reference: vLLM ───────────────────────────────────────────────────── |
| 29 | +try: |
| 30 | + import os |
| 31 | + |
| 32 | + os.environ["VLLM_CONFIGURE_LOGGING"] = "0" |
| 33 | + from vllm._custom_ops import fused_add_rms_norm as vllm_fused_add_rms_norm |
| 34 | + |
| 35 | + HAS_VLLM = True |
| 36 | +except (ImportError, AttributeError): |
| 37 | + HAS_VLLM = False |
| 38 | + print("vLLM not available, skipping vLLM baseline\n") |
| 39 | + |
| 40 | + |
| 41 | +# ── benchmark helper ──────────────────────────────────────────────────── |
| 42 | +def bench_fn(fn, warmup=20, rep=100): |
| 43 | + for _ in range(warmup): |
| 44 | + fn() |
| 45 | + torch.cuda.synchronize() |
| 46 | + t0 = time.perf_counter() |
| 47 | + for _ in range(rep): |
| 48 | + fn() |
| 49 | + torch.cuda.synchronize() |
| 50 | + t1 = time.perf_counter() |
| 51 | + return (t1 - t0) / rep * 1000 # ms |
| 52 | + |
| 53 | + |
| 54 | +# ── main ──────────────────────────────────────────────────────────────── |
| 55 | +shapes = [ |
| 56 | + (1, 4096), |
| 57 | + (32, 4096), |
| 58 | + (128, 4096), |
| 59 | + (512, 4096), |
| 60 | + (1024, 4096), |
| 61 | + (4096, 4096), |
| 62 | + (128, 8192), |
| 63 | + (128, 11008), |
| 64 | +] |
| 65 | +dtypes = [torch.float16, torch.bfloat16] |
| 66 | + |
| 67 | +print(f"{'shape':>18s} {'dtype':>10s} | {'naive':>8s} {'compile':>8s}", end="") |
| 68 | +if HAS_VLLM: |
| 69 | + print(f" {'vllm':>8s}", end="") |
| 70 | +print(f" {'flaggems':>8s} (ms)") |
| 71 | +print("-" * 80) |
| 72 | + |
| 73 | +for shape in shapes: |
| 74 | + for dtype in dtypes: |
| 75 | + M, N = shape |
| 76 | + device = "cuda" |
| 77 | + eps = 1e-5 |
| 78 | + |
| 79 | + x_ref = torch.randn(M, N, dtype=dtype, device=device) |
| 80 | + r_ref = torch.randn(M, N, dtype=dtype, device=device) |
| 81 | + w = torch.randn(N, dtype=dtype, device=device) |
| 82 | + |
| 83 | + # ── naive torch ── |
| 84 | + t_naive = bench_fn( |
| 85 | + lambda: torch_fused_add_rms_norm(x_ref.clone(), r_ref.clone(), w, eps) |
| 86 | + ) |
| 87 | + |
| 88 | + # ── torch.compile ── |
| 89 | + # warmup compile |
| 90 | + _ = compiled_fused_add_rms_norm(x_ref.clone(), r_ref.clone(), w, eps) |
| 91 | + t_compile = bench_fn( |
| 92 | + lambda: compiled_fused_add_rms_norm(x_ref.clone(), r_ref.clone(), w, eps) |
| 93 | + ) |
| 94 | + |
| 95 | + # ── vLLM ── |
| 96 | + if HAS_VLLM: |
| 97 | + # vLLM's fused_add_rms_norm is in-place: (x, residual) modified |
| 98 | + def run_vllm(): |
| 99 | + xc = x_ref.clone() |
| 100 | + rc = r_ref.clone() |
| 101 | + vllm_fused_add_rms_norm(xc, rc, w, eps) |
| 102 | + |
| 103 | + t_vllm = bench_fn(run_vllm) |
| 104 | + |
| 105 | + # ── FlagGems ── |
| 106 | + def run_gems(): |
| 107 | + xc = x_ref.clone() |
| 108 | + rc = r_ref.clone() |
| 109 | + flag_gems.fused_add_rms_norm(xc, rc, (N,), w, eps) |
| 110 | + |
| 111 | + t_gems = bench_fn(run_gems) |
| 112 | + |
| 113 | + # ── print ── |
| 114 | + tag = f"({M}, {N})" |
| 115 | + print(f"{tag:>18s} {str(dtype):>10s} | {t_naive:8.3f} {t_compile:8.3f}", end="") |
| 116 | + if HAS_VLLM: |
| 117 | + print(f" {t_vllm:8.3f}", end="") |
| 118 | + print(f" {t_gems:8.3f}") |
0 commit comments