ONNX Runtime Web (ORT Web) предоставляет гибкие возможности для загрузки и исполнения моделей машинного обучения прямо в браузере на JavaScript. При работе с крупными моделями критическим аспектом становится оптимизация времени загрузки и экономия ресурсов устройства. Lazy loading и разбиение модели позволяют управлять этим процессом эффективно, уменьшая начальную задержку и повышая отзывчивость приложения.
Lazy loading — это отложенная загрузка ресурсов, которая позволяет загружать модель или её части только в момент необходимости, а не сразу при инициализации приложения. В контексте ONNX Runtime Web это означает, что модель не загружается полностью при старте, а частично или по запросу.
Основные преимущества:
Пример использования ORT Web с lazy loading:
import * as ort from 'onnxruntime-web';
async function runInference() {
// Создание сессии без немедленной загрузки модели
const session = await ort.InferenceSession.create(
'model.onnx',
{ executionProviders: ['wasm'], enableLazyInitialization: true }
);
// Подготовка входных данных
const inputTensor = new ort.Tensor('float32', new Float32Array([1, 2, 3, 4]), [2, 2]);
// Модель загружается и выполняется только при вызове run()
const feeds = { input: inputTensor };
const results = await session.run(feeds);
console.log(results.output.data);
}
Ключевым моментом является использование опции
enableLazyInitialization: true. Она откладывает загрузку и
компиляцию модели до момента первого выполнения
session.run().
При работе с крупными моделями размером сотни мегабайт целесообразно применять модульное разбиение модели. Это позволяет загружать и исполнять только необходимую часть модели, что особенно важно для веб-приложений с ограниченной пропускной способностью сети и ресурсами устройства.
Способы разбиения модели:
Сегментация графа Модель разбивается на несколько ONNX файлов, каждый из которых выполняет отдельный блок вычислений. Например, при классификации изображений можно выделить предварительную обработку, основной нейронный блок и post-processing в отдельные модели.
Использование subgraphs и custom operators Сложные операции можно вынести в отдельные подграфы с собственными вычислительными операторами, которые подключаются только при необходимости.
Динамическая загрузка подмоделей JavaScript-код управляет загрузкой подмоделей по мере выполнения цепочки вычислений:
async function runSegmentedModel() {
const preprocessor = await ort.InferenceSession.create('preprocessor.onnx');
const coreModel = await ort.InferenceSession.create('core_model.onnx', { enableLazyInitialization: true });
const postprocessor = await ort.InferenceSession.create('postprocessor.onnx');
const inputTensor = new ort.Tensor('float32', new Float32Array([1, 2, 3, 4]), [2, 2]);
const preprocessed = await preprocessor.run({ input: inputTensor });
const coreOutput = await coreModel.run({ input: preprocessed.output });
const finalOutput = await postprocessor.run({ input: coreOutput.output });
console.log(finalOutput.output.data);
}
Такой подход позволяет загружать только те части модели, которые нужны на текущем этапе выполнения, минимизируя задержку и нагрузку на память.
Параллельная загрузка подмоделей: Сессии моделей можно создавать асинхронно в фоне, чтобы подготовить их к моменту выполнения. Это особенно важно для web-приложений с интерактивным интерфейсом.
Использование WebAssembly и WebGPU: В ORT Web
поддерживаются различные провайдеры выполнения (wasm,
webgl, webgpu). Lazy loading позволяет
выбирать провайдер на лету, загружая оптимизированные бинарные файлы для
конкретного устройства.
Кэширование ресурсов: Подмодели можно кэшировать в IndexedDB или в памяти браузера, чтобы повторная загрузка была мгновенной.
Эти подходы позволяют создавать высокопроизводительные веб-приложения с машинным обучением, где тяжелые модели не становятся узким местом, а их использование становится управляемым и предсказуемым.