Кэширование моделей: Cache API и IndexedDB

ONNX Runtime Web предоставляет возможность запускать модели машинного обучения прямо в браузере на JavaScript, обеспечивая при этом высокую производительность и кроссплатформенность. Одной из ключевых задач при работе с большими моделями является эффективное кэширование, позволяющее сократить время загрузки и снизить сетевую нагрузку. В веб-контексте для этих целей используются Cache API и IndexedDB.


Принципы кэширования в ONNX Runtime Web

ONNX Runtime Web загружает модели в формате .onnx или .ort и выполняет их через WebAssembly (WASM) или WebGPU. Поскольку загрузка модели с сервера может занимать значительное время, особенно для крупных сетей, кэширование позволяет:

  • хранить модель локально между сессиями;
  • ускорять инициализацию модели;
  • минимизировать повторные сетевые запросы.

Используемые методы кэширования должны обеспечивать надежное хранение бинарных данных и быстрый доступ.


Cache API

Cache API — стандартный механизм браузеров для хранения сетевых ресурсов. Он хорошо подходит для кэширования моделей, если модель загружается по URL.

Основные возможности:
  • Хранение ответов Response объектов fetch;
  • Простая интеграция с сервис-воркерами;
  • Автоматическое управление устаревшими ресурсами через стратегии кэширования.
Пример кэширования модели:
async function cacheONNXModel(modelUrl) {
    const cache = await caches.open('onnx-models');
    const cachedResponse = await cache.match(modelUrl);

    if (cachedResponse) {
        return cachedResponse.arrayBuffer();
    }

    const response = await fetch(modelUrl);
    await cache.put(modelUrl, response.clone());
    return response.arrayBuffer();
}

В этом примере:

  • открывается кэш с именем onnx-models;
  • проверяется наличие модели в кэше;
  • при отсутствии модели она загружается и сохраняется для последующего использования.
Особенности использования:
  • Кэширование через Cache API идеально для моделей, которые загружаются напрямую с сервера;
  • Ограничение по объему зависит от браузера, обычно несколько сотен мегабайт;
  • Поддерживается автоматическое удаление устаревших данных через стратегию cache.delete.

IndexedDB

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

Основные возможности:
  • Хранение ArrayBuffer, Blob, TypedArray;
  • Асинхронный доступ с использованием промисов через обертки вроде idb;
  • Возможность создания индексов для версий моделей и метаданных.
Пример сохранения модели в IndexedDB:
import { openDB } from 'idb';

async function saveModelToIndexedDB(modelName, arrayBuffer) {
    const db = await openDB('ONNXModelsDB', 1, {
        upgrade(db) {
            db.createObjectStore('models');
        }
    });
    await db.put('models', arrayBuffer, modelName);
}

async function loadModelFromIndexedDB(modelName) {
    const db = await openDB('ONNXModelsDB', 1);
    return db.get('models', modelName);
}

В этом примере:

  • создается база ONNXModelsDB с хранилищем models;
  • модели сохраняются и извлекаются по ключу modelName;
  • использование ArrayBuffer обеспечивает совместимость с ONNX Runtime Web.
Особенности использования:
  • Поддержка версионирования моделей через отдельные ключи или метаданные;
  • Можно комбинировать с Cache API: Cache API для сетевых запросов, IndexedDB для долговременного хранения;
  • Более надежная работа с крупными моделями по сравнению с Cache API.

Рекомендации по интеграции кэширования

  1. Комбинированная стратегия:

    • Первичная загрузка через Cache API для быстрого доступа;
    • Долгосрочное хранение и управление версиями через IndexedDB.
  2. Проверка актуальности модели:

    • Использовать хеш-суммы или версии модели;
    • При несовпадении обновлять данные в IndexedDB и кэше.
  3. Асинхронная загрузка и инициализация:

    • Загружать модель в фоне перед использованием;
    • Позволяет ускорить первый запуск инференса.
  4. Управление объемом данных:

    • Для Cache API отслеживать устаревшие записи;
    • Для IndexedDB удалять старые версии моделей при достижении лимитов.

Практический пример полной загрузки модели с кэшированием

async function loadONNXModel(modelUrl, modelName) {
    // Проверка IndexedDB
    let modelBuffer = await loadModelFromIndexedDB(modelName);
    if (modelBuffer) return modelBuffer;

    // Проверка Cache API
    modelBuffer = await cacheONNXModel(modelUrl);
    
    // Сохранение в IndexedDB для будущих сессий
    await saveModelToIndexedDB(modelName, modelBuffer);
    
    return modelBuffer;
}

Эта схема обеспечивает:

  • минимальные задержки при повторной загрузке;
  • долговременное хранение модели в браузере;
  • удобное управление версиями и обновлениями.

Использование Cache API и IndexedDB в ONNX Runtime Web позволяет создавать высокопроизводительные веб-приложения с локальным хранением моделей, снижая сетевую нагрузку и обеспечивая мгновенный доступ к большим нейронным сетям. Правильная комбинация этих инструментов является основой для эффективного и надежного кэширования в современных браузерных решениях.