Установка и первый запуск: npm, CDN, сборщики

Подключение ONNX Runtime Web через npm

Для интеграции ONNX Runtime Web в проект на JavaScript самым распространённым способом является использование npm. Пакет предоставляет удобный интерфейс для работы с нейронными сетями в браузере и поддерживает различные бэкенды: WebAssembly (WASM) и WebGL.

Установка через npm выполняется командой:

npm install onnxruntime-web

После установки пакет можно импортировать в код следующим образом:

import * as ort from 'onnxruntime-web';

Или, при использовании CommonJS:

const ort = require('onnxruntime-web');

Особенности:

  • ort предоставляет основной API для создания сессий, загрузки моделей и выполнения инференса.
  • Поддерживаются асинхронные операции, что особенно важно для браузерной среды, чтобы не блокировать основной поток.

Использование через CDN

Для быстрого тестирования и интеграции без сборщика можно подключить ONNX Runtime Web через CDN:

После подключения объект ort становится доступен глобально:

const session = await ort.InferenceSession.create('model.onnx');

Преимущества CDN:

  • Нет необходимости настраивать сборщик или устанавливать npm-пакет.
  • Удобно для прототипов и демонстраций.

Недостатки:

  • Меньший контроль над версией пакета.
  • Зависимость от внешнего источника, что может быть критично для продакшена.

Интеграция с современными сборщиками

ONNX Runtime Web совместим с основными сборщиками JavaScript, такими как Webpack, Vite, Rollup.

Пример конфигурации для Webpack:

// webpack.config.js
module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'bundle.js',
    path: __dirname + '/dist'
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: 'babel-loader'
      }
    ]
  },
  resolve: {
    fallback: {
      fs: false,
      path: require.resolve('path-browserify')
    }
  }
};

Особенности сборки:

  • Пакет содержит WASM-модули, которые Webpack корректно инлайнит или копирует в dist.
  • Для WebGL-бэкенда требуется проверка поддержки браузера и корректная настройка шейдеров.
  • При использовании TypeScript необходимо подключить типы, предоставляемые вместе с пакетом.

Создание сессии инференса

Основной шаг после установки — создание InferenceSession:

const session = await ort.InferenceSession.create('model.onnx', {
  executionProviders: ['wasm'], // или 'webgl'
  graphOptimizationLevel: 'all'
});

Ключевые параметры:

  • executionProviders — массив провайдеров выполнения. Возможные значения: 'wasm', 'webgl', 'cpu' (в некоторых сборках).
  • graphOptimizationLevel — уровень оптимизации графа модели. Возможные значения: 'disabled', 'basic', 'extended', 'all'.

Подготовка данных для инференса

Данные передаются в виде объекта feeds, где ключи соответствуют именам входов модели:

const tensor = new ort.Tensor('float32', new Float32Array([1, 2, 3, 4]), [2, 2]);
const feeds = { input_name: tensor };

const results = await session.run(feeds);

Особенности работы с тензорами:

  • ort.Tensor требует указания типа данных (float32, int32 и др.), массива значений и формы (shape).
  • Браузерные ограничения могут влиять на размер массивов, особенно при WebGL.

Загрузка модели и обработка ошибок

ONNX Runtime Web поддерживает загрузку моделей как с локального сервера, так и по URL. Важно правильно обрабатывать возможные ошибки:

try {
  const session = await ort.InferenceSession.create('https://example.com/model.onnx');
} catch (e) {
  console.error('Ошибка загрузки модели:', e);
}

Типичные причины ошибок:

  • Несовместимость модели с выбранным execution provider.
  • Ошибки при загрузке через CORS.
  • Некорректная структура тензоров при запуске инференса.

Советы по производительности

  • Использование WebGL может ускорить выполнение, но требует поддержки браузера.
  • Оптимизация модели через ONNX Graph Optimization Toolkit уменьшает время инференса.
  • Разделение больших данных на батчи предотвращает зависание интерфейса.

Интеграция в клиентские приложения

ONNX Runtime Web легко интегрируется с фреймворками вроде React или Vue. Пример асинхронного вызова в компоненте:

useEffect(() => {
  async function runModel() {
    const session = await ort.InferenceSession.create('/model.onnx');
    const input = new ort.Tensor('float32', new Float32Array([1,2,3,4]), [2,2]);
    const result = await session.run({ input_name: input });
    console.log(result);
  }
  runModel();
}, []);

Особенности:

  • Все операции асинхронные, что предотвращает блокировку рендеринга.
  • Можно использовать хуки состояния для хранения результатов инференса.