SharedArrayBuffer и заголовки COOP/COEP: почему они нужны

ONNX Runtime Web (ORT Web) представляет собой JavaScript-реализацию высокопроизводительного движка для выполнения моделей машинного обучения в браузере. Основная цель ORT Web — обеспечение быстрого и эффективного запуска моделей ONNX с использованием возможностей современных браузеров, включая WebAssembly (WASM) и WebGL.

Инициализация и загрузка модели

Работа с ORT Web начинается с создания сессии исполнения модели. Сессия строится на основе бинарного файла модели в формате ONNX.

import * as ort from 'onnxruntime-web';

async function runModel() {
  const session = await ort.InferenceSession.create('model.onnx');
}

Ключевой аспект — использование асинхронной загрузки. Это позволяет браузеру не блокировать основной поток, что критично при работе с тяжелыми моделями и большими данными.

Передача данных в модель

ORT Web использует формат TypedArray для представления тензоров. Тензоры создаются через объект ort.Tensor, где указываются тип данных (float32, int32 и т.д.) и форма массива.

const input = new ort.Tensor('float32', new Float32Array([1, 2, 3, 4]), [2, 2]);
const feeds = { input_name: input };
const results = await session.run(feeds);

Использование TypedArray обеспечивает непосредственный доступ к памяти, что ускоряет выполнение операций и снижает накладные расходы на копирование данных между JavaScript и WebAssembly.


SharedArrayBuffer

SharedArrayBuffer — это объект, который позволяет совместно использовать участок памяти между основным потоком JavaScript и Web Worker. Для ORT Web это критично, так как позволяет моделям, выполняемым в WebAssembly, работать с большими массивами данных без постоянного копирования.

Преимущества использования

  1. Минимизация накладных расходов — данные не копируются между потоками, что ускоряет передачу тензоров в сессии модели.
  2. Параллельное выполнение — Web Worker может обрабатывать часть модели, пока основной поток занимается другой задачей.
  3. Снижение использования памяти — один участок памяти может быть разделён между несколькими компонентами приложения.

Пример создания SharedArrayBuffer:

const buffer = new SharedArrayBuffer(Float32Array.BYTES_PER_ELEMENT * 1024);
const tensorData = new Float32Array(buffer);
const inputTensor = new ort.Tensor('float32', tensorData, [32, 32]);

Использование SharedArrayBuffer позволяет ORT Web выполнять массивные операции с тензорами без блокировок и лишних копирований, что особенно важно при работе с нейросетями в реальном времени.


Заголовки COOP и COEP

Для использования SharedArrayBuffer в современных браузерах требуется настройка заголовков COOP (Cross-Origin-Opener-Policy) и COEP (Cross-Origin-Embedder-Policy).

Cross-Origin-Opener-Policy (COOP)

COOP управляет поведением окна при открытии контента из другого происхождения. Для корректной работы SharedArrayBuffer необходимо, чтобы страница была изолирована в своем пространстве происхождения. Пример заголовка:

Cross-Origin-Opener-Policy: same-origin

Это предотвращает доступ посторонних вкладок или фреймов к памяти страницы и обеспечивает безопасность совместного использования памяти.

Cross-Origin-Embedder-Policy (COEP)

COEP контролирует возможность встраивания ресурсов с других источников. Чтобы разрешить использование SharedArrayBuffer, все ресурсы должны быть либо из того же происхождения, либо иметь корректный заголовок Cross-Origin-Resource-Policy. Пример:

Cross-Origin-Embedder-Policy: require-corp

Эти заголовки вместе гарантируют, что браузер разрешает создание SharedArrayBuffer только в безопасной и изолированной среде, предотвращая потенциальные атаки через совместно используемую память.


Влияние на производительность ORT Web

Совмещение SharedArrayBuffer с правильно настроенными заголовками COOP/COEP обеспечивает:

  • Ускорение операций с тензорами за счёт прямого доступа к общей памяти.
  • Возможность распараллеливания вычислений между главным потоком и воркерами.
  • Снижение потребления памяти при работе с большими моделями.

Без этих заголовков браузеры запрещают использование SharedArrayBuffer, что делает выполнение ресурсоёмких моделей в браузере значительно медленнее, так как каждый тензор требует отдельного копирования.


Практическая схема интеграции

  1. Настройка серверных заголовков COOP/COEP.
  2. Создание сессии ORT Web с использованием SharedArrayBuffer.
  3. Передача данных через ort.Tensor, созданные на основе общей памяти.
  4. Асинхронное выполнение модели с поддержкой Web Workers для распараллеливания.

Эта схема позволяет достигать максимальной производительности в браузере при работе с ONNX моделями, используя современные возможности WebAssembly и потоков JavaScript.