Обзор инструментов для ускорения ML-моделей

ONNX Runtime, OpenVINO и TVM: обзор инструментов для ускорения ML-моделей

В статье рассказываем о том, какие инструменты лучше использовать для инференса ML на CPU. А также сравниваем ONNX Runtime, OpenVINO и TVM.

Изображение записи

Большинство вычислений при работе ML-моделей — матричные. Для работы с ними подходят Tensor и CUDA — специальные графические ядра, интегрированные в GPU. Это дает видеокартам преимущества перед CPU в машинном обучении. Однако они стоят дороже. Если нужно развернуть инференс на процессоре, есть компромисс — использовать инструменты для оптимизации.

По мотивам выступления Артема Земляка, инженера-программиста Smart Consulting, рассказываем о том, какие фреймворки лучше использовать для эффективного продакшена ML-сервисов.


Если вам интересна тема статьи, присоединяйтесь к нашему сообществу «MLечный путь» в Телеграме. Там мы вместе обсуждаем проблемы и лучшие практики организации production ML-сервисов, а также делимся собственным опытом. А ещё там раз в неделю выходят дайджесты по DataOps и MLOps.


Способы оптимизации

Скорость инференса зависит от используемых инструментов. Например, можно разворачивать модели только на базовых фреймворках — PyTorch, TensorFlow, PaddlePaddle, TFLite, TorchScript — и получать не самые лучшие результаты. Такие инструменты больше подходят для обучения и тестового инференса моделей, когда нет потребности в высокой скорости ML-сервиса. Для эффективной работы нужно использовать более мощные фреймворки. Например, ONNX Runtime, OpenVINO или TVM.

Скорость разных фреймворков в режиме инференса.

В зависимости от выбранного фреймворка могут быть разные способы оптимизации.

Первый способ — конвертация в ONNX Runtime, OpenVINO или TVM. В большинстве случаев это и последний шаг на пути к ускорению инференса. Посмотрите на график: если конвертировать модель ResNet18 из TensorFlow в OpenVINO, можно ускорить инференс примерно в 10 раз.

Второй способ — использование функций дополнительной оптимизации. В каждом фреймворке, в том числе базовом, есть свои инструменты для ускорения инференса. Яркий пример — динамическая квантизация. Она жертвует «излишней» точностью весов модели, округляет их. Тем самым ускоряет вычисления и инференс.

График зависимости времени инференса от выбранной модели. PyTorch, с применением и без оптимизации.

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

Третий способ — конвертировать модель в EDGE-версию базового фреймворка. У некоторых базовых фреймворков есть свои оптимизированные под «мобильное» (EDGE) железо версии — в них можно «экспортировать» модели. 

PyTorch-модели можно конвертировать в TorchScript, а TensorFlow — в TensorFlow Lite. 
Иногда это дает преимущество: если фреймворк адаптирован под EDGE, то, грубо говоря, он лучше справляется с инференсом на процессорах. 

График зависимости времени инференса от выбранной модели. Сравнение TensorFlow и TF Lite.

Больше информации о базовых фреймворках можно узнать из полной версии доклада.

Четвертый способ — гибридная оптимизация. Если скорости недостаточно, можно поэкспериментировать. Например, конвертировать PyTorch-модель в TorchScript и сделать квантизацию весов. 

Но практика показывает, что лучший вариант — конвертировать в ONNX Runtime, OpenVINO или TVM, а после — использовать их методы дополнительной оптимизации. Но какой фреймворк выбрать?

Бенчмарки эксперимента

Чтобы понять, какой фреймворк лучше использовать, команда из Smart Consulting провела эксперимент. Они проверили, сколько времени и памяти потребляет инференс разных моделей на ONNX Runtime, OpenVINO и TVM. И при каких методах дополнительной оптимизации эти параметры наилучшие. 


Правила проведения эксперимента:

  1. Все рассматриваемые модели должны быть запущены в режиме инференса.
  2. В рамках одного бенчмарка — несколько циклов тестирования.
  3. Память и время вычисляются по 100 раз внутри каждого цикла.
  4. В итоговую таблицу записываются средние значения показателей.

