Home 論文解説: DeepSeek-V2 — Multi-Head Latent Attentionによる93.3%のKVキャッシュ削減
投稿
キャンセル

📄 論文解説: DeepSeek-V2 — Multi-Head Latent Attentionによる93.3%のKVキャッシュ削減

本記事は DeepSeek-V2: A Strong, Economical, and Efficient Mixture-of-Experts Language Model (arXiv:2405.04434) の解説記事です。

論文概要(Abstract)

DeepSeek-V2は、236Bパラメータ(トークンあたり21Bアクティブ)のMixture-of-Experts(MoE)言語モデルである。著者らが提案するMulti-Head Latent Attention(MLA)は、KeyとValueを低ランクの潜在ベクトルに圧縮してキャッシュすることで、標準的なMHA(Multi-Head Attention)比で93.3%のKVキャッシュ削減を達成した。DeepSeek 67Bと比較して、学習コスト42.5%削減、推論スループット5.76倍を報告している。

この記事は Zenn記事: Attention機構の全史 Bahdanauから FlashAttention4・MLAまでの数学と実装 の深掘りです。

情報源

  • arXiv ID: 2405.04434
  • URL: https://arxiv.org/abs/2405.04434
  • 著者: DeepSeek-AI(156名以上の共同研究チーム)
  • 発表年: 2024年5月(最終改訂: 2024年6月)
  • 分野: cs.CL, cs.AI, cs.LG

背景と動機(Background & Motivation)

LLMの推論において、KVキャッシュのメモリ消費は深刻なボトルネックとなっている。標準的なMHA(Multi-Head Attention)では、各トークンに対して全ヘッドのKey・Value対を保持する必要があり、モデルサイズとコンテキスト長に比例してメモリが増大する。

GQA(Grouped-Query Attention)はKVヘッド数を削減するアプローチだが、これは本質的に情報を「捨てる」操作である。ヘッド数を減らすほどKVキャッシュは小さくなるが、各ヘッドの表現力が制限される。

DeepSeek-V2の著者らは、情報を捨てるのではなく「圧縮して保持する」という異なるアプローチを提案した。低ランクの潜在ベクトルにKVを圧縮し、使用時に復元することで、品質劣化を最小限に抑えつつKVキャッシュを大幅に削減する。

主要な貢献(Key Contributions)

  • 貢献1: Multi-Head Latent Attention(MLA)の提案。低ランクKV圧縮により、MHA比で93.3%のKVキャッシュ削減を達成
  • 貢献2: DeepSeekMoEアーキテクチャの改良。236Bパラメータのうち21Bのみ活性化し、計算効率を大幅に向上
  • 貢献3: 学習コスト42.5%削減と推論スループット5.76倍という、経済性と性能の両立

技術的詳細(Technical Details)

MLAの圧縮・復元メカニズム

MLAの核心は、KVの低ランク共同圧縮(low-rank joint compression)である。以下に数式の詳細を示す。

ステップ1: ダウンプロジェクション(圧縮)

入力の隠れ状態 $h_t \in \mathbb{R}^{d_{model}}$ を低次元の潜在ベクトル $c_t^{KV}$ に圧縮する。

\[c_t^{KV} = W^{DKV} h_t\]

ここで、

  • $h_t$: 第 $t$ トークンの隠れ状態(次元 $d_{model}$)
  • $W^{DKV} \in \mathbb{R}^{d_c \times d_{model}}$: ダウンプロジェクション行列
  • $c_t^{KV} \in \mathbb{R}^{d_c}$: 圧縮された潜在ベクトル(次元 $d_c$)
  • $d_c \ll d_{model}$: 圧縮次元(DeepSeek-V2では $d_c = 512$、$d_{model} = 5120$)

KVキャッシュに保存するのは $c_t^{KV}$ のみである。これにより1トークンあたりのキャッシュサイズは $d_c = 512$ 次元に削減される。

ステップ2: アッププロジェクション(復元)

アテンション計算時に、潜在ベクトルからKey・Valueを復元する。

\[K_t = W^{UK} c_t^{KV}, \quad V_t = W^{UV} c_t^{KV}\]

ここで、

  • $W^{UK} \in \mathbb{R}^{(n_h \cdot d_k) \times d_c}$: Key用アッププロジェクション行列
  • $W^{UV} \in \mathbb{R}^{(n_h \cdot d_v) \times d_c}$: Value用アッププロジェクション行列
  • $n_h$: ヘッド数

