Share
Embed
Transcript
50 slides
-
目次 ・自己回帰型モデルでの言語生成方法のおさらい ・実際に推論してみよう(通常のtorch) ・アルゴリズム的な高速要素: KVCache, FlashAttention, Super Sequence + Continual
Batching, PagedAttention, Speculative Decoding ・アルゴリズム的な高速要素の実装: CUDA, Triton, CuTe, KernelFusion ・アーキテクチャ面: GQA, MLA, Sliding Attention, Linear Attention ・量子化 ・Profiler: Nsight Compute, Nsight Systems + NVTX ・CUDAGraph ・vLLMの紹介とコントリビュート方法: Chunked Prefill, Preemption, Prefill-Decode Disaggregation ・実際に推論してみよう(vLLM) ・複数ノード分散(概念のみ): MPI, Data Parallel, Pipeline Parallel, Tensor Parallel, Context Parallel ・NVIDIA製GPU: Tensor Core, TMA, Compute Capability -
本日のまとめ Attention部分: ・KVCacheでDecodeを高速化 ・PagedAttentionでメモリ使用量・ アクセス量を効率化 ・GQAなどのアーキテクチャで計 算量とKVCacheメモリを削減 Tokens生成部分: ・Speculative Decodingで1度に予測す
るTokens数を増加 処理全体: ・量子化でメモリ使用量 , 転送量 を削減 ・CUDAGraphでCPU待ち時間を 削減 ・Super Sequence + Continual Batchingで余分なメモリ使用量を 削減 ・PrefillとDecodeは分離するか同 時に処理するかしてリクエストの 割り込みを許可 ・大きいモデルは並列分散処理 -
まずはともあれ推論してみよう URL: https://colab.research.google.com/drive/1ZVHxBKH9L4r3yf5AF7hEzMP7CONHLb 9l?usp=sharing 今回のイベントを通して使用するモデルはQwen/Qwen2.5-0.5B-Instruct, Colabの無 料枠で使えるTesla GPUのハードウェア上で動くモデルかつ軽量なもので適合したのが これであった Transformersの部分までの推論を動かすと,
現時点では5.97 tokens / secとなるはず 後半のvLLMは94.84 tokens / secとなるので最後まで聞くと何故Transformersを使っ た推論が遅いのかという問題に答えられるようになるはず -
アルゴリズム的な要素での高速化: KVCache ・文章を生成する時に必要な情報 はAttention計算後の最後の Tokensが持つ隠れ層 ・この最後の隠れ層はKとVの計測 結果をCacheし続けておくことで計 算量を減らすことが可能(右図) ・余談として最初のPrompt全てを 計算してKVCacheを構築する段階
をPrefill, KVCacheを使用して1トー クンずつ予測していく段階を Decodeといいます。 -
・正直説明されてもよくわからないと思うのでColabを作成しました https://colab.research.google.com/drive/1uZLXqNGUsoRwFOGQQ8pQ422iNQvU mEP9?usp=sharing ・KVCacheが長系列の推論時にはメモリボトルネックになりえます。KVCacheのsizeは 以下の式で求められます 2 * batch_size * num_layers
* sequence_length * head_dim * num_heads ・batch_size = 16, num_layers = 96, sequence_length = 32768, head_dim = 128, num_heads = 8, float16とかで計算をしてみるとなんと192GiBとなります ・KVCacheのsizeを減らすための研究は後々話します アルゴリズム的な要素での高速化: KVCache -
Super Sequence + Continual Batching ・PagedAttentionの前にvLLMなどで使われているBatching方法について解説する ・推論システムとしては複数のリクエストをバッチ処理する必要がある ・この時PyTorchでやるようにBatchを組み立てるとRequestのtoken_idの列は (batch_size, max_n_tokens)となるため,
リクエストの中で最もtokens長が長い部分に 引っ張られ, 余分なpaddingが生じてしまう ・Super Sequence (命名はvLLMのブログより)ではリクエストのtokens列を2次元のテ ンソルではなく1次元のtokens列にして処理を行い,paddingを無くしている -
Super Sequence + Continual Batching Super Sequenceにより新しくリクエストがきた時には末尾に新しいtokens列をくっつけ るだけでよくなる。現在きているリクエストを処理しながら新しいリクエストを受け付けるこ の方法をContinual Batchingという
その場合, Attentionのmask計算を工夫することで違いの文章の相互作用を防いでいる (次スライド) -
アルゴリズム的な要素での高速化: PagedAttention PagedAttention はOSのPaging機構からインスピレーションを受け, KVCacheをBlock 単位で管理し, Batch推論におけるKVCacheの余分な断片化, Paddingを無くす手法で ある。 詳しくはvLLMのブログのgifが詳しいため確認するが,
実際には概念だけではなく vLLM内部でこれを可能にする実装が偉い(HPCは実装の方が大切) -
アルゴリズム的な要素での高速化: Speculative Decoding ・最後の2段階のCluster行列の計算を見積もってみます。 通常の1 tokensあたりの行列積の計算量はhidden_dim * vocab_sizeです。 ・2段階のCluster行列の場合計算量はhidden_dim *
(cluster_size + vocab_size_in_cluster)です。 -
アルゴリズム的な要素での高速化: Speculative Decoding 均等に割り振られているとしてvocab_size_in_cluster = vocab_size / cluster_sizeとし てみます。 1
<= cluster_size <= vocab_sizeであることに注意すると(相加相乗平均などで整理), 大雑把に評価して 2√vocab_size <= cluster_size + vocab_size / cluster_size <= vocab_size + 1 となるので, 大体の極端じゃないcluster_sizeにおいては多分cluster_size + vocab_size / cluster_sizeはvocab_sizeより小さくなり, Cluster行列にした方が早いと 思います(あと2段階目のメモリloadが減るのも嬉しい) 余談: 等号成立条件は工学部なので確認しない -
アルゴリズム的な要素での高速化の実装: CUDA ・CUDAの最適化の80%はメモリをどう効率的に読んでいくかを最適化することになる ・CUDAはshared memoryと呼ばれるConfigurableなCache領域を持つ, ここに複数回 アクセスされるデータをloadして最適化することが多い ・余談: このような高速な有限メモリと低速な大容量メモリの間を扱うような理論として Red-Blue
Pebble gameとかCommunication Avoiding Algorithmがあるので調べてみ てください -
アーキテクチャ面: GQA, MLA ・普通のMulti-Head Attentionは1つのQueryに対して1 pairのKVが対応したが Grouped Query Attentionでは複数のGrouped Queryに対して1
pairのKVが対応する ・これにより1トークンあたりのKVCacheの量が少なくなる -
Multi-Head Latent Attention: 具体的な計算 (昔計算した) ・low-rankにすることの意義を計算する。計算に使う parameterはGitHubから取得, 計算は1 batch分で行う ・従来はSequence
× hidden_dim -> n_heads * (k_head_dim + q_head_dim)の計算が走る ・なので計算量は Sequence(S) × hidden_dim × n_heads × (k_head_dim + q_head_dim) = 8,388,608 × S, KV Cacheは4096×F×S bytesだけ保存する(Fはfloat32で4, float16で2) ・ここで512にlow-rankにすると ・計算量はS × hidden_dim × low-rank + S × low-rank × n_heads × (k_head_dim + q_head_dim) = 3,145,728 × S, KV Cacheは512×F×S bytesだけ保存する ・以上より, 計算量は3 / 8に, KV Cacheの容量は1 / 8になる →AttentionのKV部分の計算時間は 3 / 8に, KV Cacheのload時間が1 / 8に, しかも同一容量で 8倍の sequenceを扱うこともできる ・このあたりは性能とメモリ削減量のトレードオフを見ながら調整されているだろうことを考えると相当の努力が 見られる -
アーキテクチャ面: Linear Attention ・Qwen3.5以降のQwenで採用されているAttention ・Attention部分の計算が小さく, KVCacheのメモリ消費量も小さい ・おそらく実装はここ https://github.com/fla-org/flash-linear-attention/blob/6f62104c1ec677e5951ac5464 2fd166e765db54e/fla/ops/common/fused_recurrent.py#L30 ・KVの代わりに前のhidden_stateを使う都合上,
採択tokens数に応じてSpeculative Decodingのような途中までのKVCacheを廃棄するような手法に弱い -
量子化 パラメーターを表現するための必要なbit数を減らすことでメモリ容量を削減し, かつ計算 時のメモリストールの時間を減らすことができる技術 GPT-OSSなどのMoE部分はFP4で量子化されていたりする。これはMoEが全体のうち 90%以上を占めるメモリボトルネックであるためである 精度を保つための方法として以下の工夫がある ・Block-wise Scaling ・Mixed
Precision Accumulation Mixed Precisionに関して少し面白い話があるので紹介する -
量子化: Mixed Precision Accumulation ・多分HPCの人間にしか知られていない手法として, Ozaki Schemeが存在する ・Ozaki Schemeは低精度計算を利用して高精度の行列演算をEmulateする手法であ る
・つまり, FP32の精度を計算するのにFP16のTensor coreやハードウェアを使うことが でき, FP32演算のカタログ値以上の速度を出すことが可能となる ・これはcuBLASにも統合されている -
まとめ Attention部分: ・KVCacheでDecodeを高速化 ・PagedAttentionでメモリ使用量・ アクセス量を効率化 ・GQAなどのアーキテクチャで計 算量とKVCacheメモリを削減 Tokens生成部分: ・Speculative Decodingで1度に予測す
るTokens数を増加 処理全体: ・量子化でメモリ使用量 , 転送量 を削減 ・CUDAGraphでCPU待ち時間を 削減 ・Super Sequence + Continual Batchingで余分なメモリ使用量を 削減 ・PrefillとDecodeは分離するか同 時に処理するかしてリクエストの 割り込みを許可 ・大きいモデルは並列分散処理 -
他の話題 ・Roofline modelは見てください, 大体は行列積ぐらいじゃないとCompute boundになら ないです ・複数ノード分散(概念のみ): MPI, Data Parallel,
Pipeline Parallel, Tensor Parallel, Context Parallel ・NVIDIA製GPU: Tensor Core, TMA, Compute Capability