Инференс ONNX-моделей в функциях на Python
Запускайте обученную модель за HTTP-маршрутом без отдельного model server. Среда выполнения — Python 3.12 на glibc (Debian slim), поэтому manylinux-колёса ставятся чисто: объявите onnxruntime, onnx или scikit-learn в inquir.yaml, и деплой их установит. Положите файл модели внутрь функции — он лежит рядом с обработчиком в /var/task, — загрузите его один раз на холодном старте и переиспользуйте в тёплых вызовах. Это инференс на CPU: GPU нет.
Обновлено: 2026-06-28
- Python 3.12 на glibc (Debian slim): manylinux-колёса работают, без ограничений edge-изолятов
- Пакеты в build.dependencies в inquir.yaml: onnxruntime, onnx, scikit-learn
- Модель в /var/task рядом с обработчиком — загрузка один раз на холодном старте, переиспользование в тёплых
- Память 256 МБ по умолчанию (до 2 ГБ); таймаут 5 с по умолчанию, настраивается до 24 ч
Кратко
Суть ответа
Инференс ONNX-моделей в функциях на Python. Inquir запускает Python 3.12 в контейнерах на glibc (Debian slim), поэтому manylinux-колёса ставятся так же, как на обычной Linux-машине. Перечислите onnxruntime, onnx или scikit-learn в build.dependencies в inquir.yaml функции: деплой поставит опубликованные колёса, и класть колесо в исходники не нужно.
Когда подходит
- Инференс по запросу для небольшой или средней модели, экспортированной в ONNX (классификатор, ранкер, голова эмбеддингов)
- Модели scikit-learn или другие CPU-модели, которые нужно выставить за HTTP-маршрутом с авторизацией без model server
- Всплесковый или малообъёмный скоринг, где платить за всегда включённый GPU или контейнер расточительно
На что обратить внимание
- Edge и V8-изоляты вообще не запускают нативные ML-колёса —
onnxruntimeпоставляет скомпилированный бинарник, и изоляты не могут его загрузить. Так что инференс, которому нужен настоящий процесс CPython, в таких средах выполнения недоступен, какой бы маленькой ни была модель. - Даже там, где Python есть, образ на musl (Alpine) ломает готовые manylinux-колёса, которые публикуют
onnxruntimeиscikit-learn: приходится собирать из исходников или фиксировать старые версии. База на glibc — то, что позволяет колёсам ставиться как опубликовано.
Нагрузка и где ломается
Во что обходится одна обученная модель в продакшене
У вас есть обученная модель — классификатор scikit-learn, экспортированный в ONNX, небольшой градиентный ранкер, голова эмбеддингов. Обычно её обслуживание — это контейнер или model server, работающий круглосуточно, рассчитанный на пик и оплачивающий простой между запросами. Для инференса по запросу, в основном всплескового, это слишком много постоянной инфраструктуры ради функции, которая грузит файл и вызывает session.run().
Сама модель небольшая, а код инференса короткий. Не хватает места, где запускать её по требованию: поставить среду выполнения, держать модель в памяти между вызовами, выставить за HTTP-маршрутом с авторизацией и не платить, когда вызовов нет.
Компромиссы
Почему edge и минимальные среды выполнения мешают инференсу
Edge и V8-изоляты вообще не запускают нативные ML-колёса — onnxruntime поставляет скомпилированный бинарник, и изоляты не могут его загрузить. Так что инференс, которому нужен настоящий процесс CPython, в таких средах выполнения недоступен, какой бы маленькой ни была модель.
Даже там, где Python есть, образ на musl (Alpine) ломает готовые manylinux-колёса, которые публикуют onnxruntime и scikit-learn: приходится собирать из исходников или фиксировать старые версии. База на glibc — то, что позволяет колёсам ставиться как опубликовано.
Как помогает Inquir
Python на glibc, где ML-колёса ставятся как опубликованы
Inquir запускает Python 3.12 в контейнерах на glibc (Debian slim), поэтому manylinux-колёса ставятся так же, как на обычной Linux-машине. Перечислите onnxruntime, onnx или scikit-learn в build.dependencies в inquir.yaml функции: деплой поставит опубликованные колёса, и класть колесо в исходники не нужно.
Файл модели едет внутри бандла функции и лежит рядом с обработчиком в /var/task. Загрузите его один раз на уровне модуля — на холодном старте — и тёплый пул контейнеров (от 1 до 8 на функцию) переиспользует загруженную сессию между вызовами, так что при стабильном трафике модель не перечитывается на каждый вызов. Инференс идёт на CPU: GPU на платформе нет, поэтому это подходит для небольших и средних моделей, а не для крупных сетей под GPU.
Что вы получаете
Что покрывает инференс ONNX в функциях
Объявите ONNX Runtime в inquir.yaml
Добавьте onnxruntime (и onnx или scikit-learn при необходимости) в build.dependencies в inquir.yaml — деплой его установит. База на glibc означает, что опубликованное manylinux-колесо грузится как есть.
Модель грузится один раз на холодном старте
Создавайте InferenceSession на уровне модуля. Первый вызов в свежем контейнере оплачивает загрузку; тёплые контейнеры в пуле переиспользуют сессию, так что большинство запросов вообще пропускают загрузку модели.
Инференс за маршрутом с авторизацией
Привяжите обработчик к маршруту шлюза с авторизацией по API-ключу или bearer-токену. Вызывающие шлют признаки JSON-ом по POST; обработчик возвращает предсказания. Память по умолчанию 256 МБ и поднимается до 2 ГБ под крупные модели или батчи.
Батч- или async-инференс
Для одного предсказания отвечайте синхронно в пределах таймаута 5 с по умолчанию. Для объёмного скоринга, который идёт дольше, примите запрос, верните 202 и запускайте инференс в шаге пайплайна (таймаут шага настраивается до 24 часов).
Что дальше
Как обслужить ONNX-модель как функцию
Экспортируйте модель в ONNX, отправьте её с обработчиком, объявите ONNX Runtime в inquir.yaml и выставьте за маршрутом.
Экспортируйте и отправьте модель
Экспортируйте обученную модель в ONNX (например, через skl2onnx для оценщика scikit-learn). Положите файл .onnx в бандл функции, чтобы он попал в /var/task рядом с обработчиком.
Объявите ONNX Runtime и загрузите модель один раз
Объявите onnxruntime в build.dependencies в inquir.yaml. Создайте InferenceSession на уровне модуля, указав путь к модели в /var/task, чтобы она грузилась на холодном старте и оставалась в тёплых контейнерах.
Выставьте и наблюдайте
Привяжите обработчик к маршруту шлюза с авторизацией по API-ключу. Каждый вызов даёт запись прогона — длительность, статус, логи, — чтобы видеть задержку холодного и тёплого пути в истории выполнения.
Пример кода
Обработчик инференса ONNX: загрузка один раз, запуск на каждый запрос
Модель грузится во время импорта (холодный старт) и переиспользуется каждым тёплым вызовом. Обработчик читает признаки из тела запроса и возвращает предсказания. Файл модели лежит рядом с этим обработчиком в /var/task.
# Python 3.12 on glibc (Debian slim) — manylinux wheels install as published. build: dependencies: - onnxruntime>=1.20 - numpy>=1.26
import os import json import numpy as np import onnxruntime as ort # Loaded ONCE on cold start, at module scope. # The model ships inside the function and lives next to this handler in /var/task. MODEL_PATH = os.path.join(os.path.dirname(__file__), "model.onnx") _session = ort.InferenceSession(MODEL_PATH, providers=["CPUExecutionProvider"]) # CPU only — no GPU _input_name = _session.get_inputs()[0].name def handler(event, context): body = json.loads(event.get("body") or "{}") features = body.get("features") if not features: return {"statusCode": 400, "body": json.dumps({"error": "features required"})} x = np.asarray(features, dtype=np.float32) if x.ndim == 1: x = x.reshape(1, -1) # single row -> batch of 1 # Warm containers reuse _session — no per-request model load. outputs = _session.run(None, {_input_name: x}) predictions = outputs[0].tolist() return {"statusCode": 200, "body": json.dumps({"predictions": predictions})}
Когда подходит
Когда уместен инференс ONNX в функциях
Когда это уместно
- Инференс по запросу для небольшой или средней модели, экспортированной в ONNX (классификатор, ранкер, голова эмбеддингов)
- Модели scikit-learn или другие CPU-модели, которые нужно выставить за HTTP-маршрутом с авторизацией без model server
- Всплесковый или малообъёмный скоринг, где платить за всегда включённый GPU или контейнер расточительно
Когда лучше выбрать другое
- Крупные модели под GPU или низколатентное высоконагруженное обслуживание — GPU нет, а холодные старты на CPU реальны
Частые вопросы
Частые вопросы
Какая версия Python и базовый образ запускают модель?
Python 3.12 на glibc (Debian slim). Поскольку база — glibc, manylinux-колёса, которые публикуют onnxruntime, onnx и scikit-learn, ставятся и грузятся как есть — без сборки из исходников и без поломок колёс на Alpine/musl.
Как затащить onnxruntime в функцию?
Объявите его в inquir.yaml функции: build.dependencies: ["onnxruntime>=1.20"], плюс onnx или scikit-learn, если нужны. Деплой ставит список через pip; упаковывать ничего вручную не нужно.
Где лежит файл модели и когда он грузится?
Отправьте файл .onnx внутри бандла функции — он попадает рядом с обработчиком в /var/task. Создавайте InferenceSession на уровне модуля, чтобы он грузился один раз на холодном старте; тёплые контейнеры в пуле переиспользуют загруженную сессию между вызовами.
Есть ли GPU?
Нет. Инференс идёт на CPU (CPUExecutionProvider). Это подходит для небольших и средних моделей и оценщиков уровня scikit-learn. Крупные сети под GPU и обучение для этой платформы не подходят.
Какие лимиты памяти и таймаута?
Память по умолчанию 256 МБ и поднимается до 2 ГБ под крупные модели или батчи. Таймаут функции по умолчанию 5 с и настраивается до 24 часов. Для объёмного скоринга дольше этого верните 202 и запускайте инференс в шаге пайплайна.