Использование внешних данных: external_data в ONNX

ONNX-модели могут содержать большие бинарные данные, такие как веса нейронной сети, которые не всегда удобно хранить внутри одного файла .onnx. Для решения этой проблемы используется механизм external_data, позволяющий разделять модель и её большие параметры на отдельные файлы. В контексте ONNX Runtime Web это обеспечивает эффективную загрузку и работу с моделями в браузере или Node.js.

Структура external_data

Внутри ONNX-файла, использующего external_data, метаданные модели содержат ссылки на внешние бинарные файлы. Каждое тензорное поле, которое хранит большие данные, может иметь следующую структуру:

EXTERNAL

  location
  weights_0.data


  offset
  0


  length
  123456

Ключевые атрибуты:

  • location — имя файла с данными.
  • offset — смещение в файле, откуда начинаются данные тензора.
  • length — размер данных тензора в байтах.
  • checksum (необязательный) — контрольная сумма для проверки целостности.

Файл .onnx в этом случае содержит только описание структуры модели, а весовые коэффициенты хранятся в отдельных бинарных файлах.

Загрузка моделей с external_data в ONNX Runtime Web

ONNX Runtime Web поддерживает загрузку моделей с внешними данными через стандартные методы InferenceSession.create или session.loadModel. Основное отличие — необходимость правильно передавать путь к бинарным файлам.

Пример загрузки модели в браузере
import * as ort from 'onnxruntime-web';

async function loadModel() {
  // Путь к файлу модели
  const modelUrl = 'model.onnx';

  // Опции для загрузки модели с external_data
  const session = await ort.InferenceSession.create(modelUrl, {
    executionProviders: ['wasm'], // или 'webgl'
    graphOptimizationLevel: 'all',
  });

  return session;
}

Важный момент: при использовании external_data все бинарные файлы должны быть доступны по тому же пути, что указан в метаданных модели. ONNX Runtime автоматически подставляет их при инициализации сессии.

Пример загрузки модели в Node.js
import * as ort from 'onnxruntime-node';
import fs from 'fs';

async function loadModel() {
  const modelBuffer = fs.readFileSync('model.onnx');
  const session = await ort.InferenceSession.create(modelBuffer);
  return session;
}

В Node.js возможна загрузка как из буфера, так и напрямую с файловой системы, при этом external_data файлы должны находиться в том же каталоге, что и основной .onnx.

Преимущества использования external_data

  1. Разделение модели и данных — позволяет хранить тяжёлые веса отдельно, уменьшая размер основного .onnx файла.
  2. Поддержка больших моделей — ONNX Runtime Web ограничен размером загружаемых файлов, а external_data позволяет обойти это ограничение.
  3. Удобство версионирования — веса и структура модели можно обновлять отдельно.
  4. Эффективная загрузка в браузере — можно загружать отдельные чанки данных по мере необходимости, экономя трафик и время инициализации.

Ограничения и особенности

  • Все external_data файлы должны быть доступны по URL или локальному пути одновременно с .onnx.
  • Некоторые инструменты экспорта могут не поддерживать external_data для всех типов данных, поэтому рекомендуется проверять совместимость.
  • Контрольная сумма не проверяется автоматически в ONNX Runtime Web, её проверка должна выполняться вручную при необходимости.
  • При переносе модели на сервер или в другую среду пути к внешним файлам должны быть скорректированы.

Работа с external_data при конвертации моделей

Для моделей, созданных в PyTorch или TensorFlow, рекомендуется использовать флаг --external_data_format при экспорте через onnx.export или tf2onnx.convert, чтобы крупные веса автоматически сохранялись в отдельные файлы. Это особенно актуально для больших сетей типа ResNet, GPT или других трансформеров.

torch.onnx.export(
    model,
    dummy_input,
    "model.onnx",
    export_params=True,
    use_external_data_format=True
)

Итоговая структура проекта с external_data

project/
├─ model.onnx
├─ weights_0.data
├─ weights_1.data
├─ weights_2.data
└─ ...

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