ONNX Runtime

Это open source-движок для конвертации моделей из базовых фреймворков в ONNX-формат — высокопроизводительный инструмент для запуска инференсов. 

В ONNX Runtime (ORT) есть дополнительная оптимизация — квантизация и базовые графовые оптимизации. Последнее всегда включено во время тестирования производительности. 

Тест на производительность

модельвремя, сдиск, ГБоптимизацияCPU
LaBSE_en_ru0,1650,501i7-11800H
LaBSE_en_ru0,0750,126Квантизацияi7-11800H
LaBSE_ner_nerel0,2630,499i7-11800H
LaBSE_ner_nerel0,0910,125Квантизацияi7-11800H
paraphrase-mpnet-base-v20,1661,086i7-11800H
paraphrase-mpnet-base-v20,0670,272Квантизацияi7-11800H
HalfResNet341,470,038i7-11800H
HalfResNet341,300,015Квантизацияi7-11800H
BERT0,9770,692i7-11800H
BERT0,4270,173Квантизацияi7-11800H
ResNet181,100,046i7-11800H
ResNet181,040,012Квантизацияi7-11800H
Бенчмарк CPU-инференса моделей, ONNX Runtime. Оптимизация: квантизация.

По всем рассмотренным классам моделей — для распознавания образов, текста — квантизация в ORT, в среднем, сократила количество используемой памяти на 72,4%, а время работы в режиме инференса — на 42,1%. 

Но хорошие ли это показатели? Для ответа на вопрос сравним ORT с PyTorch.

Сравнение с PyTorch

Параметры бенчмарка такие же: тестирование инференса на разных моделях, без квантизации и с ней. 

Скорость инференса разных моделей, ONNX Runtime и PyTorch. Оптимизация: без квантизации и с ней.

В большинстве случаев видно, что даже без оптимизации ORT выигрывает PyTorch, который использует квантизацию. 

Другая ситуация с количеством потребляемой памяти: ORT без квантизации потребляет не меньше, чем PyTorch. Зато с оптимизацией он показал лучшие результаты. 

Потребляемая память разными моделями, ONNX Runtime и PyTorch. Оптимизация: без квантизации и с ней.

Преимущества ORT

Также ORT хорошо работает на процессорах без специальных инструкций AVX. Это хорошо, когда нужно запустить модель на слабом процессоре. С PyTorch ситуация другая: для эффективной работы нужно устанавливать дополнительные расширения. Рассмотрим пару кейсов.

Распознавание образов. Если нужно построить систему распознавания образов, но есть только слабый процессор и ограничения по времени инференса, можно воспользоваться ORT.

модельвремя, сдиск, ГБоптимизацияCPU
ResNet18 (ORT)4,690,046Xeon 8 CPU (без AVX)
ResNet18 (PyTorch)32,10,044Xeon 8 CPU (без AVX)
Бенчмарк CPU-инференса модели ResNet18, ONNX Runtime и PyTorch, без использования AVX. Оптимизация: отсутствует.

Инференс модели ResNet18 на ORT примерно в 7 раз быстрее, чем на PyTorch.


Распознавание голоса. То же самое и с моделями распознавания голоса. Для системы (например, небольшой социальной сети), которая должна обрабатывать большое количество голосовых сообщений, лучше подойдет ORT.

модельвремя, сдиск, ГБоптимизацияCPU
Voice_recognition (ORT)394КвантизацияXeon 8CPU (без AVX)
ResNet18 (PyTorch)5659Xeon 8CPU (без AVX)
Бенчмарк CPU-инференса модели Voice_recognition, запущенной в ONNX Runtime и PyTorch — на процессоре без AVX. Оптимизация: квантизация.

Инференс модели Voice_recognition на ORT примерно в 14 раз быстрее, чем на PyTorch.


Дополнительный тест

