Ошибки операторов: неподдерживаемые опсеты и кастомные операции

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


Неподдерживаемые опсеты

Опсет (Opset) в ONNX определяет набор версий операторов, которые поддерживаются моделью. Каждая модель при экспорте сохраняет версию опсета для каждого оператора. ORT Web поддерживает только определённый набор операторов и версий, что может привести к следующим типам ошибок:

  • OperatorNotSupported: возникает, когда модель использует оператор с версией опсета, которой ORT Web не обладает.
  • InvalidVersion: появляется, если версия опсета слишком новая или слишком старая для текущей реализации библиотеки.
Причины ошибок опсетов
  1. Экспорт модели с новыми операторами: при конвертации моделей из PyTorch или TensorFlow иногда используются новейшие версии операторов, которые ещё не реализованы в ORT Web.
  2. Несовпадение версий ONNX Runtime: библиотека может поддерживать только определённый диапазон версий опсетов. Модель, созданная с более новой версией ONNX, вызовет ошибку.
Обнаружение и логирование

ORT Web предоставляет подробный стек вызовов и сообщения об ошибках. При инициализации сессии модели можно использовать:

const session = await ort.InferenceSession.create('model.onnx', {
    executionProviders: ['wasm'], // или ['webgl']
    graphOptimizationLevel: 'all'
});

session.on('error', (err) => {
    console.error('Ошибка сессии ONNX:', err);
});

Это позволяет идентифицировать оператор и версию опсета, вызвавшую проблему.

Методы обхода
  • Использование более старых версий модели: часто модели можно пересоздать с опсетом, который поддерживается в ORT Web.
  • Конвертация операторов: некоторые операторы можно заменить на эквивалентные комбинации поддерживаемых операторов через инструменты типа onnx-simplifier.
  • Обновление ORT Web: новые версии библиотеки постепенно добавляют поддержку новых операторов и опсетов.

Кастомные операции

Кастомные операции — это пользовательские или экспериментальные операторы, которых нет в стандартной библиотеке ONNX. ORT Web не поддерживает их напрямую, что приводит к ошибкам вида CustomOpNotImplemented.

Создание кастомных операций

В ONNX кастомный оператор задаётся через имя и версию опсета, а также описание входов и выходов. При экспорте модели в JavaScript ORT Web будет пытаться найти реализованную функцию для этого оператора. Если функция отсутствует, модель не загрузится.

Реализация кастомных операций в ORT Web

ORT Web позволяет регистрировать кастомные операции через API CustomOp:

class MyCustomOp extends ort.CustomOp {
    constructor() {
        super();
        this.name = 'MyOp';
        this.inputTypes = ['float32'];
        this.outputTypes = ['float32'];
    }

    run(inputs) {
        const x = inputs[0];
        const y = new Float32Array(x.length);
        for (let i = 0; i < x.length; i++) {
            y[i] = x[i] * 2; // пример реализации
        }
        return [y];
    }
}

const session = await ort.InferenceSession.create('model.onnx', {
    executionProviders: ['wasm'],
    customOps: [new MyCustomOp()]
});

Ключевые моменты при реализации кастомных операторов:

  • Типы входов и выходов должны строго соответствовать определению в модели.
  • Порядок выполнения обязан сохранять семантику оригинального оператора.
  • Оптимизация производительности особенно важна при работе с WebGL, где массивы должны быть в формате, подходящем для GPU.
Проверка корректности

Для тестирования кастомного оператора следует:

  1. Создать минимальный пример модели с этим оператором.
  2. Выполнить простые входные данные через ORT Web.
  3. Сравнить результаты с ожидаемыми вычислениями на CPU.

Ошибки часто проявляются в виде несоответствия формата входов или выходов, либо нарушением порядка операций внутри сети.


Отладка и диагностика ошибок операторов

  • Использование логов сессии: session.on('error', callback) и console.warn позволяют отследить проблемные узлы.
  • Проверка структуры модели через onnx.checker перед загрузкой.
  • Использование утилиты netron.app для визуального анализа операторов и опсетов.

Ошибки, связанные с операторами, чаще всего не критичны для всей модели, если их можно заменить или реализовать кастомно. Своевременная диагностика и правильная регистрация кастомных операций позволяет запускать сложные модели ONNX в браузере с ORT Web без сбоев.