ステップ3: Queryの圧縮(オプション)

MLAではQueryに対しても同様の圧縮を適用している。

\[c_t^Q = W^{DQ} h_t, \quad Q_t = W^{UQ} c_t^Q\]

Query圧縮次元は $d_c’ = 1536$ に設定されている(論文Section 3.1より)。

Decoupled RoPE方式

RoPE(Rotary Position Embedding)との統合は、MLAの実装上の重要な課題である。RoPEは位置情報をKey・Queryに回転行列として適用するが、低ランク圧縮とRoPEを単純に組み合わせると、行列吸収テクニック(後述)が適用できなくなる。

著者らはDecoupled RoPE方式を提案し、位置依存成分と内容依存成分を分離する。

\[K_t = [K_t^{content}; K_t^{RoPE}], \quad K_t^{RoPE} = \text{RoPE}(W^{KR} h_t)\]

$K_t^{RoPE}$ は別途計算されKVキャッシュに追加される(次元 $d_R$、論文では$d_R = 64$)。

行列吸収テクニック

推論時の計算効率を最大化するため、著者らは行列吸収(matrix absorption)テクニックを導入している。

通常のアテンション計算:

\[O = \text{softmax}\left(\frac{Q K^\top}{\sqrt{d_k}}\right) V\]

MLAの圧縮表現に展開すると:

\[Q K^\top = (W^{UQ} c^Q)(W^{UK} c^{KV})^\top = c^Q (W^{UQ})^\top W^{UK} c^{KV \top}\]

ここで $\hat{W}^Q = (W^{UQ})^\top W^{UK}$ を事前計算しておくことで、推論時にはKVキャッシュの $c^{KV}$ のみを使って計算を完結できる。

MoE(Mixture-of-Experts)アーキテクチャ

DeepSeek-V2は、各Transformerブロックのフィードフォワード層にMoEを適用している。

  • 全パラメータ数: 236B
  • アクティブパラメータ数: 21B(トークンあたり)
  • エキスパート数: 160(うち6をルーティングで活性化)
  • 共有エキスパート: 2(全トークンで共有)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# MLA + MoEの概念的な実装構造
import torch
import torch.nn as nn

class MultiHeadLatentAttention(nn.Module):
    def __init__(
        self,
        d_model: int = 5120,
        n_heads: int = 128,
        d_c: int = 512,
        d_c_q: int = 1536,
        d_rope: int = 64,
    ):
        super().__init__()
        self.d_k = d_model // n_heads
        self.n_heads = n_heads

        # ダウンプロジェクション(圧縮)
        self.w_dkv = nn.Linear(d_model, d_c, bias=False)
        self.w_dq = nn.Linear(d_model, d_c_q, bias=False)

        # アッププロジェクション(復元)
        self.w_uk = nn.Linear(d_c, n_heads * self.d_k, bias=False)
        self.w_uv = nn.Linear(d_c, n_heads * self.d_k, bias=False)
        self.w_uq = nn.Linear(d_c_q, n_heads * self.d_k, bias=False)

        # Decoupled RoPE
        self.w_kr = nn.Linear(d_model, d_rope, bias=False)
        self.w_qr = nn.Linear(d_c_q, d_rope, bias=False)

    def forward(
        self,
        h: torch.Tensor,
        kv_cache: torch.Tensor | None = None,
    ) -> tuple[torch.Tensor, torch.Tensor]:
        batch, seq_len, _ = h.shape

        # 圧縮: h -> 潜在ベクトル
        c_kv = self.w_dkv(h)     # (B, T, d_c)
        c_q = self.w_dq(h)       # (B, T, d_c_q)

        # 復元: 潜在ベクトル -> Q, K, V
        q = self.w_uq(c_q)       # (B, T, n_heads * d_k)
        k = self.w_uk(c_kv)      # (B, T, n_heads * d_k)
        v = self.w_uv(c_kv)      # (B, T, n_heads * d_k)

        # KVキャッシュは c_kv のみ保存(93.3%削減の核心)
        if kv_cache is not None:
            c_kv = torch.cat([kv_cache, c_kv], dim=1)
            k = self.w_uk(c_kv)
            v = self.w_uv(c_kv)

        # Scaled Dot-Product Attention
        q = q.view(batch, -1, self.n_heads, self.d_k).transpose(1, 2)
        k = k.view(batch, -1, self.n_heads, self.d_k).transpose(1, 2)
        v = v.view(batch, -1, self.n_heads, self.d_k).transpose(1, 2)

        scores = torch.matmul(q, k.transpose(-2, -1)) / (self.d_k ** 0.5)
        attn = torch.softmax(scores, dim=-1)
        output = torch.matmul(attn, v)

        output = output.transpose(1, 2).contiguous().view(batch, seq_len, -1)
        return output, c_kv  # c_kv をKVキャッシュとして返す

