Mixed precision training (смешанная точность обучения) — это режим, в котором во время обучения одной и той же модели используются и 16-битные, и 32-битные типы чисел. По официальным руководствам TensorFlow и PyTorch, такой подход нужен, чтобы ускорить обучение, уменьшить расход памяти и при этом сохранить качество оценки модели.
Английский термин: mixed precision training. Также встречается: mixed precision, «смешанная точность», а в контексте фреймворков — AMP (Automatic Mixed Precision), хотя AMP точнее называет автоматический механизм включения этого подхода. По состоянию на 2026-08-14 актуальные официальные API — TensorFlow Keras mixed_precision и PyTorch torch.amp; NVIDIA Apex уместнее рассматривать как legacy/compatibility-вариант.
Простыми словами
Грубо говоря, mixed precision — это способ считать часть обучения в «более лёгком» формате, а критичные участки оставлять в «более точном». Можно представить это как работу с черновиком и финальной проверкой: черновые операции делаются быстрее и дешевле, но там, где ошибка особенно неприятна, вы возвращаетесь к более надёжному режиму.
Практический смысл простой: если ваше железо умеет хорошо работать с 16-битными форматами, вы чаще получаете более быстрый шаг обучения и меньший расход памяти. Но это не магическая кнопка: эффект зависит от конкретного GPU, TPU или CPU и от того, как именно фреймворк распределяет операции по типам.
Как это работает
В официальных документах идея описывается одинаково по сути: обучение использует смесь форматов вместо одного float32 на всё подряд. Для сценариев с float16 нужен механизм, который защищает маленькие градиенты от потери точности; в TensorFlow для custom loop это tf.keras.mixed_precision.LossScaleOptimizer, а в PyTorch — torch.amp.GradScaler. Для bfloat16 требования мягче: TensorFlow прямо пишет, что для mixed_bfloat16 достаточно глобальной policy, а PyTorch указывает, что CPU AMP с bfloat16 может работать только с autocast.
- Вы включаете режим смешанной точности в фреймворке: policy в TensorFlow или
autocastв PyTorch. - Подходящие операции выполняются в 16 битах, чтобы выиграть в скорости и памяти.
- Участки, где нужна устойчивость, остаются в 32 битах или временно выполняются в 32 битах.
- Если используется
float16, loss и градиенты дополнительно проходят через масштабирование, чтобы не потерять слишком маленькие значения. - После этого оптимизатор делает обычный шаг обновления.
Схема mixed precision training
входные данные
|
v
forward pass под autocast / policy
(часть операций в 16 битах)
|
v
loss
|
+--> если float16: loss scaling
|
v
backward
|
+--> unscale gradients / проверка на NaN или inf
|
v
optimizer step
|
v
следующий шаг обучения
У TensorFlow минимальное включение для GPU описано как mixed_precision.set_global_policy('mixed_float16'). Для TPU и CPU TensorFlow рекомендует mixed_bfloat16. В PyTorch текущий официальный путь — torch.amp.autocast вместе с torch.amp.GradScaler для float16-обучения; старые torch.cuda.amp.* и torch.cpu.amp.* отмечены как deprecated.
Где применяется
- Обучение Keras-моделей на современных NVIDIA GPU. TensorFlow пишет, что наибольшая польза ожидается на GPU с compute capability 7.0+.
- Обучение на Cloud TPU. Для этого сценария TensorFlow рекомендует policy
mixed_bfloat16. - Обучение и связанные AMP-сценарии в PyTorch на CUDA. Актуальный официальный стек —
torch.amp, а не deprecated-варианты старого пространства имён. - CPU-сценарии с bfloat16 на новом железе. TensorFlow отдельно указывает на недавние Intel CPU с AMX как на платформу, где mixed precision может дать наибольшую пользу; без AMX CPU может даже замедлиться.
Если вы работаете с крупными трансформерными моделями, mixed precision обычно рассматривают не как отдельную «архитектуру», а как инфраструктурный режим обучения. Поэтому рядом полезно понимать, как устроен Multi-Head Attention (многоголовое внимание) и чем полное дообучение отличается от более лёгких техник вроде prompt tuning.
Практический пример
Минимальная настройка в TensorFlow
Если вы используете Keras на GPU, официальное руководство показывает такой базовый шаг:
mixed_precision.set_global_policy('mixed_float16')
Для TPU и CPU TensorFlow рекомендует:
mixed_precision.set_global_policy('mixed_bfloat16')
Важно: в custom training loop для mixed_float16 TensorFlow требует tf.keras.mixed_precision.LossScaleOptimizer и явные шаги get_scaled_loss / get_unscaled_gradients. Для mixed_bfloat16 этого не нужно.
Текущий паттерн в PyTorch
По официальной документации и recipe, современный шаблон выглядит так:
scaler = torch.amp.GradScaler("cuda")
for inputs, targets in loader:
optimizer.zero_grad()
with torch.amp.autocast("cuda"):
outputs = model(inputs)
loss = loss_fn(outputs, targets)
scaler.scale(loss).backward()
scaler.step(optimizer)
scaler.update()
Что здесь важно на практике:
- для
float16-обучения в PyTorch используется связкаautocast+GradScaler; - если в подозрительном участке появляются
NaNили бесконечности, официальный recipe советует временно выполнить этот подучасток вfloat32; - если вам нужен bitwise-accurate resume, recipe рекомендует сохранять и затем восстанавливать
scaler.state_dict().
Проверять эффект лучше не «на глаз», а сравнением с тем же самым workload в float32. TensorFlow прямо советует повторно прогнать ту же задачу в float32 и сравнить время шага. Для быстрой проверки типа GPU в документации также упоминается nvidia-smi -L.
Чем отличается от похожих терминов
| Термин | Что это такое | Как связан с mixed precision training |
|---|---|---|
| Mixed precision training | Подход к обучению, где используются и 16-битные, и 32-битные типы. | Это сама стратегия ускорения и экономии памяти при сохранении устойчивости. |
| FP16 / float16 | Конкретный 16-битный формат чисел. | Один из форматов, который часто используется внутри mixed precision; для обучения обычно нужен loss scaling / GradScaler. |
| bfloat16 | Другой 16-битный формат. | Тоже используется в mixed precision; по reviewed docs обычно требует меньше дополнительных защитных шагов, чем float16. |
| AMP | Automatic Mixed Precision, то есть API или механизм автоматизации. | Это не отдельный числовой формат, а способ удобнее включить mixed precision во фреймворке. |
| NVIDIA Apex | Расширение для PyTorch от NVIDIA. | Это инструмент для mixed precision и distributed training, но не сам термин; по текущему состоянию официальный путь в PyTorch — torch.amp. |
Ограничения и заблуждения
- Заблуждение: «это всегда ускоряет обучение». По TensorFlow, максимальная польза ожидается на недавних NVIDIA GPU с compute capability 7.0+, Cloud TPU и недавних Intel CPU с AMX. Для P100-класса значимого ускорения не ожидается, а CPU без AMX могут замедлиться.
- Заблуждение: «достаточно перевести всё в float16». NVIDIA отдельно подчёркивает два шага: переносить модель в FP16 только там, где это уместно, и использовать loss scaling, чтобы сохранить маленькие градиенты.
- Заблуждение: «AMP = Apex». Нет. В актуальном PyTorch официальный API —
torch.amp; Apex остаётся полезным в legacy-средах, но это совместимый инструмент, а не рекомендованный базовый путь для новых проектов. - Заблуждение: «поведение не зависит от версии и железа». В source pack есть прямое ограничение: документация версионируется, а фактическое поведение зависит от установленной версии фреймворка и поколения оборудования.
- Практическое ограничение: если в отдельных участках модели появляются
NaNилиinf, придётся локально возвращаться кfloat32и искать проблемный регион, а не надеяться, что AMP «сам всё исправит».
Практический вердикт редакции: если вы обучаете модель в актуальном TensorFlow или PyTorch, начинайте со встроенных
mixed_precisionилиtorch.amp, а не с Apex. Редакционное ограничение: в этой статье нет универсальных процентов ускорения, потому что reviewed источники рекомендуют измерять выигрыш на вашем workload и вашем железе, а не переносить чужие цифры.
Связанные термины и инструменты
Mixed precision полезно понимать не изолированно, а в связке с другими понятиями обучения и использования моделей:
- Multi-Head Attention (многоголовое внимание) — чтобы лучше понимать, почему обучение трансформеров вычислительно тяжёлое.
- Prompt tuning (мягкий промпт) — когда вам нужно адаптировать модель, но вы не хотите полный цикл тяжёлого дообучения.
- Zero-shot prompting — полезный контраст: это уже про использование готовой модели, а не про ускорение её обучения.
- Reasoning-модели — чтобы связать стоимость обучения с последующим поведением сложных LLM на выводе.
Из внешних инструментов и API по текущему состоянию ориентируйтесь на TensorFlow Keras mixed precision и PyTorch torch.amp. NVIDIA Apex имеет смысл только там, где он уже является частью существующего стека или требований совместимости.
Источники
- Mixed precision | TensorFlow Core
- Automatic Mixed Precision package – torch.amp — PyTorch 2.13 documentation
- Automatic Mixed Precision — PyTorch Tutorials 2.13.0+cu130 documentation
- Train With Mixed Precision – NVIDIA Docs
- GitHub – NVIDIA/apex: A PyTorch Extension: Tools for easy mixed precision and distributed training in Pytorch · GitHub
- [1710.03740] Mixed Precision Training
Вопросы и ответы
Mixed precision training и AMP — это одно и то же?
Не совсем. Mixed precision training — это сам подход, где смешиваются 16- и 32-битные типы. AMP — это автоматизированный способ включить этот подход во фреймворке; в PyTorch текущий официальный API для этого называется torch.amp.
Нужен ли GradScaler или loss scaling всегда?
Нет. Для float16-обучения он нужен: PyTorch использует torch.amp.GradScaler, а TensorFlow в custom loop требует LossScaleOptimizer. Для bfloat16 reviewed docs описывают более простой путь: в TensorFlow для mixed_bfloat16 достаточно policy, а CPU bfloat16 AMP в PyTorch может работать только с autocast.
Будет ли mixed precision быстрее на любом GPU или CPU?
Нет. TensorFlow прямо предупреждает, что основной выигрыш ожидается на недавних NVIDIA GPU с compute capability 7.0+, Cloud TPU и недавних Intel CPU с AMX. P100-класс не должен ускоряться значительно, а CPU без AMX могут стать медленнее.
Что делать, если после включения mixed precision появились NaN или inf?
Официальный PyTorch recipe советует временно выполнить подозрительный подучасток в float32. Дополнительно полезно прогнать тот же workload в float32 и сравнить шаг обучения с baseline, чтобы понять, проблема в точности или в другой части пайплайна.