Расхождение результатов между Python и браузером

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


Влияние среды выполнения

Python-версия ONNX Runtime использует оптимизированные нативные библиотеки, часто с поддержкой многопоточности и аппаратного ускорения через CPU или GPU. В браузере ORT Web работает через JavaScript, используя либо WebAssembly (WASM), либо WebGPU. Отличия среды приводят к следующим эффектам:

  • Различие в численной точности Python-версии обычно используют стандартные типы с плавающей точкой IEEE 754 (float32, float64). В браузере WebAssembly и WebGPU также используют float32, но детали реализации операций (например, суммирование большого числа элементов) могут приводить к погрешностям на уровне порядка 1e-6–1e-5. Это особенно заметно при работе с глубокими нейронными сетями, где ошибки аккумулируются через слои.

  • Особенности оптимизаций компилятора Компиляторы для WASM и JIT-оптимизации в JavaScript могут переставлять операции для ускорения, что меняет порядок вычислений и вызывает небольшие расхождения в результатах.

  • Поддержка операторов ONNX Не все операторы ONNX полностью оптимизированы для ORT Web. Некоторые сложные операции (например, нестандартные свертки или кастомные расширения) могут выполняться через fallback-методы, которые дают результат с небольшими отличиями.


Различия в типах данных и преобразованиях

JavaScript имеет специфическое поведение при работе с числами. Все числа в JS по умолчанию представлены как float64, но при выполнении через WebAssembly большинство тензорных операций конвертируется в float32. Расхождение может возникать при:

  • Конвертации типов: Python может использовать float64 или int64, а ORT Web автоматически конвертирует в float32 или int32.
  • Переполнении и округлении: при операциях с большим диапазоном значений float32 может давать более грубое округление по сравнению с float64.
  • Индексации и срезах: JavaScript массивы и TypedArray ведут себя иначе при граничных срезах, что иногда вызывает небольшие различия при обработке батчей.

Работа с различными движками ORT Web

ORT Web поддерживает два основных движка:

  1. WebAssembly (WASM)

    • Высокая переносимость, поддержка всех браузеров.
    • Ограничение по производительности и численной точности.
    • Поддержка большинства стандартных ONNX операторов.
  2. WebGPU

    • Использует аппаратное ускорение через GPU.
    • Вычисления быстрее, особенно для больших моделей и батчей.
    • Более выраженные расхождения из-за особенностей GPU вычислений и параллельного суммирования.

Выбор движка напрямую влияет на расхождение результатов. Использование WebGPU может давать более крупные погрешности при суммировании большого числа элементов, чем WASM, из-за параллельного сложения с плавающей точкой.


Практические рекомендации для минимизации расхождений

  • Единый тип данных для всей модели: при экспорте модели в ONNX рекомендуется явно указывать float32 для всех весов и входов.
  • Согласованная нормализация данных: нормализовать входные данные одинаково в Python и в JavaScript перед инференсом.
  • Проверка критических операций: для нестандартных операторов сравнивать результаты между Python и браузером.
  • Использование одинакового движка: для тестирования в браузере фиксировать WebAssembly или WebGPU и не переключать динамически.
  • Тестирование на батчах меньшего размера: большие батчи увеличивают вероятность накопления ошибок при параллельных вычислениях.

Методы верификации результатов

Для анализа расхождения полезно применять следующие подходы:

  • Абсолютная и относительная погрешность: [ = |y_{} - y_{}|, = ]

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

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


Заключение к практическому использованию

Расхождение между Python и браузером при работе с ONNX Runtime Web является естественным явлением, обусловленным особенностями платформы, вычислительных движков и типов данных. Понимание источников этих различий позволяет корректно интерпретировать результаты инференса, проводить контроль качества и минимизировать ошибки при переносе моделей из серверной среды в браузер.