Проверка градиентов и клиппинг в объединённом AdamW (экспериментально)
English | 简体中文 | 日本語 | Deutsch | Русский
Включайте явно. Публичная сигнатура существующего adamw_step
и оптимизатор модели по умолчанию не меняются.
Что он делает
gradient_stats_sync просматривает накопленные градиенты, проверяет исходные и освобождённые от масштабирования
в FP32 значения на NaN/Inf и вычисляет общую L2-норму переданной
локальной группы. guarded_adamw_step использует эту норму для клиппинга внутри существующего
объединённого ядра AdamW/AMSGrad, не выделяя и не записывая полноразмерные обрезанные градиенты.
Порядок: преобразование типа хранения -> умножение на обратный масштаб потерь в FP32 -> проверка конечности/норма -> общий коэффициент клиппинга FP32 -> знак maximize -> AdamW. Это намеренно НЕ клиппинг FP16/BF16 на месте: эффективный градиент остаётся FP32, а не округляется обратно до половинной точности хранения перед обновлением.
Для конечных градиентов:
clip = min(max_norm / (L2_norm + epsilon), 1)
g_effective = (float32(g_stored) * reciprocal(loss_scale)) * clip
max_norm=None отключает клиппинг, но не проверки конечности. max_norm=0 обнуляет эффективный градиент,
однако обновление моментов, затухание весов и счётчики шагов продолжаются. При NaN/Inf
политика Skip пропускает ВСЮ выбранную группу, включая затухание весов и счётчики
шагов. Политика Error завершается ошибкой до запуска любого ядра обновления оптимизатора.
Все проверки метаданных и переполнения шага выполняются до отправки расчёта статистики.
Возможности и использование
gradient-guard: конфигурация хоста, статистика/типы решений и оракул CPU.gradient-guard-device: общее сокращение количества устройств и защищенный оптимизатор.gradient-guard-cuda: CUDA интеграционные тесты и тесты.
```rust,ignore use ruda_optim::fused_adamw::{ AdamWEntry, AdamWOptions, StepControl, guarded_adamw_step, gradient_norm::GradientGuardOptions, };
// master1/2: contiguous FP32; grad1/2: F32/F16/BF16, same device and queue. // Accumulation must already be finished, using ONE loss scale for this step. let entries = [ AdamWEntry { parameters: &master1, gradients: &grad1, state: state1.as_ref() }, AdamWEntry { parameters: &master2, gradients: &grad2, state: state2.as_ref() }, ]; let pending = guarded_adamw_step( &entries, &AdamWOptions::default(), StepControl { gradient_scale: 128.0, skip_update: false }, GradientGuardOptions { max_norm: Some(1.0), ..Default::default() }, )?; // Compact stats readback has completed, but the UPDATE is still asynchronous. // Await/synchronize the runtime and check completion before replacing committed // model/state or saving a checkpoint. Keep the existing committed state on failure.
Не добавляются автоматически обновляемый GradScaler, адаптер модели, редукция FSDP, разворачивание тензоров
в плоский вид, устранение повторного учёта связанных весов или повторное приведение модели
к низкой точности. Учитываются только явно переданные параметры. Норму локального шарда
НЕЛЬЗЯ использовать как глобальную норму FSDP/TP. Согласование пропуска между рангами не выполняется.
## Сокращение затрат на внедрение и ресурсы
Ядро с шагом сетки сохраняет тройку `(scale, sumsq, bad)` на полосу и сокращается с
помощью фиксированного дерева с общей памятью. Он никогда не возводит в квадрат
большое необработанное значение FP32 напрямую, поэтому, например. конечные значения вблизи `1e30` не создают
ложного переполнения FP32 при нормальных вычислениях. До 1024 частичных троек сокращаются на
один дополнительный блок. Нет атомов с плавающей запятой; это не автоматический автотюнер устройства.
Для конфигурации требуется 256 X-потоков и 3072 байта общей памяти на
блок. Неподдерживаемые конфигурации отклоняются, а не отправляются в CPU автоматически. Пустые
тензоры не передают никакой работы. Каждый непустой тензор отправляет одно или два
ядра редукции и возвращает одну 12-байтовую сводку. Все сокращения тензора ставятся
в очередь перед одним пакетным вызовом обратного чтения хоста API; среда
выполнения может реализовать несколько копий DMA. Хост явно суммирует компактные сводки в
FP64 и определяет коэффициент. Тензору требуется не более 12 частичных данных
KiB плюс 12-байтовая итоговая информация, исключая выравнивание распределителя и метаданные. `scratch_bytes`
суммирует эти суммы для каждого тензора и не является измерением распределителя пиков.
Повторная ассоциация, FMA и ненормальная обработка зависят от бэкенда. Нормы
проверяются с допусками, а не с обещанной побитовой идентичностью PyTorch или
на разных устройствах. Это не полная реализация LAPACK LASSQ и не рекламируется
как ее числовая совместимость. Большие конечные градиенты все равно могут перекрывать
второй момент AdamW, когда отсечение отключено. Старые параметры/моменты не проверяются на конечность.
## Заявление о производительности и явные ограничения
По сравнению с включенной базовой линией (то же стандартное вычисление, затем
отдельное ядро unscale+clip, создающее градиенты FP32, а затем объединенное AdamW), это удаляет
один запуск клипа и один временный байт `4*N` для каждого непустого тензора,
а также позволяет избежать байтов `8*N` логических временных записей/чтений. Это подсчеты
на уровне источника, а не измеренный трафик памяти устройства или ускорение. Старый
неохраняемый оптимизатор не оплачивает стоимость новой статистики; добавление диагностики может замедлить процесс.
Эта первая версия блокирует хост при компактном чтении на каждом этапе
оптимизатора. Он небезопасен для захвата графов, не обещает перекрытия вычислений/коммуникаций и
может плохо работать на многих крошечных тензорах. Стабильная редукция имеет дополнительную
арифметику. Проверьте производительность перед включением; Никаких претензий к PyTorch Fused/foreach AdamW
не предъявляется. Исходное распределение выходов AdamW не изменилось (главные и моменты
out места FP32). Градиенты нельзя изменять с помощью другого псевдонима/очереди, пока
статистика или зависимые обновления находятся в работе. Сбои во время выполнения
не являются фиксацией транзакционной группы; перед запуском обновления принимается только решение
о неконечном пропуске/пропуске проверки. API-интерфейсы распределения/запуска среды выполнения сохраняют свой контракт ошибок.
## Проверка и сравнение
```bash
python tools/run_gradient_guard_regressions.py --suite oracle
python tools/run_gradient_guard_regressions.py --suite reference
python tools/run_gradient_guard_regressions.py --suite host
python tools/run_gradient_guard_regressions.py --suite build
python tools/run_gradient_guard_regressions.py --suite cuda --compiler both
python tools/run_gradient_guard_regressions.py --suite bench --compiler both --elements 65536 --tensors 4 --dtype bf16 --amsgrad
oracle требует NumPy и PyTorch CPU. Он выполняет только числовую модель
Python, а не код RUDA. reference компилирует автономные тесты Rust без
доступа к реестру Cargo. build проверяет как старые, так и новые функции
устройства. cuda выполняет как старые регрессии AdamW, так и новые аппаратные
тесты. Недостающие инструменты блокируются; время ожидания и сбой фиксируются. --dry-run печатает
только запланированные команды. --offline требует кэширования зависимостей Cargo. Установка инструмента не производится.
Тестирование меняет пути после прогрева, включает в себя распределение, норму, считывание/решение хоста, отправку и окончательную синхронизацию устройства, а также проверяет параметры и все моменты после каждой измеренной партии. Повторное чтение, используемое только для сравнений, осуществляется вне времени. Сохраняйте версии среды/исходного кода с необработанными образцами JSON.
Числовые ссылки
Концептуальные ссылки, а не скопированные реализации: - PyTorch AMP примеры (не масштабировать перед обрезкой градиента): https://docs.pytorch.org/docs/main/notes/amp_examples.html - PyTorch локальный контракт нормы составного градиента: https://docs.pytorch.org/docs/stable/generated/torch.nn.utils.clip_grad.clip_grad_norm_.html - Масштабированное представление суммы квадратов: https://www.netlib.org/lapack/explore-html/d8/d76/group__lassq.html