- Вопрос или проблема
- Ответ или решение
- 1. Использование потокобезопасных объектов
- 2. Использование torch.cuda.FloatTensor и torch.cuda.synchronize()
- 3. Закрытие и освобождение ресурсов
- 4. Проверка версий драйвера и библиотек
- 5. Установка переменной окружения CUDA_LAUNCH_BLOCKING
- 6. Проверка тензоров на наличие NaN или Inf
- 7. Попробуйте уменьшить количество потоков
- 8. Альтернативные опции для управления потоками
- 9. Проверка использования памяти GPU
- Заключение
Вопрос или проблема
Я пытаюсь провести инференс модели обнаружения объектов. У меня есть несколько камер с одинаковым сценарием использования, поэтому я использую многопоточность для обработки этого.
У меня есть объект Model()
. Он содержит инициализацию любой модели на основе параметра.
У меня есть следующая функция внутри, чтобы обрабатывать предобработку сырых изображений, в основном для инференса модели.
def preprocess(self, image):
try:
torch.cuda.synchronize()
self.im = letterbox(self.im0, (640, 640), stride=self.stride)[0] # изменяем размер с заполнением
self.im = self.im.transpose((2, 0, 1))[::-1] # HWC в CHW, BGR в RGB
self.im = np.ascontiguousarray(self.im) # смежная
self.im = torch.from_numpy(self.im).to(self.DEVICE).float() # uint8 в fp16/32
self.im /= 255 # 0 - 255 в 0.0 - 1.0
if len(self.im.shape) == 3:
self.im = self.im[None] # расширяем для размерности батча
return self.im
except Exception as e:
torch.cuda.synchronize()
self.logger.print_function_error(f"ModelInference - Ошибка в preprocess(); {e}")
self.logger.print_function_error(f"ModelInference - трассировка {traceback.format_exc()}")
raise # Повторно генерируем исключение для обработки позже, если потребуется
return None
и предсказатель
def predict(self, image):
try:
im = self.preprocess(image)
self.pred = self.model(im)
self.pred = non_max_suppression(self.pred, self.conf_thres, self.iou_thres, self.classes, self.agnostic_nms, max_det=self.max_det)
except Exception as e:
self.logger.print_function_error(f"ModelInference - Ошибка в predictObj(); {e}")
self.logger.print_function_error(f"ModelInference - трассировка {traceback.format_exc()}")
return None # Вернуть None или соответствующее значение в случае ошибки
return self.detectionsBoxV3()
Теперь, когда я вызываю этот объект в основном потоке и выполняю его, у меня нет никаких проблем.
Когда я создаю несколько объектов Model() и запускаю их в разных потоках, поначалу все работает без сбоев. Спустя некоторое время я получаю эту ошибку
2024-09-20 16:43:13,534 - ERROR - ModelInference - Ошибка в predictObj(); ошибка cuDNN: CUDNN_STATUS_MAPPING_ERROR
2024-09-20 16:43:13,535 - ERROR - ModelInference - трассировка Traceback (самый последний вызов):
Файл "/home/test/Project/Module/Side/ModelInference.py", строка 214, в predict
self.pred = self.model(im)
Файл "/home/test/env/python_files/auto/lib/python3.8/site-packages/torch/nn/modules/module.py", строка 1501, в _call_impl
return forward_call(*args, **kwargs)
Файл "/home/test/Project/Module/models/yolo.py", строка 209, в forward
return self._forward_once(x, profile, visualize) # инференс с единственным масштабом, обучение
Файл "/home/test/Project/Module/models/yolo.py", строка 121, в _forward_once
x = m(x) # выполнить
Файл "/home/test/env/python_files/auto/lib/python3.8/site-packages/torch/nn/modules/module.py", строка 1501, в _call_impl
return forward_call(*args, **kwargs)
Файл "/home/test/Project/Module/models/common.py", строка 167, в forward
return self.cv3(torch.cat((self.m(self.cv1(x)), self.cv2(x)), 1))
Файл "/home/test/env/python_files/auto/lib/python3.8/site-packages/torch/nn/modules/module.py", строка 1501, в _call_impl
return forward_call(*args, **kwargs)
Файл "/home/test/env/python_files/auto/lib/python3.8/site-packages/torch/nn/modules/container.py", строка 217, в forward
input = module(input)
Файл "/home/test/env/python_files/auto/lib/python3.8/site-packages/torch/nn/modules/module.py", строка 1501, в _call_impl
return forward_call(*args, **kwargs)
Файл "/home/test/Project/Module/models/common.py", строка 120, в forward
return x + self.cv2(self.cv1(x)) if self.add else self.cv2(self.cv1(x))
Файл "/home/test/env/python_files/auto/lib/python3.8/site-packages/torch/nn/modules/module.py", строка 1501, в _call_impl
return forward_call(*args, **kwargs)
Файл "/home/test/Project/Module/models/common.py", строка 59, в forward_fuse
return self.act(self.conv(x))
Файл "/home/test/env/python_files/auto/lib/python3.8/site-packages/torch/nn/modules/module.py", строка 1501, в _call_impl
return forward_call(*args, **kwargs)
Файл "/home/test/env/python_files/auto/lib/python3.8/site-packages/torch/nn/modules/conv.py", строка 463, в forward
return self._conv_forward(input, self.weight, self.bias)
Файл "/home/test/env/python_files/auto/lib/python3.8/site-packages/torch/nn/modules/conv.py", строка 459, в _conv_forward
return F.conv2d(input, weight, bias, self.stride,
RuntimeError: ошибка cuDNN: CUDNN_STATUS_MAPPING_ERROR
даже после обработки потоков, чтобы остановиться и перезапуститься самостоятельно, я получаю постоянную нижеуказанную ошибку, пока не перезапущу программу
2024-09-21 10:16:21,356 - ERROR - ModelInference - Ошибка в predictObj(); ошибка CUDA: неверный адрес
Ошибки CUDA могут асинхронно сообщаться на каком-либо другом вызове API, поэтому трассировка стека может быть некорректной.
Для отладки рассмотрите возможность передачи CUDA_LAUNCH_BLOCKING=1.
Скомпилируйте с `TORCH_USE_CUDA_DSA`, чтобы включить утверждения на стороне устройства.
Ответ или решение
Для решения проблемы с ошибкой cuDNN CUDNN_STATUS_EXECUTION_FAILED
и другими связанными ошибками во время мультипоточности с использованием PyTorch и CUDA, можно предпринять несколько шагов. Приведенные ниже рекомендации могут помочь вам диагностировать и исправить эти ошибки.
1. Использование потокобезопасных объектов
Проблема с потоками: PyTorch не всегда безопасен для использования в многопоточном среде, особенно если разные потоки работают с одними и теми же объектами моделей или тензорами. Убедитесь, что каждый поток создает свою уникальную копию модели.
2. Использование torch.cuda.FloatTensor
и torch.cuda.synchronize()
Проверьте, что переданные данные и модели находятся на правильном устройстве (GPU). Специально в функции preprocess()
убедитесь, что тензоры передаются на устройство CUDA.
3. Закрытие и освобождение ресурсов
При завершении работы каждого потока убедитесь, что все ресурсы освобождаются. Используйте конструкцию finally
, чтобы гарантировать, что освобождаются все используемые ресурсы, такие как память.
4. Проверка версий драйвера и библиотек
Убедитесь, что используете последние стабильные версии:
- NVIDIA драйвера
- cuDNN
- PyTorch
Обновленные версии могут содержать исправления, влияющие на вашу проблему.
5. Установка переменной окружения CUDA_LAUNCH_BLOCKING
Для более точной диагностики проблем с CUDA вы можете установить переменную окружения CUDA_LAUNCH_BLOCKING=1
. Это приведет к синхронизации всех вызовов CUDA и может помочь вам быстрее локализовать проблему.
export CUDA_LAUNCH_BLOCKING=1
6. Проверка тензоров на наличие NaN или Inf
Ошибка может быть вызвана неправильными значениями в тензорах (например, NaN или Inf). Введите проверку значений после этой строки:
if torch.any(torch.isnan(self.im)) or torch.any(torch.isinf(self.im)):
self.logger.print_function_error("Найден NaN или Inf в тензоре!")
7. Попробуйте уменьшить количество потоков
Если ваша система имеет ограниченные ресурсы (например, недостаточно памяти на GPU), попробуйте уменьшить количество одновременно работающих потоков, чтобы избежать исчерпания ресурсов.
8. Альтернативные опции для управления потоками
Если ошибки продолжаются, вы можете рассмотреть использование ThreadPoolExecutor
или ProcessPoolExecutor
из модуля concurrent.futures
, чтобы контролировать количество одновременно работающих потоков, что может привести к более стабильной работе.
9. Проверка использования памяти GPU
Ваша проблема может быть связана с исчерпанием памяти на GPU. Используйте утилиту nvidia-smi
для мониторинга использования памяти и убедитесь, что она не заполнена.
Заключение
Если после выполнения всех предложенных шагов проблема не разрешится, возможно стоит рассмотреть возможность обращения в сообщество PyTorch или на форумы разработчиков с предоставлением дополнительной информации о конфигурации вашей системы, версиях используемых библиотек и ваших тестах.