модельвремя, сдиск, ГБоптимизацияCPU
ResNet181,100,046i7-11800H
BERT len=101,880,692i7-11800H
BERT len=1286,440,692i7-11800H
BERT len=25613,440,692i7-11800H
SR1,60,0003i7-11800H
Бенчмарк CPU-инференса модели, ORT. Будет использоваться для сравнения с OpenVINO и TVM. Оптимизация: отсутствует.

OpenVINO

Это открытый ML-фреймворк для оптимизации и развертывания моделей глубокого обучения. В отличие от ORT OpenVINO не такой «гибкий»: инструмент умеет конвертировать только из ONNX. Из минусов — для работы нужны инструкции процессора (SSE4.2 и AVX). Без них OpenVINO либо не запустится, либо не будет просчитывать модель.

Тест на производительность

модельвремя, сдиск, ГБоптимизацияCPU
HalfResNet341,410,038i7-11800H
ResNet180,66i7-11800H
ResNet180,67i7-11800H
ResNet181,81i7-11800H
ResNet180,55i7-11800H
SR1,19i7-11800H
SR1,25i7-11800H
SR3,11i7-11800H
SR1,38i7-11800H
Бенчмарк CPU-инференса модели, OpenVINO. Оптимизация: отсутствует.

Без оптимизации OpenVINO выдает хорошие результаты, как и ORT на некоторых моделях распознавания образов. 

Динамические шейпы

Во время инференса на статических шейпах размеры и форма тензоров не меняются. Но есть ситуации, когда параметры тензора не известны заранее — например, когда меняется размер входных данных модели. Разработчики OpenVINO это учли и добавили динамические шейпы. 


При тестировании OpenVINO скорость инференса проверяли как на статическом, так и динамическом шейпе.


Режимы инференса

В OpenVINO есть инструменты для дополнительной оптимизации. Среди них — квантизация и специальные режимы инференса: 

  • LATENCY — режим на сокращение задержек,
  • THROUGHPUT — режим оптимизации RPM,
  • ASYNC — асинхронный режим инференса.

Их можно комбинировать и добиваться хорошего времени инференса. Например, с помощью режимов можно ускорить модель BERT на 20-30%. Для этого нужно правильно подобрать комбинацию режимов в связке с динамическим или статическим шейпом.

модель(DYNAMIC) время, с(STATIC)время, сдиск, ГБоптимизацияCPU
BERT len=102,222,16i7-11800H
BERT len=102,222,08LATENCYi7-11800H
BERT len=102,162,24THROUGHPUTi7-11800H
BERT len=101,471,69THROUGHPUT + ASYNCi7-11800H
BERT len=1286,476,06i7-11800H
BERT len=1286,956,37LATENCYi7-11800H
BERT len=1288,913,2THROUGHPUTi7-11800H
BERT len=1286,75,22THROUGHPUT + ASYNCi7-11800H
BERT len=25613,510,4i7-11800H
BERT len=25613,610,4LATENCYi7-11800H
BERT len=2561826THROUGHPUTi7-11800H
BERT len=25612,510,2THROUGHPUT + ASYNCi7-11800H
Бенчмарк CPU-инференсов (DYNAMIC и STATIC) BERT-моделей с разной длиной входных данных, OpenVINO. Оптимизация: специальные режимы инференса.

TVM

Это open source-оптимизатор ML, разработанный компанией Apache в 2018 году. Позволяет оптимизировать модели для эффективной работы на любом аппаратном сервере. По сути, это целая система для автоматического создания и оптимизации моделей. А также их конвертации в DLL- и so-форматы для запуска на Windows и Linux соответственно. 

Как и ORT, инструмент может конвертировать модели из большого числа фреймворков и форматов. Среди них — ONNX, TorchScript, TensorFlow, TFLite, Keras, MXNet, Darknet, Caffe и Caffe 2, Coreml, Oneflow, PaddlePaddle.

Также в TVM много дополнительных оптимизаций. Некоторые из них еще «сырые»: 

  • Квантизация — может ускорить инференс в два раза, но пока плохо реализована и может сократить точность модели.
  • Компилятор модели — использует три уровня оптимизации под определенный target.
  • Auto TVM и Auto Scheduler — необходимы для автоматического тюнинга моделей и улучшения производительности.

Тест на производительность

модельвремя, сдиск, ГБоптимизацияCPU
ResNet181,090,046(opt_level=3) llvm -mcpu=skylake-avx512i7-11800H
ResNet181,06(opt_level=3) llvm -mcpu=skylake-avx512 autoscheduleri7-11800H
ResNet180.74(opt_level=3) llvm -mcpu=skylake-avx512 quantize_dynamici7-11800H
BERT len=102,5(opt_level=3) llvm -mcpu=skylake-avx512i7-11800H
BERT len=1288,29(opt_level=3) llvm -mcpu=skylake-avx512 FastMathi7-11800H
BERT len=25623,33(opt_level=3) llvm -mcpu=skylake-avx512 i7-11800H
SR2,1(opt_level=3) llvm -mcpu=skylake-avx512 i7-11800H

Бенчмарк CPU-инференсов моделей, TVM. Оптимизация: квантизация, Auto Scheduler.

Сложно сказать, насколько эффективны дополнительные оптимизации в TVM. Если у вас есть опыт использования, поделитесь им в комментариях.


Скорость без использования AVX

TVM хорошо работает на процессорах и без использования инструкций типа AVX. Но делает это немного хуже, чем ORT.

модельвремя, сдиск, ГБоптимизацияCPU
ResNet18 (TVM)6,370,046(opt_level=3) llvm Xeon 8CPU (без AVX)

ResNet18 (ORT)4,69(opt_level=3) llvm Xeon 8CPU (без AVX)
ResNet18 (PyTorch)32,10,044Xeon 8CPU (без AVX)
Бенчмарк CPU-инференса модели ResNet18, TVM, ONNX Runtime и PyTorch, без использования AVX. Оптимизация отсутствует.

Инференс модели ResNet18 на TVM примерно в 4 раза быстрее, чем на PyTorch. Однако это на 35% медленней инференса на ORT. 

Сравнение инструментов

На протяжении всего эксперимента ONNX Runtime (ORT) был отправной точкой — неким примером для сравнений. Но заслуженный ли этот титул? 

На примере нескольких моделей — ResNet18, SR и BERT — был проведен заключающий тест:

Скорость инференса моделей, ONNX Runtime, OpenVINO, TVM.

Эксперимент показал: TVM медленней соперников в два раза, а OpenVINO и ORT идут «впритык» — они оба хорошо подходят для оптимизации моделей обработки языка и компьютерного зрения.

Скорость инференса моделей, ONNX Runtime, OpenVINO, TVM. Крупный масштаб.

В более крупном масштабе видно: OpenVINO, как и TVM, быстрее ORT. Хотя TVM сильно потерял в точности из-за использования квантизации.


«Топ-3» по скорости можно построить так: на первом месте — OpenVINO, на втором — ORT, на третьем — TVM. 


Какой фреймворк выбрать?

Выбор фреймворка зависит от конкретной ситуации и предпочтений инженера.

Хотите поэкспериментировать с настройками — используйте TVM. Это перспективный проект. Но его методы для оптимизации еще «сырые»: можно выиграть в скорости инференса, но потерять в качестве модели. 

Если нужно гибкое стабильное и «гибкое» решение — используйте ONNX Runtime.Много базовых фреймворков поддерживают конвертацию в ONNX-формат и обратно. Это особенно полезно, если в компании обучают нейросети, например, сразу на PyTorch, TensorFlow и PaddlePaddle. Итоговые модели можно конвертировать в один формат — без затрат времени на оптимизацию каждой из них по отдельности. 

Хотите максимально ускорить инференс — используйте OpenVINO. Инструмент несильно опережает ONNX Runtime в производительности, но в работе с большим количеством моделей разница может быть существенной. Из минусов: в OpenVINO можно конвертировать модели только из ONNX. Это препятствует сценарию из прошлого пункта. 


Какой фреймворк для оптимизации моделей используете вы? Подключайтесь к обсуждению в нашем чате.