Гайд · TNWS AI

Как узнать имя, форму и тип входа ONNX-модели

4 мин—

Инспекция get_inputs и get_outputs в ONNX Runtime: имена, динамическая batch-размерность, tensor(float), точный тест и ошибки предположений.

Задача и применимость

Актуальный запрос: «как узнать input name shape type ONNX Runtime». Получить контракт модели до подготовки данных. session.get_inputs() и get_outputs() возвращают метаданные, включая name, shape и type. В тестовой модели вход x имеет форму [None,2]: первая размерность динамическая, вторая обязана равняться двум. Тип — tensor(float), то есть float32 в NumPy для этого примера. Материал сверён 26 сентября 2026 года с официальной документацией ONNX Runtime и фактически проверяется на ONNX Runtime 1.30.0, ONNX 1.19.0 и NumPy 2.3.5. Тестовая модель создаётся локально и не скачивает веса.

Пошаговое выполнение

  1. Загрузите модель в InferenceSession.
  2. Получите первый NodeArg через get_inputs.
  3. Сравните name, shape и type с ожидаемым контрактом.
  4. Постройте preprocessing по этим данным и отдельно проверьте outputs.

Сначала запускайте пример во временном каталоге. Для реальной модели зафиксируйте checksum, opset, версию exporter и preprocessing. ONNX Runtime исполняет граф, но не знает предметного смысла признаков, поэтому одинаковая shape ещё не доказывает правильную подготовку данных.

Готовый проверяемый шаблон

import tempfile
from pathlib import Path
import numpy as np
import onnx
from onnx import TensorProto, helper
import onnxruntime as ort

tmp = Path(tempfile.mkdtemp())
model_path = tmp / "add.onnx"
x_info = helper.make_tensor_value_info("x", TensorProto.FLOAT, [None, 2])
y_info = helper.make_tensor_value_info("y", TensorProto.FLOAT, [None, 2])
bias = helper.make_tensor("bias", TensorProto.FLOAT, [2], [1.0, -1.0])
node = helper.make_node("Add", ["x", "bias"], ["y"])
graph = helper.make_graph([node], "add_graph", [x_info], [y_info], [bias])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
onnx.checker.check_model(model)
onnx.save(model, model_path)
session = ort.InferenceSession(str(model_path), providers=["CPUExecutionProvider"])
inp = session.get_inputs()[0]
out = session.get_outputs()[0]
print(inp.name, inp.shape, inp.type)
assert inp.name == "x"
assert inp.shape == [None, 2]
assert inp.type == "tensor(float)"
assert out.name == "y"

Вход и ожидаемые данные

Ожидаемые метаданные входа: имя x, форма [None,2], тип tensor(float). Выход называется y. None не означает пустой тензор: это динамическое значение batch-размерности. Массив формы (3,2) допустим по схеме, а (1,3) — нет.

Проверка результата

Запишите контракт при сборке артефакта и сравнивайте его на старте сервиса. Для многовходовой модели не берите безусловно индекс 0: составьте словарь по именам и проверьте каждое поле. После замены версии модели тест должен обнаружить переименование или новую размерность до первого пользовательского запроса. Перед рабочим применением повторите проверку на точных входах экспортированной нейросети: универсальный пример не заменяет контракт конкретного артефакта. Сохраните минимальный воспроизводимый вход, чтобы сравнить старую и новую версии без персональных данных.

Как перенести пример на настоящую нейросеть

Заменяйте учебный граф только после того, как базовый пример проходит полностью. Получите имена, типы и формы через API сессии, затем воспроизведите тот же preprocessing, который использовался при обучении или экспорте. Для изображения это включает порядок каналов, resize, нормализацию и цветовое пространство; для текста — конкретный tokenizer, специальные токены, padding и attention mask. Эти параметры не восстанавливаются надёжно по одной форме tensor. Храните конфигурацию рядом с моделью и версионируйте её вместе с ONNX-файлом. Сначала сравните ONNX output с исходным framework на одинаковых входах, а затем отдельно проверяйте предметную метрику: accuracy, F1, Recall@k или другую заранее выбранную величину.

Критерии приёмки

  1. Модель проходит onnx.checker и загружается выбранным provider.
  2. dtype, rank, shape и имена совпадают с метаданными.
  3. Положительный вход совпадает с численным эталоном.
  4. Негативный вход вызывает ожидаемую ошибку, а не случайный результат.
  5. Тест повторяется после смены модели, runtime или provider.

Регрессионный протокол

Сохраните версии пакетов, providers, имена tensor, shape и dtype. Используйте минимум пять входов: стандартный, другой batch, нули, отрицательные значения и граничный допустимый диапазон. Сравнивайте outputs с эталонной реализацией и явно задавайте абсолютный и относительный допуск. Измерение производительности отделяйте от проверки точности: сначала докажите эквивалентность, затем делайте прогрев и много повторов. Не выбирайте лучший прогон вручную — публикуйте p50, p95 и условия машины. Ошибка одного теста должна блокировать замену модели, но не требует останавливать независимые сервисы.

Диагностика расхождений

Если значения отличаются, локализуйте слой по порядку: исходный файл, preprocessing, dtype и shape, выбранный provider, затем численная точность операторов. Сохраните небольшой обезличенный вход и outputs обеих реализаций. Не начинайте с увеличения допуска: так можно скрыть переставленные каналы или неверную токенизацию. Для динамического batch проверяйте каждую строку отдельно и вместе, чтобы обнаружить ошибочную зависимость между элементами. Для stateful preprocessing сбрасывайте состояние между тестами. После исправления повторите весь набор, включая негативные случаи, а не только один пример, который раньше падал.

Типичные ошибки и чего не делать

  • Не считайте None нулевой длиной измерения.
  • Не предполагайте имя input_ids для любой модели.
  • Не игнорируйте порядок и число выходов.

Не изменяйте модель, dtype или форму случайными преобразованиями, лишь бы исчезло исключение. Не используйте вход из недоверенного источника без ограничений размера: огромный tensor способен исчерпать память. Не выдавайте арифметический мини-граф за оценку качества настоящей нейросети.

FAQ

Что возвращает get_inputs?

Список объектов метаданных входов.

Что значит tensor(float)?

32-битный floating-point tensor ONNX.

Как трактовать None в shape?

Как динамическую размерность, значение задаёт конкретный вход.

Официальные источники

Частые вопросы

Что возвращает get_inputs?

Список объектов метаданных входов.

Что значит tensor(float)?

32-битный floating-point tensor ONNX.

Как трактовать None в shape?

Как динамическую размерность, значение задаёт конкретный вход.

Читайте также

Комментарии

Пока тихо. Скажите первое слово