# LLM のしくみ（Transformer）（コース全体）

ハチコロのコース「LLM のしくみ（Transformer）」の全ページの本文です。学習者の質問に答えるときは、この教材での説明の順序や用語の使い方に合わせてください。

## 目次

1. LLM のしくみ（Transformer）（/llm.md）
2. 1. トークン化（/llm/tokenization.md）
3. 2. 埋め込みベクトル（/llm/embedding.md）
4. 3. Attention（/llm/attention.md）
5. 4. Transformer ブロック全体（/llm/transformer-block.md）
6. 5. 次のトークンを選ぶ（/llm/sampling.md）
7. 理解度クイズ（/llm/quiz.md）

---

## LLM のしくみ（Transformer）

> ChatGPT や Claude の中で何が起きているのかを、手を動かしながら理解するコース

ChatGPT や Claude のような LLM（大規模言語モデル）がやっていることは、突き詰めると **「ここまでの文章の次に来るトークンを予測する」** ことだけです。
トークンは、文章を細かく区切った単位です（1 回目で詳しく扱います）。
このコースでは、その予測が中でどう計算されているかを、ブラウザ上で数値を動かしながら確かめます。

先に全体の流れを眺めてから各回に進むのがおすすめですが、すぐに始めたい人は [1. トークン化](tokenization/) からどうぞ。

### 全体の流れ

:::tip[全回で同じ例文を使います]
このコースでは、例文 **「猫が魚を食べた。それは新鮮だった」** が各段階でどう変わっていくかを追いかけます。説明のため、この例文は「猫 / が / 魚 / を / 食べた / 。 / それ / は / 新鮮 / だった」の 10 トークンに区切れるものとします（実際のトークナイザは、もっと細かく区切ることが多いです）。
:::

LLM が次の 1 トークンを出すまでの処理を 1 枚の図にすると、次のようになります。
例文の 10 個のトークンが 1 行ずつ、左から右へ流れていきます。図の中の下線の付いた処理名（①〜⑥）をクリックすると、その回に移動します。

```text
（全体図）文章「猫が魚を食べた。それは新鮮だった」を例に、次の 1 トークンを出すまで
① トークン化：文章をトークンに区切り、番号にする → トークン ID の列（10 個。猫 / が / 魚 / … / だった）
② 埋め込み：番号ごとにベクトルを取り出す（GPT-2 などでは位置の情報も足す）→ ベクトルの列（10 × d）。この時点では「魚」はどの文でも同じベクトル
Transformer ブロック × N 個（形は同じで、パラメータは別々。③ と ④ のセットを繰り返す。形は 10 × d のまま）
  ③ Attention：各トークンが、自分と前のトークンから情報を集めて書き足す（例：「それ」が「魚」の情報を取り込む。後ろは見ない）
  ④ MLP：各トークンのベクトルを 1 本ずつ変換して、学習で覚えた知識を書き足す（トークンどうしは混ぜない）
⑤ 出力層：末尾のトークン（だった）のベクトル 1 本と、語彙の各トークン用のベクトルとの内積で、語彙のすべてのトークンにスコア（logits。GPT-2 では 50,257 個）を付ける（例：「。」3.1、「ね」2.0、「が」1.1、…）
⑥ 確率にして選ぶ：スコアを softmax で確率（合計 1）にし（例：「。」0.62、「ね」0.21、「が」0.08、残り 0.09 はほかのトークン）、確率に従って 1 つ選ぶ（例：「。」）→ その ID を ID の列の末尾に足して（11 個）、② の埋め込みからもう一度（文章をトークン化し直すわけではない）
（d は次元数：GPT-2 最小構成では 768。N はブロック数：GPT-2 最小構成では 12。各ブロックの LayerNorm と残差接続、最後の LayerNorm は省略。末尾以外の行も計算されるが、次の予測に使うのは末尾の 1 本だけ）
```

:::caution[よくある誤解]
- **MLP が次の語を予測する、わけではありません**。MLP は Attention と同じく、各トークンのベクトルを書き換える部品で、③ と ④ のセットを N 回（GPT-2 最小構成で 12 回、大きなモデルでは数十〜百数十回）繰り返します。次の語の候補にスコアを付けるのは、最後の ⑤ 出力層です。
- **出力層がトークンを選ぶ、わけでもありません**。出力層は語彙のすべてにスコアを付けるところまでで、それを確率にして 1 つ選ぶのは ⑥ の別の手順です（選び方は設定で変えられます。5 の回）。
- **Attention が文全体を 1 本のベクトルにまとめる、わけでもありません**。10 個のトークンは最後までそれぞれ自分のベクトルを持ちます。末尾のトークンは前のすべてを見られるので、次の予測にはその 1 本を使います。
:::

#### 末尾の「だった」のベクトルが、次の予測に使えるようになるまで

図の ③〜⑤ で、末尾の「だった」のベクトルに何が起きているかを、順に追ってみます（書き足される中身はたとえです。実際のベクトルは数百個の数値で、何が書き足されたかを人がそのまま読み取ることはできません）。

1. **② の直後は、「だった」という語そのもの**: 猫も魚も知りません。このまま ⑤ に入れても、「だった」の後に一般によく来るものを当てずっぽうに出すだけです。
2. **③ Attention で、前の語の情報が足される**: 「新鮮」から「何かが新鮮だという話」、「それ」から「何についての話か」（「それ」は前の層で「魚」の情報を取り込み済み）、「は」「。」から「新しい文の述語の部分にいる」といった情報を集めます。
3. **④ MLP で、学習で覚えた知識が足される**: たとえば「述語が『〜だった』で終わったら、文が終わることが多い」のような、大量の文章から覚えたパターンです。
4. **③ と ④ を N 回繰り返す**: 層を重ねるたびに、「次に何が来そうか」の判断に役立つ情報が足され、磨かれていきます（なぜ 1 回では足りないのかは、4 の回の「なぜ何回も通すのか」）。
5. **⑤ 出力層は、このベクトルと各トークン用のベクトルの内積でスコアを付ける**: 末尾のベクトルが「。」用のベクトルと同じ向きを向くほど、「。」のスコアが高くなります（計算の例は 4 の回）。「次に来そうなものを表すベクトルになる」とは、こういう向きになるということです。

末尾の位置がこの役を担えるのは、学習のときに **すべての位置で「自分の次のトークン」を当てさせている** からです。どの位置の最終的なベクトルも「自分の次を当てるためのもの」に鍛えられていて、生成のときは、まだ次が分からない末尾の 1 本だけを使います。

#### 各回で扱うこと

| 回（図の番号） | 処理 | 入力 → 出力 |
| --- | --- | --- |
| [1. トークン化](tokenization/)（①） | 文章を区切り、番号に変える | 文章 → ID の列 |
| [2. 埋め込み](embedding/)（②） | 番号をベクトルに変える | ID の列 → ベクトルの列 |
| [3. Attention](attention/)（③） | トークン同士で情報をやり取りする | ベクトルの列 → 同じ形の列 |
| [4. ブロック全体](transformer-block/)（④ ⑤） | MLP と組んで積み重ね、最後にスコアを出す | ベクトルの列 → 語彙数個のスコア |
| [5. 次のトークンを選ぶ](sampling/)（⑥） | スコアを確率にして、1 つ選ぶ | スコア → トークン 1 個 |

### おすすめの進め方

最初に動画で全体像をつかみ、その後このサイトで手を動かすと理解しやすくなります。

