ONNX Runtime Web (ORT Web) предоставляет возможность запуска моделей машинного обучения в браузере и в Node.js. Основной способ установки — через npm:
npm install onnxruntime-web
Подключение в JavaScript осуществляется через импорт:
import * as ort from 'onnxruntime-web';
Для работы с WebAssembly (WASM) и WebGL доступны различные бэкенды, которые позволяют оптимизировать производительность на различных устройствах.
Сессия ONNX Runtime Web создается через конструктор
InferenceSession. Для веб-приложений модель можно загрузить
напрямую с сервера или из локального файла:
const session = await ort.InferenceSession.create('model.onnx', {
executionProviders: ['wasm'] // 'webgl' для ускорения через GPU
});
Ключевой параметр executionProviders определяет
используемый движок выполнения. Выбор между WASM и WebGL зависит от
требуемой производительности и доступных ресурсов устройства.
Для эффективной работы с большими данными в браузере часто требуется передавать массивы между потоками без копирования. Здесь важную роль играют объекты Transferable и SharedArrayBuffer.
Transferable объекты позволяют перемещать память из одного потока в
другой без дублирования. Основной пример — ArrayBuffer:
const buffer = new ArrayBuffer(1024);
worker.postMessage(buffer, [buffer]);
console.log(buffer.byteLength); // 0, память передана
После передачи оригинальный объект теряет доступ к памяти, что предотвращает лишнее копирование и снижает нагрузку на сборщик мусора.
ORT Web поддерживает передачу данных модели через Transferable
объекты. Например, входные тензоры можно упаковать в
Float32Array и передать в воркер:
const inputTensor = new ort.Tensor('float32', new Float32Array([1, 2, 3, 4]), [2, 2]);
worker.postMessage({ tensor: inputTensor.data.buffer }, [inputTensor.data.buffer]);
Если требуется одновременное чтение и запись данных из разных
потоков, используют SharedArrayBuffer. Этот объект не
теряет доступ при передаче между потоками и позволяет организовать
синхронизацию через атомарные операции:
const sharedBuffer = new SharedArrayBuffer(1024 * 4);
const sharedArray = new Float32Array(sharedBuffer);
sharedArray[0] = 42;
worker.postMessage({ buffer: sharedBuffer });
Использование SharedArrayBuffer важно для сценариев с
большим объемом данных, где необходимо минимизировать накладные расходы
на копирование.
ORT Web поддерживает работу с SharedArrayBuffer и
Transferable объектами для входных и выходных тензоров. Пример создания
тензора с SharedArrayBuffer:
const sharedData = new SharedArrayBuffer(Float32Array.BYTES_PER_ELEMENT * 4);
const inputTensor = new ort.Tensor('float32', new Float32Array(sharedData), [2, 2]);
const feeds = { input: inputTensor };
const results = await session.run(feeds);
const outputTensor = results.output;
console.log(outputTensor.data);
Преимущество такого подхода — возможность многопоточной подготовки данных и минимизация задержек при взаимодействии с моделью.
Для оптимальной производительности часто применяют воркеры:
const worker = new Worker('worker.js');
worker.onmess age = (event) => {
const outputTensor = new ort.Tensor('float32', new Float32Array(event.data.buffer), [2, 2]);
console.log(outputTensor.data);
};
const inputData = new Float32Array([1, 2, 3, 4]);
worker.postMessage({ buffer: inputData.buffer }, [inputData.buffer]);
Асинхронное использование позволяет одновременно выполнять предобработку данных и инференс, что критично для приложений с высокой частотой обновления.
ArrayBuffer с
Transferable объектами.SharedArrayBuffer.SharedArrayBuffer, чтобы избежать гонок данных.Эти методы позволяют максимально эффективно использовать ONNX Runtime Web в высоконагруженных браузерных приложениях.