実装のポイント(Implementation)

KVキャッシュの削減効果: DeepSeek-V2のMLA設定($d_c = 512$, $d_{model} = 5120$, $n_h = 128$, $d_k = 128$)では、1トークンあたりのKVキャッシュサイズは以下のように計算される。

  • MHA: $2 \times n_h \times d_k = 2 \times 128 \times 128 = 32,768$ 要素
  • MLA: $d_c + d_R = 512 + 64 = 576$ 要素
  • 削減率: $1 - 576/32768 = 98.2\%$(論文では93.3%と報告。層ごとの設定の違いによる)

行列吸収の事前計算: 推論開始前に $\hat{W}^Q$ と $\hat{W}^V$ を事前計算しておくことが、推論レイテンシの最適化に重要である。

RoPE統合の注意点: Decoupled RoPEの $K_t^{RoPE}$ 成分は、潜在ベクトル $c_t^{KV}$ とは別にキャッシュする必要がある。この設計により、行列吸収テクニックとRoPEの位置エンコーディングを両立している。

Production Deployment Guide

AWS実装パターン(コスト最適化重視)

MLA搭載LLMの推論システムをAWSに構築する場合の構成を示す。

規模月間リクエスト推奨構成月額コスト概算主要サービス
Small~3,000 (100/日)API Gateway + Bedrock$100-300Bedrock (Claude) + API Gateway
Medium~30,000 (1,000/日)SageMaker Endpoint$3,000-6,000SageMaker (g5.12xlarge)
Large300,000+ (10,000/日)EKS + vLLM$10,000-25,000EKS + p5 (H100) × 2-4

Small構成の詳細(月額$100-300):

  • Amazon Bedrock: Claude/Llama系モデル利用(MLA相当の最適化はプロバイダ側で実施)
  • API Gateway: RESTエンドポイント($5/月)
  • DynamoDB: リクエストログ/キャッシュ($10/月)

Large構成の詳細(月額$10,000-25,000):

  • EKS + p5.48xlarge(H100×8): vLLMでDeepSeek-V2をサーブ
  • MLA対応のvLLM設定によりKVキャッシュメモリを大幅削減
  • Karpenter: GPUノード自動スケーリング(Spot優先で最大70%削減)

コスト試算の注意事項: 上記は2026年4月時点のAWS東京リージョン料金に基づく概算値。GPU Spotの可用性により大幅に変動する。

Terraformインフラコード

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
module "vpc" {
  source  = "terraform-aws-modules/vpc/aws"
  version = "~> 5.0"
  name    = "mla-inference-vpc"
  cidr    = "10.0.0.0/16"
  azs     = ["ap-northeast-1a", "ap-northeast-1c"]
  private_subnets = ["10.0.1.0/24", "10.0.2.0/24"]
  enable_dns_hostnames = true
}

module "eks" {
  source  = "terraform-aws-modules/eks/aws"
  version = "~> 20.0"
  cluster_name    = "mla-inference"
  cluster_version = "1.31"
  vpc_id     = module.vpc.vpc_id
  subnet_ids = module.vpc.private_subnets
  enable_cluster_creator_admin_permissions = true
}

resource "kubectl_manifest" "karpenter_gpu" {
  yaml_body = <<-YAML
    apiVersion: karpenter.sh/v1
    kind: NodePool
    metadata:
      name: gpu-mla-inference
    spec:
      template:
        spec:
          requirements:
            - key: karpenter.sh/capacity-type
              operator: In
              values: ["spot", "on-demand"]
            - key: node.kubernetes.io/instance-type
              operator: In
              values: ["p5.48xlarge", "g5.48xlarge"]
          nodeClassRef:
            group: karpenter.k8s.aws
            kind: EC2NodeClass
            name: default
      limits:
        nvidia.com/gpu: "16"
      disruption:
        consolidationPolicy: WhenEmptyOrUnderutilized
        consolidateAfter: 120s
  YAML
}