| 3Blue1Brown の動画 | 対応する回 |
| --- | --- |
| [GPT とは何か — Transformer の視覚的解説](https://www.youtube.com/watch?v=KlZ-QmPteqM)（深層学習 第 5 章） | 1・2・5 |
| [Attention の可視化](https://www.youtube.com/watch?v=eMlx5fFNoYc)（第 6 章） | 3 |
| [LLM はどう事実を記憶するのか](https://www.youtube.com/watch?v=9-Jl0dxWQs8)（第 7 章） | 4 |

:::tip[日本語で見るには]
3Blue1Brown の動画には日本語吹き替え版があります。YouTube の設定（歯車アイコン）→「音声トラック」で切り替えられるほか、「3Blue1Brown Japan」チャンネルでも公開されています。
:::

各回の **試してほしいこと** にあるデモは、すべてブラウザの中だけで計算しています。好きなだけ数値をいじってみてください。

### 読んでいてわからないときは

- 点線の下線が付いた用語は、クリックすると短い解説が出ます。全項目は [用語集](../glossary/) にまとめています。
- 本文を選択すると **「AI 向けに引用をコピー」** ボタンが出ます。「このページのこの箇所について」という引用がコピーされるので、普段使っている AI（ChatGPT・Claude・Gemini など）に貼り付けて、続けて質問を書いてください。
- 右下の **「ノート」**（狭い画面では ✎ のボタン）から、ページごとのノートを書けます。


	- [1. トークン化から始める](tokenization/)
	- [理解度クイズ](quiz/)

**このページの用語**

- **MLP（多層パーセプトロン）**: 線形変換と活性化関数を交互に重ねた、基本的なニューラルネットワーク。Transformer では、各トークンのベクトルを 1 つずつ別々に変換する部分を指す。

---

## 1. トークン化

> 文章をモデルが扱える番号の列に変える。BPE トークナイザを自分で学習させて確かめる

ニューラルネットワークが扱えるのは数値だけです。そこで LLM は、まず文章を **トークン** という単位に区切り、それぞれに番号（トークン ID）を振ります。この区切って番号を振る道具を **トークナイザ** と呼びます。

**この回の入力と出力**

- **入力**: 文章（文字列）。例：「猫が魚を食べた。それは新鮮だった」
- **出力**: トークン ID の列（整数の並び）。例：「猫 / が / 魚 / を / 食べた / 。 / それ / は / 新鮮 / だった」の 10 トークンに区切って `[3412, 12, 2901, 18, 15873, 6, 911, 14, 20417, 7088]`（区切り方も番号も説明用の仮定。実際のトークナイザは、もっと細かく区切ることが多い）
- **使うもの**: トークナイザが持つ語彙（どの文字の並びを 1 トークンにするかと、その番号の一覧）。語彙は、LLM 本体の学習の前に作っておく


### どこで区切るか

区切り方には、大きく 3 つの考え方があります。

| 単位 | 長所 | 短所 |
| --- | --- | --- |
| 1 文字ずつ | 語彙が比較的小さい（ただし、語彙に入れていない文字は表せない） | 系列（トークンの並び）がとても長くなり、計算量が増える |
| 単語ごと | 系列が短い | 語彙が膨大になり、辞書にない語（未知語）を扱えない |
| **サブワード**（文字と単語の中間） | よく出る並びは 1 トークン、まれな語は細かく分けて表せる | 区切り方を学習で決める必要がある |

現在の LLM はほぼすべてサブワードを使っています。その代表的な作り方が **BPE（Byte Pair Encoding）** です。

### BPE のアルゴリズム

BPE は、大量の文章（コーパス）を見て、「よく隣り合う 2 つをくっつける」ことを繰り返して語彙を作ります。

1. すべての文章を 1 文字（GPT-2 などの「バイトレベル BPE」では 1 バイト）ずつのトークンに分ける
2. 隣り合うトークンのペアのうち、コーパス全体で **一番多く出てくるペア** を探す
3. そのペアをくっつけて新しいトークンとし、語彙に加える（この操作を **マージ** と呼ぶ）
4. 決めた語彙数に達するまで 2〜3 を繰り返す

このページのデモでは、先に空白や改行で文章を区切り、その区切りをまたぐペアはくっつけません。また、2 回以上出てくるペアだけをくっつけ、そうしたペアがなくなったら止まります。

できあがったトークナイザで新しい文章を区切るときは、1 文字ずつ（バイトレベル BPE では 1 バイトずつ）に分けたうえで、学習で覚えたマージを **覚えた順番どおりに** 適用します。後のマージは、前のマージで作ったトークンを材料にしているからです。たとえば「の」と「天気」をくっつけるマージは、先に「天」と「気」から「天気」を作っておかないと使えません。

（ここにはブラウザで操作できるインタラクティブなデモがあります）

#### 試してほしいこと

- **マージ回数を少しずつ増やす**: 「です。」「の天気」「の天気は」のような、何度も出てくる並びから先にまとまっていくのが分かります。
- **トークン化する文に、コーパスにない言葉を入れる**: その言葉の中で、コーパスによく出た並び（「の天気」など）だけがまとまり、残りは 1 文字ずつに分かれます。学習データに多い言語ほど、少ないトークンで表せるのはこのためです。
- **コーパスを書き換える**: 同じ専門用語が何度も出てくる文章を貼ります。マージ回数は 0 に戻るので、もう一度少しずつ増やすと、その語の並びがまとまっていきます（2 回以上出てくるペアしかまとめないので、必ず 1 語が 1 トークンになるわけではありません）。

### 実際の LLM では

- GPT-2 の語彙は 50,257 トークンでした（[Radford ら、2019 年](https://cdn.openai.com/better-language-models/language_models_are_unsupervised_multitask_learners.pdf)）。最近のモデルはもっと大きな語彙を持つものが多く、たとえば [Llama 3](https://arxiv.org/abs/2407.21783) は約 128,000（128K）トークンです。
- GPT-2 などは、1 文字ではなく **1 バイト** から始めます（バイトレベル BPE）。バイトは 256 種類しかないので、絵文字でも未知の文字でも必ず表せます（「?」になる文字がありません）。その代わり、UTF-8 では日本語の文字の多くが 3 バイトなので、まれな漢字は 1 文字が複数のトークンに分かれることがあります。
- 文字単位で BPE を学習し、語彙にない文字だけをバイトに分解する方式（バイトフォールバック）を使うモデルもあります。バイトレベル BPE もバイトフォールバックも、「どんな文字でも表せる」ための工夫です。
- 多くのトークナイザは、BPE の前に、空白や記号などで文章を大まかに区切ります（プレトークナイズ）。マージは、その区切りの中でだけ行います（SentencePiece のように、空白も文字の 1 つとして扱う方式もあります）。
- API の料金やコンテキスト長は、文字数ではなく **トークン数** で数えます。同じ内容でも、言語やトークナイザによってトークン数は変わります。

:::note[ここまでのまとめ]
文章 → トークンの列 → トークン ID の列。この ID の列が、LLM 本体への本当の入力です。
ただし ID は単なる通し番号で、それ自体は意味を持ちません。次の回で、ID を「意味」を持った数値（ベクトル）に変えます。
:::

**このページの用語**

- **ニューラルネットワーク**: 数値を受け取り、掛け算・足し算と簡単な関数を何段も重ねて、別の数値を出す計算のしくみ。掛ける数（重み）を学習で調整して、目的の出力に近づける。
- **トークン ID**: 語彙の中の各トークンに振られた番号。LLM に実際に入力されるのは、この整数の並び。
- **語彙（ボキャブラリ）**: トークナイザが知っているトークンの一覧。LLM は、この一覧のどれか 1 つを次のトークンとして選ぶ。語彙の数を語彙サイズという。
- **系列**: 順番に並んだデータの列。ここでは、文章を区切ってできたトークンの並びのこと。並びの個数を系列の長さという。
- **コーパス**: 学習などに使うために集めた、大量の文章のこと。トークナイザやモデルは、コーパスの中の文章から規則や傾向を学ぶ。
- **バイト**: コンピュータがデータを扱う単位で、0〜255 の整数 1 つ分。文字は UTF-8 などの規則でバイトの並びに直して保存される。
- **コンテキスト長**: LLM が一度に読み込めるトークン数の上限。入力（指示や会話の履歴）と、生成した出力の合計で数える。

---

## 2. 埋め込みベクトル

> トークン ID を、意味を持つベクトルに変える。単語をベクトル空間に置いて、距離と方向を確かめる

トークン ID は単なる番号です。ID 1234 と 1235 が意味的に近いわけではありません。
そこで LLM は、各 ID を **埋め込みベクトル**（数百〜数万個の数値の並び）に変換してから計算に使います。

**この回の入力と出力**

- **入力**: トークン ID の列。例：10 個の整数
- **出力**: ベクトルの列。トークン 1 個につきベクトル 1 本なので、10 本。各ベクトルは d 個の数値の並び（d は次元数。GPT-2 最小構成では 768、このページのデモでは 6）
- **形で書くと**: 10 個 → 10 × d（10 行 d 列の表）
- **使うもの**: 埋め込み行列（語彙数 × d）と、位置の情報


### 埋め込み行列から 1 行取り出すだけ

LLM は「語彙数 × 次元数」の大きな表（**埋め込み行列**）を持っています。トークン ID が 1234 なら、その表の「ID 1234 に対応する行」を取り出したものが、そのトークンの埋め込みベクトルです。計算はそれだけです。

- GPT-2（最小構成）: 50,257 語彙 × 768 次元
- GPT-3（175B）: 約 5 万語彙 × 12,288 次元（次元数は [Brown ら、2020 年](https://arxiv.org/abs/2005.14165) の表 2.1。語彙は GPT-2 と同じトークナイザ）

表の中身は最初はランダムで、学習を通じて **「次のトークンを当てやすい値」に調整されていきます**。つまり表の数値はすべて、学習で決まるパラメータです。その結果、意味の近いトークンは近い位置に並ぶようになります。関係の似たペアが同じ向きに並ぶ傾向も見られます（はっきり確かめられているのは、次の節の word2vec のような単語ベクトルです）。

### 「近さ」と「方向」

ベクトルは、図形として読むこともできます。2 次元の [3, 4] なら「横に 3、縦に 4」の点で、原点からその点に向かう矢印とも見られます。次元が増えても、この「位置」と「向き」の考え方はそのまま使えます。

ベクトル同士の近さは、よくコサイン類似度（2 つのベクトルの向きがどれだけ揃っているか）で測ります。1 に近いほど同じ向き、0 なら直交（向きがまったく揃っていない）、−1 なら正反対です（範囲は −1〜1）。意味の近さの目安としてよく使われ、学習済みの埋め込みでは、0 に近いペアは関連が薄いことが多くなります（どこまで当てはまるかはモデルによります）。

さらに面白いのは、**方向に意味が宿る** ことです。有名な例が次の式です。

> 王 − 男 + 女 ≒ 女王

この例は、word2vec という、LLM より前の単語ベクトルの研究で有名になりました（[Mikolov ら、2013 年](https://arxiv.org/abs/1301.3781)。原論文の英語の例 King − Man + Woman ≒ Queen を、日本語にしたものです）。

ベクトルの足し算・引き算は、同じ位置の数値どうしを足し引きします。下のデモの値のうち［王族, 女性］の 2 つの次元だけで見ると、王 [0.95, 0.05] − 男 [0.05, 0.05] + 女 [0.05, 0.95] = [0.95, 0.95] で、女王 [0.95, 0.95] に着きます。これは、男から女への差 [0, 0.90]（「女性」の方向への移動）を、王にそのまま足したのと同じです。

なお、いちばん近い単語を探すときは、計算に使った王・男・女を候補から除くのがふつうです。下のデモも同じです。

（ここにはブラウザで操作できるインタラクティブなデモがあります）

#### 試してほしいこと

- **最初の「若さ × 女性」の 2 軸で見る**: 人間の単語が「大人の男性・大人の女性・若い男性・若い女性」の 4 つの塊に分かれます。ただし、王と男のように重なって区別できない単語もあります。
- **縦軸を「王族」に変える**: 王と男は離れますが、今度は王と女王のように別の組が重なります。2 つの軸では表しきれない違いがあり、たくさんの次元があると、それだけ多くの違いを表せるのです。
- **足し算・引き算で「子犬 − 犬 + 猫」を試す**: 「若さの方向」が動物の種類と関係なく使えることが分かります。
- **「寿司」を選んで類似度ランキングを見る**: 食べ物同士が近く、人間や王族からは遠くなっています。最初の「若さ × 女性」の図では寿司が男の近くに見えますが、ランキングは図の 2 軸だけでなく、6 つの次元すべてで向きを比べています。横軸を「食べ物」に変えると、図でも寿司はりんごやパンの近くに移ります。

:::caution[おもちゃの例であることに注意]
このデモは、各次元に「王族」「女性」などの意味を手で割り当てて作りました。本物の埋め込みでは、意味の方向はたくさんの次元に混ざり合って分布しており、1 つの次元を見ても意味は読み取れません。
:::

### 位置の情報も足す

次の回で見る Attention は、各トークンが、ほかのトークンの中身（ベクトル）を見て情報を集める仕組みで、相手が **何番目にいるかは直接は見ません**。そのままでは「猫が魚を食べた」と「魚が猫を食べた」を区別しにくいので、各トークンの埋め込みに「何番目にあるか」を表す情報を加えます。

- **GPT-2 の方式**: 位置ごとに学習したベクトル（1 番目用、2 番目用、…）を、埋め込みベクトルに足す。足し算なので、出力の形（10 × d）は変わらない
- **最近のモデルの方式**: 埋め込みには何も足さず、Attention の計算の中で、比べるためのベクトル（次の回の Query と Key）を位置に応じて回転させる RoPE という方式が多い

:::note[発展：位置の情報がなくても]
マスク（3 の回で扱う）をかけない Attention では、文中のトークンを並べ替えても、各トークンの出力は並べ替える前と同じになります（なぜそうなるかは、次の回の計算を見ると分かります）。一方、未来を隠すマスクを使う Attention では、各トークンが見られる範囲が位置によって違うので、それだけでも語順の手がかりになります。位置の情報を足さずに学習しても、ある程度うまくいくことが知られています（Haviv ら、2022 年）。それでも実際の LLM のほとんどは、位置の情報を明示的に与えています。
:::

:::note[ここまでのまとめ]
トークン ID の列（10 個）→ ベクトルの列（10 × d。GPT-2 などでは位置の情報も足されている）。
ただし、この時点の各ベクトルは、まだ **周りの文脈を知りません**。埋め込み行列から取り出した「それ」のベクトルは、どの文に出てきても同じです（位置の情報を足しても、周りのトークンの中身はまだ入っていません）。「それ」のベクトルに、前の文脈（猫や魚）の情報を取り込むのが、次の Attention です。
:::

**このページの用語**

- **トークン ID**: 語彙の中の各トークンに振られた番号。LLM に実際に入力されるのは、この整数の並び。
- **ベクトル**: 数値を決まった個数だけ並べたもの。たとえば [0.2, -1.3, 0.8] は 3 つの数値からなるベクトル。並んだ個数を次元数という。ベクトルの「長さ」は個数ではなく、矢印としての大きさ（例：[3, 4] の長さは 5）。
- **次元**: ベクトルに並んでいる数値の個数。768 次元のベクトルは、768 個の数値の並び。
- **語彙（ボキャブラリ）**: トークナイザが知っているトークンの一覧。LLM は、この一覧のどれか 1 つを次のトークンとして選ぶ。語彙の数を語彙サイズという。
- **行列**: 数値を縦横の表の形に並べたもの。横の並びを行、縦の並びを列という。ベクトルに行列を掛けると、別のベクトルに変換できる。
- **学習**: 大量のデータで予測を試し、外れた分だけパラメータを少しずつ調整して、予測を当たりやすくしていくこと。LLM は「次のトークンの予測」で学習する。
- **パラメータ**: モデルが学習で調整する数値。埋め込み行列や、Attention・MLP の行列の中身がすべてパラメータ。「70B のモデル」は、パラメータが 700 億個あるという意味。
- **コサイン類似度**: 2 つのベクトルの向きがどれだけ揃っているかを、-1〜1 の数値で表したもの。1 なら同じ向き、0 なら直交（向きがまったく揃っていない）、-1 なら正反対。
- **RoPE（回転位置埋め込み）**: Attention でトークンどうしを比べるときに使うベクトルを、位置に応じた角度だけ回転させて、位置の情報を入れる方式。埋め込みには何も足さない。Rotary Position Embedding の略。

---

## 3. Attention

> 各トークンが文中のどこから情報を集めるかを決める仕組み。Q・K・V の計算を数値で追う

> 猫が魚を食べた。**それ**は新鮮だった

この「それ」が魚を指すことは、人間なら後ろの「新鮮だった」まで読んですぐ分かります。でも、埋め込みの時点では、「それ」のベクトルは周りの文を何も知りません。

この回では、「それ」のベクトルに、前にある「猫」や「魚」の情報を取り込むしくみを見ます。

**Attention** は、各トークンが「文中のどのトークンから情報をもらうべきか」を計算し、もらう情報を集めてくる仕組みです。集めた情報は、次の回で見るように元のベクトルに **足される** ので、元の「それ」の情報が残る通り道を保ちながら、「魚」の情報が加わります。Transformer の心臓部と言える部分です。

**この回の入力と出力**

- **入力**: ベクトルの列（10 × d）。前の回の出力、またはひとつ前のブロックの出力（実際には LayerNorm で整えてから入れる。4 の回）
- **出力**: 同じ形のベクトルの列（10 × d）。各行は、そのトークンが自分自身と前のトークンから集めてきた情報（後ろは見ない。下の「未来を隠す」の節）
- **その後**: 次の回で、元のベクトルに足される
- **途中で作るもの**: Query・Key・Value の 3 種類のベクトル（それぞれ 10 本）と、「どのトークンがどのトークンをどれだけ見るか」を表す 10 × 10 の重みの表
- **使うもの**: Query・Key・Value を作るための行列と、出力を整えるための行列（下のマルチヘッドの節で説明。どれも学習で決まるパラメータ）


### Query・Key・Value

Attention では、各トークンのベクトルから 3 種類のベクトルを作ります。それぞれ、学習済みの行列を掛けて作ります（線形変換）。

ベクトルに行列を掛けると、出力の各数値は「入力の数値に重みを掛けて足したもの」になります。たとえば入力が [2, 1] で、行列が「1 つ目の出力 = 1×(1 つ目) + 0×(2 つ目)、2 つ目の出力 = 1×(1 つ目) + 2×(2 つ目)」なら、出力は [2, 4] です。同じ入力でも、Query 用・Key 用・Value 用に別々の行列を掛けるので、3 種類の違うベクトルができます。

| ベクトル | 役割 | たとえ |
| --- | --- | --- |
| **Query（q）** | 自分がどんな情報を探しているか | 検索ワード |
| **Key（k）** | 自分がどんな情報を持っているか | 検索される側の見出し |
| **Value（v）** | 実際に渡す情報の中身 | 見出しの先にある本文 |

あるトークン（たとえば「それ」）の出力は、次の 3 ステップで計算します。

1. **スコア**: 自分の q と、各トークンの k の内積を取る。内積は、同じ位置の数値どうしを掛けて全部足した値（下の表に途中式があります）。ベクトルの長さが同じなら、向きが揃っているほど大きくなる。「それ」の q と「魚」の k の向きが揃っていれば、「魚」のスコアが高くなる。
2. **重み**: スコアを $\sqrt{d_k}$（$d_k$ は q と k の次元数）で割ってから softmax にかけ、合計 1 の重みにする。softmax は、各値を指数関数 $e^x$（$e$ は約 2.718 の定数で、その $x$ 乗）に通してから、その合計で割る計算です（くわしくは 5 の回）。
3. **出力**: 各トークンの v を、その重みで加重平均する。ベクトルの加重平均は、同じ位置の数値ごとに計算する。重みの大きい「魚」の v が多く混ざる。

小さな数値例で、3 ステップを通して追ってみます。2 次元で、各次元を［動物, 食べ物］とし、トークンは「猫」「魚」「それ」の 3 つだけに絞ったおもちゃの例です（v は k と同じ値にします）。「それ」の q は [0, 2]（食べ物を探している）と仮に決めます。

| キー | k（= v） | 1. スコア（q・k） | ÷ $\sqrt{2}$（$d_k = 2$） | 2. 重み（softmax） |
| --- | --- | --- | --- | --- |
| 猫 | [2, 0] | 0×2 + 2×0 = 0 | 0 | 0.045 |
| 魚 | [0, 2] | 0×0 + 2×2 = 4 | 2.83 | 0.769 |
| それ | [1, 1] | 0×1 + 2×1 = 2 | 1.41 | 0.186 |

重みの計算：$e^0 = 1$、$e^{2.83} \approx 16.95$、$e^{1.41} \approx 4.10$ で、合計は約 22.05。それぞれを合計で割ると、約 [0.045, 0.769, 0.186] です（小数 3 桁に四捨五入）。

最後に 3. の加重平均をすると、出力は 0.045×[2, 0] + 0.769×[0, 2] + 0.186×[1, 1] = [0.276, 1.724] ≈ [0.28, 1.72]。「食べ物」の成分が大きく、「魚」の情報が多く混ざっています。

これを 10 個のトークン全部について同時に行います。行列でまとめて書くと、有名な次の式になります（$Q, K, V$ は q・k・v を 10 本ずつ縦に並べた行列、$K^\top$ は K の転置、$M$ は後述のマスク）。

$$
\mathrm{Attention}(Q, K, V) = \mathrm{softmax}\left(\frac{QK^\top}{\sqrt{d_k}} + M\right) V
$$

ここで計算しているのは、1 組の Q・K・V（下のマルチヘッドの節でいう 1 ヘッド）の分です。v の次元も q・k と同じ $d_k$ とするので、出力は 10 × $d_k$ になります（10 × d に戻す方法は、マルチヘッドの節で見ます）。行列の形は、次の順に変わります。



- **$QK^\top$**: $Q$（10 × $d_k$）と $K^\top$（$d_k$ × 10）を掛けて、10 × 10 のスコアの表にする。$i$ 行 $j$ 列は「$i$ 番目の q と $j$ 番目の k の内積」
- **softmax**: 行ごと（クエリのトークンごと）にかけて、10 × 10 の重みの表にする
- **$V$ を掛ける**: 重みの表（10 × 10）に $V$（10 × $d_k$）を掛けて、1 ヘッド分の出力（10 × $d_k$）にする。$i$ 行目は「$i$ 番目のトークンの重みで v を加重平均したもの」

上の数値例は、この表の「それ」の 1 行ぶん（図の色のついた行）の計算に当たります（ただし数値例は、見る相手を「猫」「魚」「それ」の 3 つに絞っています）。

:::note[なぜ √d_k で割るのか]
内積は $d_k$ 個の積の足し算なので、次元が大きいほど足す項が増え、値の振れ幅も大きくなります（各数値がばらばらなら、振れ幅はおよそ $\sqrt{d_k}$ に比例します）。値が大きすぎると softmax がほぼ 1 か 0 になり、学習が進みにくくなります（勾配がほとんど 0 になる）。そのため、次元数に応じて縮めています。
:::

（ここにはブラウザで操作できるインタラクティブなデモがあります）

デモには 2 つの「ヘッド」があります。ヘッドとは、1 組の Q・K・V を使う Attention のことです（くわしくは下のマルチヘッドの節）。

:::caution[おもちゃの例であることに注意]
このデモの q・k・v は、仕組みが見えるように手で決めた値です（各次元に「動物」「食べ物」などの意味を割り当て、v は k と同じ値にしています。「直前を見るヘッド」は、直前のトークンのスコアが高くなるように直接決めています）。本物のモデルでは、q・k・v は学習済みの行列から計算され、1 つの次元を見ても意味は読み取れません。
:::

#### 試してほしいこと

- **クエリ「それ」の重みを見る**: 「魚」に最も強く注目しています。これは「それ」の q が「食べ物らしさ」の方向を向き、「魚」の k も同じ方向を向いているからです。
- **「それ」の q の「食べ物」スライダーを 0 にし、「動物」を上げる**: 注目先が「猫」に移ります。q は「何を探すか」を表している、ということが体感できます。
- **スケールの強さを動かす**: このスライダーは、$\sqrt{d_k}$ で割ったあと、さらに割る数です（実際の Attention にはない、デモのためのつまみ。5 の回の temperature と同じ働き）。大きくすると重みが平らに（いろいろなところを少しずつ見る）、小さくすると 1 か所に集中します。
- **「未来を隠す」を外す**: 「未来を隠す」は、各トークンが自分より後ろのトークンを見られないようにする仕組みです（理由は次の節）。外すと、「猫」が後ろの「魚」や「食べた」も見られるようになります。

### 未来を隠す（causal mask）

LLM は「次のトークンを予測する」ように学習します。学習のときは、完成した文章を丸ごと入力し、すべての位置で「次のトークン」を同時に当てさせます（そのほうが効率よく学習できる）。このとき、たとえば「猫」の位置から後ろの「が」が見えたら、答えを見ながら解くのと同じです。
そこで、各トークンは **自分より前（と自分自身）しか見られない** ようにします。具体的には、未来の位置のスコアを $-\infty$ にしてから softmax にかけ、重みを 0 にします（$e^{-\infty} = 0$）。式の $M$ がこれで、10 × 10 の表のうち、見てよい位置（自分と前）は 0、未来の位置は $-\infty$ になっています。スコアの表に足すと、未来の位置だけが $-\infty$ になります。

冒頭の例文でいうと、「それ」の位置からは後ろの「は新鮮だった」が見えず、集められるのは前の「猫」や「魚」の情報までです。その代わり、後ろの「新鮮」の位置からは「それ」も「魚」も見えるので、「新鮮なのは魚」という手がかりは、そこで集められます。

上の数値例では、「それ」の q を「食べ物を探している」向きに仮に決めましたが、この向きは「新鮮」からは来られません。本物のモデルでこう向くとしたら、前のブロックで「魚を食べた」などの前の文脈を取り込んだ結果です（埋め込み直後の最初のブロックでは、「それ」はまだ周りを知りません）。

### マルチヘッド Attention

1 組の Q・K・V では、1 つのトークンにつき 1 通りの重みづけしかできないので、「代名詞の指す先」と「直前のトークン」のように違う種類の関係を同時に集めにくくなります。そこで実際には、別々の行列を持つ Attention（**ヘッド**）を何個も並列に動かします（数はモデルによります。GPT-2 最小構成では 12 個）。

- あるヘッドは「代名詞が指すもの」を探す
- 別のヘッドは「直前のトークン」を見る（デモの「直前を見るヘッド」）
- また別のヘッドは「文法的な主語」を探す

各ヘッドは、d より小さい次元の q・k・v を使います（v の次元は一般には q・k と別にもできますが、GPT-2 など多くのモデルでは同じです）。よくあるのは、d をヘッド数で割った次元にする方法です。たとえば GPT-2 最小構成では、d = 768 を 12 ヘッドで割って、各ヘッドは 64 次元。

12 個のヘッドの出力（各 10 × 64）を横に並べて（連結して）、10 × 768 に戻します。それにもう 1 つの行列（各ヘッドが集めた情報を混ぜ合わせ、元のベクトルに足せる形に整えるためのもの）を掛けたものが、Attention 層の出力（10 × d）です。

どのヘッドが何を担当するかは人間が決めるのではなく、学習の結果として分かれていきます（上の例のように、きれいに役割を言い表せるヘッドばかりではありません）。

:::note[発展：K と V をヘッドどうしで共有する]
最近の多くの LLM では、メモリ（後で見る KV キャッシュ）を節約するため、複数のヘッドで K・V を共有する方式（GQA など）を使っています。Q はヘッドごとに別々です。
:::

:::note[ここまでのまとめ]
Attention は、各トークンが「誰の情報をどれだけ取り込むか」を q と k の内積で決め、v を混ぜ合わせる仕組みです。入力も出力も 10 × d で、形は変わりません。この出力を元のベクトルに足すことで（次の回）、「それ」の q が食べ物の向きなら、「それ」のベクトルに「魚」の情報が流れ込みます。「新鮮なのは魚」という後ろの手がかりは、「それ」の位置ではなく「新鮮」の位置で集められます。
:::

**このページの用語**

- **行列**: 数値を縦横の表の形に並べたもの。横の並びを行、縦の並びを列という。ベクトルに行列を掛けると、別のベクトルに変換できる。
- **パラメータ**: モデルが学習で調整する数値。埋め込み行列や、Attention・MLP の行列の中身がすべてパラメータ。「70B のモデル」は、パラメータが 700 億個あるという意味。
- **線形変換**: ベクトルに行列を掛けて、別のベクトルに変えること。各出力は、入力の数値に重みを掛けて足し合わせたものになる。
- **内積**: 2 つのベクトルの同じ位置の数値どうしを掛けて、全部足した値。それぞれの長さを変えずに比べれば、向きが揃っているほど大きく、逆向きなら負になる。ベクトルが長いほど、値の振れ幅も大きくなる。
- **softmax（ソフトマックス）**: 数値の並びを、すべて 0 以上で合計がちょうど 1 になる「確率の並び」に変える関数。元の値が大きいものほど大きな確率になる。
- **加重平均**: 値ごとに「重み」を掛けてから足し合わせる平均。重みの合計は 1 にする。重みの大きい値ほど結果に強く効く。
- **転置**: 行列の行と列を入れ替えること。A の転置を Aᵀ と書く。
- **学習**: 大量のデータで予測を試し、外れた分だけパラメータを少しずつ調整して、予測を当たりやすくしていくこと。LLM は「次のトークンの予測」で学習する。
- **勾配**: 各パラメータを少し動かしたとき、予測の外れ具合（損失）がどれだけ増えるか減るかを表す値。学習では、勾配の逆向きにパラメータを動かして損失を減らす。

---

## 4. Transformer ブロック全体

> Attention と MLP を残差接続でつなぎ、何十層も積み重ねる。LLM の骨格の全体像

この回では、ここまでの部品がどう組み合わさって 1 つのモデルになっているかを見ます。新しく出てくる部品は、残差接続・MLP・LayerNorm・出力層の 4 つです。

**この回の入力と出力**

- **ブロック 1 つの入力と出力**: ベクトルの列（10 × d）→ 同じ形のベクトルの列（10 × d）。形が変わらないので、何十個でも直列につなげられる
- **モデル全体の入力と出力**: トークン ID の列（10 個）→ 次のトークンについての、語彙のすべてのトークンのスコア（logits。語彙数ぶん。GPT-2 では 50,257 個）


### 1 ブロックの中身

Transformer は、同じ形の **ブロック** を何十層も積み重ねたものです。1 つのブロックは、次の 2 段構えになっています。



図では、左の太い縦線が $x$ の流れです。そこから右へ枝分かれして LayerNorm → Attention（または MLP）を通り、＋のところで元の流れに足されて戻ります。



1. **Attention 層**: トークン同士で情報をやり取りする（前回の内容）

   入力 $x$（10 × d）を LayerNorm で整えてから Attention に通し、その出力を **元の $x$ に足します**。

   $$x \leftarrow x + \mathrm{Attention}(\mathrm{LayerNorm}(x))$$

2. **MLP 層**: 各トークンが、それぞれ自分のベクトルだけを見て変換する

   同じように LayerNorm → MLP に通し、結果を足します。

   $$x \leftarrow x + \mathrm{MLP}(\mathrm{LayerNorm}(x))$$



足し算をしているので、どの段階でも $x$ の形は 10 × d のままです。

### 残差接続：「書き換える」のではなく「書き足す」

上の式で大事なのは、各層の出力を **元のベクトルに足している**（残差接続）点です。

ベクトル $x$ は、入力から出力まで 1 本の流れ（**残差ストリーム**）として通り抜けます。各層は、その流れを置き換えるのではなく、「足し込む更新分」を出します。更新分は新しい情報を書き足すこともあれば、既存の成分を強めたり打ち消したりすることもありますが、元のベクトルが通る道は常に残ります。

前の回の小さな数値例で見てみます（説明を簡単にするため、LayerNorm と、ヘッドの出力にかける最後の行列は省きます）。「それ」のベクトルを $x = [1, 1]$（前の回で [1, 1] だったのは k ですが、ここでは元のベクトル $x$ もたまたま同じ値だったとします）、Attention の出力を $[0.28, 1.72]$ とすると、足したあとは $x = [1.28, 2.72]$ です。もし置き換えていたら $[0.28, 1.72]$ になり、元の $[1, 1]$ は消えます。この例では、足すことで元の値の上に「食べ物」の成分が上乗せされています。

足し算でつなぐと、次の 2 つの良いことがあります。

- 層が深くなっても、元の情報が失われにくい
- 学習のときに、勾配が、出力側から入力に近い層まで、何十層さかのぼっても届きやすい。何十層も積めるのはこのおかげ（上の図の太い縦線は、出力から入力まで何も掛けずに通れる「素通りの道」です。学習の手がかりは出力側から層をさかのぼって伝わりますが、層を通るたびに小さな係数が掛かると、何十層で消えるほど薄まってしまいます。素通りの道があれば、薄まらずに戻ってこられます）

### MLP：知識が蓄えられる場所

MLP は、各トークンのベクトルを 1 本ずつ変換する小さなニューラルネットワークです。同じブロックの中では、すべてのトークンに同じ MLP（同じ行列）を使いますが、トークンどうしのベクトルは混ぜません。GPT-2 型の MLP は、次の 3 ステップです。

1. 線形変換で、d 次元を 4 倍ほど（4d 次元）に広げる
2. 活性化関数（GELU など）を通す。ここで非線形な変換が入る
3. もう一度線形変換して、d 次元に戻す

広げた各次元は、「この特徴があるか」を調べる検出器のように働きます。一度広げるのは、検出器をたくさん用意するためです。前の節の「それ」のベクトル [1.28, 2.72]（[動物, 食べ物]）を、4 つの検出器で調べてみます。

1. 広げる：4 つの検出器［動物, 食べ物, 食べ物 − 動物, 動物 − 食べ物］を計算する → [1.28, 2.72, 1.44, −1.44]。2 個だった数値が 4 個に増えた
2. ReLU：負の値を 0 にする → [1.28, 2.72, 1.44, 0]。「動物寄りか」を調べる 4 つ目の検出器は反応しなかった
3. 戻す：2 次元に戻す。ここでは 3 つ目（食べ物寄りか）の値の 0.25 倍だけを「食べ物」の次元に入れるとする → 更新分 [0, 0.36]。残差接続で足すと [1.28, 3.08]

この MLP は、「食べ物寄りなら、食べ物らしさをさらに強める」という規則を、行列の値（0.25 など）として覚えていることになります。本物の MLP には、こうした「検出器」と「書き足す先」の組が何千もあり、下で見る「事実の記憶」も、同じ形で蓄えられていると考えられています（MLP をこうした組の集まりとして読む見方は、[Geva ら、2021 年](https://arxiv.org/abs/2012.14913) などによる解釈の 1 つです）。

（この例は説明用です。LayerNorm は前の節と同じく省き、活性化関数は GELU の代わりに、負の値を 0 にするだけの ReLU を使い、本来は 4 倍の 8 次元に広げるところを 2 倍の 4 次元にしています。）

:::note[発展：最近のモデルの MLP（SwiGLU）]
Llama などの最近のモデルでは、SwiGLU という形が多く使われています。入力を 2 つの行列で別々に広げ、一方を SiLU（Swish。GELU に似た活性化関数）に通してから、もう一方と要素ごとに掛け合わせます（ゲートをかける。片方が「どれだけ通すか」の係数になる）。最後に d 次元へ戻すのは同じです。
:::

Attention が「他のトークンから情報を集める」のに対し、MLP は「集めた情報をもとに、自分の中で考える」部分だと言えます。
「マイケル・ジョーダン」というトークン列から「バスケットボール」という知識を引き出すような、**事実の記憶の多くは MLP に蓄えられている** と考えられています（[3Blue1Brown の動画「LLM はどう事実を記憶するのか」](https://www.youtube.com/watch?v=9-Jl0dxWQs8) がこの話です。研究が続いている分野で、すべてが解明されているわけではありません）。パラメータの数で見ても、各ブロックの約 3 分の 2 は MLP が占めています（4 倍に広げる場合）。

:::note[発展：パラメータ数の内訳]
バイアスと LayerNorm のパラメータは小さいので省き、重み行列だけを数えます。

- Attention：Q・K・V 用と最後の行列で、d × d が 4 つ → 4d²（Q 用の行列はヘッドごとに d × 64 だが、12 ヘッド分を並べると d × 768 = d × d。K・V も同じ。GPT-2 最小構成の場合）
- MLP：d × 4d と 4d × d → 8d²
- MLP の割合：8d² ÷（4d² + 8d²）＝ 3 分の 2
:::

### LayerNorm：値のスケールを揃える

LayerNorm は、各トークンのベクトルの数値を、いったん平均が 0、分散（数値の散らばり具合）が 1 になるように正規化し、そのあと学習した倍率とずれで調整する処理です。Attention や MLP に入れる値の大きさを揃え、層を重ねても各層の計算が極端な値で不安定にならないようにします。

上の図のとおり、LayerNorm がかかるのは枝に入る値だけで、左の本線の $x$ にはかかりません。本線には層ごとに更新分が足されていくので、最後に出力層へ渡す前に、もう一度 LayerNorm で揃えます（下の「モデル全体」の 4.）。

[2, 4, 6] というベクトルなら、次の順に計算します。

1. 平均（4）を引く → [−2, 0, 2]
2. 標準偏差（散らばりの大きさ。分散の平方根）で割る。分散は 1. の値の 2 乗の平均で (4 + 0 + 4) ÷ 3 ≈ 2.667、標準偏差は √2.667 ≈ 1.633 → 約 [−1.22, 0, 1.22]
3. 次元ごとに学習した倍率を掛け、次元ごとに学習した値を足す（揃えすぎた値を、モデルが使いやすい大きさと位置に戻せるようにするため）

:::note[発展：細かい違い]
- **0 で割らない工夫**: 実際には、分散にごく小さな定数を足してから平方根を取ります。そのため 2. のあとの分散は 1 ではなく「ほぼ 1」です（元の分散がその定数と同じくらい小さいときは 1 より小さくなり、全部の数値が同じなら 0 のままです）。
- **RMSNorm**: Llama などの最近のモデルでは、平均を引かずに大きさだけを揃える RMSNorm を使うものが多くなっています。
- **かける位置**: 上の手順のように Attention や MLP に入れる前にかける形（Pre-LN）は、GPT-2 以降の多くのモデルの方式です。元の Transformer の論文では、足したあとの $x$ に LayerNorm をかけていました（Post-LN）。
:::

### なぜ何回も通すのか

Attention と MLP を 1 回ずつ通すだけでは足りず、ブロックを何十層も重ねるのには、主に 3 つの理由があります。

#### 1. 情報を「伝言リレー」で運ぶには、段数が要る

**1 つの層の中では、「A の情報を B が受け取り、その B を C が見る」という伝言はできません。** 各層の Attention が見るのは、どのトークンについても、その層に入ってくる時点のベクトル（前の層までの結果）だからです。その層で誰かが集めた情報は、次の層になって初めて、ほかのトークンから見えるようになります。だから、伝言を回すには層を重ねる必要があります。

例文で、「それ」と「だった」のベクトルに何が足されていくかを、層ごとに追ってみます（中身はたとえで、実際のモデルがちょうどこの層でこう動くとは限りません）。

| | 「それ」のベクトル | 「だった」のベクトル |
| --- | --- | --- |
| 埋め込みの直後 | 「それ」という語だけ | 「だった」という語だけ |
| 1 層目の後 | 前の「食べた」などの文脈が薄く混ざる。まだ、どれを指すかは決まっていないが、「食べられたものを探そう」という手がかりになる | 「新鮮」「それ」などを見て、「何かが新鮮だった」の情報が入る |
| 2 層目の後 | その手がかりで q が食べ物の向きになり、「魚」に強く注目して「それ＝魚」の情報が入る | まだ「それ＝魚」は届いていない（1 層目の後の「それ」は、まだ指す先を特定していなかった） |
| 3 層目の後 | （さらに情報が足される） | 2 層目で「魚」を知った「それ」を見るので、「新鮮なのは魚」という情報が届く |

「それ＝魚」という情報が「だった」に届くまでに、3 層かかりました。前の段で得た結果を使って次を調べる、という処理を多く重ねるほど、たくさんの段が要ります（文章が長いだけで、必要な段数が増えるわけではありません）。

:::note[この例の前提]
- 1 層目で文脈の手がかりを集め、2 層目でその手がかりに応じて「魚」を探す、という経路を仮定しています。3 の回で見たとおり、埋め込み直後の「それ」は周りを知らないので、「食べ物を探す」向きの q は文脈を取り込んでから作られる、と考えるのが自然だからです（1 層目から「魚」に注目すること自体は、構造上は可能です）。
- 実際のモデルでは、「だった」が「魚」や「食べた」を直接見て組み立てるなど、ほかの経路もありえます。それでも、「手がかりを使って探す」「それをさらに別の位置が受け取る」といった多段の処理には、段数が要ります。
:::

#### 2. 「集める → 考える → それを踏まえて、また集める」ができる

Attention は情報を **集める** 係、MLP は集めたものを **加工する** 係です。MLP が加工した結果は残差ストリームに足され、次の層の Attention で Query（何を探すか）や Key（自分が何を持っているか）を作る材料になります。

人が文章を読むときも、「『それ』は何を指す？ → 魚だ → では『新鮮だった』は何の話？」と、分かったことを足場にして次を調べます。1 回集めて 1 回考えるだけでは、この足場を使った読み方ができません。

#### 3. 深くすると、少ない部品で複雑な処理を表せる

段を重ねると、単純な特徴を組み合わせて、複雑な特徴を作れます。同じ処理を 1 段だけで表そうとすると、ずっと多くの部品（上の MLP の例の「検出器」のような、数値を受け取って 1 個の数値を返す小さな計算。ニューロンと呼ぶ）が要ることがあります。

ただし、深くするほど計算は重くなります。何層にするかは、精度と計算のコストの兼ね合いで決まります（GPT-2 最小構成で 12 層、大きなモデルでは数十〜百数十層。下の「モデル全体」）。各ブロックの形は同じでも、パラメータは別々なので、同じ処理を繰り返しているわけではなく、層ごとに違う役割を学習します。

:::note[発展：層ごとの役割の傾向]
学習済みのモデルを調べると、おおまかに、浅い層では近くの語どうしの関係や文法のような局所的なこと、深い層ほど意味や文脈に関わることを扱う傾向が見られます（[Tenney ら、2019 年](https://arxiv.org/abs/1905.05950) は BERT というモデルで、こうした順序を報告しています）。ただし、モデルによって違い、きれいに分かれるわけでもありません。
また、「前に出てきた並びを見つけて、その続きをまねる」という、LLM でよく見つかる仕組み（induction head）は、2 つの層の Attention が、上の「1. 伝言リレー」の節のように組み合わさって働くことが知られています（[Olsson ら、2022 年](https://arxiv.org/abs/2209.11895)）。
:::

### モデル全体



1. トークン化して ID の列にする（10 個）
2. 埋め込み行列でベクトルに変換する（10 × d。GPT-2 などでは位置の情報も足す）
3. Transformer ブロックを $N$ 回通す（10 × d のまま。GPT-2 最小構成で 12 層。大きなモデルでは数十〜百数十層で、たとえば [Llama 3](https://arxiv.org/abs/2407.21783) の 70B で 80 層、405B で 126 層、[GPT-3](https://arxiv.org/abs/2005.14165) の 175B で 96 層）
4. 最後の LayerNorm を通す（10 × d）
5. **一番最後のトークン**（例文なら「だった」）のベクトル 1 本（d 次元）に、「d × 語彙数」の行列を掛けて、語彙のすべてのトークンのスコア（logits、語彙数ぶん）を出す。この最後の変換を **出力層** と呼びます。GPT-2 では、この行列に埋め込み行列の転置を使い回します

   たとえば説明用に d = 2、語彙が「。」「ね」「が」の 3 個だけだとします。最後のベクトルが [2, 1]、行列の各候補の列が「。」[1, 0]、「ね」[0, 1]、「が」[1, −2] なら、スコアは各列との内積で、2×1 + 1×0 = 2、2×0 + 1×1 = 1、2×1 + 1×(−2) = 0 → logits [2, 1, 0]。次の回の softmax の例でも、この [2, 1, 0] を使います。



最後のトークンは、Attention で前のすべてのトークンを見られます。学習によって、そこから予測に役立つ文脈を取り込むようになっているので、「次に何が来るか」の予測に使えます。
（実際には全トークンについて同じ計算ができ、学習のときは「各位置で次のトークンを当てる」問題を一度にまとめて解いています。生成のときに使うのは最後の 1 つだけです。）

最後の logits から次のトークンをどう選ぶかは、次の回で扱います。

:::tip[全体を可視化して眺める]
次の 2 つは英語のサイトですが、ここまでの流れを実際のモデルの数値で追いかけられます。説明が読めなくても、見るだけで十分に面白いです。

- [Transformer Explainer](https://poloclub.github.io/transformer-explainer/) — 実物の GPT-2 がブラウザで動く。Attention の重みも見られる
- [LLM Visualization](https://bbycroft.net/llm) — 小さな GPT の行列演算を 1 ステップずつ 3D で追える（こちらは立体表示）
:::

:::note[ここまでのまとめ]
LLM = 埋め込み → （Attention + MLP）× N 層 → logits。各層は残差ストリームに情報を書き足していき、最後のトークンのベクトルが「次に来るもの」の予測に使われます。
:::

**このページの用語**

- **語彙（ボキャブラリ）**: トークナイザが知っているトークンの一覧。LLM は、この一覧のどれか 1 つを次のトークンとして選ぶ。語彙の数を語彙サイズという。
- **ロジット（logits）**: モデルが最後に出す、語彙のトークン 1 つ 1 つに対するスコア。大きいほど「次に来そう」という意味だが、まだ確率ではなく、負の値もとる。
- **LayerNorm（層正規化）**: 1 つのトークンのベクトルの数値を、平均が 0、分散（数値の散らばり具合）が 1 になるように揃え、学習した倍率を掛けて、学習したずれを足す処理。値が大きくなりすぎたり小さくなりすぎたりするのを防ぐ。
- **MLP（多層パーセプトロン）**: 線形変換と活性化関数を交互に重ねた、基本的なニューラルネットワーク。Transformer では、各トークンのベクトルを 1 つずつ別々に変換する部分を指す。
- **残差接続**: 層の出力で入力を置き換えるのではなく、入力に出力を足し合わせるつなぎ方。x ← x + 層(x) と書ける。入力をそのまま伝える通り道ができるので、元の情報が残りやすく、深く積んでも学習しやすくなる。
- **学習**: 大量のデータで予測を試し、外れた分だけパラメータを少しずつ調整して、予測を当たりやすくしていくこと。LLM は「次のトークンの予測」で学習する。
- **勾配**: 各パラメータを少し動かしたとき、予測の外れ具合（損失）がどれだけ増えるか減るかを表す値。学習では、勾配の逆向きにパラメータを動かして損失を減らす。
- **線形変換**: ベクトルに行列を掛けて、別のベクトルに変えること。各出力は、入力の数値に重みを掛けて足し合わせたものになる。
- **活性化関数（GELU など）**: ニューラルネットワークの層の間に挟む、曲がった形（非線形）の関数。これがないと、線形変換を何層重ねても 1 回の線形変換と同じになり、複雑な関係を表せない。
- **非線形**: 線形ではない関係。グラフにすると 1 本の直線（平面）にならない。たとえば ReLU（負なら 0、正ならそのまま）は、ReLU(1) + ReLU(-1) = 1 なのに ReLU(1 + (-1)) = 0 で、「足してから変換する」と「変換してから足す」の結果が食い違う。
- **パラメータ**: モデルが学習で調整する数値。埋め込み行列や、Attention・MLP の行列の中身がすべてパラメータ。「70B のモデル」は、パラメータが 700 億個あるという意味。
- **正規化**: 数値の大きさや範囲を、扱いやすい基準に揃えること。たとえば「平均 0・分散 1 にする」「合計を 1 にする」「長さを 1 にする」など。
- **転置**: 行列の行と列を入れ替えること。A の転置を Aᵀ と書く。

---

## 5. 次のトークンを選ぶ

> logits を確率に変え、temperature・top-k・top-p で 1 つ選ぶ。生成の最後の一歩

モデルの最後の出力は、語彙のすべてのトークンに対するスコア（logits）です。ここから次の 1 トークンを選びます。

**この回の入力と出力**

- **入力**: logits（語彙数ぶんの実数。GPT-2 なら 50,257 個）。例：「猫が魚を食べた。それは新鮮だった」の次として、「。」に 9.1、「ね」に 7.4、「が」に 6.2、…（数値は下のデモ用の仮の値。前の回の小さな計算例 [2, 1, 0] とは別）
- **途中で作るもの**: 確率（語彙数ぶん。すべて 0 以上で、合計 1）
- **出力**: 次のトークン 1 個（例：「。」）
- **その後**: 選んだトークンの ID を ID の列の末尾に足して 11 個にし、埋め込みからもう一度計算する


### logits を確率にする：softmax

logits はただの実数で、負の値もあります。これを softmax で確率分布に変えます。$z_i$ を $i$ 番目のトークンの logit とすると、

$$
p_i = \frac{e^{z_i}}{\sum_j e^{z_j}}
$$

$p_i$ は $i$ 番目のトークンの確率、$e$ は約 2.718 の定数（ネイピア数）、分母の $\sum_j$ は語彙のすべてのトークンについての合計です。指数関数をかけてから合計で割るので、すべて正の値になり、合計は 1 になります。

例：前の回の出力層の小さな例（候補は「。」「ね」「が」の 3 つで、logits は [2, 1, 0]）なら、$e^2 \approx 7.39$、$e^1 \approx 2.72$、$e^0 = 1$ で、合計は約 11.1。それぞれを合計で割ると、確率は約 [0.67, 0.24, 0.09] になります。

$e^{z+1} / e^{z} = e$ なので、logit が 1 違うと、確率は約 2.7 倍違います。差が 2 なら約 7.4 倍、差が 3 なら約 20 倍と、logits の差が少し増えるだけで、確率の比は急に大きくなります。

### 確率からどう選ぶか

- **貪欲法（greedy）**: 常に一番確率の高いトークンを選ぶ。同じ入力なら毎回同じ文章になり（実際のサービスでは、計算の細かな誤差でわずかに変わることもある）、同じ言い回しを繰り返しやすい。
- **サンプリング**: 確率に従ってサイコロを振る。自然で多様な文章になるが、まれに変なトークンも選ばれる。

その中間を調整するのが、次の 3 つのつまみです。

- **temperature** $T$：logits を $T$ で割ってから softmax にかける。$T<1$ で一番手に集中し、$T>1$ で平らになる。$T \to 0$ で貪欲法と同じ（一番大きい logit が 1 つだけなら）。
- **top-k**：確率の高い上位 $k$ 個だけを残す。確率の低い候補を切り捨てて、選ぶ範囲を絞る（候補の数は分布によらず $k$ 個）。
- **top-p**（nucleus）：上位から確率を足していき、合計が $p$ に達するまでを残す。自信があるときは候補が少なく、迷っているときは多くなる。

残した候補だけで確率を割り直してから（合計が 1 になるように）、サンプリングします。

top-p の例：確率が [0.67, 0.24, 0.09] で $p = 0.9$ なら、上から足して 0.67 → 0.91 で 0.9 に達するので、2 個が残ります（割り直すと約 [0.74, 0.26]）。迷っている分布 [0.40, 0.35, 0.25] なら、0.40 → 0.75 → 1.00 で、3 個とも残ります。

temperature が効く理由：logits [2, 1, 0] を $T = 0.5$ で割ると [4, 2, 0] になり、差が 2 倍に開きます。softmax にかけると約 [0.87, 0.12, 0.02] で、一番手に集中します。$T$ を 0 に近づけるほど差は限りなく開き、一番手の確率が 1 に近づく（貪欲法と同じになる）のです。ただし、一番大きい logit が同点で複数あるときは、その候補どうしで確率を分け合います。

（ここにはブラウザで操作できるインタラクティブなデモがあります）

#### 試してほしいこと

- **例文「…それは新鮮だった」で 1 回サンプリングする**: 上の IOBox の logits（「。」9.1、「ね」7.4、「が」6.2、…）から確率を作り、多くの場合「。」が選ばれます。これで例文が 1 トークン伸びます。
- **「吾輩は…」で temperature を 0.1 まで下げる**: ほぼ確実に「猫」になります。上げていくと「人間」や「犬」も出始めます。
- **top-p だけを効かせて、迷い具合で候補数が変わるのを見る**:
  1. 「設定を初期値に戻す」を押す（temperature 1、top-k 10。このデモでは候補を 1 つも切らない設定）
  2. 「好きな食べ物は…」を選び、top-p を 0.5 にする → 候補が拮抗しているので、3 個残ります
  3. 「吾輩は…」に切り替える → 「猫」だけが残ります

  top-p は「モデルの迷い具合」に合わせて候補数が変わるのが特徴です。
- **100 回サンプリングする**: 「好きな食べ物は…」を選び、「設定を初期値に戻す」を押してから試します。各候補が選ばれた回数を 100 で割ると、棒グラフの確率に近い値になることを確かめましょう。

### 1 トークンずつ、繰り返す

選んだトークンの ID を入力の末尾に足し、もう一度モデル全体を計算して、次のトークンを選ぶ。LLM の文章生成は、これを「終わり」を表す特別なトークン（終了トークン）が出るか、決めた長さに達するまで繰り返しているだけです（**自己回帰生成**）。

同じ質問をしても毎回違う答えが返ってくるのは、主にこのサンプリングに乱数が使われているからです。

:::note[発展：毎回すべてを計算し直しているわけではない]
考え方としては「末尾に足して、もう一度全体を計算する」ですが、実際の実装では、前のトークンについて計算した Key と Value を保存しておき（KV キャッシュ）、新しく足した 1 トークンの分だけを計算します。causal mask があるので、前のトークンの計算結果は後ろにトークンが増えても変わらないからです。
:::

:::note[コースのまとめ]
文章 → トークン ID の列 → ベクトルの列 → （Attention + MLP）× N → 最後のトークンの logits → softmax → サンプリング → 末尾に追加 → 繰り返し。
これが LLM の全体像です。一通り読んだら、[理解度クイズ](../quiz/) で確かめてみましょう。
:::

**このページの用語**

- **語彙（ボキャブラリ）**: トークナイザが知っているトークンの一覧。LLM は、この一覧のどれか 1 つを次のトークンとして選ぶ。語彙の数を語彙サイズという。
- **ロジット（logits）**: モデルが最後に出す、語彙のトークン 1 つ 1 つに対するスコア。大きいほど「次に来そう」という意味だが、まだ確率ではなく、負の値もとる。
- **softmax（ソフトマックス）**: 数値の並びを、すべて 0 以上で合計がちょうど 1 になる「確率の並び」に変える関数。元の値が大きいものほど大きな確率になる。
- **確率分布**: 起こりうる結果のそれぞれに、どれくらいの確率で起こるかを割り当てたもの。確率はすべて 0 以上で、合計は 1。

---

## 理解度クイズ

> LLM のしくみコースの理解度を、選択式と記述式の問題で確かめる

選択式と記述式の問題が混ざって出題されます。問題文の言い回しや選択肢は、出題のたびに複数の候補からランダムに選ばれます。

- **記述式** は、解答すると AI が採点観点ごとに判定し、結果がチェックに入ります。判定は目安なので、模範解答と見比べて、納得できなければ直してから記録してください。AI の採点が使えないときは、「採点用の文章をコピー」してお使いの AI に判定してもらうか、自己採点できます。
- 結果は **忘却曲線に沿った復習スケジュール** に記録されます。忘れかけたころに [復習ページ](../../review/) へ問題が戻ってきます。
