Работа с ONNX Runtime Web (ORT Web) в JavaScript требует внимательного отношения к управлению памятью, особенно на этапе предобработки данных перед подачей в модель. Лишние аллокации массивов и промежуточных объектов не только замедляют выполнение, но и создают дополнительную нагрузку на сборщик мусора, что особенно критично для веб-приложений с высокой частотой запросов к модели.
Ключевой принцип оптимизации — минимизация повторного создания массивов. Для этого целесообразно заранее выделять буферы фиксированного размера и переиспользовать их для каждого нового входа.
const inputSize = 224 * 224 * 3; // пример для модели обработки изображений
const inputBuffer = new Float32Array(inputSize);
// при предобработке изображения
function preprocessImage(imageData) {
// заполняем заранее выделенный буфер
for (let i = 0; i < inputSize; i++) {
inputBuffer[i] = imageData[i] / 255.0;
}
return inputBuffer;
}
Преимущества:
Ort.Tensor без
дополнительных копирований.ONNX Runtime Web позволяет создавать тензоры напрямую из уже существующего массива, что полностью исключает создание промежуточных структур.
const tensor = new ort.Tensor('float32', inputBuffer, [1, 3, 224, 224]);
Особенности:
inputBuffer для разных запросов
ускоряет предобработку.Tensor.При стандартной нормализации изображений часто создаются временные массивы для каждого канала. Эффективнее нормализовать данные «на лету» в уже выделенном буфере.
function normalizeChannels(imageData, mean, std) {
for (let i = 0; i < imageData.length; i += 3) {
inputBuffer[i] = (imageData[i] / 255.0 - mean[0]) / std[0];
inputBuffer[i + 1] = (imageData[i + 1] / 255.0 - mean[1]) / std[1];
inputBuffer[i + 2] = (imageData[i + 2] / 255.0 - mean[2]) / std[2];
}
return inputBuffer;
}
Эффект:
Для веб-приложений с потоковой подачей изображений или батчами данных важно использовать один общий буфер для пакета запросов. Создание единого большого буфера и заполнение отдельных частей для каждого примера в батче позволяет полностью избежать многократных аллокаций.
const batchSize = 4;
const batchBuffer = new Float32Array(batchSize * inputSize);
for (let b = 0; b < batchSize; b++) {
const offset = b * inputSize;
preprocessImageBatch(imageDataArray[b], batchBuffer, offset);
}
function preprocessImageBatch(imageData, buffer, offset) {
for (let i = 0; i < inputSize; i++) {
buffer[offset + i] = imageData[i] / 255.0;
}
}
Результат:
session.run().TypedArray вместо обычных массивовJavaScript TypedArray (Float32Array,
Int32Array и др.) обеспечивает плотное размещение данных и
прямую совместимость с ORT Web. Это позволяет передавать массивы
напрямую в Ort.Tensor без копирования, в отличие от обычных
массивов Array, которые требуют конвертации.
Рекомендации:
Float32Array для моделей с типом
float32.Array при любой
арифметической обработке.TypedArray исключает лишние
копирования.Эти подходы позволяют сократить время предобработки и снизить нагрузку на сборщик мусора, что особенно важно для приложений с высокой частотой обработки изображений или потоковых данных.