arcisvlm / autokernel /benchmark.py
Hardik Sanghvi
feat: integrate Gemma 4 E2B backbone for production-quality VLM inference
7a564e3
Raw
History Blame Contribute Delete
7.59 kB
"""
ArcisVLM AutoKernel Benchmark Suite
Runs all Triton kernel benchmarks at multiple sizes and reports a
comparison table showing PyTorch vs Triton performance for each kernel.
Usage:
python -m autokernel.benchmark
python autokernel/benchmark.py
"""
import sys
import os
# Ensure project root is on path
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from autokernel.kernels.fused_attention import benchmark_attention, validate_attention
from autokernel.kernels.fused_moe import benchmark_moe, validate_moe
from autokernel.kernels.fused_layernorm import benchmark_layernorm, validate_layernorm
from autokernel.kernels.fused_mlp import benchmark_mlp, validate_mlp
def print_header():
print("=" * 80)
print(" ArcisVLM AutoKernel Benchmark Suite")
print("=" * 80)
print()
try:
import triton
print(f" Triton version: {triton.__version__}")
except ImportError:
print(" Triton: NOT INSTALLED (using PyTorch fallback for all kernels)")
import torch
print(f" PyTorch version: {torch.__version__}")
print(f" CUDA available: {torch.cuda.is_available()}")
if torch.cuda.is_available():
print(f" GPU: {torch.cuda.get_device_name(0)}")
print()
def run_correctness_tests():
"""Run correctness validation for all kernels."""
print("-" * 80)
print(" Correctness Validation")
print("-" * 80)
tests = [
("fused_attention (bidir)", lambda: validate_attention(is_causal=False)),
("fused_attention (causal)", lambda: validate_attention(is_causal=True)),
("fused_layernorm", validate_layernorm),
("fused_mlp (SwiGLU)", validate_mlp),
("fused_moe", validate_moe),
]
all_pass = True
for name, fn in tests:
max_diff, close = fn()
status = "PASS" if close else "FAIL"
if not close:
all_pass = False
print(f" {name:30s} {status} (max_diff={max_diff:.2e})")
print()
return all_pass
def run_benchmarks():
"""Run all kernel benchmarks at multiple sizes."""
print("-" * 80)
print(" Performance Benchmarks")
print("-" * 80)
print()
# Define benchmark configurations
configs = {
"fused_attention": [
{"batch": 1, "seq_len": 256, "dim": 768, "num_heads": 12},
{"batch": 4, "seq_len": 512, "dim": 768, "num_heads": 12},
{"batch": 4, "seq_len": 1024, "dim": 1024, "num_heads": 16},
{"batch": 2, "seq_len": 2048, "dim": 1024, "num_heads": 16},
],
"fused_layernorm": [
{"batch": 4, "seq_len": 512, "embed_dim": 768},
{"batch": 4, "seq_len": 1024, "embed_dim": 768},
{"batch": 4, "seq_len": 1024, "embed_dim": 1536},
],
"fused_mlp": [
{"batch": 4, "seq_len": 512, "embed_dim": 768, "expansion": 4},
{"batch": 4, "seq_len": 1024, "embed_dim": 768, "expansion": 4},
],
"fused_moe": [
{"batch": 4, "seq_len": 256, "embed_dim": 768, "num_experts": 5, "top_k": 2},
{"batch": 4, "seq_len": 512, "embed_dim": 768, "num_experts": 5, "top_k": 2},
],
}
all_results = []
# Table header
print(f" {'Kernel':<22s} {'Config':<30s} {'PyTorch (ms)':>12s} {'Triton (ms)':>12s} {'Speedup':>8s}")
print(f" {'-'*22} {'-'*30} {'-'*12} {'-'*12} {'-'*8}")
# Attention benchmarks
for cfg in configs["fused_attention"]:
res = benchmark_attention(**cfg, warmup=3, iters=10)
conf_str = f"B={cfg['batch']} T={cfg['seq_len']} D={cfg['dim']}"
print(f" {'fused_attention':<22s} {conf_str:<30s} {res['pytorch_ms']:>12.3f} {res['triton_ms']:>12.3f} {res['speedup']:>7.2f}x")
all_results.append(res)
# LayerNorm benchmarks
for cfg in configs["fused_layernorm"]:
res = benchmark_layernorm(**cfg, warmup=3, iters=10)
conf_str = f"B={cfg['batch']} T={cfg['seq_len']} D={cfg['embed_dim']}"
print(f" {'fused_layernorm':<22s} {conf_str:<30s} {res['pytorch_ms']:>12.3f} {res['triton_ms']:>12.3f} {res['speedup']:>7.2f}x")
all_results.append(res)
# MLP benchmarks
for cfg in configs["fused_mlp"]:
res = benchmark_mlp(**cfg, warmup=3, iters=10)
conf_str = f"B={cfg['batch']} T={cfg['seq_len']} D={cfg['embed_dim']}"
print(f" {'fused_mlp (SwiGLU)':<22s} {conf_str:<30s} {res['pytorch_ms']:>12.3f} {res['triton_ms']:>12.3f} {res['speedup']:>7.2f}x")
all_results.append(res)
# MoE benchmarks
for cfg in configs["fused_moe"]:
res = benchmark_moe(**cfg, warmup=3, iters=10)
conf_str = f"B={cfg['batch']} T={cfg['seq_len']} E={cfg['num_experts']}"
print(f" {'fused_moe':<22s} {conf_str:<30s} {res['pytorch_ms']:>12.3f} {res['triton_ms']:>12.3f} {res['speedup']:>7.2f}x")
all_results.append(res)
print()
return all_results
def estimate_model_speedup(results):
"""
Estimate overall model speedup based on kernel benchmarks.
Uses approximate time breakdown for a typical ArcisVLM forward pass:
- Attention: ~40% of compute
- FFN/MLP: ~30% of compute
- MoE routing: ~15% of compute
- LayerNorm: ~5% of compute
- Other (embeddings, projections): ~10%
"""
print("-" * 80)
print(" Estimated Model Speedup")
print("-" * 80)
# Get average speedup per kernel type
kernel_speedups = {}
for res in results:
name = res["kernel"]
if name not in kernel_speedups:
kernel_speedups[name] = []
kernel_speedups[name].append(res["speedup"])
avg_speedups = {k: sum(v) / len(v) for k, v in kernel_speedups.items()}
# Weighted contribution to overall speedup
weights = {
"fused_attention": 0.40,
"fused_mlp": 0.30,
"fused_moe": 0.15,
"fused_layernorm": 0.05,
}
other_fraction = 0.10 # unoptimised portion
print(f"\n {'Component':<22s} {'Weight':>8s} {'Avg Speedup':>12s} {'Effective':>10s}")
print(f" {'-'*22} {'-'*8} {'-'*12} {'-'*10}")
weighted_time_fraction = other_fraction # unoptimised stays at 1.0x
for kernel, weight in weights.items():
spd = avg_speedups.get(kernel, 1.0)
effective = weight / spd # fraction of original time this component now takes
weighted_time_fraction += effective
print(f" {kernel:<22s} {weight:>7.0%} {spd:>11.2f}x {effective:>9.3f}")
print(f" {'other (unoptimised)':<22s} {other_fraction:>7.0%} {'1.00':>11s}x {other_fraction:>9.3f}")
overall_speedup = 1.0 / weighted_time_fraction
print(f"\n Overall estimated model speedup: {overall_speedup:.2f}x")
if not any(r["has_triton"] and r["device"] == "cuda" for r in results):
print("\n NOTE: Running on CPU without Triton. Speedup is 1.0x (fallback path).")
print(" Install Triton and run on a CUDA GPU to see actual kernel speedups.")
print(" Expected GPU speedups: attention ~2-3x, layernorm ~1.5-2x, mlp ~1.3-1.5x")
print()
def main():
print_header()
all_pass = run_correctness_tests()
if not all_pass:
print(" WARNING: Some correctness tests failed!")
print()
results = run_benchmarks()
estimate_model_speedup(results)
# Final summary
print("=" * 80)
correctness_status = "ALL PASS" if all_pass else "SOME FAILURES"
print(f" Correctness: {correctness_status}")
print(f" Benchmarks completed: {len(results)}")
print("=" * 80)
if __name__ == "__main__":
main()