Работа с File API и Drag & Drop для загрузки пользовательских моделей

ONNX Runtime Web предоставляет возможность загружать и выполнять модели машинного обучения непосредственно в браузере. Для динамической работы с пользовательскими моделями важно уметь интегрировать веб-технологии, позволяющие загружать файлы локально, такие как File API и интерфейс Drag & Drop. Эти подходы позволяют создавать интерактивные приложения, где пользователи могут подгружать свои собственные модели ONNX без необходимости серверной обработки.


File API: основы загрузки файлов

File API — это стандартный веб-API для работы с локальными файлами, выбранными пользователем через . Основные классы, используемые в контексте ONNX Runtime Web:

  • FileList — список выбранных файлов.
  • File — объект отдельного файла с метаданными (name, size, type) и методами для чтения содержимого.
  • FileReader — позволяет считывать содержимое файла в формате ArrayBuffer, необходимом для загрузки модели в ONNX Runtime Web.

Пример базовой загрузки модели:

const fileInput = document.getElementById('model-input');

fileInput.addEventListener('change', async (event) => {
    const file = event.target.files[0];
    if (!file) return;

    const arrayBuffer = await file.arrayBuffer();
    const session = await ort.InferenceSession.create(arrayBuffer);

    console.log('Модель загружена', session);
});

Ключевые моменты:

  • Метод file.arrayBuffer() возвращает промис, который разрешается в ArrayBuffer, совместимый с ort.InferenceSession.create.
  • Проверка на существование файла предотвращает ошибки при отмене выбора пользователем.
  • Использование async/await упрощает асинхронное чтение больших моделей.

Drag & Drop: интерактивная загрузка

Интерфейс Drag & Drop позволяет перетаскивать файл в область страницы для загрузки. Основные события:

  • dragover — нужно вызвать event.preventDefault(), чтобы разрешить сброс.
  • drop — событие, которое содержит список файлов в event.dataTransfer.files.

Пример интеграции с ONNX Runtime Web:

const dropArea = document.getElementById('drop-area');

dropArea.addEventListener('dragover', (event) => {
    event.preventDefault();
    dropArea.classList.add('highlight');
});

dropArea.addEventListener('dragleave', () => {
    dropArea.classList.remove('highlight');
});

dropArea.addEventListener('drop', async (event) => {
    event.preventDefault();
    dropArea.classList.remove('highlight');

    const file = event.dataTransfer.files[0];
    if (!file) return;

    const arrayBuffer = await file.arrayBuffer();
    const session = await ort.InferenceSession.create(arrayBuffer);

    console.log('Модель загружена через Drag & Drop', session);
});

Особенности использования:

  • Класс highlight позволяет визуально сигнализировать пользователю о зоне сброса.
  • Проверка event.dataTransfer.files.length позволяет безопасно обрабатывать несколько файлов, если это необходимо.
  • Поддержка асинхронной загрузки позволяет избежать блокировки интерфейса при работе с большими моделями.

Валидация и безопасная работа с моделями

При загрузке пользовательских файлов важно учитывать потенциальные ошибки:

  • Неподдерживаемый формат: ONNX Runtime Web поддерживает только .onnx. Проверка расширения или MIME-типа предотвращает попытки загрузки других файлов.
  • Большой размер файла: чтение и создание сессии с массивом больших размеров может привести к задержкам или ошибкам памяти. Можно ограничивать размер файла, например, до 100 МБ.
  • Асинхронные ошибки: try/catch блоки позволяют корректно обрабатывать ошибки при создании сессии:
try {
    const session = await ort.InferenceSession.create(arrayBuffer);
    console.log('Модель успешно загружена', session);
} catch (err) {
    console.error('Ошибка загрузки модели', err);
}

Объединение File API и Drag & Drop

Для более универсального интерфейса загрузки рекомендуется комбинировать оба подхода. Например, область Drag & Drop может работать совместно с , предоставляя пользователю возможность выбора привычным способом или перетаскиванием.

const fileInput = document.getElementById('file-input');
const dropArea = document.getElementById('drop-area');

async function handleFile(file) {
    const arrayBuffer = await file.arrayBuffer();
    const session = await ort.InferenceSession.create(arrayBuffer);
    console.log('Модель загружена', session);
}

fileInput.addEventListener('change', (e) => handleFile(e.target.files[0]));
dropArea.addEventListener('drop', (e) => {
    e.preventDefault();
    handleFile(e.dataTransfer.files[0]);
});

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


Интеграция с интерфейсом ONNX Runtime Web

После загрузки модели с помощью File API или Drag & Drop, полученный ArrayBuffer передается в ort.InferenceSession.create, что позволяет:

  • Выполнять инференс на клиенте без сервера.
  • Использовать WebGL или WebAssembly backend для ускорения работы.
  • Обрабатывать несколько моделей динамически, сохраняя сессии в памяти для повторного использования.

Для асинхронного выполнения инференса:

const feeds = { input_tensor: new ort.Tensor('float32', inputData, [1, 3, 224, 224]) };
const results = await session.run(feeds);
console.log('Результаты инференса', results.output_tensor.data);

Преимущества динамической загрузки моделей:

  • Возможность тестировать модели на лету.
  • Поддержка пользовательских данных и экспериментальных моделей.
  • Снижение нагрузки на сервер, так как вычисления выполняются полностью на клиенте.