NVIDIA CUDA TileによるMamba-2フォワードパスカーネルの高速化と実装詳解
NVIDIA CUDA Tile(cuTile)による次世代GPUプログラミングのパラダイム
NVIDIAが提供する CUDA Tile(cuTile) は、スレッドレベルおよびワープレベルの複雑なスケジューリングを抽象化し、高水準のタイル中心プリミティブによってTensor Coreなどの高度なハードウェア機能を自動的に活用するためのPythonベースDSL(ドメイン固有言語)および並列プログラミングモデルです。
従来のGPUプログラミング(CUDA C++など)では、共有メモリの管理やスレッド間の同期、メモリアクセスの最適化において膨大なボイラープレートコードと深いハードウェア知識が必要でした。しかし、cuTileを採用することで、機械学習エンジニアはPython環境上で直感的なタイル単位の演算記述を行いながら、コンパイラ側の自動最適化によってハードウェアの限界性能を引き出すことが可能になります。Jane Streetの機械学習エンジニアは、このcuTileの早期導入パートナーとして最先端の状態空間モデル(SSM)である Mamba-2 の実装を行い、NVIDIAとの共同作業によってフォワードパスのカスタムカーネル最適化を達成しました。
Mamba-2の計算トレードオフと3つのカスタムカーネルアーキテクチャ
シーケンスモデリングにおいて、従来のソフトマックスアテンションはTensor Coreを活用した高い並列学習性能を誇る一方で、推論時の計算量とメモリ要件がシーケンス長に対して線形に増加するという課題を抱えています。対照的に、従来のリカレントニューラルネットワーク(RNN)は学習の並列化が困難な反面、推論時はシーケンス長に依存せず計算量とメモリフットプリントが一定という特徴があります。
Mamba-2はこの両者の長所を統合するアーキテクチャであり、リカレント更新をチャンク単位で効率的に処理します。本記事で解説する最適化されたフォワードパスは、主に以下の3つのカスタムカーネルで構成されています:
-
chunk_cumsumカーネル: 各チャンク内における減衰項(decay term)のトークン毎・ヘッド毎の累積和を対数空間(log-space)で計算します。ct.cumsumプリミティブを使用し、後続のカーネルで再利用するための結果を効率的にストレージに格納します。また、expよりも低コストなexp2を活用するため、スケーリング係数としてlog2(e)を乗算する数値安定性の工夫も盛り込まれています。 -
fwd_pass_stateカーネル: ジャンプ公式を用いて、シーケンスチャンクを跨ぐ隠れ状態(hidden state)を逐次的に進めるための初期状態を計算します。ct.mmaによるTensor Coreの行列積演算を駆使し、指数減衰と事前に乗算されたオペランドを適用します。 -
compute_outカーネル: 持ち越された状態項、減衰および因果マスク(causal mask)された相互作用行列、そしてスキップ接続(skip connection)を単一のタイル化されたカーネルへと融合します。中間行列をレジスタ内に保持し、Tensor Core実行のためにTF32へキャストすることで、DRAMトラフィックを最小限に抑えています。
# 実装例: chunk_cumsum カーネルの基本構造 (cuTile)
@ct.kernel
def chunk_cumsum_kernel(
a: torch.Tensor, # [num_heads]
dt: torch.Tensor, # [batch_size, num_tokens, num_heads]
output: torch.Tensor, # [batch_size, num_tokens, num_heads]
chunk_size: ct.Constant[int],
BLOCK_H: ct.Constant[int],
) -> None:
chunk_idx, head_tile_idx, batch = ct.bid(0), ct.bid(1), ct.bid(2)
dt_tile = ct.load(dt, index=(batch, chunk_idx, head_tile_idx),
shape=(1, chunk_size, BLOCK_H),
padding_mode=ct.PaddingMode.ZERO).astype(ct.float32)
a_tile = ct.load(a, index=(head_tile_idx,),
shape=(BLOCK_H,),
padding_mode=ct.PaddingMode.ZERO).astype(ct.float32)
d_tile = ct.cumsum(a_tile * dt_tile, axis=1) * LOG2E
ct.store(output, index=(batch, chunk_idx, head_tile_idx), tile=d_tile.astype(output.dtype))
数値安定性とメモリレイアウトの最適化
Mamba-2のコア再帰方程式およびその出力計算を高速にGPU上で実行するにあたっては、厳密な数値安定性の担保とメモリ帯域のボトルネック解消が不可欠です。
特に、減衰項の累積和 $G$ を用いた計算において、指数関数の中に正の値が混入するとオーバーフローや数値不安定性を引き起こすリスクがあります。Mamba-2の数学的構造では、モデルパラメータである $a_t$ が常に負の値であるため、差分 $g_i - g_j$ も一貫して負になり、因果マスク(causal mask)によって未来の不正な正の指数項が完全に排除される仕組みになっています。これにより、安全かつ高速なFP32/TF32演算パイプラインが維持されます。
さらに、メモリアクセスの最適化においては、TMA(Tensor Memory Accelerator)フレンドリーな転置メモリレイアウトの採用や、DRAMトラフィックを隠蔽するためのレイテンシヒント、さらには入力形状ごとに最適なブロックサイズや占有率(occupancy)を動的に探索するオートチューナーの統合など、ハードウェアの性能限界を引き出すための高度なエンジニアリングが施されています。
開発者・エンジニア視点での考察
-
PythonファーストなGPUカーネル開発の現実解: cuTileの導入により、低水準なCUDA C++やPTXを書くことなく、Pythonエコシステム(PyTorch等)の親和性を保ったままカスタムカーネルを記述・最適化できるようになる。これは、AI研究者やMLエンジニアが独自のアーキテクチャ(Mambaなどの非アテンション系モデル)を迅速にハードウェアに最適化する上で強力な武器となる。
-
メモリスループットと演算器の融合(Kernel Fusing)の重要性:
compute_outカーネルにおけるスキップ接続、因果マスク付き行列積、指数減衰項のインレジスタ処理は、メモリ帯域がボトルネックになりやすいTransformer以外のモデルにおいて、GPUの演算能力(FLOPs)を最大限に引き出すための設計パターンとして他のSSMやRNN系アーキテクチャの拡張にも広く応用できる。 -
数値表現とハードウェア命令の密な連携: 対数空間(log-space)への変換による乗算の加算化や、
exp2の積極採用、TF32への型キャストによるTensor Coreの効率的駆動など、アルゴリズムの数学的性質(負の減衰項の特性など)とGPUのハードウェア命令を高度に一致させるアプローチは、今後の高効率LLM/SSM開発の標準的なベストプラクティスとなる。
Source / 元記事
この記事について
この記事は、公開されているニュース、論文、公式発表、RSSフィードなどをもとに、AIが要約・補足調査・考察を行って作成しています。
元記事の完全な翻訳・逐語的な要約ではなく、AIによる背景説明や開発者向けの考察を含みます。
重要な技術仕様・価格・提供状況などは、必ず元記事または公式情報をご確認ください。


