English translation is not available yet. Showing Russian content.

Что такое ONNX Runtime и когда он выгоден для LLM?

Краткий тезис

ONNX Runtime (ORT) — это кроссплатформенный движок инференса для моделей в формате ONNX. Он оптимизирует выполнение за счёт слияния операций (graph fusion), квантизации и аппаратно-зависимых бэкендов. Для LLM ORT выгоден в сценариях гибридного CPU/GPU деплоя, на edge-устройствах и при необходимости низкой задержки на разнородном железе. Однако для чистого GPU с высокой пропускной способностью (batch inference) ORT уступает специализированным решениям вроде vLLM или TensorRT-LLM.


1. Термин: ONNX Runtime (ORT)

ONNX Runtime — это высокопроизводительный движок для запуска моделей машинного обучения, представленных в формате Open Neural Network Exchange (ONNX). ONNX — открытый стандарт для представления моделей, поддерживаемый Microsoft, Facebook, AWS и другими. ORT может работать на CPU, GPU (CUDA, ROCm, DirectML), NPU и мобильных процессорах.

Ключевые возможности ORT

  • Оптимизация графа вычислений — retrieval|автоматическое слияние операций, удаление лишних узлов, перестановка для лучшей локализации данных.
  • Квантизация — снижение точности весов (INT8, FP16) для ускорения и уменьшения памяти.
  • Исполнение через аппаратные бэкенды — CUDA Execution Provider для NVIDIA GPU, DirectML для Windows, OpenVINO для Intel, TensorRT для NVIDIA.
  • Кроссплатформенность — Windows, Linux, macOS, Android, iOS, WebAssembly.

Для LLM ORT поддерживает модели трансформеров через интеграцию с HuggingFace Optimum и специальный пакет onnxruntime-genai, который добавляет оптимизации для генерации текста (кэширование KV, beam search).


2. Формат ONNX и его преимущества

ONNX — это промежуточное представление модели (IR), которое отделяет архитектуру от фреймворка обучения. Модель из PyTorch, TensorFlow или JAX экспортируется в ONNX-граф, после чего ORT может выполнять его на любом поддерживаемом бэкенде.

Преимущества для LLM

  • Переносимость — одна модель работает на CPU, GPU, NPU без переписывания кода.
  • Оптимизация графа — ORT применяет десятки пассов (например, слияние слоёв attention, удаление лишних transpose), которые могут ускорить инференс на 20–50% по сравнению с наивным запуском.
  • Квантизация — ORT поддерживает Dynamic Quantization (квантизация весов на лету) и Static Quantization (с калибровочным датасетом). Для LLM часто используют INT8 квантизацию, снижающую размер модели в 2 раза при минимальной потере качества.

Пример экспорта модели GPT-2 в ONNX:

from transformers import GPT2Model, GPT2Tokenizer
import torch

model = GPT2Model.from_pretrained("gpt2")
dummy_input = torch.randint(0, 1000, (1, 128))  # batch=1, seq_len=128

torch.onnx.export(
    model,
    dummy_input,
    "gpt2.onnx",
    input_names=["input_ids"],
    output_names=["last_hidden_state"],
    dynamic_axes={"input_ids": {0: "batch", 1: "seq"}},
    opset_version=17
)

3. Оптимизация графа (Graph Optimization)

ORT автоматически применяет ряд оптимизаций к ONNX-графу:

ОптимизацияОписаниеВлияние на LLM
FusionСлияние последовательных операций (например, MatMul + Add + ReLU → единый узел)Уменьшает число вызовов ядер, снижает latency
Constant FoldingВычисление константных подграфов на этапе загрузкиУскоряет первый проход (warm-up)
Layout OptimizationПерестановка тензоров для лучшего использования кэшаДо 10% ускорения на CPU
Memory PatternПереиспользование буферов для промежуточных результатовСнижает пиковое потребление памяти

Для LLM особенно важна оптимизация attention: ORT может заменить стандартный attention на FlashAttention (если бэкенд поддерживает) или слить операции QKV.


4. Квантизация в ORT

