GPU для ваших проектов · оплата криптовалютой без KYC Как арендовать
Русский
Открыть консоль
Практическое руководство / KERNODECK

Появляется ошибка CUDA: какую операцию нужно проверить?

Сохраните первый сбой, определите затронутый batch и сократите приложение до операции, которая его вызывает. В CUDA асинхронное выполнение может привести к появлению ошибки позже её причины. Затем проверьте индексы, формы, типы и устройства, прежде чем изменять окружение. Этот метод относится к уже запущенному приложению; он не заменяет первичную проверку доступности GPU.

6 мин чтения · Руководство для разработчиков

Сохранить первый сбой и его контекст

Это руководство начинается после успешного запуска: PyTorch видит устройство, затем ваше приложение терпит сбой на batch или операторе. Если никакое небольшое вычисление не работает, вернитесь к первичной диагностике. В противном случае сохраните первую ошибку, номер итерации и последний завершённый шаг. Последовательность сообщений после первого сбоя может описывать его последствия, а не несколько независимых причин.

Зафиксируйте ревизию кода, версии Python и PyTorch, бэкенд, числовой тип и формы входов. Для данных предпочитайте внутренний идентификатор и размеры вместо полной копии содержимого. Ищите то, что отличает проблемный батч: длина, отсутствующая цель, последний неполный батч, аугментация или редко используемая ветка. Это досье позволяет воспроизвести случай без повторного запуска всей кампании.

Локализовать проблемный запуск вопреки асинхронности

На CUDA операции ставятся в очередь и могут завершиться после возврата из функции Python. Ошибка, всплывшая во время копирования на CPU или чтения скаляра, может происходить из предыдущего вычисления. Документация PyTorch объясняет это асинхронное выполнение. Строка, указанная в трейсе, — это точка наблюдения, которую нужно изучить, а не всегда причина.

Для короткого воспроизведения на NVIDIA/CUDA предложите отдельный запуск с CUDA_LAUNCH_BLOCKING=1. Эта опция делает вызовы синхронными и может приблизить ошибку к её источнику. Она служит для диагностики, а не для измерения времени. Вы также можете временно расставить синхронизации между крупными этапами, чтобы сузить подозрительный интервал. Затем уберите эту инструментацию: она меняет обычный порядок выполнения.

Следующая команда носит обучающий характер и не выполнялась. Она предполагает терминал POSIX и существующий скрипт train.py. Присваивание действует только для этого запуска; адаптируйте синтаксис под вашу оболочку. Не переносите эту переменную NVIDIA на стек ROCm.

Предложенный диагностический запуск, не выполнялся
CUDA_LAUNCH_BLOCKING=1 python train.py

Читать семейство ошибок, не делая поспешных выводов

Сообщение сужает область поиска; оно не заменяет воспроизводимый случай. Индекс вне диапазона, тензор не на том устройстве и невозможное выделение памяти требуют разных проверок. Сохраняйте различие между недопустимыми данными, контрактом оператора и бинарным окружением. Одновременное изменение батча, точности и библиотек стирает это различие.

После сработавшей на устройстве проверки-утверждения не пытайтесь продолжить то же обучение в том же процессе. NVIDIA указывает, что cudaErrorAssert делает существующие выделения недействительными и требует завершить и перезапустить процесс. В блокноте это подразумевает перезапуск ядра до исправленного воспроизведения. Перезапуск, однако, не исправляет ни ошибочную цель, ни недопустимый индекс.

Прокрутите таблицу, чтобы увидеть все столбцы.
Направления диагностики, без автоматической связи между сообщением и причиной
Наблюдаемый признакПервая проверкаВывод, которого следует избегать
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 везде, пока не знаете, используют ли все источники одну и ту же конвенцию. Добавьте проблемный случай в небольшой набор проверок, сохраняемый вместе с проектом.

Учебная проверка на CPU для индексов классов
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, непрерывности и размерах. Ищите пример, который падает до исправления и проходит после, с проверкой вывода, а не только с отсутствием исключения.

Проверить исправление на исходном участке

Приемлемое исправление должно проходить минимальный случай, соседние случаи и репрезентативную часть исходного пути. В частности, возьмите последний батч, короткий вход, длинный вход и граничные значения отображения. Убедитесь, что отклонённые элементы можно идентифицировать, а число обработанных входов остаётся ожидаемым. Молчаливое игнорирование исключений может превратить видимый сбой в неполный результат.

Отключите режим диагностики, начните с чистого процесса и подтвердите поведение при обычной конфигурации. Сохраните причину, внесённое изменение и проверку на отсутствие регрессий. Если вы прерывали обучение, начните с согласованного чекпоинта, проверенного до ошибки; наличия файла, записанного во время сбоя, недостаточно для гарантии его возобновления.

Знать, когда запрашивать более точечный анализ

Если один и тот же минимальный случай падает с корректными входными данными, подготовьте точный запрос: операция, формы, типы, backend, версии и первое значимое сообщение. Уберите персональные идентификаторы и лишние пути. Бинарному расширению может требоваться собственная матрица совместимости; общая поддержка PyTorch не подтверждает это расширение автоматически.

В ROCm PyTorch сохраняет интерфейс torch.cuda и имена устройств cuda. Проверьте torch.version.hip, чтобы идентифицировать этот стек, прежде чем применять процедуру для NVIDIA. Сообщения, инструменты и параметры диагностики могут отличаться. Ни одна из описанных здесь проверок не доказывает совместимость подготовленных окружений с предложением Kernodeck; используйте эти критерии, чтобы уточнить свою потребность перед выбором GPU.

Ваши вопросы

Исправляет ли CUDA_LAUNCH_BLOCKING=1 ошибку CUDA?

Нет. Он делает вызовы CUDA синхронными, чтобы помочь локализовать виновную операцию. Используйте его на коротком воспроизведении, затем устраните причину и уберите его перед измерением обычной производительности.

Можно ли продолжить работу в ноутбуке после device-side assert?

Перезапустите ядро перед повторным запуском исправленного случая. Утверждение на стороне устройства может оставить контекст непригодным, а выделения памяти — некорректными. Перезапуск восстанавливает контекст, но не исправляет ошибочные индексы или данные.

Если тот же расчёт проходит на CPU, неисправен ли GPU?

Нет. Этот результат различает два пути выполнения. Причиной различия может быть dtype, расширение, ядро или ограничение на данные. Воспроизведите минимальную операцию на соответствующем стеке GPU, прежде чем делать вывод.

Идентична ли процедура NVIDIA на ROCm?

Не полностью. PyTorch для ROCm тоже использует torch.cuda, но инструменты и некоторые переменные диагностики различаются. Определите HIP с помощью torch.version.hip и обратитесь к документации, соответствующей реальному backend.