一文要約: Q は「私が探しているもの」、K は「私が掲げているラベル」、V は「私が実際に持っている中身」です。Attention は Q を K と照合し、関連する V ベクトルを見つけ、重み付き和を計算します。


10.1 本章で扱うこと

前章では幾何学的な直感を築きました。内積は類似度の指標である、というものです。

しかし、まだいくつかの問いが残っています。

  • Q, K, V はそれぞれ何を意味するのでしょうか?
  • 入力からどのように生成されるのでしょうか?
  • 計算の各ステップで形状はどう変わるのでしょうか?

本章では Attention の計算全体を一歩ずつたどり、すべての次元変化を追いかけます。


10.2 入力の形状

10.2.1 入力次元を理解する

Input tensor shape: batch, sequence, model dimension

実際の学習では、複数のシーケンスを同時に処理します。入力テンソルの形状は次のとおりです。

X: [batch_size, ctx_length, d_model]

図に示した具体的な数値を使うと、

  • batch_size = 4: 4 つのシーケンスを並列に処理
  • ctx_length = 16: 各シーケンスは 16 個のトークンを持つ
  • d_model = 512: 各トークンは 512 次元のベクトルで表される

10.2.2 具体例

学習中に同時に流れる 4 つのプロンプトを思い浮かべてください。

1. "The agent opened a pull request for the..."
2. "The reviewer left a comment on line..."
3. "A tool call returned an error because..."
4. "The workflow passed all checks and was..."

各プロンプトは 16 トークンに切り分けられ、各トークンは 512 次元のベクトルで表されます。

入力全体の形状は [4, 16, 512] です。

  • 4 シーケンス
  • 各シーケンスは 16 ポジション
  • 各ポジションは 512 次元

10.2.3 三つの次元

次元名称意味
batch_sizeバッチ同時に処理するシーケンス数
ctx_length文脈長シーケンスあたりのトークン数
d_modelモデル次元各トークンベクトルの幅

10.3 Q, K, V を生成する

10.3.1 中心となる考え方

Q, K, V generated from the same input via three weight matrices

Q, K, V はすべて 同じ入力 X から、3 つの異なる重み行列を経て生成されます。

Q = X @ Wq
K = X @ Wk
V = X @ Wv

これらの重み行列 Wq, Wk, Wv は 学習可能なパラメータ です。ランダムに初期化された状態から始まり、学習中に調整されていきます。

10.3.2 次元の計算

Matrix multiplication X @ Wq with dimension tracking

Q を生成する場合を例にとります。

X:  [4, 16, 512]   (batch_size, ctx_length, d_model)
Wq: [512, 512]     (d_model, d_model)
Q:  [4, 16, 512]   (batch_size, ctx_length, d_model)

行列積のルール [..., A, B] @ [B, C] = [..., A, C] に従うと、

[4, 16, 512] @ [512, 512] = [4, 16, 512]

Q, K, V は入力 X とまったく同じ形状になります。

10.3.3 なぜ 3 つの異なる行列なのか?

出力の形状が同じなら、わざわざ 3 つに分ける意味はあるのでしょうか?

それは Q, K, V がそれぞれ異なる役割を担うからです。

  • Q (Query): 「私はどんな情報を探しているのか?」
  • K (Key): 「私はどんな情報として見つけられるのか?」
  • V (Value): 「選ばれたら私はどんな中身を提供するのか?」

別々の Wq, Wk, Wv を学習することで、モデルは同じ入力トークンを 3 つの異なる意味空間に射影することを学びます。検索のための空間、検索される側の空間、中身を運ぶ空間です。

10.3.4 覚えておきたいアナロジー

コードレビューのワークフローを考えてみてください。

役割アナロジー機能
Query (Q)レビュアーのコメント「この関数の文脈について情報がほしい」
Key (K)各ファイルのラベルやヘッダ「このファイルは認証を扱っている」
Value (V)実際のファイル内容実装の本文すべて

レビューの流れはこうです。

  1. あなたの Query (コメント/質問) が各ファイルの Key (説明) と照合される
  2. マッチスコアの高いファイルの内容が表に出てくる
  3. 最も関連の深い内容が応答に集約される

Attention も同じ仕組みで動きます。


10.4 第一の行列積: Q @ K^T

10.4.1 類似度行列の計算

Q @ K^T produces a sequence-by-sequence score matrix

Q と K がそろったら、次は両者の類似度を計算します。

scores = Q @ K^T

K は 転置 (K^T) する必要があります。こうすることで、Q の各行 (トークンごと) と K の各行 (こちらもトークンごと) の内積が取れるようになります。

10.4.2 次元の変化

