[Performance] FusedAdam capturable kernel is ~1.9x slower than regular Adam on GB300
I maintainer di solito rispondono entro 2 giorni
Valutazione
Questa issue non è ancora stata valutata.
Descrizione
Transformer Engine's FusedAdam optimizer exhibits approximately 1.9x higher kernel latency with capturable=True compared to capturable=False on GB300.
This was observed in Nemotron 3.5 30B training when enabling optimizer.optimizer_cuda_graph=true in Megatron. The optimizer kernel changes from AdamFunctor to AdamCapturableFunctor, increasing average kernel execution time from approximately 104 µs to 196 µs.
GPU: NVIDIA GB300
Container: nvidia+nemo+26.08.01
Training workload: Nemotron 3.5 30B (BF16, 2 nodes)
To reproduce the issue, run the standalone benchmark: python3 adam_bench.py --graph
"""
Benchmark Transformer Engine FusedAdam: regular vs capturable.
Compares optimizer kernel latency with capturable=False and
capturable=True using large FP32 tensors.
Usage:
python3 adam_bench.py
python3 adam_bench.py --n-tensors 10 --steps 5
python3 adam_bench.py --graph
"""
import argparse
import statistics
import torch
from torch.profiler import profile, ProfilerActivity
from transformer_engine.pytorch.optimizers import FusedAdam
parser = argparse.ArgumentParser()
parser.add_argument("--n-tensors", type=int, default=201)
parser.add_argument("--numel", type=int, default=320 * 65536)
parser.add_argument("--steps", type=int, default=6)
parser.add_argument("--graph", action="store_true")
args = parser.parse_args()
print(f"GPU: {torch.cuda.get_device_name(0)}")
print(f"Tensors: {args.n_tensors}, Elements/tensor: {args.numel:,}")
def benchmark(capturable):
# Create parameters and gradients
params = [
torch.randn(args.numel, device="cuda", requires_grad=True)
for _ in range(args.n_tensors)
]
for p in params:
p.grad = torch.randn_like(p) * 1e-3
optimizer = FusedAdam(
params,
lr=1.6e-3,
betas=(0.9, 0.95),
eps=1e-8,
weight_decay=0.1,
adam_w_mode=True,
capturable=capturable,
exp_avg_dtype=torch.float32,
exp_avg_sq_dtype=torch.float32,
)
# Warmup and initialize optimizer states
for _ in range(2):
optimizer.step()
torch.cuda.synchronize()
# Measure individual Adam CUDA kernels
with profile(activities=[ProfilerActivity.CPU, ProfilerActivity.CUDA]) as prof:
for _ in range(args.steps):
optimizer.step()
torch.cuda.synchronize()
kernel_times = [
e.device_time
for e in prof.events()
if e.device_type == torch.autograd.DeviceType.CUDA
and "multi_tensor_apply_kernel" in e.name
]
# Measure total optimizer step time
start = torch.cuda.Event(enable_timing=True)
end = torch.cuda.Event(enable_timing=True)
start.record()
for _ in range(args.steps):
optimizer.step()
end.record()
torch.cuda.synchronize()
step_ms = start.elapsed_time(end) / args.steps
kernel_us = statistics.mean(kernel_times)
print(f"\nCapturable: {capturable}")
print(f" Kernels/step: {len(kernel_times) / args.steps:.0f}")
print(f" Mean kernel: {kernel_us:.1f} us")
print(f" Step time: {step_ms:.2f} ms")
# Optional CUDA graph benchmark
if capturable and args.graph:
graph = torch.cuda.CUDAGraph()
stream = torch.cuda.Stream()
stream.wait_stream(torch.cuda.current_stream())
with torch.cuda.stream(stream):
optimizer.step()
torch.cuda.current_stream().wait_stream(stream)
with torch.cuda.graph(graph):
optimizer.step()
start.record()
for _ in range(args.steps):
graph.replay()
end.record()
torch.cuda.synchronize()
print(f" Graph replay: {start.elapsed_time(end) / args.steps:.2f} ms")
del optimizer, params
torch.cuda.empty_cache()
return kernel_us, step_ms
regular_us, regular_ms = benchmark(capturable=False)
capturable_us, capturable_ms = benchmark(capturable=True)
print("\n=== Comparison ===")
print(f"Kernel slowdown: {capturable_us / regular_us:.2f}x")
print(f"Step slowdown: {capturable_ms / regular_ms:.2f}x")
- Lingua principale
- Python
- Stelle
- 3.6k
- Fork
- 883
- Merge medio
- 4g 17h
- PR unite (30g)
- 70
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Ha un modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di NVIDIA/TransformerEngine
-
[PyTorch] fp8_cs_quantize fake implementation returns a vector inverse scale instead of a scalarForse di nuovo libera @sanjana658 l’ha presa 23 giorni fa e non c’è nessuna pull request aperta. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
NVIDIA/TransformerEngine#3636 · 2 commenti ·
I maintainer di solito rispondono entro 2 giorni
-
[Bug] Backend selection picks FA3 for training with head_dim_qk=192 / v_head_dim=128, but FA3 backward cannot run itForse di nuovo libera @modelpath-dev l’ha presa 57 giorni fa e non c’è nessuna pull request aperta. Apertaattention
Difficoltà 2/5 1-3 ore Idoneità per principianti 85/100
NVIDIA/TransformerEngine#3481 · 4 commenti ·
I maintainer di solito rispondono entro 2 giorni
-
Increase MAX_TENSOR_NUMApertabug
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
NVIDIA/TransformerEngine#2189 · 7 commenti · 5 reazioni ·
I maintainer di solito rispondono entro 2 giorni
-
`DotProductAttention` with `fp8_dpa=True` does not update its backward scales when no Linear-family module is in the autocast region, and dQ/dK lose most of their normForse già presa @sha7doww l’ha presa 1 giorno fa. Aperta
Difficoltà 4/5 3-5 giorni Idoneità per principianti 48/100
NVIDIA/TransformerEngine#3778 ·
I maintainer di solito rispondono entro 2 giorni
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 55/100
NVIDIA/TransformerEngine#3765 ·
I maintainer di solito rispondono entro 2 giorni
Tutte le issue di NVIDIA/TransformerEngine
Issue simili
-
bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 86/100
NousResearch/hermes-agent#147104 ·
I maintainer di solito rispondono entro 1 giorno
-
premises-missing
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 88/100
WingedGuardian/GENesis-AGI#3801 ·
I maintainer di solito rispondono entro 1 giorno
-
[oblt-aw][autodoc] Document new required `shared-org-key` input for `obs-aw-dependency-review`Forse già presa @github-actions l’ha presa oggi. Aperta
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 90/100
I maintainer di solito rispondono entro 1 giorno
-
bot-triaged module: inductor oncall: pt2 topic: fuzzer triaged
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
I maintainer di solito rispondono entro 4 giorni