gpu_benchmark_post
Твой GPU-бенчмарк врёт тебе
Ты замеряешь время на GPU — получаешь 0.1ms. Запускаешь в продакшн — реально 50ms. Знакомо?
Причина: time.time() измеряет CPU dispatch, а не GPU execution.
Почему это происходит
GPU работает асинхронно. Когда ты пишешь model(x), CPU просто ставит команду в очередь и сразу возвращает управление. GPU выполнит её потом — через несколько миллисекунд или больше. time.time() успевает закрыться до того, как GPU вообще начал работать.
# НЕПРАВИЛЬНО — замеряем CPU dispatch
import time
start = time.time()
output = model(x) # CPU → очередь, GPU ещё не стартовал
end = time.time()
print(f"{(end-start)*1000:.2f} ms") # ~0.1ms — ложь
Правильно: torch.cuda.Event
import torch
# Создаём события на GPU timeline
start_event = torch.cuda.Event(enable_timing=True)
end_event = torch.cuda.Event(enable_timing=True)
# Прогрев — обязательно!
for _ in range(10):
_ = model(x)
start_event.record()
output = model(x)
end_event.record()
# Ждём завершения GPU
torch.cuda.synchronize()
ms = start_event.elapsed_time(end_event)
print(f"{ms:.3f} ms") # реальное время
elapsed_time() возвращает время прямо с GPU-таймера — без накладных расходов CPU.
Чеклист правильного бенчмарка
— Warmup: 10+ итераций перед измерением. Первый запуск включает JIT-компиляцию, загрузку весов в кэш.
— torch.cuda.synchronize(): CPU должен дождаться GPU перед тем как читать результат.
— Median, не mean: выбросы от планировщика ОС и других процессов искажают среднее. np.median(times) честнее.
— torch.no_grad(): отключи граф автодиффа — он добавляет overhead даже на инференсе.
— model.eval(): BatchNorm и Dropout меняют поведение в train-режиме.
model.eval()
with torch.no_grad():
times = []
for _ in range(100):
start_event.record()
_ = model(x)
end_event.record()
torch.cuda.synchronize()
times.append(start_event.elapsed_time(end_event))
print(f"median: {np.median(times):.3f} ms")
print(f"p95: {np.percentile(times, 95):.3f} ms")
Сохрани — пригодится каждый раз, когда будешь профилировать модель.
#ML #PyTorch #GPU #deeplearning #benchmark