Первый вывод onnxruntime-gpu после запуска программы потребляет больше системных ресурсов и занимает больше времени. В этой статье описан метод оптимизации.
существовать Python Вниз onnxruntime-gpu
нагрузка onnx После модели создайте seddion Сделайте выводы по данным,существование займет больше времени в первый раз, чем последующие казни,Необходимо больше ресурсов.
session = onnxruntime.InferenceSession(str(model_path), providers=[
"CUDAExecutionProvider",
"CPUExecutionProvider"
])
session.run(None, inputs)
onnxruntime В официальной документации есть некоторая информация о Provider Описание элементов конфигурации:NVIDIA - CUDA | onnxruntime
в https://onnxruntime.ai/docs/execution-providers/CUDA-ExecutionProvider.html#cudnn_conv_algo_search
The type of search done for cuDNN convolution algorithms.
Value | Description |
---|---|
EXHAUSTIVE (0) | expensive exhaustive benchmarking using cudnnFindConvolutionForwardAlgorithmEx |
HEURISTIC (1) | lightweight heuristic based search using cudnnGetConvolutionForwardAlgorithm_v7 |
DEFAULT (2) | default algorithm using CUDNN_CONVOLUTION_FWD_ALGO_IMPLICIT_PRECOMP_GEMM |
Оннкс описан оптимизация Операция поиска инициализации операции свертки, существует свертка больше, и Onnx Этот вариант требует много времени при приеме нескольких входных данных переменного размера. По умолчанию EXHAUSTIVE
, Это самый трудоемкий вид.
Поэтому, если вы столкнулись с вышеуказанными проблемами, вы можете попробовать изменить эту опцию на DEFAULT
session = onnxruntime.InferenceSession(str(model_path), opts, providers=[
("CUDAExecutionProvider", {"cudnn_conv_algo_search": "DEFAULT"}),
"CPUExecutionProvider"
])
Этот вариантоптимизациясуществовать Linux Вниз Доход не слишком большой, существуют Windows Вниз может изменить время прогрева инициализации с 500s сокращено до 70s。
ОРТ будет использовать библиотеку CuDNN для выполнения вычислений свертки. Первый шаг — решить, какой алгоритм свертки лучше, основываясь на форме входных данных, форме фильтра…
Рабочее пространство необходимо выделить заранее. Если рабочее пространство недостаточно велико, оптимальный алгоритм свертки может не выполняться.
Поэтому вам нужно сделать рабочую область как можно больше, чтобы выбрать алгоритм свертки с более высокой производительностью.
В версиях до 1.14 флаг cudnn_conv_use_max_workspace по умолчанию равен 0, что означает, что будет выделено только 32 МБ. В версиях после 1.14 значение по умолчанию установлено на 1, что гарантирует выбор оптимального алгоритма свертки, но может привести к пиковому использованию памяти. увеличивать.
Официальное заявление: fp16. модель,cudnn_conv_use_max_workspace установлен на 1 очень важно,float
anddouble
Не обязательно
Если его необходимо изменить:
providers = [("CUDAExecutionProvider", {"cudnn_conv_use_max_workspace": '1'})]
Это может сократить время копирования данных (иногда между устройствами).
Если вы хотите использовать это, вам нужно заменить InferenceSession.run() на InferenceSession.run_with_iobinding().
При рассуждении:
session.run_with_iobinding(binding)
существования Перед этим нужно создать привязку:
binding = session.io_binding()
Привяжите необходимые входные и выходные данные к привязке:
# входить X от numpy array
io_binding.bind_cpu_input('X', X)
# входить X от torch tensor
X_tensor = X.contiguous()
binding.bind_input(
name='X',
device_type='cuda',
device_id=0,
element_type=np.float32,
shape=tuple(x_tensor.shape),
buffer_ptr=x_tensor.data_ptr(),
)
# Пусть выход непосредственно выводит существующий один torch tensor начальство
np_type = np.float32
DEVICE_NAME = 'cuda' if torch.cuda.is_available() else 'cpu'
DEVICE_INDEX = 0 # Replace this with the index of the device you want to run on
z_tensor = torch.empty(x_tensor.shape, dtype=torch_type, device=DEVICE).contiguous()
binding.bind_output(
name='z',
device_type=DEVICE_NAME,
device_id=DEVICE_INDEX,
element_type=np_type,
shape=tuple(z_tensor.shape),
buffer_ptr=z_tensor.data_ptr(),
)
# Пусть вывод идет непосредственно в существование numpy array начальство
binding.bind_output(
)
Когда свертка преобразуется в умножение больших матриц, вы можете выбрать два метода заполнения: N, C, D, 1 или N, C, 1, D. Результаты одинаковы, но поскольку выбраны разные алгоритмы свертки, производительность может снизиться. быть очень хорошим.
Особенно такая видеокарта, как A100.
Метод установки:
providers = [("CUDAExecutionProvider", {"cudnn_conv1d_pad_to_nc1d": '1'})]
Можно установить 0 и настройки 1 Попробуйте оба и посмотрите, какой из них быстрее.
Ссылка на статью: