ONNX Runtime Web (ORT Web) предоставляет возможности запуска моделей машинного обучения непосредственно в браузере с использованием JavaScript. Особое внимание уделяется обработке асинхронных операций и управлению конкурентными запросами, что критично для производительных веб-приложений, работающих с нейросетевыми моделями.
Асинхронный инференс позволяет выполнять предсказания модели без
блокировки основного потока выполнения JavaScript, что особенно важно в
однопоточном окружении браузера. В ORT Web это реализуется через
использование промисов и async/await.
Создание сессии асинхронно:
import * as ort from 'onnxruntime-web';
async function createSession(modelUrl) {
const session = await ort.InferenceSession.create(modelUrl, {
executionProviders: ['wasm', 'webgl'] // Выбор провайдера вычислений
});
return session;
}
Параметр executionProviders определяет способ выполнения
модели:
wasm — WebAssembly, обеспечивает кроссплатформенность и
стабильность, но медленнее GPU.webgl — использование GPU через WebGL, ускоряет
вычисления на графическом процессоре.Асинхронное создание сессии важно для загрузки больших моделей без блокировки интерфейса.
Асинхронный вызов инференса:
async function runInference(session, inputData) {
const feeds = { input: new ort.Tensor('float32', inputData, [1, 3, 224, 224]) };
const results = await session.run(feeds);
return results.output.data;
}
Особенности:
session.run(feeds) возвращает промис, который
разрешается после завершения инференса.float32, int32) и форма (shape)
должны совпадать с определением модели.В реальных приложениях может потребоваться запуск нескольких инференсов параллельно. ORT Web позволяет управлять конкурентными запросами, но существует несколько важных ограничений.
Ограничения конкуренции:
run из разных потоков.Пример организации очереди запросов:
class InferenceQueue {
constructor(session) {
this.session = session;
this.queue = [];
this.running = false;
}
enqueue(inputData) {
return new Promise((resolve, reject) => {
this.queue.push({ inputData, resolve, reject });
this.processQueue();
});
}
async processQueue() {
if (this.running || this.queue.length === 0) return;
this.running = true;
const { inputData, resolve, reject } = this.queue.shift();
try {
const result = await runInference(this.session, inputData);
resolve(result);
} catch (error) {
reject(error);
} finally {
this.running = false;
this.processQueue();
}
}
}
Преимущества такого подхода:
session.run одной
сессии.Для действительно высокой нагрузки рекомендуется создавать пул сессий:
async function createSessionPool(modelUrl, poolSize) {
const sessions = [];
for (let i = 0; i < poolSize; i++) {
const session = await createSession(modelUrl);
sessions.push(session);
}
return sessions;
}
function getNextSession(sessions) {
const session = sessions.shift();
sessions.push(session);
return session;
}
Использование пула позволяет:
Ключевые подходы к оптимизации:
async/await для вызова
session.run, чтобы избежать блокировки UI.Асинхронный инференс и грамотное управление конкурентными запросами являются критически важными аспектами при работе с ONNX Runtime Web, позволяя строить высокопроизводительные и отзывчивые веб-приложения для обработки нейросетевых моделей.