ONNX Runtime или OpenVINO: как выбрать среду инференса — вопрос распадается на три части. ONNX задаёт формат модели, ONNX Runtime и OpenVINO исполняют её, а OpenVINO дополнительно работает провайдером вычислений внутри ONNX Runtime. Выбор начинается с того, какой слой у вас уже есть и какое железо вы собираетесь задействовать.
Формат ONNX, ONNX Runtime и OpenVINO: три разные сущности
Разделение уровней снимает половину путаницы. ONNX — это спецификация формата: файл с графом вычислений, тензорами и метаданными. Документация ONNX Runtime описывает свой продукт как кросс-платформенный ускоритель моделей машинного обучения с гибким интерфейсом для подключения аппаратно-зависимых библиотек, который принимает модели из PyTorch, TensorFlow/Keras, TFLite, scikit-learn и других фреймворков (onnxruntime.ai). То есть ONNX Runtime — среда исполнения, читающая формат ONNX.
OpenVINO занимает другую позицию. Документация проекта определяет OpenVINO Runtime как набор библиотек C++ с привязками для C и Python, дающий общий API для запуска инференса на разных устройствах; каждое устройство подключено через плагинную архитектуру и предоставляет как общий, так и аппаратно-специфичный API (docs.openvino.ai). OpenVINO Runtime способен работать бэкендом для других фреймворков, например через torch.compile.
Третья сущность — провайдер вычислений. ONNX Runtime применяет оптимизации графа, затем разбивает модель на подграфы под доступные аппаратные ускорители; оптимизированные ядра в ядре ONNX Runtime дают прирост, а выделенные подграфы получают дополнительное ускорение от каждого Execution Provider (onnxruntime.ai). Провайдер — это мост между средой исполнения и конкретным железом.
Практический вывод для выбора: формат ONNX переносим между средами, среда исполнения определяет API и жизненный цикл модели, провайдер определяет, на каком устройстве считаются подграфы. Путать эти уровни опасно: настройка, относящаяся к провайдеру, не переносится на уровень формата, а API среды исполнения не заменяет API провайдера.
Устройства, операторы и входные формы модели
Совместимость проверяется по трём осям одновременно. Первая — устройство. Документация Optimum Intel сообщает, что библиотека загружает оптимизированные модели с хаба и создаёт пайплайны для инференса через OpenVINO Runtime на различных процессорах Intel, а для запуска на интегрированном или дискретном GPU Intel используется .to("gpu"), причём на GPU модели по умолчанию считаются в точности FP16 (huggingface.co).
Вторая ось — операторы. Файл ONNX может содержать оператор, который конкретная среда исполнения не реализует. Документация ONNX Runtime прямо возлагает на разработчика ответственность за тестирование и валидацию любой используемой модели, включая её точность, производительность и пригодность для задачи; сама среда проверяет соответствие модели спецификации ONNX (onnxruntime.ai). Соответствие спецификации и поддержка оператора на конкретном устройстве — разные проверки.
Третья ось — входные формы. Документация Optimum Intel предупреждает: при фиксации форм методом reshape() инференс с входом другой формы выполнить нельзя (huggingface.co). Если вы зафиксировали форму под один размер батча или разрешение, смена входа потребует перекомпиляции.
Порядок проверки для читателя: сначала выпишите требуемое устройство, затем прогоните модель через проверку поддерживаемых операторов, затем зафиксируйте входную форму и не меняйте её без перекомпиляции. Ошибка на любой оси даёт отказ, который легко принять за проблему производительности.
OpenVINO Runtime отдельно и OpenVINO Execution Provider внутри ORT
Это два разных маршрута с разными точками входа. OpenVINO Runtime как самостоятельная среда даёт собственный API: документация проекта описывает компиляцию модели через ov::Core::compile_model() с указанием устройства или режима, причём режим AUTO выбирает устройство за вас, запуск инференса через ov::InferRequest::start_async или ov::infer_request.infer(), а затем получение выходных тензоров и обработку результатов (docs.openvino.ai). Здесь вы работаете напрямую с объектами OpenVINO.
Маршрут внутри ONNX Runtime выглядит иначе. Вы сохраняете слой ONNX Runtime, а вычисления на Intel-железе поручаете провайдеру. Документация ONNX Runtime объясняет механику: среда оптимизирует граф и разбивает его на подграфы под доступные ускорители, а каждый Execution Provider ускоряет свои подграфы (onnxruntime.ai). Ваш код остаётся кодом ONNX Runtime, меняется конфигурация сессии.
Разница проявляется в жизненном цикле. В самостоятельном OpenVINO Runtime вы управляете компиляцией модели и устройством через API OpenVINO. В маршруте с провайдером компиляцию и размещение подграфов выполняет ONNX Runtime, а вы проверяете, какие операторы провайдер взял на себя. Документация Optimum Intel добавляет деталь про кэш: библиотека использует кэширование моделей OpenVINO для ускорения компиляции на GPU, по умолчанию создаётся каталог model_cache в каталоге модели в кэше хаба, переопределить это можно параметром ov_config и значением CACHE_DIR, а отключить кэширование на GPU — пустой строкой в CACHE_DIR (huggingface.co).
Выбор между маршрутами диктуется существующим кодом. Приложение на ONNX Runtime получает Intel-бэкенд через провайдер. Отдельный пайплайн на Intel-устройстве может использовать API OpenVINO напрямую.
Современный Plugin EP и статус прежней встроенной интеграции
Здесь важно не переносить статус одной интеграции на весь OpenVINO. Документация ONNX Runtime сообщает: встроенный OpenVINO Execution Provider в репозитории ONNX Runtime объявлен устаревшим, и проект настоятельно рекомендует использовать отдельный Plugin EP, документация по которому доступна на странице OpenVINO Plugin EP (onnxruntime.ai).
Практическое следствие: примеры и настройки, написанные под прежний встроенный провайдер, относятся к устаревшему пути. Актуальный маршрут — Plugin EP, у которого своя документация и свой способ подключения. Копировать старые конфигурации в новый проект рискованно: они описывают другой компонент.
Статус устаревания касается конкретной интеграции внутри ONNX Runtime. OpenVINO Runtime как самостоятельная среда исполнения продолжает развиваться и описана в собственной документации с текущим API компиляции и инференса (docs.openvino.ai). Эти два утверждения живут раздельно.
Порядок действий при миграции: определите, какой именно провайдер подключён в вашей конфигурации; если это встроенный OpenVINO EP, планируйте переход на Plugin EP по его документации; проверьте, что набор поддерживаемых операторов и устройств на новом пути покрывает вашу модель. Проверку совместимости выполняйте до переноса продакшн-нагрузки.
Одинаковый preprocessing и контроль correctness до сравнения скорости
Сравнение маршрутов имеет смысл только при идентичном входе. Подготовьте один и тот же предобработанный тензор, одну и ту же модель и один и тот же набор примеров для всех маршрутов. Документация ONNX Runtime напоминает, что валидация точности и пригодности модели лежит на разработчике (onnxruntime.ai). Это относится к каждому маршруту по отдельности.
Контроль корректности ставьте перед замерами. Учебный пример ниже показывает ручную сверку четырёх строк: эталонный ответ сравнивается с фактическим, совпадение фиксируется по каждой строке.
Учебный ручной контроль, не выход реальной модели:
id=A, эталон=1, ответ=1, совпадение=1
id=B, эталон=2, ответ=2, совпадение=1
id=C, эталон=2, ответ=1, совпадение=0
id=D, эталон=3, ответ=3, совпадение=1
Итог: 3/4 = 75% совпадения, 1 ошибка из 4.
Эти значения служат арифметике проверки и не описывают качество какой-либо среды исполнения. Смысл упражнения в другом: вы получаете процедуру, которую можно применить к реальным ответам модели. Если совпадение ниже ожидаемого, ищите причину в предобработке, версии модели или наборе операторов, прежде чем переходить к замерам времени.
Отдельно зафиксируйте, что успешный HTTP-ответ или отсутствие исключения не доказывают корректность. Инференс может пройти, а результат оказаться неверным из-за подмены каналов или неверной формы входа. Контроль совпадения ответов на размеченном наборе даёт проверяемый сигнал.
Матрица выбора по трём сценариям
Матрица ниже — учебный артефакт решения. Она не содержит скоростных обещаний и не заменяет замеры на вашем железе.
| Сценарий | Что уже есть | Рекомендуемый маршрут | Что проверить |
|---|---|---|---|
| 1 | Приложение на ONNX Runtime, нужен Intel-бэкенд | Пилот ORT + OpenVINO Plugin EP | Поддержку операторов и устройства |
| 2 | Отдельный пайплайн на Intel-устройстве | OpenVINO Runtime с компиляцией модели | Устройство, режим, кэш компиляции |
| 3 | Один интерфейс, разные аппаратные бэкенды | ORT с подходящими Execution Providers | Совместимость каждого провайдера отдельно |
Ни один из сценариев не гарантирует лучшую скорость. Паспорт будущего пилота: классификатор с входом float32[1,3,224,224], одинаковая предобработка и заранее размеченный набор, который читатель готовит сам.
| Строка пилота | startup | p50 | p95 | peak RAM | correctness |
|---|---|---|---|---|---|
| ORT CPU | не измерено | не измерено | не измерено | не измерено | не измерено |
| OpenVINO Runtime | не измерено | не измерено | не измерено | не измерено | не измерено |
| ORT + OpenVINO Plugin EP | не измерено | не измерено | не измерено | не измерено | не измерено |
Поля остаются пустыми до реального прогона. Заполняйте их на своём устройстве, на своей модели и на своём наборе. Документация Optimum Intel предупреждает о детали, влияющей на первый замер: по умолчанию модель компилируется при создании OVModel, а при изменении формы или переносе на другое устройство компиляция повторится перед первым инференсом, что увеличит задержку первого запуска; избежать лишней компиляции можно параметром compile=False (huggingface.co). Прогревайте модель перед замерами p50 и p95.
Ошибки экспорта, неподдержанный оператор и подмена RGB/BGR
Две частые ошибки различаются по природе. Первая — отказ совместимости: файл ONNX экспортирован, но среда исполнения не поддерживает оператор. Симптом — исключение при создании сессии или при первом инференсе. Лечение — проверить список поддерживаемых операторов для выбранного провайдера и устройства, при необходимости заменить оператор в графе или изменить маршрут.
Вторая — ошибка предобработки: инференс проходит, но вместо RGB подаётся BGR. Симптом — результат есть, качество падает. Лечение — зафиксировать порядок каналов в одном месте пайплайна и покрыть его тестом на эталонном примере.
Промпт для разбора такой ошибки с помощью модели:
Ты помогаешь диагностировать ошибку инференса ONNX-модели.
Контекст: модель [название и задача], среда исполнения [ONNX Runtime или OpenVINO Runtime],
провайдер [название], устройство [CPU или GPU], входная форма [например, float32[1,3,224,224]].
Симптом: [текст исключения или описание неверного результата].
Задача: раздели возможные причины на три группы — совместимость операторов,
предобработка входа, конфигурация устройства. Для каждой группы дай одну проверку,
которую можно выполнить локально, и ожидаемый результат проверки.
Не предлагай замеры скорости до подтверждения корректности.
В квадратных скобках подставьте свои значения. Вариации той же задачи: разбор ошибки экспорта из PyTorch в ONNX; проверка списка операторов для конкретного провайдера; сверка порядка каналов на эталонном изображении; разбор расхождения ответов между двумя маршрутами на одном входе.
Порядок диагностики: сначала подтвердите корректность на размеченном наборе, затем проверяйте производительность. Документация ONNX Runtime возлагает валидацию точности и пригодности модели на разработчика (onnxruntime.ai), и это правило действует для любого выбранного маршрута.
Частые вопросы
Чем ONNX отличается от ONNX Runtime?
ONNX — спецификация формата модели с графом вычислений и метаданными. ONNX Runtime — среда исполнения, которая читает этот формат и запускает вычисления. Документация ONNX Runtime описывает его как кросс-платформенный ускоритель с интерфейсом для подключения аппаратно-зависимых библиотек.
Можно ли использовать OpenVINO внутри ONNX Runtime?
Да, через Execution Provider. Документация ONNX Runtime сообщает, что встроенный OpenVINO EP объявлен устаревшим и проект рекомендует отдельный Plugin EP. Актуальный маршрут — Plugin EP со своей документацией.
Почему инференс прошёл, а результат неверный?
Успешный запуск подтверждает отсутствие исключения. Корректность требует сверки ответов на размеченном наборе. Частая причина расхождения — подмена порядка каналов RGB и BGR в предобработке.
Нужно ли прогревать модель перед замерами?
Да. Документация Optimum Intel предупреждает, что при изменении формы или переносе на другое устройство компиляция повторится перед первым инференсом и увеличит задержку первого запуска. Прогрев отделяет компиляцию от рабочих замеров.
Что делать, если оператор не поддерживается?
Проверьте список поддерживаемых операторов для выбранного провайдера и устройства. Варианты — заменить оператор в графе, изменить маршрут исполнения или использовать другую среду. Документация ONNX Runtime возлагает валидацию модели на разработчика.
