Структура .onnx файла: protobuf, граф, узлы, тензоры

ONNX (Open Neural Network Exchange) представляет собой открытый формат для описания моделей машинного обучения, который обеспечивает переносимость между различными фреймворками. Основой формата является файл с расширением .onnx, который структурирован на базе протокола Protocol Buffers (protobuf) и содержит описание вычислительного графа, его узлов, входных и выходных тензоров, а также метаданных модели.

Protocol Buffers (Protobuf)

Файлы ONNX сериализованы с использованием protobuf — эффективного бинарного формата для хранения структурированных данных. Преимущества protobuf:

  • Компактность и скорость: бинарная сериализация значительно быстрее текстовой и требует меньше памяти.
  • Строгая схема данных: каждая модель описывается набором заранее определённых сообщений (messages), что упрощает валидацию.
  • Совместимость версий: protobuf поддерживает расширение схем без нарушения совместимости с предыдущими версиями.

В контексте ONNX protobuf хранит следующие ключевые структуры:

  • ModelProto: корневой объект модели, включающий описание графа и метаданных.
  • GraphProto: вычислительный граф, содержащий узлы, входы и выходы.
  • NodeProto: отдельные операции (операторы), их атрибуты и связи с тензорами.
  • TensorProto: данные тензоров, включая тип, размерность и содержимое.

Вычислительный граф (Graph)

В ONNX каждая модель представлена ориентированным ациклическим графом (DAG), где:

  • Узлы (NodeProto) представляют операции или слои модели, например, Conv, Relu, MatMul.
  • Рёбра графа — это тензоры, соединяющие выходы одного узла с входами другого.
  • Входы и выходы графа (ValueInfoProto) описывают типы данных и размерности тензоров, которые подаются на вход модели или извлекаются как результат вычислений.

Структура GraphProto включает:

  • node: массив NodeProto, описывающий последовательность операций.
  • initializer: массив TensorProto для хранения весов и констант.
  • input и output: массивы ValueInfoProto, определяющие интерфейс модели.
  • value_info: дополнительные промежуточные тензоры для оптимизации и отладки.

Узлы (NodeProto)

Каждый узел графа описывает единичную операцию, которая может иметь несколько входов и выходов. Основные компоненты NodeProto:

  • op_type: тип операции, например, Conv, Add, Softmax.
  • input и output: массивы строк с именами входных и выходных тензоров.
  • attribute: массив атрибутов, специфичных для конкретной операции (например, ядро свертки или коэффициенты нормализации).
  • name и doc_string: опциональные поля для идентификации и документации узла.

Особенность ONNX заключается в том, что узлы не содержат данные напрямую, кроме константных тензоров, которые помещаются в initializer. Это позволяет отделять структуру вычислений от параметров модели.

Тензоры (TensorProto)

Тензоры в ONNX — это фундаментальные объекты, через которые передаются данные между узлами. TensorProto описывает:

  • Тип данных (data_type): например, FLOAT, INT32, UINT8.
  • Размерность (dims): массив целых чисел, определяющий форму тензора.
  • Сами данные (raw_data или массивы конкретного типа, таких как float_data).
  • Имя (name), связывающее тензор с узлами графа.

Тензоры, находящиеся в initializer, содержат постоянные параметры модели, такие как веса сверточных слоев, а остальные тензоры создаются динамически во время выполнения графа.

Связь компонентов

  • ModelProto объединяет все элементы и хранит глобальные метаданные.
  • GraphProto описывает структуру вычислений внутри модели.
  • NodeProto представляет отдельные операции графа.
  • TensorProto хранит данные, передаваемые между узлами.

Эта иерархия обеспечивает гибкость и совместимость ONNX с различными средами выполнения, включая ONNX Runtime Web, где вычисления выполняются прямо в браузере через JavaScript.

Особенности для ONNX Runtime Web

ONNX Runtime Web позволяет запускать модели ONNX в браузере:

  • Используется WebAssembly (WASM) или WebGPU для ускорения вычислений.
  • Модель загружается как бинарный .onnx файл, который затем десериализуется в объекты NodeProto и TensorProto.
  • Узлы графа выполняются последовательно, передавая тензоры между операциями, что полностью повторяет вычислительный граф, описанный в ModelProto.
  • Оптимизации графа и поддержка различных типов данных позволяют эффективно использовать ресурсы браузера без сервера.

Этот подход делает ONNX Runtime Web мощным инструментом для запуска глубоких нейронных сетей и моделей машинного обучения непосредственно на клиенте, сохраняя точность вычислений, заданную структурой .onnx файла.