Q:    [4, 16, 128]   (batch_size, ctx_length, d_key)
K^T:  [4, 128, 16]   (batch_size, d_key, ctx_length)
Result: [4, 16, 16]  (batch_size, ctx_length, ctx_length)

ここで d_key = 128 となっているのは、Multi-Head Attention が d_model を複数のヘッドに分割するためです。各ヘッドは d_key = d_model / num_heads = 512 / 4 = 128 を受け取ります。この分割は次章で扱います。

10.4.3 結果の意味

結果は [4, 16, 16] のテンソルになります。

  • 4 シーケンス
  • 各シーケンスごとに 16×16 の「スコア行列」
  • 位置 (i, j) の値はトークン i がトークン j にどれだけ注意を向けるべきかを表す

短いプロンプト "agent reviews PR ." を例にした 4×4 の簡略版を見てみましょう。以下の値はスケーリングやマスクをかける前の生の内積です。

             agent   reviews    PR      .
agent    [   8.2,    3.1,     6.5,    1.2  ]
reviews  [   3.4,   11.7,     7.8,    2.0  ]
PR       [   6.8,    7.2,    12.3,    1.9  ]
.        [   1.3,    2.1,     1.7,    9.4  ]

各セルは Q の対応する行と K の対応する列の内積です。対角成分 (トークンが自身に注意を向ける) は大きくなりがちで、意味的に関連の深いペア (reviews/PRagent/PR など) も高いスコアを示します。dkey\sqrt{d_{key}} でスケーリングして Softmax を適用すると、これらの生のスコアが正規化された Attention の重みになります。


10.5 Scale: なぜ dkey\sqrt{d_{key}} で割るのか

10.5.1 スケーリングの一手

Score matrix divided by sqrt(d_key)

Q @ K^T で得られる生のスコアは 小さくする 必要があります。

Attention Scores = (Q @ K^T) / sqrt(d_key)

この除算によって、数十から数百に達することもあった値が、ずっと狭い範囲に収まります。

10.5.2 なぜスケールが必要か?

問題: d_key が大きい (たとえば 128) と、内積も大きくなります。

dot product = sum(q_i × k_i)   # 128 個の積和

各 q_i, k_i の分散が 1 のとき、内積の分散はおおよそ d_key になります。

結果: 値が大きいと Softmax が極端に振れます。

Softmax([100, 1, 2])    [1.000, 0.000, 0.000]   # 一人勝ち
Softmax([1.0, 0.1, 0.2])  [0.400, 0.300, 0.300]  # 滑らかな分布

鋭い Softmax は、ほとんどの位置で勾配がほぼゼロになることを意味します。学習が止まってしまうのです。

対処: dkey\sqrt{d_{key}} で割ることで、スコアの分散を妥当な範囲に戻します。

dot product / sqrt(128)  dot product / 11.3

10.5.3 数式の中での位置づけ

Attention(Q,K,V)=softmax ⁣(QKTdkey)V\text{Attention}(Q, K, V) = \text{softmax}\!\left(\frac{QK^T}{\sqrt{d_{key}}}\right) V

この dkey\sqrt{d_{key}} こそが Scale ステップです。


10.6 Mask: 未来を「のぞき見」させない

10.6.1 なぜマスクが必要か

Causal mask blocks future positions with -inf

GPT 系の自己回帰モデルでは、次のトークンを予測するときに未来のトークンを使ってはいけません。しかし Q @ K は すべての 位置間の類似度を計算してしまうため、未来の位置も含まれます。

たとえば "The agent opened a pull request and merged it." で学習しているモデルが "merged" を処理しているとき、その後ろに何が続くかをモデルに見せてはなりません。

10.6.2 マスクの仕組み

解決策は 三角マスク で、未来の位置を負の無限大で埋めます。

Before mask:                     After mask:
[0.3, 0.2, 0.1, 0.4]          [0.3, -inf, -inf, -inf]
[0.2, 0.5, 0.2, 0.1]          [0.2, 0.5,  -inf, -inf]
[0.1, 0.3, 0.4, 0.2]          [0.1, 0.3,  0.4,  -inf]
[0.2, 0.1, 0.3, 0.4]          [0.2, 0.1,  0.3,  0.4 ]

右上の三角形 (未来の位置) が -inf になります。

10.6.3 なぜ -inf なのか?

Softmax は -inf をちょうど 0 に写すからです。

Softmax([0.3, -inf, -inf, -inf]) = [1.0, 0.0, 0.0, 0.0]

Softmax を通すと未来の位置の重みは 0 になり、モデルはそこから情報を読み取れなくなります。


10.7 Softmax: スコアを確率に変換する

10.7.1 変換のステップ

Softmax turns scores into a probability distribution per row

マスク後、行ごとに Softmax を適用します。

