Почати з еталона, який відповідає потребі
Виберіть короткий набір зі звичайними входами, граничними випадками та межами рішень. Зафіксуйте модель, ваги, попередню обробку та режим train або eval. Порівняння між двома моделями чи двома батчами не дає змоги приписати їхню різницю точності.
Записуйте вихід, корисний для вашого застосунку, а не лише втрати. Для класифікатора це можуть бути оцінки та рішення; для регресії — похибка та екстремальні значення. Уже в еталоні перевірте наявність NaN або inf. Некоректне виконання FP32 не стає надійною основою лише тому, що має більше бітів.
Задайте допуск, мінімальну якість і відсутність нефінітних значень до спроби. PyTorch нагадує, що обчислення з плаваючою точкою не гарантує однакових результатів між пристроями чи шляхами виконання.
Розрізняти autocast, числовий формат і GradScaler
autocast обирає тип для окремих операцій відповідно до їхньої політики обчислень. Він не перетворює всю програму на єдиний формат. За такого використання уникайте ручного перетворення всієї моделі через half(). Поточна документація рекомендує torch.autocast або torch.amp.autocast; старі інтерфейси torch.cuda.amp застаріли.
GradScaler впливає на масштаб втрат і градієнтів під час навчання. Він не використовується як прискорювач інференсу, який не виконує backward. FP16 має вужчий числовий діапазон, ніж BF16; модель, розрахована на BF16, може переповнюватися в FP16. Тому повторне зниження масштабу не доводить, що проблему вирішено.
Обирайте формат, виходячи з обмежень моделі та операцій, які реально використовуються, а потім перевірте підтримку цільової платформи. Комерційна назва карти чи налаштування підготовки PyTorch не доводить, що ваш власний оператор має потрібне ядро.
Прокрутіть таблицю, щоб побачити всі стовпці.| Вибір | Роль | Потрібна перевірка |
|---|---|---|
| Довідковий FP32 | Точка порівняння проєкту | Скінченні результати та очікувана якість |
| Autocast FP16 | Деякі операції в зниженій точності | Числовий діапазон і градієнти |
| Autocast BF16 | Інший компроміс між діапазоном і точністю | Доступні оператори та якість |
| GradScaler | Керування масштабом градієнтів | Фактично виконані оновлення |
Розташуйте етапи навчання в правильному порядку
Запропонований фрагмент припускає, що модель і оптимізатор уже створені, вхідні дані та цільова змінна на одному GPU, а втрата є скаляром. Він не виконувався і не є підтвердженням будь-якої пропозиції. Контекст autocast охоплює forward і втрату; backward відбувається після його закриття. Scaler створюється один раз для сесії навчання, а не для кожного батчу.
Щоб переглянути або обрізати градієнти, спершу зніміть їхній масштабний множник через unscale_. Офіційні приклади AMP уточнюють, що це слід робити один раз на оптимізатор і після накопичення градієнтів, призначених для його оновлення. Порогове значення обрізання 1.0 нижче є ілюстративним і його слід обирати для вашого проєкту, а не універсальною рекомендацією.
Тут перевірки переривають діагностику, якщо втрата, градієнти чи загальна норма не є скінченними. Ці зчитування на CPU є накладними: не заміряйте час цього фрагмента. Накопичення, кілька оптимізаторів і планувальник потребують власного визначення оновлення.
import torch
# Передумови: model, optimizer, loss_fn, inputs і targets існують.
# Модель і вхідні дані на одному пристрої CUDA/HIP.
dtype = torch.float16 # Вибір, який слід перевірити; BF16 — інша спроба.
scaler = torch.amp.GradScaler("cuda", enabled=(dtype == torch.float16))
# Розмістіть у своєму циклі, зберігаючи scaler між батчами.
optimizer.zero_grad(set_to_none=True)
with torch.autocast(device_type="cuda", dtype=dtype):
prediction = model(inputs)
loss = loss_fn(prediction, targets)
if not bool(torch.isfinite(loss).item()):
raise FloatingPointError("Нескінченна втрата: перервати діагностику")
scaler.scale(loss).backward()
scaler.unscale_(optimizer)
if any(p.grad is not None and
not bool(torch.isfinite(p.grad).all().item())
for p in model.parameters()):
raise FloatingPointError("Нескінченний градієнт: перервати діагностику")
torch.nn.utils.clip_grad_norm_(
model.parameters(), max_norm=1.0, error_if_nonfinite=True,
)
scaler.step(optimizer)
scaler.update()Розібраний приклад: два близькі рішення не є взаємозамінними
Припустімо, сервіс обирає клас із максимальним балом. На навчальному вході довідковий результат дає два дуже близькі бали: 1,0000 і 1,0003. Інший числовий шлях міг би змінити їхній порядок або створити рівність. Ці числа ілюструють межу рішення; вони не є виміряними результатами FP16 чи BF16.
Правильна перевірка має два рівні. Порівняйте бали з явними допусками, а потім порівняйте рішення та правило, застосоване до рівностей. Невелика різниця за абсолютним значенням може змінити обрану дію. І навпаки, помітна числова різниця може залишитися без наслідків для задачі, чий поріг розташований далеко від спостережуваних балів.
Фіксуйте ідентифікатори, референсні виходи, тест AMP і вплив на рішення. Встановіть правило прийняття до того, як читати результати. Не розширюйте допуск, щоб прибрати незручний випадок; виходи різних масштабів можуть потребувати окремих критеріїв.
Прокрутіть таблицю, щоб побачити всі стовпці.| Критерій | Референс | Тест AMP | Рішення |
|---|---|---|---|
| Готові виходи | Потрібно перевірити | Потрібно перевірити | Відхиляти непояснені незавершені виходи |
| Числове відхилення | Збережені значення | Відхилення потрібно обчислити | Допуск визначено до тесту |
| Прикладне рішення | Клас або дія | Клас або дія | Розглянути зміни |
| Якість на фіксованому наборі | Потрібно виміряти | Потрібно виміряти | Дотримуватися порогу проєкту |
Тлумачення NaN і пропущених оновлень
Коли з'являються незавершені виходи, знайдіть перший крок, який їх породжує: вхід, проміжний вихід, втрату чи градієнт. Відтворіть той самий випадок у референсі, потім локально вимкніть autocast навколо підозрілої операції, контролюючи також тип її входів. Повернення всього навчання до FP32 може слугувати порівнянням, але не локалізує проблему автоматично.
Scaler може запобігти оновленню, коли градієнти містять inf або NaN. Тому цикл, який продовжується, не обов'язково виконав стільки оновлень, скільки ітерацій. Фіксуйте цю поведінку під час діагностики. Не просувайте наосліп політику навчання, яка нібито відповідає фактичним оновленням.
Скінченна втрата не гарантує скінченних градієнтів. І навпаки, поодинокий інцидент не дає підстав оголосити навчання непридатним: розгляньте його частоту, прогрес і якість. Рецепт AMP надає метод для окремого ізолювання autocast і scaling, коли один із них підозрілий.
Підготовка відтворюваного відкату
Перед тестом збережіть референсну конфігурацію, ваги, стан оптимізатора та узгоджений checkpoint. Якщо ваше навчання використовує scaler, його стан також є частиною відновлення. Задокументуйте dtype та можливі ділянки, залишені в FP32. Відновлення з іншою політикою — це експериментальна зміна, яку слід ідентифікувати, а не неявно еквівалентне продовження.
Поверніться до попередньої конфігурації, якщо виходи стають незавершеними, якщо якість виходить за встановлений критерій або якщо оновлення перестають просуватися придатним чином. Збережіть випадок, який спричинив це повернення. Після зміни повторіть порівняння на тому самому наборі, перш ніж збільшувати тривалість.
Вправа Kernodeck щодо checkpoints перевіряє відновлення на CPU без AMP. Використайте її метод порівняння, додавши стани, які фактично споживає ваш цикл.
Вимірювання виграшу лише після числової валідації
Після валідації виміряйте пам'ять і час без детальної діагностики. Збережіть форми, batch, модель і якість. Зчитування скалярів, синхронізації та профайлери можуть змінювати тривалість; приберіть інтрузивні перевірки з фінального вимірювання.
На ROCm назва пристрою PyTorch залишається cuda, і відповідні інтерфейси використовуються повторно. Це не гарантує ні тих самих ядер, ні ідентичних результатів із NVIDIA. Перевірте backend та оператори проєкту на цільовій платформі. Цей посібник не заявляє жодного фіксованого зменшення пам'яті, прискорення чи сумісності з підготовкою Kernodeck.