Решения
Оптимизация на GPU: смешанная точность, профайлинг и I/O
Цель. Дать практичные приёмы, которые быстро повышают скорость и снижают стоимость: смешанная точность (BF16/FP16), оптимизация памяти (pinned memory, чекпоинтинг), ускорение I/O и базовый профайлинг. Подходит для обучения, инференса, CV/рендера и HPC.
Быстрые результаты за 10 минут
Если времени мало — начните с этих переключателей:
Смешанная точность (BF16/FP16).
• Для A100/H100 чаще всего рационален BF16 (без скейлера).
• Для карт с FP16 — autocast + GradScaler (для обучения).
• Для инференса — autocast достаточно.
TF32 для матричных операций (Ampere+).
В обучении CNN/трансформеров TF32 почти всегда даёт прирост без заметной потери качества.
Формат памяти channels_last (CNN).
Ускоряет свёртки: model.to(memory_format=torch.channels_last) и храните тензоры в том же формате.


CuDNN autotune для фиксированных размеров.
torch.backends.cudnn.benchmark = True — если входные размеры стабильны.

pin_memory=True, num_workers>0, persistent_workers=True, prefetch_factor=2–4.

torch.compile(model) как простой способ убрать питоновские накладные расходы (особенно в инференсе).
Смешанная точность: BF16/FP16/FP8 — когда и зачем
Лучший баланс «скорость/стабильность» для обучения LLM/CV; обычно без GradScaler.
Даёт максимум скорости в инференсе/части обучающих стадий, но требует подготовленного стека и тщательной валидации качества (смотрите специализированные страницы решения).
Мини‑шаблоны:
Обучение с BF16:
with torch.autocast(device_type="cuda", dtype=torch.bfloat16):
loss = model(inputs).loss
loss.backward()
Обучение с FP16:
scaler = torch.cuda.amp.GradScaler()
with torch.autocast("cuda", dtype=torch.float16):
loss = model(inputs).loss
scaler.scale(loss).backward()
scaler.step(optimizer); scaler.update()
Память и стабильность: как влезть в VRAM
- Gradient checkpointing. Вычисляйте часть активаций повторно, экономя VRAM; особенно полезно на LLM и больших CNN.
- Gradient accumulation. Эмулируйте большой батч за несколько шагов при меньшем VRAM.
- Fused‑ядра и оптимизаторы. Fused Adam/Adan/Lion снижают накладные расходы.
- Offload/ZeRO/FSDP. Для гигантских моделей переносите часть состояния на CPU/диск или распределяйте по данным/параметрам (см. /solutions/llm-training/fsdp-deepspeed/).
- MIG/партиционирование (A100/H100). Когда нужен предсказуемый QoS под много мелких задач (см. /solutions/mig/).


I/O и подготовка данных: чтобы GPU не простаивал
Симптом: загрузка GPU < 70%, при этом CPU/Disk заняты.
- Pinned memory + prefetch. Включайте закрепление памяти и заблаговременную подачу батчей.
- Persistent workers. Исключают перезапуски процессов загрузчиков между эпохами.
- Шардирование датасетов и стриминг. Подача через tar‑шарды/веб‑стрим снижает накладные расходы на мелкие файлы.
- NVMe кэш/ramdisk для «горячих» данных. Перенесите часто используемые выборки ближе к GPU.
- Аугментации на GPU. Перенесите тяжёлые преобразования в GPU‑поток (там, где это уместно).
Инференс: как получить больше TPS и ниже латентность
- Движок под задачу.
• Универсальный высокоскоростной сервинг — см. /solutions/llm-inference/vllm/.
• Минимальная латентность и компиляция графа — /solutions/llm-inference/tensorrt-llm/.
• Готовый прод‑сервер — /solutions/llm-inference/tgi/. - Квантизация. INT8/INT4/FP8 — снижает VRAM и ускоряет инференс (см. /solutions/llm-inference/quantization/).
- Пакетирование запросов. Грамотный батчинг и настройка очередей резко повышают TPS.
- KV‑кэш, attention‑оптимизации. Ускоряют генерацию длинных последовательностей.

Профилирование: быстрый ритуал на 15 минут
- Снимите базовую метрику: wall‑time на эпоху/100 итераций, загрузку GPU (nvidia-smi), пропускную способность (samples/sec или токены/сек).
- Разделите на Compute vs Data. Замерьте, сколько времени уходит на forward/backward/optimizer.step и сколько — на DataLoader/аугментации/диск/сеть.
- Локализуйте «узкое место»:
- если GPU «ждёт» — идите в раздел I/O;
- если GPU «упёрся» в память — включайте mixed precision/accumulation/checkpointing;
- если «упёрся» в вычисления — пробуйте torch.compile, fused‑операции, специализированные ядра.
- Внесите 1–2 изменения и перепрофилируйте. Двигайтесь итеративно, фиксируя прирост.
Чек‑лист перед «боем»
- Смешанная точность выбрана (BF16/FP16/FP8) и проверена на стабильность лосса/метрик.
- DataLoader: pin_memory, num_workers, persistent_workers, prefetch_factor настроены.
- Batch size и grad accumulation подобраны под VRAM; при необходимости включён checkpointing.
- torch.backends.cudnn.benchmark включён только для фиксированных размеров.
- Для инференса выбран профиль: vLLM / TensorRT‑LLM / TGI + стратегия батчинга.
- Логи метрик и времени записываются; есть эталонная «до/после».
Типовые рецепты по задачам
LLM — обучение. BF16 + checkpointing + grad accumulation; при больших моделях — FSDP/ZeRO.
LLM — инференс. Выберите движок (vLLM или TensorRT‑LLM) + квантизация + грамотный батчинг.
CV — обучение. channels_last + TF32 (или BF16/FP16) + аугментации на GPU.
Генерация изображений/видео. Параллельный рендер/батчи, вывод артефактов на NVMe, статические размеры.
HPC. Синхронизация и раскладка данных по узлам, профилирование I/O, NUMA‑аффинность.
Частые ошибки
- benchmark=True при переменных размерах → неоптимальные алгоритмы и дерганая скорость.
- GradScaler с BF16 → лишние накладные расходы без пользы.
- Пустые воркеры DataLoader → GPU простаивает, хотя «карта занята».
- Слишком большой диск «на всякий случай» → растёт стоимость хранения.
- Батчи «на грани VRAM» → флуктуации и OOM; держите небольшой запас.