ORT поддерживает два подхода к квантизации:

  • Dynamic Quantization — веса квантизуются в INT8 при загрузке, активации остаются в FP32. Простота, но меньший прирост скорости.
  • Static Quantization — требует калибровочного датасета для подбора диапазонов активаций. Даёт лучшее ускорение (до 2x на CPU).

Пример квантизации модели через Optimum

from optimum.onnxruntime import ORTQuantizer
from optimum.onnxruntime.configuration import AutoQuantizationConfig

quantizer = ORTQuantizer.from_pretrained("gpt2-onnx")
dqconfig = AutoQuantizationConfig.avx512_vnni(is_static=False)
quantizer.quantize(save_dir="gpt2-quantized", quantization_config=dqconfig)

Влияние на LLM INT8 квантизация снижает размер модели с 7B до ~3.5GB (для FP16INT8), что позволяет запускать LLM на устройствах с ограниченной памятью. На CPU ускорение может достигать 2–3x, на GPU — 1.2–1.5x.


5. Кроссплатформенность и аппаратные бэкенды

ORT поддерживает множество Execution Providers (EP):

EPАппаратураОсобенности для LLM
CUDANVIDIA GPUИспользует cuBLAS, Tensor Cores. Поддерживает FP16, INT8
TensorRTNVIDIA GPUДополнительная оптимизация через TensorRT (слияние слоёв, kernel auto-tuning)
DirectMLWindows GPU (AMD, Intel, NVIDIA)Работает через DirectX 12, подходит для игровых карт
OpenVINOIntel CPU, GPU, NPUОптимизирован для Intel, поддерживает INT8
CoreMLApple Neural EngineДля iOS/macOS
XNNPACKARM CPU (Android, iOS)Использует NEON-инструкции

Выгода для LLM одна и та же ONNX-модель может работать на сервере с NVIDIA GPU (CUDA EP), на ноутбуке с Intel CPU (OpenVINO EP) и на смартфоне (CoreML EP) — без переобучения.


6. Сравнение ORT с другими runtime

ХарактеристикаONNX RuntimevLLMTensorRT-LLMPyTorch eager
Основной фокусКроссплатформенностьВысокая пропускная способность GPUМаксимальная производительность NVIDIA GPUГибкость разработки
Поддержка LLMЧерез Optimum/onnxruntime-genaiНативная (PagedAttention, continuous batching)Нативная (in-flight batching, FP8)Прямой запуск
КвантизацияINT8, FP16, (INT4 экспериментально)INT8, FP8, AWQ, GPTQINT4, INT8, FP8Через torch.quantization
КроссплатформенностьОтличная (CPU, GPU, NPU, mobile)Только NVIDIA GPUТолько NVIDIA GPUЗависит от бэкенда
Производительность (pure GPU)Хорошая, но уступает vLLM при batch > 1Лучшая для throughputЛучшая для latency на NVIDIAБазовая
Простота деплояСредняя (нужен экспорт в ONNX)Высокая (pip install + запуск)Низкая (сборка, настройка)Высокая

Вывод ORT — универсальный инструмент, но не лучший для специализированных сценариев.


7. Когда ORT выгоден для LLM

7.1 Гибридный CPU/GPU деплой

Если часть запросов обрабатывается на CPU (например, при перегрузке GPU), ORT позволяет без переключения модели запускать инференс на обоих устройствах. Это полезно для agentic RAG, где агенты могут динамически выбирать ресурсы.

7.2 Edge-устройства и мобильные платформы

ORT с бэкендами XNNPACK, CoreML, OpenVINO позволяет запускать LLM на Raspberry Pi, iPhone или Intel NUC. Например, Microsoft Phi-3-mini (3.8B) в ONNX формате работает на CPU с задержкой < 1 сек на токен.

7.3 Мультиплатформенная поставка

Если продукт должен работать на Windows, Linux, macOS и Android — ORT единый runtime для всех платформ.

7.4 Сценарии с низкой latency (single request)

Для одного запроса (batch=1) ORT на GPU может быть быстрее vLLM, так как не требует накладных расходов на continuous batching. Это актуально для real-time агентов.