運用・監視設定

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import boto3

cloudwatch = boto3.client('cloudwatch')

# KVキャッシュメモリ使用率の監視
cloudwatch.put_metric_alarm(
    AlarmName='kv-cache-memory-high',
    ComparisonOperator='GreaterThanThreshold',
    EvaluationPeriods=2,
    MetricName='GPUMemoryUtilization',
    Namespace='Custom/vLLM',
    Period=300,
    Statistic='Average',
    Threshold=85.0,
    AlarmDescription='GPU メモリ使用率85%超過: KVキャッシュ圧縮設定の確認を推奨'
)

コスト最適化チェックリスト

  • MLA対応モデル使用(DeepSeek-V2/V3/R1)でKVキャッシュメモリ削減
  • vLLMの --kv-cache-dtype fp8 でさらにKVキャッシュを圧縮
  • GPU Spotインスタンス優先(最大70%削減)
  • Karpenterでアイドル時ゼロスケール
  • Continuous Batching有効化でスループット最大化
  • プロンプトキャッシュでBedrock利用コスト削減
  • AWS Budgets月額予算アラート設定
  • CloudWatch GPU メモリ/使用率アラーム設定
  • Cost Anomaly Detection有効化
  • 開発環境のGPUインスタンス夜間停止
  • Savings Plans(1年コミット)検討

実験結果(Results)

著者らが報告しているベンチマーク結果を以下にまとめる(論文Table 3, Table 8より)。

ベンチマークDeepSeek 67B (MHA)DeepSeek-V2 (MLA)備考
MMLU71.378.5+7.2pt
GSM8K63.479.2+15.8pt
HumanEval73.881.1+7.3pt

KVキャッシュ削減: 著者らは、MLAにより1トークンあたりのKVキャッシュサイズを標準MHAの1/11.9に削減したと報告している(93.3%削減)。

推論スループット: DeepSeek 67B比で5.76倍のスループット向上を達成(論文Section 5.2より)。

学習コスト: 8.1兆トークンの学習データで560万GPU時間。DeepSeek 67B比で42.5%のコスト削減(論文Section 4.1より)。

制約事項: MLAの低ランク圧縮は情報の損失を伴う可能性がある。著者らはベンチマークでMHAと同等以上の性能を示しているが、圧縮次元 $d_c$ の選択がモデル品質に影響するため、タスクに応じたチューニングが必要である。

実運用への応用(Practical Applications)

MLAの実運用上の最大の価値は、同一GPUメモリでより長いコンテキストを処理できる点にある。標準MHAで128Kトークンのコンテキストを処理する際にKVキャッシュだけで数十GBを消費するケースでも、MLAであれば数GBに収まる。

DeepSeek-V3(2024年12月)およびDeepSeek-R1(2025年1月)もMLAを採用しており、この手法は実運用で検証済みのアプローチである。vLLMやSGLangなどの推論フレームワークもMLA対応を進めている。

ただし、MLAの実装は標準MHAへのドロップイン置換が困難であり、Decoupled RoPEや行列吸収テクニックの正確な実装が求められる。既存モデルのファインチューニングでMLAを後付けすることは難しく、事前学習時からMLAを組み込む設計が必要である。

関連研究(Related Work)

  • GQA (Grouped-Query Attention) (Ainslie et al., 2023): KVヘッド数を削減するアプローチ。MLAとは異なり「情報を捨てる」方式であり、品質と圧縮率のトレードオフがある
  • MQA (Multi-Query Attention) (Shazeer, 2019): 全ヘッドでKVを共有。GQAの極端なケースに相当
  • DeepSeek-V3 (DeepSeek-AI, 2024): MLAを継承しつつMoEの設計を改良。671Bパラメータ

まとめと今後の展望

DeepSeek-V2で提案されたMLAは、低ランク圧縮によるKVキャッシュ削減という新しいアプローチで、従来のGQA/MQAとは異なる設計思想を示した。93.3%のKVキャッシュ削減と同時にMHAと同等以上の性能を維持した点は注目に値する。

今後の方向性として、MLAとFlashAttentionの統合最適化、動的な圧縮率調整(タスク難易度に応じた$d_c$の適応的変更)、および他のアーキテクチャ(SSMハイブリッド等)との組み合わせが考えられる。

参考文献

この投稿は CC BY 4.0 でライセンスされています。