ONNX Runtime Web (ORT Web) представляет собой высокопроизводительную библиотеку для запуска моделей ONNX непосредственно в браузере или в среде Node.js. Основной задачей ORT Web является выполнение инференса с использованием различных бэкендов, таких как WebAssembly (WASM) и WebGPU, обеспечивая при этом переносимость моделей и минимальные накладные расходы на инфраструктуру.
Модель в ONNX загружается через InferenceSession,
который является точкой входа для выполнения всех вычислений. Создание
сессии требует указания пути к файлу модели или буфера с её содержимым.
Базовый пример:
import * as ort from 'onnxruntime-web';
const session = await ort.InferenceSession.create('./model.onnx', {
executionProviders: ['wasm', 'webgl'] // порядок приоритета
});
При инициализации можно задать настройки конкретного провайдера, например уровень параллелизма для WASM или выбор устройства для WebGPU.
Авторегрессионные модели, такие как GPT, используют предсказание
токена за токеном. Каждый новый токен вычисляется на основе предыдущих,
что при naïve реализации приводит к повторной обработке всей
последовательности заново. KV-кэш (Key-Value cache) решает эту проблему,
позволяя сохранять промежуточные представления key и
value для каждого слоя трансформера, чтобы при генерации
следующего токена повторно использовать уже вычисленные значения.
KV-кэш хранится в виде тензоров с размерами
[num_heads, seq_len, head_dim] для каждого слоя. При каждом
шаге инференса:
Пример создания KV-кэша в ORT Web:
// Инициализация KV-кэша для модели с N слоями
const kvCache = {};
for (let i = 0; i < numLayers; i++) {
kvCache[`layer_${i}_key`] = new ort.Tensor('float32', new Float32Array(maxSeqLen * numHeads * headDim), [1, numHeads, maxSeqLen, headDim]);
kvCache[`layer_${i}_value`] = new ort.Tensor('float32', new Float32Array(maxSeqLen * numHeads * headDim), [1, numHeads, maxSeqLen, headDim]);
}
Каждый шаг инференса теперь использует этот кэш:
const feeds = {
input_ids: new ort.Tensor('int32', inputIds, [1, inputIds.length]),
...kvCache
};
const results = await session.run(feeds);
// Обновление KV-кэша
for (let i = 0; i < numLayers; i++) {
kvCache[`layer_${i}_key`] = results[`layer_${i}_key`];
kvCache[`layer_${i}_value`] = results[`layer_${i}_value`];
}
При работе с авторегрессионными моделями важна организация последовательности:
KV-кэш позволяет хранить позиционные представления каждого токена без необходимости повторного пересчёта всей последовательности. Это критично для длинных текстов и моделей с сотнями миллионов параметров.
ORT Web поддерживает несколько стратегий ускорения:
Пример запуска с WebGPU:
const session = await ort.InferenceSession.create('./model.onnx', {
executionProviders: ['webgpu'],
graphOptimizationLevel: 'all'
});
Алгоритм пошаговой генерации текста с KV-кэшем:
argmax или сэмплингом
(top-k, top-p).Эта схема позволяет поддерживать непрерывный контекст без повторного инференса всей последовательности.
KV-кэш растёт пропорционально длине последовательности, поэтому важно:
maxSeqLen в модели и сессии.Пример очистки кэша:
for (const key in kvCache) {
kvCache[key].data = null;
}
Это освобождает память, не разрушая структуру KV-кэша, чтобы его можно было инициализировать заново при следующем инференсе.
Ключевой принцип работы — хранение промежуточных представлений и минимизация повторных вычислений для каждого шага генерации. Такой подход делает ORT Web эффективным инструментом для интерактивного и потокового инференса моделей трансформеров.