7.5 Интеграция с существующей инфраструктурой

Многие компании уже используют ONNX для других моделей (CV, NLP). Добавление LLM в тот же пайплайн упрощает поддержку.


8. Когда ORT невыгоден для LLM

  • Pure GPU с высокой пропускной способностьюvLLM или TensorRT-LLM дают в 2–5 раз больше токенов в секунду за счёт PagedAttention и continuous batching.
  • Очень большие модели (70B+) — ORT не поддерживает тензорный параллелизм (TP) и pipeline parallelism из коробки. Для таких моделей нужны специализированные системы (vLLM с TP, DeepSpeed).
  • Сложные сэмплинг-стратегии — ORT не поддерживает top-k, top-p, temperature напрямую; требуется обёртка на Python, что добавляет latency.
  • Динамические графы — ORT оптимизирует статический граф. Если модель меняет структуру (например, branching), производительность падает.

9. Интеграция с HuggingFace Optimum и onnxruntime-genai

Optimum — библиотека для экспорта и оптимизации моделей HuggingFace в ONNX. Позволяет одним вызовом export() получить ONNX-модель.

onnxruntime-genai — расширение ORT для генеративных моделей. Добавляет:

  • Кэширование KV-кэша.
  • Поддержку beam search и greedy decoding.
  • Оптимизированные ядра для attention.

Пример запуска LLM через onnxruntime-genai

import onnxruntime_genai as og

model = og.Model("phi-3-mini-onnx")
tokenizer = og.Tokenizer(model)
prompt = "What is ONNX Runtime?"
input_ids = tokenizer.encode(prompt)

params = og.GeneratorParams(model)
params.set_search_options(max_length=200)
params.input_ids = input_ids

generator = og.Generator(model, params)
while not generator.is_done():
    generator.compute_logits()
    generator.generate_next_token()

output = generator.get_sequence(0)
print(tokenizer.decode(output))

10. Практические рекомендации

СценарийРекомендуемый runtime
Сервер NVIDIA GPU, batch > 1vLLM или TensorRT-LLM
Гибрид CPU/GPU, edge, mobileONNX Runtime
Прототипирование, быстрое тестированиеPyTorch eager
Мультиплатформенный продуктONNX Runtime
Максимальная latency на одном запросеONNX Runtime (GPU) или TensorRT-LLM

Пет-проект для закрепления

Задача Развернуть небольшую LLM (например, Phi-3-mini) на CPU с помощью ONNX Runtime и сравнить latency с PyTorch.

Инструменты

  • Python, HuggingFace Transformers, Optimum, ONNX Runtime, onnxruntime-genai.
  • Модель: microsoft/Phi-3-mini-4k-instruct.
  • Метрики: время генерации 100 токенов, пиковое использование памяти.

Шаги:

  1. Экспортировать модель в ONNX через Optimum:
    optimum-cli export onnx --model microsoft/Phi-3-mini-4k-instruct phi-3-onnx
    
  2. Запустить инференс через PyTorch (baseline):
    • Замерить время генерации 100 токенов с generate().
  3. Запустить инференс через ONNX Runtime (onnxruntime-genai):
    • Использовать код из раздела 9.
  4. Применить INT8 квантизацию (Dynamic Quantization) и повторить замеры.
  5. Построить таблицу сравнения:
МетодВремя на токен (ms)Память (GB)
PyTorch FP32457.2
ONNX FP32326.8
ONNX INT8183.5

Ожидаемый результат Ускорение в 2–2.5x на CPU при квантизации, снижение памяти вдвое. Понимание trade-off между точностью и скоростью.


Связь с другими вопросами

ВопросТема
318Что такое vLLM и как он ускоряет инференс LLM?
319TensorRT-LLM: особенности и сравнение с vLLM
321Методы квантизации LLM (GPTQ, AWQ, GGUF)
322Дистилляция знаний для LLM
323Прунинг (pruning) моделей: когда оправдан?
317Развёртывание LLM на edge-устройствах

Навигация