FlashAttention: как ускорить внимание, ничего не приближая
Механизм внимания в трансформерах квадратичен по длине последовательности. Годами это пытались лечить приближёнными версиями внимания, которые на бумаге быстрее, но на практике часто не дают выигрыша по реальному времени. Три Дао с соавторами зашли с другой стороны.
Где на самом деле теряется время
У GPU два уровня памяти:
- HBM: большая (гигабайты), но относительно медленная;
- SRAM на кристалле: крошечная, но на порядок быстрее.
Обычное внимание считает матрицу QKᵀ размером N×N, записывает её в HBM, читает обратно для softmax, записывает результат, читает для умножения на V. Сама арифметика быстрая. Медленно гонять огромную матрицу туда-обратно по памяти.
Ключевая идея статьи — IO-awareness: алгоритм должен считать не только операции, но и обращения к памяти.
Как работает FlashAttention
- Тайлинг. Q, K и V режутся на блоки, которые помещаются в SRAM. Внимание считается по блокам, и полная матрица N×N никогда не записывается в HBM.
- Онлайн-softmax. Softmax вроде бы требует видеть всю строку сразу, но его можно считать по частям, поддерживая текущий максимум и сумму и пересчитывая частичный результат на лету.
- Пересчёт вместо хранения. Для обратного прохода промежуточная матрица не сохраняется, а пересчитывается из Q, K, V. Лишние вычисления дешевле лишних чтений.
Результат — точное внимание, без приближений, с памятью, линейной по длине.
Цифры
- на 15% быстрее обучение BERT-large (последовательности 512) по реальному времени;
- в 3 раза быстрее GPT-2 на контексте 1K;
- в 2,4 раза быстрее на Long Range Arena (1K–4K);
- блочно-разреженный вариант позволил впервые решить Path-X (16K) с точностью 61,4% и Path-256 (64K) с 63,1%.
Мой комментарий
Мне больше всего нравится, что это не про машинное обучение, а про архитектуру компьютера. Тот же урок я вынес из статьи про кольцевой буфер: узкое место почти всегда там, где данные переезжают между уровнями памяти, а не там, где их считают.
На практике это даёт длинный контекст на маленькой видеокарте. Без FlashAttention-подобных ядер контекст в 16 тысяч токенов на 8 ГБ не поместился бы даже теоретически.