Зберегти перший збій та його контекст
Цей посібник починається після успішного запуску: PyTorch бачить пристрій, а потім ваш застосунок зазнає збою на батчі або операторі. Якщо жодне невелике обчислення не працює, поверніться до початкової діагностики. Інакше збережіть першу помилку, номер ітерації та останній завершений крок. Послідовність повідомлень після першого збою може описувати його наслідки, а не кілька незалежних причин.
Занотуйте ревізію коду, версії Python і PyTorch, бекенд, числовий тип і форми входів. Для даних віддавайте перевагу внутрішньому ідентифікатору та розмірам, а не повній копії вмісту. Шукайте те, чим відрізняється проблемний батч: довжина, відсутня ціль, останній неповний лот, аугментація або рідко використовувана гілка. Це досьє дає змогу відтворити випадок, не перезапускаючи всю кампанію.
Локалізувати хибний запуск попри асинхронність
У CUDA операції ставляться в чергу й можуть завершитися після повернення з функції Python. Тому помилка, що спливла під час копіювання на CPU або читання скаляра, може походити з попереднього обчислення. Документація PyTorch пояснює це асинхронне виконання. Рядок, указаний у трасуванні, — це точка спостереження, яку слід перевірити, а не завжди причина.
Для короткого відтворення на NVIDIA/CUDA запустіть окремий процес із CUDA_LAUNCH_BLOCKING=1. Ця опція робить виклики синхронними й може наблизити помилку до її джерела. Вона призначена для діагностики, а не для вимірювання часу. Також можна тимчасово розставити синхронізації між великими етапами, щоб звузити підозрілий інтервал. Після цього приберіть цю інструментацію: вона змінює звичайний порядок виконання.
Наступна команда має навчальний характер і не виконувалася. Вона передбачає наявність термінала POSIX та існуючого скрипту train.py. Присвоєння застосовується лише до цього запуску; адаптуйте синтаксис до вашої оболонки. Не переносьте цю змінну NVIDIA на стек ROCm.
CUDA_LAUNCH_BLOCKING=1 python train.pyЧитати сімейство помилок, не роблячи передчасних висновків
Повідомлення звужує поле пошуку; воно не замінює відтворюваний випадок. Індекс поза межами, тензор на неправильному пристрої та неможливе виділення пам'яті вимагають різних перевірок. Зберігайте розрізнення між некоректними даними, контрактом оператора та бінарним середовищем. Одночасна зміна batch, точності та бібліотек стирає це розрізнення.
Після спрацювання твердження (assertion) на пристрої не намагайтеся продовжити те саме навчання в тому самому процесі. NVIDIA зазначає, що cudaErrorAssert робить наявні виділення пам'яті недійсними та вимагає завершити й перезапустити процес. У notebook це означає перезапуск ядра перед виправленим відтворенням. Однак перезапуск не виправляє ні помилкову ціль, ні недійсний індекс.
Прокрутіть таблицю, щоб побачити всі стовпці.| Спостережувана ознака | Перша перевірка | Висновок, якого слід уникати |
|---|---|---|
| device-side assert | Індекси, цілі та умови оператора | GPU точно несправний |
| Out of memory | Форми, час життя тензорів, пам'ять процесу | Будь-яка помилка CUDA — це брак VRAM |
| Оператор або ядро недоступні | Версії, розширення, бекенд і dtype | Перевстановити все навмання |
| Різні периферійні пристрої | Розміщення моделі та кожного входу | Додати копію, не розуміючи її походження |
Розібраний приклад: клас 4 у задачі з чотирма класами
Візьмімо навчальний класифікатор, вихід якого має чотири стовпці. Його класи індексовано від 0 до 3. Файл анотацій, що містить значення 4, може вказувати на кодування від 1 до 4 або на неочікуваний п'ятий клас. Просте збільшення розміру виходу прибрало б обмеження, не з'ясувавши значення анотацій.
Наведена нижче перевірка застосовується до перенесення цілей на CPU. Її не було виконано. Вона ілюструє контракт CrossEntropyLoss для індексів класів типу long, з явно вибраним ignore_index=-100. Вона не охоплює цілі, що складаються з розподілів імовірностей. У цьому сценарії [0, 2, 4] має бути відхилено; цей очікуваний результат випливає з правила, а не подається як вимірювання.
Потім виправте відображення під час підготовки даних і перевірте його бієкцію з назвами класів. Не віднімайте 1 всюди, поки не дізнаєтеся, чи всі джерела використовують ту саму умовність. Додайте проблемний випадок до невеликого набору для перевірки, який зберігається разом із проєктом.
import torch
classes = 4
ignore_index = -100
target = torch.tensor([0, 2, 4], dtype=torch.long)
if target.ndim != 1 or target.dtype != torch.long:
raise ValueError("Цілі: очікується вектор індексів")
valid = target[target != ignore_index]
if valid.numel() == 0:
raise ValueError("У цьому батчі немає жодної придатної цілі")
if bool(((valid < 0) | (valid >= classes)).any()):
raise ValueError("Індекс класу поза діапазоном")Зменшити програму, не прибираючи тригер
Спочатку відтворіть один вхід або один батч із тими самими перетвореннями. Приберіть віддалене відстеження, запис результатів і гілки, не пов'язані зі збоєм. Збережіть dtype, форми та підозрілий оператор. Якщо помилка залежить від певної довжини або розташування в пам'яті, довільний маленький тензор може її більше не відтворити.
Порівнюйте по одній зміні за раз: вимкнене необов'язкове розширення, еталонний оператор, звична точність або та сама операція на CPU, якщо вона там існує. Успіх на CPU — це підказка, а не підтвердження для CUDA. Для власної функції також зафіксуйте припущення щодо strides, неперервності та розмірів. Шукайте приклад, який падає до виправлення і проходить після, з перевіркою результату, а не лише з відсутністю винятку.
Перевірити виправлення на початковому обсязі
Прийнятне виправлення має проходити мінімальний випадок, суміжні випадки та репрезентативну частину початкового шляху. Зокрема, повторіть останній батч, короткий вхід, довгий вхід і граничні значення мапінгу. Переконайтеся, що відхилені елементи можна ідентифікувати, а кількість оброблених входів залишається очікуваною. Тихе ігнорування винятків може перетворити видимий збій на неповний результат.
Вимкніть режим діагностики, почніть із нового процесу та підтвердьте поведінку зі звичайною конфігурацією. Збережіть причину, застосовану зміну та перевірку на відсутність регресій. Якщо ви перервали навчання, відновіть його з узгодженого checkpoint, перевіреного до помилки; наявність файлу, записаного під час збою, ще не гарантує, що його можна використати для відновлення.
Знати, коли просити цілеспрямованіший аналіз
Якщо той самий мінімальний випадок падає з коректними входами, підготуйте точний запит: операція, форми, типи, backend, версії та перше доречне повідомлення. Приберіть персональні ідентифікатори та зайві шляхи. Бінарне розширення може потребувати власної матриці сумісності; загальна підтримка PyTorch не підтверджує це розширення автоматично.
На ROCm PyTorch зберігає інтерфейс torch.cuda і назви пристроїв cuda. Перевірте torch.version.hip, щоб ідентифікувати цей стек, перш ніж застосовувати процедуру для NVIDIA. Повідомлення, інструменти та параметри діагностики можуть відрізнятися. Жодна з описаних тут перевірок не доводить сумісність підготовлених середовищ із пропозицією Kernodeck; використовуйте ці критерії, щоб уточнити свою потребу перед вибором GPU.