Before Softmax: [0.32, 0.04, -inf, -inf, ...]
After Softmax:  [0.52, 0.48, 0.00, 0.00, ...]

10.7.2 Softmax の働き

  1. 正規化: 各行の総和が 1 になる
  2. 差を強調: 大きい値はさらに相対的に大きくなる
  3. -inf の処理: そのまま 0 に写る

10.7.3 パターンの読み取り方

マスクされたシーケンスの最初のトークンは自身にしか注意を向けられないので、行は [1.00, 0.00, 0.00, ...] になります。2 番目のトークンは位置 0 と 1 を見られるので、行はたとえば [0.61, 0.39, 0.00, ...] のようになります。後ろのトークンほど注意を分散できる位置が増えるため、行はより滑らかに広がります。

これが Attention の重み行列 です。各位置が他のすべての位置からどれだけ情報を引き出すかを表します。


10.8 第二の行列積: Attention 重み @ V

10.8.1 重み付き和

Attention weights multiplied by V to produce the output

Attention の重みが計算できたら、最後のステップでその重みを使って Value ベクトルを混ぜ合わせます。

Output = Attention_Weights @ V

10.8.2 次元の変化

Attention_Weights: [4, 4, 16, 16]   (batch, heads, ctx_len, ctx_len)
V:                 [4, 4, 16, 128]  (batch, heads, ctx_len, d_key)
Output:            [4, 4, 16, 128]  (batch, heads, ctx_len, d_key)

ここに登場するマルチヘッド構造 (4 ヘッド) は次章のテーマです。

10.8.3 このステップが行うこと

各出力位置は、Attention スコアを重みとした、すべての V ベクトルの加重平均になります。

output[i] = sum(attention_weight[i, j] × V[j])

トークン i が注意の 70% をトークン j に、30% をトークン k に向けるなら、

output[i] = 0.7 × V[j] + 0.3 × V[k]

出力は文脈を踏まえた混合であり、特定の単一トークンのコピーではありません。


10.9 Attention の出力が意味するもの

10.9.1 出力の次元

Attention output: each token gets an updated vector representation

Attention @ V の後、各トークンは新しいベクトルを得ます。

Output: [batch_size, ctx_length, d_key] = [4, 16, 128]

(マルチヘッドの場合、すべてのヘッドの出力が連結されます。これは次章で扱います。)

10.9.2 意味の変化

ここが肝心な点です。Attention の前は、各トークンのベクトルは そのトークン自身 の情報しか持っていませんでした。Attention の後は、各トークンのベクトルが 文脈全体の重み付き組み合わせ になります。

"merged" のトークン埋め込みは、当初その単語単独の表現でしかありませんでした。Attention を経た後は、周囲のトークンからの情報を取り込みます。誰がその動作を行ったのか、どの PR が関係するのか、その前に何があったのか、といった情報です。

これがモデルが文脈を「理解する」仕組みです。魔法ではなく、学習された Value ベクトルの加重平均にすぎません。

10.9.3 ループ

Attention の出力は、

  1. その位置の入力埋め込みを置き換える
  2. 次のコンポーネント (FFN や次のブロック) に渡される
  3. レイヤーを重ねるごとに洗練される

各ブロックは、各トークンの表現にさらに多くの文脈を積み上げていきます。


10.10 Attention の計算全体像

10.10.1 ステップごとの整理

Complete Attention flow with shapes at each step
Step 1: Q, K, V を生成
        Q = X @ Wq    [4, 16, 512]
        K = X @ Wk    [4, 16, 512]
        V = X @ Wv    [4, 16, 512]
              
        ヘッドに分割 (4 ヘッド, d_key = 128)
        Q, K, V それぞれ: [4, 4, 16, 128]   (batch, heads, seq, d_key)
              
Step 2: 類似度を計算 (ヘッドごと)
        scores = Q @ K^T    [4, 4, 16, 16]
              
Step 3: スケーリング
        scores = scores / sqrt(d_key)    [4, 4, 16, 16]
              
Step 4: マスク (デコーダのみのモデル)
        scores[future] = -inf    [4, 4, 16, 16]
              
Step 5: Softmax
        weights = softmax(scores)    [4, 4, 16, 16]
              
Step 6: 重み付き和 (ヘッドごと)
        output = weights @ V    [4, 4, 16, 128]   (batch, heads, seq, d_key)
              
        ヘッドを連結: [4, 16, 512]   (batch, seq, d_model)

10.10.2 PyTorch 実装

import torch
import torch.nn.functional as F

def attention(Q, K, V, mask=None):
    """
    Scaled Dot-Product Attention.

    Q: [batch, seq_len, d_k]
    K: [batch, seq_len, d_k]
    V: [batch, seq_len, d_v]
    mask: [batch, 1, seq_len] or [batch, seq_len, seq_len]

    Returns:
        output: [batch, seq_len, d_v]
        attention_weights: [batch, seq_len, seq_len]
    """
    d_k = Q.size(-1)

    # Step 2: Q @ K^T
    scores = torch.matmul(Q, K.transpose(-2, -1))

    # Step 3: スケーリング
    scores = scores / (d_k ** 0.5)

    # Step 4: マスク
    if mask is not None:
        scores = scores.masked_fill(mask == 0, float('-inf'))

    # Step 5: Softmax
    attention_weights = F.softmax(scores, dim=-1)

    # Step 6: 重み付き和
    output = torch.matmul(attention_weights, V)

    return output, attention_weights

10.11 Q, K, V のさらに深い理解

10.11.1 役割のまとめ

役割生成元目的使われる場所
QX @ Wq「私が探しているもの」Q @ K^T
KX @ Wk「私が掲げるラベル」Q @ K^T
VX @ Wv「私が運ぶ中身」Attention @ V

10.11.2 なぜ K と V を分けるのか?

K も V も同じ入力から生まれます。それなのに、なぜ別々の行列を使うのでしょうか?

マッチングと取り出しを切り離すためです。

  • K は どの 位置に注意が向くかを制御する
  • V は注意が向いたとき どんな情報 が流れるかを制御する

この分離がモデルに柔軟性を与えます。あるトークンは「見つけられやすい」自分を演出する (多くの Query と高い K の内積を取る) と同時に、運ぶ実際の内容 (V) はまったく異なるものにできます。

10.11.3 例

「The agent merged the pull request after review.」を考えましょう。

"merged" を処理するとき、

  • Q("merged") は探している: 「この動作を行ったのは誰か?」
  • K("agent") はシグナルを発する: 「私は動作を行う主語である」
  • V("agent") は運ぶ: agent が持つ意味的内容

Q と K のマッチングが、"merged" は "agent" に注意を向けるべきだとモデルに伝えます。V が実際の情報を届けます。


10.12 章のまとめ

10.12.1 重要な概念

概念形状意味
X[batch, seq, d_model]入力テンソル
Wq / Wk / Wv[d_model, d_model]学習可能な射影行列
Q[batch, seq, d_model]Query: 私が探しているもの
K[batch, seq, d_model]Key: 私が掲げるラベル
V[batch, seq, d_model]Value: 私が運ぶ中身
Scores[batch, seq, seq]類似度行列
Weights[batch, seq, seq]Attention の確率 (各行の和は 1)
Output[batch, seq, d_model]文脈を反映したトークン表現

10.12.2 計算の流れ

X  [Wq, Wk, Wv]  Q, K, V
              
        Q @ K^T (類似度)
              
        / sqrt(d_key) (スケール)
              
        マスク (未来を遮る)
              
        Softmax (正規化)
              
        @ V (重み付き和)
              
           Output

10.12.3 押さえておきたい核心

Q, K, V は Attention の三主役です。Q が問い、K がラベルを示し、V が中身を運びます。Q を K と照合して関連する位置を見つけ、そのスコアで V を加重平均すると、文脈が織り込まれた表現が得られます。これこそが Attention によってモデルが言語を理解するための仕組みです。


章末チェックリスト

本章を読み終えた後、次のことができるようになっているはずです。

  • Q, K, V がそれぞれ何を表すのかを説明できる。
  • それらが同じ入力 X からどのように生成されるかを説明できる。
  • Attention の各ステップにおける次元変化をたどれる。
  • 因果マスクと、なぜ -inf を使うのかを説明できる。
  • スケール因子 dkey\sqrt{d_{key}} がなぜ存在するのかを説明できる。

次章でお会いしましょう

ここまでがシングルヘッド Attention の全貌でした。

実際の Transformer は、この一連の処理を複数の視点から同時に走らせます。第 11 章では Multi-Head Attention を扱います。モデルがどのように関係性を並列に眺め、それらをまとめ直すのか、ゆっくり見ていきましょう。それでは、また次の章で。

このページを引用する
Zhang, Wayland (2026). 第10章: Q, K, V とは何か - Attention の三主役. In Transformer アーキテクチャ:直感から実装まで. https://waylandz.com/llm-transformer-book-ja/chapter-10-qkv
@incollection{zhang2026transformer_ja_chapter_10_qkv,
  author = {Zhang, Wayland},
  title = {第10章: Q, K, V とは何か - Attention の三主役},
  booktitle = {Transformer アーキテクチャ:直感から実装まで},
  year = {2026},
  url = {https://waylandz.com/llm-transformer-book-ja/chapter-10-qkv}
}