Недетерминированность на графическом процессоре в XLA обусловлена двумя различными причинами :
- Недетерминированность на этапе компиляции (автонастройка)
- Недетерминированность времени выполнения (недетерминированные операции)
Источник 1: Недетерминированность на этапе компиляции (автонастройка)
Причина
В процессе компиляции автонастройщик XLA профилирует несколько вариантов реализации ядра (например, cuBLAS, cuDNN, Triton, собственные эмиттеры) в режиме реального времени на графическом процессоре хоста, чтобы найти самый быстрый алгоритм для таких инструкций, как GEMM и свертки.
Поскольку профилирование в реальном времени основано на измерениях времени с точностью до микросекунды, незначительные колебания аппаратной среды (температурное дросселирование графического процессора, динамическое масштабирование тактовой частоты, планирование работы хост-системы) могут привести к тому, что в разных запусках компиляции в качестве победителя будут выбраны/сгенерированы разные бинарные файлы ядра .
Поскольку разные алгоритмы ядра используют разные размеры блоков, шаблоны доступа к памяти и структуры деревьев редукции, они накапливают числа с плавающей запятой в разном порядке. Из-за неассоциативности чисел с плавающей запятой компиляция одного и того же графа HLO дважды может привести к созданию бинарных файлов, выдающих несколько отличающиеся результаты численных вычислений.
Как добиться детерминизма на этапе компиляции
- Сохранение и кэширование решений автонастройки : Запустите автонастройку один раз и сохраните выбранные параметры в постоянном кэше (см. сохраненную автонастройку ). Использование флага
--xla_gpu_require_complete_aot_autotune_resultsгарантирует, что XLA будет строго использовать кэшированные решения и немедленно завершит компиляцию с ошибкойNotFound, если запись отсутствует, полностью избегая тестирования производительности оборудования в реальном времени. - Отключение автонастройки : Установка параметра
--xla_gpu_autotune_level=0полностью отключает тесты автонастройки на этапе компиляции и детерминированно выбирает конфигурацию по умолчанию/первую допустимую конфигурацию.
Источник 2: Недетерминированность времени выполнения (недетерминированные операции)
Причина
Даже если скомпилированный бинарный файл на 100% идентичен при каждом запуске, многократный запуск одного и того же исполняемого файла может, естественно, привести к различным числовым результатам.
На графических процессорах тысячи потоков выполняются параллельно. Такие операции, как scatter , накапливают значения в буферах памяти с помощью атомарных операций над нескоординированными потоками. Поскольку порядок планирования потоков естественным образом меняется от запуска к запуску, сложение чисел с плавающей запятой происходит в недетерминированном порядке. Поскольку сложение чисел с плавающей запятой является неассоциативным ( (a + b) + c != a + (b + c) ), результаты выполнения различаются между запусками.
Как достичь детерминизма
-
--xla_gpu_exclude_nondeterministic_ops: Обеспечивает детерминированность выполнения, указывая XLA:- При выборе конфигурации следует отфильтровывать недетерминированные варианты алгоритмов/ядер/бэкендов и обеспечивать детерминированные преобразования (для scatter, GEMM, convolution).
- Перепишите операции, такие как
select-and-scatterв последовательность детерминированных операций, чтобы исключить недетерминированные атомарные операции рассеивания. - Отключить проверку производительности автонастройки в реальном времени (выбор первой допустимой детерминированной конфигурации).
Побочные эффекты и компромиссы
Обеспечение детерминизма на графическом процессоре влечет за собой существенные компромиссы:
- Снижение производительности во время выполнения (замедление работы) :
- Детерминированные реализации таких операций, как
scatter(и расширеннаяselect-and-scatter), заменяют нескоординированные атомарные обновления дополнительными проходами сортировки индекса или детерминированными шагами сокращения, что может привести к существенной потере пропускной способности во время выполнения по сравнению с недетерминированными атомарными быстрыми путями. - Отключение автоматической настройки в реальном времени (
--xla_gpu_autotune_level=0) не позволяет XLA определить самое быстрое ядро для конкретной архитектуры графического процессора, что приводит к выбору неоптимального ядра.
- Детерминированные реализации таких операций, как
- Ошибки компиляции :
- Если граф HLO содержит инструкции без какой-либо детерминированной реализации, включение
--xla_gpu_exclude_nondeterministic_opsприводит к остановке компиляции с ошибкой. - При использовании
--xla_gpu_require_complete_aot_autotune_resultsкомпиляция немедленно завершится ошибкойNotFound, если какая-либо инструкция не имеет записи в предварительно заполненном кэше автонастройки.
- Если граф HLO содержит инструкции без какой-либо детерминированной реализации, включение
- Отключенные оптимизации и излучатели :
- Некоторые высокопроизводительные генераторы ядер и преобразования слияния (например, автонастройка слияния Triton) автоматически исключаются из рассмотрения, когда требуется детерминизм.