FlashAttention(フラッシュアテンション)は、Transformerのアテンションを、数式を変えずにGPUのメモリ往復だけ減らして速くするカーネル実装です。2022年5月にTri DaoらがarXiv 2205.14135で発表し、いまはPyTorch・Hugging Face Transformers・vLLM・llama.cppのどれにも組み込まれています。この記事では、仕組み(タイリングとオンラインsoftmax)、FA2からFA4までの対応GPU、flash-attnのインストール、フレームワークごとの有効化の書き方、そして入れても速くならない条件までを、2026年10月時点の版で整理します。
まとめ:FlashAttentionの仕組みと版選択の結論
FlashAttentionは近似ではありません。L×Lのスコア行列をHBM(GPUの主メモリ)へ書き出さず、SRAM上のブロック単位で計算しきるため、出力は標準アテンションと丸め誤差の範囲で一致し、メモリは系列長に対して線形で済みます。手元のCPUで測っても、系列長8,192でメモリの増分は4,294MiBから22MiBに下がりました(後述)。
版はGPUの世代で決まります。A100やRTX 4090ならFlashAttention-2(PyPIのflash-attn、最新は2026年10月14日の2.8.3.post2)、H100ならFA3かFA4、B200ならFA4です。FA4のflash-attn-4は同日公開の4.0.0b35でまだpre-releaseのため、本番の既定はFA2か、PyTorch内蔵のSDPA経由にしておくのが無難です。
採用判断は単純です。Ampere以降のGPUでfp16かbf16を使い、長い系列のプリフィルや学習を回すなら、代表的な系列長で速度とピークメモリを測ったうえで入れます。V100やfp32入力はCUDA版FA2の対応外です。SDPAの自動選択では別の対応経路を利用できますが、FA2を直接指定するとエラーになる場合があります。
FlashAttentionが削るもの|HBM往復とO(L²)メモリの内訳
スコア行列L×LのHBM往復が生む帯域律速
標準的なアテンションは、QとKの内積からL×Lのスコア行列を作ってHBMへ書き出し、softmaxのために読み戻し、結果をまた書き出し、Vとの積のために再度読み込みます。系列長8,192なら1ヘッドあたり約6,700万要素、fp16で128MiBの行列がこの往復を何度も通り、演算器は待たされます。これが帯域律速です。アテンションの数式そのものはTransformerの自己注意の仕組みで扱っています。
A100のメモリ階層|SMあたり192KBのSRAMとGPU全体で約19TB/sの帯域
削る余地はメモリ階層の落差から生まれます。論文のセクション2.1は、A100について「40〜80GBのHBM、帯域1.5〜2.0TB/s」「108基のSMそれぞれに192KBのオンチップSRAM、帯域は19TB/s程度と推定」と書いています。SRAMは一桁速く、容量は何桁も小さい。192KBの枠にQ・K・Vのブロックを収めれば、中間結果をHBMへ出さずに済みます。理論解析ではHBMアクセス量が標準実装のΘ(Nd+N²)からΘ(N²d²M⁻¹)に下がります(Nは系列長、dはヘッド次元、MはSRAMに格納できる要素数で、原論文の定理はd≤M≤Ndを仮定)。GPU側の実行モデルはCUDAの仕組みとGPU並列計算にまとめています。
厳密計算のまま省メモリ化する点でスパース化と分かれる境界線
FlashAttentionは全トークン対を計算します。省くのはメモリ往復で、計算するペアではありません。一方、スパースアテンションによる疎化は見る相手を減らす近似で、精度と引き換えに計算量を落とします。両者の違いは、全トークン対を計算するか、計算するペアを絞るかにあります。疎パターンをFlashAttention系のカーネル上に実装する構成もあり、両者は排他ではありません。
タイリング・オンラインsoftmax・再計算という3つの仕組み
QKVをブロック分割してSRAMへ載せるタイリングの手順
- K・Vを行方向のブロックに割り、外側ループで1ブロックずつSRAMへ読み込む
- 内側ループでQのブロックを読み込み、そのブロック対だけのスコアを計算する
- スコアに部分的なsoftmaxを掛け、Vブロックとの積を出力バッファへ足し込む
- 全ブロックを回り終えた時点で、出力バッファが完全なアテンション出力になる
ブロックの大きさはSRAM容量とヘッド次元で決まります。ヘッド次元が大きいほどブロックを小さく取らざるを得ず、FA2の公式READMEはヘッド次元の上限を256としています。
最大値と正規化項を持ち回るオンラインsoftmaxの再スケール
softmaxは全要素の最大値と総和を必要とするので、素直に分割すると計算できません。FlashAttentionはブロックごとに「これまでの最大値」と「これまでの正規化項の総和」を持ち回り、新しいブロックでより大きな値が出たら、足し込み済みの出力を新しい最大値の基準へ再スケールしてから加算します。この補正があるため、分割しても最終値は一括計算と一致します。
逆伝播でL×L行列を保存せず再計算する設計
学習時の勾配計算には順伝播のスコア行列が要りますが、保存すればメモリはO(N²)に戻ります。FlashAttentionはスコア行列全体を保存せず、逆伝播でQとKのブロックからスコアを再計算し、順伝播で保存したsoftmaxの正規化統計量を使って確率を復元します。演算量は増えても、HBM往復が減るぶん実時間は短くなる、という判断です。論文はこの省メモリ性で、系列長16KのPath-XではFlashAttentionで正解率61.4%、64KのPath-256では近似を含むBlock-sparse FlashAttentionで63.1%と、従来のTransformerが偶然以上の精度を出せなかった長さでの学習を報告しました。
CPUのPyTorch SDPAで測った一致度とメモリ削減の実測値
「厳密」と「省メモリ」が本当かを、GPUなしで確かめられる範囲で測りました。PyTorchのscaled_dot_product_attentionはCPUにもFlashAttention型の実装を持っており、素朴な計算(MATH)と切り替えて比べられます。環境はIntel Core i9-9880H(PyTorchの使用スレッド数8)・Python 3.11.15・torch 2.2.2のCPU版、バッチ1・8ヘッド・ヘッド次元64・fp32・因果マスクありで、時間は各経路でウォームアップ1回後の5回平均、メモリは別プロセスでQ・K・V生成後から計測したピークRSSの増分です。
| 系列長 | MATHの時間 | FLASHの時間 | 出力の最大誤差 | MATHのメモリ増分 | FLASHのメモリ増分 |
|---|---|---|---|---|---|
| 1,024 | 66.3ms | 14.0ms | 1.1e-06 | ― | ― |
| 2,048 | 240.4ms | 55.3ms | 5.4e-07 | ― | ― |
| 4,096 | 1,155.2ms | 172.2ms | 4.8e-07 | 1,146MiB | 14MiB |
| 8,192 | ― | ― | ― | 4,294MiB | 22MiB |
読み取れることは3つです。出力の差はfp32の丸め誤差(1e-06前後)に収まり、近似ではありません。MATHのメモリ増分は系列長が2倍になると約4倍に増え、8ヘッド×8,192²×4バイト=2,048MiBのスコア行列2つ分に近い値です。ただし、ピークRSSの差分だけでは確保されたテンソルの内訳までは特定できません。FLASHは同じ条件で22MiBに留まりました。時間の比はCPUの値で、GPUの公称値とは比べられません。
もう1点、FLASH経路だけを許可して任意のattn_maskを渡すと、torch 2.2.2では「No available kernel」の例外になりました。経路を強制すると、条件に合わないときに黙って遅い経路へ落ちず、例外で止まります。この性質は後述の切り分けに使えます。
import torch, torch.nn.functional as F
try:
from torch.nn.attention import sdpa_kernel, SDPBackend
except ImportError: # torch 2.2系は旧API torch.backends.cuda.sdp_kernel
import enum
class SDPBackend(enum.Enum):
MATH = "math"
FLASH_ATTENTION = "flash"
def sdpa_kernel(backend):
return torch.backends.cuda.sdp_kernel(
enable_flash=backend is SDPBackend.FLASH_ATTENTION,
enable_math=backend is SDPBackend.MATH,
enable_mem_efficient=False,
)
q, k, v = (torch.randn(1, 8, 4096, 64) for _ in range(3))
with sdpa_kernel(SDPBackend.MATH):
a = F.scaled_dot_product_attention(q, k, v, is_causal=True)
with sdpa_kernel(SDPBackend.FLASH_ATTENTION):
b = F.scaled_dot_product_attention(q, k, v, is_causal=True)
print((a - b).abs().max()) # 値は乱数入力と環境で変わる。検証ログの一例は4.8e-07
FA1からFA4までの世代差|対応GPUと公称スループット
版が上がるたびに変わったのはアルゴリズムの骨格ではなく、そのGPU世代の非同期機構をどこまで使い切るかです。
FA1の3倍・FA2の225TFLOPs・FA3の740TFLOPsという公称値
初代は、BERT-largeの学習でMLPerf 1.1の記録比15%の高速化、GPT-2(系列長1K)で3倍、Long-Range Arenaで2.4倍を示しました。FlashAttention-2(arXiv 2307.08691・2023年7月)は仕事の分割を見直して初代比約2倍、GPT系モデルの学習でA100あたり225TFLOPs(モデルFLOPs利用率72%)。FlashAttention-3(arXiv 2407.08608・2024年7月)はHopperのTMAとワープ特化を使い、H100でFP16がFA2比1.5〜2.0倍・740TFLOPs(利用率75%)、FP8で1.2PFLOPs近くに届きました。FP8時の数値誤差は従来のFP8アテンションの2.6分の1です。FP8自体の形式はFP8とFP16・BF16の違いで解説しています。
FA4のB200で1613TFLOPsとflash-attn-4のpre-release状態
FlashAttention-4(arXiv 2603.05451・2026年3月5日)は、B200のBF16でcuDNN 9.13比最大1.3倍、Triton比最大2.7倍、最大1613TFLOPs(利用率71%)を公称しています。Blackwellではテンソルコアの速度が倍になった一方で、共有メモリ帯域と指数関数ユニットは伸びが小さいか据え置きです。そこで指数関数をソフトウェアで近似し、softmaxの再スケールを必要なときだけ行う設計に変えました。実装はC++テンプレートをやめ、PythonのCuTe-DSLで書かれています。公式READMEはFA4を「Hopper and Blackwell」向けとしており、H100でも動きます。
ただしPyPIのflash-attn-4は4.0.0b35(2026年10月14日)で、9月から毎週ベータ番号が上がっている段階です。本番では検証済みの版に固定し、採用する版を更新するときに互換性・性能・出力品質を再検証します。
VoltaからBlackwellまでのGPU世代と使える実装の一覧
| 世代 | 代表機種 | FA2 | FA3 | FA4 | PyTorch SDPAのCUDA FLASH経路 |
|---|---|---|---|---|---|
| Volta | V100 | × | × | × | ×(sm80未満) |
| Turing | T4、RTX 2080 | 別リポジトリで一部 | × | × | ×(sm80未満) |
| Ampere | A100、RTX 3090 | ○ | × | × | ○ |
| Ada | RTX 4090、L40S | ○ | × | × | ○ |
| Hopper | H100、H800 | ○ | ○(beta) | ○(pre-release) | ○ |
| Blackwell | B200 | README記載なし | × | ○(pre-release) | ○ |
| AMD CDNA・RDNA | MI200、MI300、RDNA | ROCm版 | × | × | ― |
T4はVoltaではなくTuring世代です。FA2本体は対応していませんが、READMEが案内するflash-attention-turingが機能の一部を提供しています。PyTorch SDPAの列は、torch 2.14.1のソースがCUDAのFLASH経路にsm80〜sm121を要求していることによります。
flash-attnのインストール手順|pip・MAX_JOBS・Windows・ROCm
FA2のpip導入とMAX_JOBSによるビルド並列数の制限
公式READMEの要件は、Linux、CUDA 12.0以上、PyTorch 2.2以上、packaging・psutil・ninjaです。READMEによると、ninjaが無いとCPUコアを1つしか使わずビルドに2時間かかることがあり、ninjaありなら64コアのマシンで3〜5分です。逆にメモリが96GB未満でコア数が多いマシンでは並列ジョブがメモリを使い切ることがあるため、MAX_JOBSで絞ります。
pip install packaging psutil ninja
MAX_JOBS=4 pip install flash-attn==2.8.3.post2 --no-build-isolation
FA3のhopper配下からの導入とFA4のパッケージ導入
FA3は「統合前のテスト・ベンチマーク用のbeta release」とREADMEにあり、H100かH800とCUDA 12.3以上(12.8推奨)が要件です。公開済みの機能はFP16・BF16の順伝播と逆伝播、FP8の順伝播までで、FP8の逆伝播はまだありません。FA4はビルド不要のパッケージで入ります。
# FA3(リポジトリをcloneしてから)
cd hopper && python setup.py install
# FA4(CUDA 13系はcu13の追加指定を推奨)
pip install flash-attn-4
pip install "flash-attn-4[cu13]"
WindowsとAMD ROCmで導入するときの条件
Windowsについて、READMEは「v2.3.2以降は動く可能性があるが、コンパイルにはさらに検証が要る」という扱いで、Windows向けの事前ビルドは協力者を募っている段階です。PyPIの2.8.3.post2もソース配布(tar.gz)だけです。Windowsで試すなら、まずPyTorch SDPA経由で内蔵の実装を使い、それで足りないときだけビルドに進むほうが早く結論が出ます。
AMDはROCm 6.0以上で、2つのバックエンドがFA2を提供します。既定のComposable Kernel版は、2.8.3.post2のREADMEではMI200・MI300を対応GPUとして挙げています。開発版mainの記載はMI200x・MI250x・MI300x・MI355xとRDNA 3/4まで広がっています。CK版のdtypeはfp16とbf16、ヘッド次元は256までです。Triton版はCDNAとRDNAでfp32も扱え、FLASH_ATTENTION_TRITON_AMD_ENABLE="TRUE"を付けてソースから入れます。
Hugging Face Kernelsの事前ビルド版でビルドを省く
CUDAツールキットを持ち込めない環境では、kernelsライブラリがHubから事前ビルド済みのFA2・FA3を取ってきます。Transformersならattn_implementation="kernels-community/flash-attn2"と書くだけで、flash-attnパッケージ自体は要りません。
Transformers・PyTorch SDPA・vLLMでFlashAttentionを有効にする設定
Transformersのattn_implementationで指定する値
Transformers 5.20.1(2026年10月16日)では、attn_implementationにflash_attention_2・flash_attention_3・flash_attention_4・sdpa・flex_attentionが登録されています。from_pretrainedで渡すのが基本で、読み直さずに切り替えるならset_attn_implementationを呼びます。マルチモーダルモデルでは{"text_config": "flash_attention_2"}のように辞書で部位ごとに指定できます(Attention backendsのドキュメント)。
import torch
from transformers import AutoModelForCausalLM
# 事前にモデルのアクセス承認を取得し、承認済みアカウントで認証する
# transformers・accelerateと、対応するCUDA版PyTorch・flash-attnを導入しておく
model = AutoModelForCausalLM.from_pretrained(
"meta-llama/Llama-3.2-1B",
dtype=torch.bfloat16, # CUDA版FA2はfp16かbf16を使用
device_map="cuda", # 対応するCUDA GPUへ配置
attn_implementation="flash_attention_2",
)
model.set_attn_implementation("sdpa") # 比較用に切り替え
PyTorchのsdpa_kernelによるFLASH_ATTENTIONの強制指定と動作確認
scaled_dot_product_attentionは条件を見て内部の実装を自動で選びます。torch 2.14.1のソースでは、CUDAのFLASH経路の条件はsm80〜sm121のGPU、Q・K・Vのヘッド次元が等しく256以下、dtypeがfp16かbf16(sm90以上でFA3を有効にしたときはFP8も可)です。torch.nn.attention.sdpa_kernel(SDPBackend.FLASH_ATTENTION)で囲めば、条件を外れたときに例外が出るので、ベンチマークの前に一度通しておくと「実は使われていなかった」を防げます。
vLLMのattention-backend引数によるFLASH_ATTNの指定
vLLMの環境変数VLLM_ATTENTION_BACKENDは、v0.13.0のリリースノートで--attention-backend引数に置き換えられました。古い記事の手順をそのまま使うと設定が効きません。最新の0.32.0(2026年10月18日)ではFLASH_ATTNがFlashAttentionの識別名で、設定項目flash_attn_versionに2・3・4を指定できます。未指定なら自動選択なので、FP8のKVキャッシュなど組み合わせで選択がずれたときだけ触ります。サーバー全体の構成はvLLMとPagedAttentionの解説にあります。
vllm serve Qwen/Qwen3-8B --attention-backend FLASH_ATTN
llama.cppとOllamaのFlash Attention設定(-fa・OLLAMA_FLASH_ATTENTION)
ローカルLLMで「--flash-attn」を検索する人が多いのは、llama.cppのオプション名がそのままだからです。llama.cppのFlash Attentionはggml内の独自カーネル(CUDA版はggml-cuda/fattn.cu)で、Dao-AILabのflash-attnパッケージは使いません。Apple SiliconのMetalのように、flash-attnの対象外の環境でも、対応するバックエンドなら有効にできます。
llama-serverのREADMEでは、-fa, --flash-attnの値はon・off・autoで既定はauto、環境変数はLLAMA_ARG_FLASH_ATTNです。Ollamaは対応するバックエンドとデバイスなら自動で使い、サーバー起動時にOLLAMA_FLASH_ATTENTION=1で強制、0で無効にします(Ollama FAQ)。
実利が大きいのはKVキャッシュの量子化との組み合わせです。OllamaのOLLAMA_KV_CACHE_TYPE=q8_0はFlash Attentionが有効なときに効き、FAQはf16の約半分のメモリと説明しています。ローカル環境の組み方はローカルLLMの必要スペックとOllamaでの構築手順を参照してください。
llama-server -m model.gguf -fa on -ctk q8_0 -ctv q8_0
OLLAMA_FLASH_ATTENTION=1 OLLAMA_KV_CACHE_TYPE=q8_0 ollama serve
導入しても速くならない原因|dtype・head_dim・マスク形式・系列長
「入れたのに変わらない」ときは、まず入力条件、マスク形式、プリフィルとデコードの違いを切り分けます。対応条件を満たさず別の経路が選ばれる場合や例外になる場合に加え、カーネルが選ばれていても処理全体の高速化が小さい場合があります。
CUDA版FA2のfp32入力・head_dim 256超の非対応条件
CUDA版FA2が扱えるのはfp16とbf16だけで、bf16はAmpere以降に限られます。ヘッド次元は256までです。SDPAの自動選択では別の対応バックエンドが選ばれますが、FLASH経路の強制やFA2の直接呼び出しでは例外になる場合があります。まずmodel.dtypeとconfig.head_dimを出力し、前提を数値で確かめてください。
TransformersのFA2における4Dマスクの非対応
Transformersのドキュメントは、sdpaがboolかfloatの4Dマスクを受け取る一方、flash_attention_2とflex_attentionは独自の形式(2Dのパディングマスクと BlockMask)しか受け付けず、生の4Dマスクは使えないと明記しています。自前で4Dマスクを組んで渡している既存コードは、FA2へ切り替えたところで噛み合いません。
短い系列の効果とデコード向け最適化の違い
削る対象がL×L行列の往復である以上、Lが小さいほど効果も小さくなります。1トークンずつ生成するデコードではQ側の長さが1で、律速はKVキャッシュの読み出しに移ります。FA2は2.2からこの場面向けに、KVキャッシュの読み込みを複数のスレッドブロックへ分割する最適化を入れており、関数flash_attn_with_kvcacheとして提供しています。デコードはプリフィルとは別の経路として測ってください。効果はGPU・バッチサイズ・系列長・比較対象で変わります。
FlashAttentionを採用してよい条件と、見送るべき場面
条件を満たすなら、FlashAttentionは既定で入れておく実装です。数学的には同じアテンションを計算しますが、演算順序やdtypeによる数値差があるため、対象モデルの品質評価は必要です。
採用してよい条件はGPU世代・系列長・dtypeの3点
GPUがAmpere以降(A100、RTX 3090、RTX 4090、L40S、H100、B200)であること。学習かプリフィルで扱う系列長の分布を確認し、代表的な長さとバッチサイズで速度・ピークメモリを比較すること。モデルをfp16かbf16で動かせること。この3点に加え、モデル側の対応、ヘッド次元、マスク形式、学習時のdropout条件、必要な依存パッケージを確認できれば、対応モデルではattn_implementationで切り替えられ、空いたメモリでバッチを増やせばスループットにも効きます。
見送るべき場面はfp32必須・V100のみ・依存を固定できない環境
数値の完全再現のためにfp32推論が要件の検証系、V100しか調達できない環境では、flash-attnを入れても依存が増えるだけです。また、FA3(beta)やFA4(pre-release)を、更新の検証体制なしに本番の依存へ固定するのも避けるべきです。H100でもまずFA2かSDPAで動かし、FA3・FA4は効果を測ってから切り替えます。
LLM基盤の構築を外注するとき見積書で確認する5項目
- 採用するアテンション実装と版が明記され、調達GPUの世代と対応しているか
- fp16・bf16・FP8のどれで動かす前提か、精度検証の工程があるか
- カーネルが実際に選ばれたことをログかベンチマークで確かめる手順があるか
- 系列長の実測分布をもとに、プリフィルとデコードの費用を分けているか
- CUDA版・ツールキットなどビルド環境の前提が納品環境と一致しているか
この5項目が見積書や検収仕様にない場合、想定したカーネルの使用と性能を何で確認するか、発注前に合意しておく必要があります。GPU調達や構成の選定から相談したい場合は、機械学習モデル開発の受託で相談できます。推論全体の高速化手段の優先順位はLLM推論の高速化手法と推論基盤の選び方、導入の全体像はLLMの仕組みと企業導入の判断基準で整理しています。
よくある質問
FlashAttentionを使うと出力の精度は落ちますか?
標準アテンションと数学的には同じ計算ですが、演算順序や使用する数値形式によって差が生じるため、モデル品質が常に不変とは保証できません。CPUでのfp32実測では最大誤差が1e-06前後で、丸め誤差の範囲でした。FP8などの低精度形式で動かす場合は、対象モデルで品質を評価してから切り替えてください。
FlashAttention-3と4のどちらを入れればよいですか?
B200ならFA4しか選べません。H100ならどちらも動きますが、FA3はbeta、FA4はpre-releaseです。FA3はFP8の逆伝播がまだ無く、FA4は毎週ベータ番号が上がっています。本番で使うなら、まずFA2かSDPAで基準を測り、差が出る系列長のときだけ切り替えるのが安全です。
V100やT4でFlashAttentionは使えますか?
CUDA版FlashAttention-2とPyTorch SDPAのCUDA用FLASH経路は、いずれもAmpere(sm80)以降の対応GPUが対象で、V100とT4では使えません。T4(Turing)には別リポジトリのflash-attention-turingが機能の一部を提供しています。llama.cppとOllamaのFlash Attentionは独自実装なので、この制約とは別に判断します。
WindowsでFlashAttentionは使えますか?
flash-attnの公式な対応はLinuxで、Windowsはv2.3.2以降で動いた報告がある段階です。配布ビルドも無いため、Windowsではまずattn_implementation="sdpa"でPyTorch内蔵の実装を使い、それで足りない場合だけビルドを試してください。
FlashAttentionとPagedAttentionは何が違うのですか?
削る対象が違います。FlashAttentionはアテンション計算のメモリ往復を減らすカーネルで、プリフィルと学習に効きます。PagedAttentionはvLLMのKVキャッシュ管理方式で、キャッシュをページ単位に分けて断片化を抑え、デコード段階のバッチ密度を上げます。両者は競合せず、vLLMでは同時に使えます。