ONNX Runtime Web (ORT Web) предоставляет средства для выполнения моделей ONNX непосредственно в браузере или на Node.js, что позволяет создавать приложения с высокой производительностью без необходимости обращения к серверу. Одной из ключевых возможностей является организация многоэтапного инференса, где несколько моделей работают последовательно или параллельно, обмениваясь данными.
Каждая модель загружается через объект OrtSession,
который предоставляет интерфейс для выполнения инференса. Для
многоэтапного инференса требуется:
import * as ort from 'onnxruntime-web';
const sessionOptions = { executionProviders: ['wasm'] };
// Загрузка первой модели
const session1 = await ort.InferenceSession.create('model1.onnx', sessionOptions);
// Загрузка второй модели
const session2 = await ort.InferenceSession.create('model2.onnx', sessionOptions);
Ключевой момент: каждая модель создается отдельной сессией. Это позволяет гибко управлять памятью и ресурсами, особенно при работе с большими моделями.
При многоэтапном инференсе важно корректно трансформировать выход
одного этапа в формат, ожидаемый следующим. Для этого используется
структура ort.Tensor.
const inputTensor1 = new ort.Tensor('float32', inputData1, [batchSize, featureSize]);
// Выполнение инференса первой модели
const output1 = await session1.run({ input: inputTensor1 });
// Подготовка входа для второй модели
const processedData = preprocessForSecondModel(output1.output);
const inputTensor2 = new ort.Tensor('float32', processedData, [batchSize, newFeatureSize]);
const output2 = await session2.run({ input: inputTensor2 });
Важное замечание: размерности и типы тензоров должны полностью соответствовать спецификации модели. Любое несоответствие приведет к ошибкам выполнения.
Для упрощения работы можно реализовать обертку, которая управляет несколькими сессиями и автоматически передает данные между этапами:
class Pipeline {
constructor(models) {
this.sessions = models;
}
async run(input) {
let currentInput = input;
for (const session of this.sessions) {
const tensor = new ort.Tensor('float32', currentInput.data, currentInput.shape);
const output = await session.run({ input: tensor });
currentInput = processOutput(output.output);
}
return currentInput;
}
}
Особенность: такой подход облегчает расширение цепочки до любой длины и позволяет централизованно обрабатывать ошибки и логирование.
В веб-среде критически важно использовать асинхронные операции. В ORT
Web все вызовы session.run возвращают промисы, что
обеспечивает нен блокирующее выполнение:
const [result1, result2] = await Promise.all([
session1.run({ input: tensor1 }),
session2.run({ input: tensor2 })
]);
Совет по оптимизации: при параллельном выполнении моделей следует учитывать нагрузку на основной поток браузера. Web Workers могут быть использованы для изоляции тяжелых вычислений.
Типичный сценарий многоэтапного инференса — использование специализированных моделей для разных задач: предварительная обработка, детекция объектов, классификация. Выход одной модели может быть картой признаков, которая подается на вход другой модели:
const features = await featureExtractor.run({ input: inputTensor });
const detectionInput = new ort.Tensor('float32', features.output.data, features.output.dims);
const detections = await objectDetector.run({ input: detectionInput });
Вывод: разделение задач между моделями повышает модульность и позволяет легче обновлять отдельные компоненты без перестройки всей системы.
ORT Web использует WebAssembly и WebGL для ускорения вычислений. При многоэтапном инференсе следует учитывать:
session.run.Ошибки при многоэтапном инференсе чаще всего связаны с несовпадением форматов данных. Рекомендуется:
tensor.dims и tensor.type после
каждого этапа.debug: true при создании сессий для
расширенной информации об исполнении.Многоэтапный инференс может быть интегрирован в веб-приложение через асинхронные функции, промисы и Web Workers. Это позволяет: