We reverse-engineered Flash Attention 4
Новая версия Flash Attention 4 оптимизирована под архитектуру Blackwell от Nvidia и обещает ~20% прирост скорости по сравнению с предыдущим рекордсменом — закрытыми ядрами внимания в библиотеке cudnn. Хотя официального отчёта нет, исходный код уже доступен, что позволило разобрать его устройство. Главное изменение — не математические трюки (вроде быстрых приближённых экспонент или эффективного онлайн-softmax), а сложная асинхронная конвейеризация операций, напоминающая принципы параллельного программирования из высокопроизводительных систем вроде баз данных или веб-серверов.
Архитектура FA4 построена вокруг обработки «тайлов» — блоков данных, которые потоково считываются из глобальной памяти GPU. Один экземпляр ядра обрабатывает два тайла запросов, последовательно сканируя все ключи и значения, чтобы вычислить взвешенные выходные данные. Это напоминает векторized-сканирование в СУБД. Масштабирование достигается за счёт массового параллельного запуска таких программ по модели «одна программа — много данных». Подход требует глубокой асинхронности и эффективного использования warp-ов, но остаётся интуитивно понятным для инженеров, работавших с конкурентными системами.
Комментарии (40)
- Обсуждение термина "reverse engineering" применительно к анализу исходного кода и его пониманию.
- Критика стиля и структуры блог-поста за избыточные отсылки к исследованиям и недостаток конкретики.
- Замечания о сложности написания эффективных GPU-кернелов для современного железа и упоминание тренда на "мегакернелы".
- Запрос рекомендаций по обучающим материалам для начинающих в GPU-программировании.
- Положительные отзывы о содержании поста и его развлекательном, доступном стиле.
Defeating Nondeterminism in LLM Inference 🔥 Горячее
Почему LLM неповторяемы и как это исправить
Проблема
Даже при temperature=0 и одном железе выводы моделей различаются от запуска к запуску. Популярное объяснение: «параллельные GPU-ядра + погрешности float = недетерминизм». Это не вся правда.
Что на самом деле происходит
- Все «математические» ядра (matmul, softmax и т.д.) внутри одного forward-прохода детерминированы — бит-в-бит.
- Недетерминизм появляется между forward-проходами:
- динамическое разбиение работы на потоки (different thread blocks);
- неупорядоченные редукции при вычислении
softmax/layernorm; - разные стратегии
cudnn/cublasв зависимости от загрузки GPU; - кэш-промахи и
atomicAddв attention.
Как убедиться
A = torch.randn(2048, 2048, device='cuda', dtype=torch.bfloat16)
B = torch.randn(2048, 2048, device='cuda', dtype=torch.bfloat16)
ref = A @ B
for _ in range(1000):
assert (A @ B == ref).all() # всегда True
Матричное умножение повторяется, а вот softmax(A @ B) — уже нет.
Побеждаем за 3 шага
-
Фиксируем редукции
torch.use_deterministic_algorithms(True)CUBLAS_WORKSPACE_CONFIG=:4096:8(для CUDA ≥10.2)export CUDA_LAUNCH_BLOCKING=1(медленно, но зато стабильно).
-
Отключаем динамические алгоритмы
torch.backends.cudnn.deterministic = Truetorch.backends.cudnn.benchmark = False- в vLLM:
--disable-custom-all-reduce,--enforce-eager.
-
Контролируем параллелизм
- фиксированный батч и длина последовательности;
- один GPU-поток (
tensor_parallel_size=1); - один и тот же порядок запросов (queuing seed).
Результат
На Llama-3-8B с vLLM + указанными флагами 1000 прогонов дают идентичные токены вплоть до последнего бита. Стоимость: ≈8 % к throughput.
TL;DR
Недетерминизм — не «float плавает», а race-conditions вне математического ядра. Убери их, и LLM станет строго воспроизводимым.
Комментарии (117)
- Корень проблемы: «один и тот же» запуск LLM выдаёт разные токены из-за race-конкуренции ядер, неассоциативности float и недетерминированных GPU-ядёр; авторы показали, как зафиксировать порядок операций и получить бит-в-бит повтор.
- Практика: temperature=0 ≠ гарантия: во-первых, библиотеки всё равно подкладывают ε>0, во-вторых, MoE-модели выбирают экспертов в зависимости от состава батча, поэтому даже «одинаковый» запуск в API почти никогда не повторяется.
- Зачем нужна детерминированность: CI-тесты, отладка багов, шеринг промптов между разработчиками, валидация через LLM, агентские цепочки и RL-обучение требуют, чтобы «один и тот же вход = один и тот же выход».
- Ограничения: статья решает только замкнутую задачу inference-ядер; контекст, семантически эквивалентные формулировки и много-нодовые коллективы остаются источником разброса; при temperature>0 нужен фиксированный PRNG-сид.
Nvidia DGX Spark 💬 Длинная дискуссия
- DGX Spark — компактный «суперкомпьютер» на базе процессора Grace Blackwell, помещающийся на столе.
- Поддерживает обучение и инференс ИИ-моделей любого размера благодаря архитектуре Grace Blackwell и 128 ГБ унифицированной памяти.
- Подключается к DGX Cloud для масштабирования задач и работает в экосистеме NVIDIA AI Enterprise.
- Поставляется с полным стеком ПО: CUDA, cuDNN, TensorRT, NeMo, RAPIDS и другими фреймворками.
- Подходит исследователям, стартапам и инженерам, которым нужна локальная мощность без серверной.
Комментарии (176)
- Jetson Thor и DGX Spark работают на зафиксированном ядре Linux от NVIDIA на Ubuntu 20.04, обновления ограничены, как на китайских SBC.
- Spark: 1000 FP4-TOPS, 128 ГБ LPDDR5x, 273 ГБ/с пропускная способность, цена $3999; по $/производительность проигрывает 5090 и Thor.
- Узкое место — низкая пропускная способность памяти: в 4 раза меньше RTX 4090 и в 8 раз меньше M4 Max, что ограничивает обучение и крупные LLM.
- Устройство позиционируется как devkit для прототипирования и дообучения, а не как универсальный ПК; потребление и дата выхода не раскрыты.
- Многие считают цену завышенной и ждут сравнения с будущими Mac Studio M4/M5 Ultra и AMD Strix Halo.