25 min
Lesson 2 of 4
Model and Kernel Optimization
From the course AI Performance Optimization
Optimize model architecture and GPU kernels for maximum computational efficiency.
Operator Fusion
torch.compile
import torch
model = YourTransformerModel()
# Compile with maximum optimization
compiled_model = torch.compile(
model,
mode="max-autotune", # Finds best kernel configurations
fullgraph=True # Compile entire model graph
)
# Typically 2-4x speedup for transformers
# First call is slow (compilation), subsequent calls are fast
output = compiled_model(input_data)
Custom CUDA Kernels
import triton
import triton.language as tl
@triton.jit
def fused_softmax_kernel(
input_ptr, output_ptr,
n_cols, BLOCK_SIZE: tl.constexpr
):
row_idx = tl.program_id(0)
row_start = row_idx * n_cols
col_offsets = tl.arange(0, BLOCK_SIZE)
mask = col_offsets < n_cols
# Load row
row = tl.load(input_ptr + row_start + col_offsets, mask=mask, other=-float('inf'))
# Compute softmax in single pass
row_max = tl.max(row, axis=0)
row_exp = tl.exp(row - row_max)
row_sum = tl.sum(row_exp, axis=0)
softmax_output = row_exp / row_sum
tl.store(output_ptr + row_start + col_offsets, softmax_output, mask=mask)
def softmax(x):
n_rows, n_cols = x.shape
output = torch.empty_like(x)
grid = (n_rows,)
fused_softmax_kernel[grid](x, output, n_cols, BLOCK_SIZE=triton.next_power_of_2(n_cols))
return output
Memory Optimization
Gradient Checkpointing
from torch.utils.checkpoint import checkpoint
class MemoryEfficientTransformer(nn.Module):
def __init__(self, num_layers):
super().__init__()
self.layers = nn.ModuleList([TransformerLayer() for _ in range(num_layers)])
def forward(self, x):
for layer in self.layers:
# Recompute activations during backward instead of storing
x = checkpoint(layer, x, use_reentrant=False)
return x
# Trade-off: 40% memory reduction, 20-30% compute overhead
# Required for training large models on limited VRAM
Mixed Precision Training
from torch.cuda.amp import autocast, GradScaler
scaler = GradScaler()
for batch in dataloader:
optimizer.zero_grad()
with autocast(dtype=torch.bfloat16): # BF16 on Ampere+
output = model(batch)
loss = criterion(output)
# Scale gradients to prevent underflow
scaler.scale(loss).backward()
scaler.unscale_(optimizer)
# Clip gradients
torch.nn.utils.clip_grad_norm_(model.parameters(), 1.0)
scaler.step(optimizer)
scaler.update()
# BF16: 2x memory reduction, 2x compute speedup on Ampere+
Key Takeaways
- •torch.compile achieves 2-4x speedup through kernel fusion and auto-tuning
- •Triton enables custom GPU kernels in Python for domain-specific optimizations
- •Gradient checkpointing trades 20% compute for 40% memory reduction
- •Mixed precision training with BF16 delivers 2x memory and compute improvement
0 of 4 lessons marked complete
Progress is kept in this browser only.