localaiforum
ログイン
ガイド › 基礎

transformerの内部

ローカルで動くものはすべてtransformerで、そのアーキテクチャはナプキンに収まる。トークンをベクトルに変換し、トークン同士が互いを見るN個の同一レイヤーに通し、最終ベクトルを語彙スコアに射影する。微分積分は不要——内積とソフトマックスが全体を担う。このページはその経路を一度、ゆっくり歩く。

残差ストリーム

モデルを貫くコンベアベルトを思い描く。各レイヤーでサブモジュールがベルトを読み、自分の寄与をベルトに加え戻す——置換はなく、すべて蓄積する。

x = embed(token_ids) + positions      # トークンがベクトルになる(次元 約4k)
for layer in range(N):                # 8Bモデルで N ≈ 32
    x = x + attention(x)              # トークン同士が情報を交換
    x = x + ffn(x)                    # 各トークンが自分自身を変換
logits = unembed(x[-1])               # 最終位置 → 語彙エントリごとのスコア
p = softmax(logits)                   # 次トークンすべての確率
  • エンベディング:各トークンIDは学習済みベクトルテーブルを指す。位置情報は混ぜ込まれる(現代のモデルではロータリーエンベディング)ので「犬が人を噛む」と「人が犬を噛む」は別物になる。
  • レイヤーは形は同一、中身は異なる。浅いレイヤーは構文と表層パターンを担い、深いレイヤーは意味、事実、タスク挙動を運ぶ。
  • アンエンベディング:最終ベクトルをすべての語彙エントリと比較し、ソフトマックスがスコアを確率に変える。サンプリングが1つ選ぶ(サンプリング)。

4トークンで見る自己アテンション

交換機構。各トークンのベクトルは3つの派生ベクトルを作る。クエリ(何を探しているか)、キー(何を名乗るか)、バリュー(選ばれたら何を渡すか)。文:「The cat sat on」。「sat」の位置は何を引き込むべきか?

token:          The     cat     sat     on
q·k scores:     1.2     4.1     3.0     0.4      (内積、説明用)
softmax →        0.05    0.60    0.31   0.04     (重みの合計は1.0)

output("sat") = 0.05·v(The) + 0.60·v(cat) + 0.31·v(sat) + 0.04·v(on)

「sat」は主に「cat」に注目する——必要な主語だ。すべての位置がこれを同時に実行する。これを言語モデルにする制約が1つ。因果マスキング——各トークンは過去のトークンだけを見て、未来は決して見ない。おかげで1パスで列中のすべての次トークン予測を同時に学習できる。

これが数学的道具のすべて。類似度スコア(内積)をミックスへ正規化(ソフトマックス)して、バリューベクトルに掛ける。

手順として、ある位置の1アテンションヘッド。

  1. すべてのトークンのクエリ・キー・バリューベクトルを計算。
  2. クエリと過去各トークンのキーの内積を取り、√(head_dim)で縮小。
  3. スコアをソフトマックスで合計1の重みに変える。
  4. それらトークンのバリューの加重和を出力。
  5. 全ヘッドの出力を連結して射影——これがそのレイヤーのアテンション寄与。

マルチヘッド:並列するパターン

1ヘッド=1組のクエリ/キー/バリュー=表現できる関係の1種類(主語↔動詞、形容詞↔名詞、共参照)。レイヤーは多数のヘッド(例:32)を低次元スライスで並列実行し、結果を連結する。ヘッドが多いほどレイヤーあたりの関係種類が増える——パターンの幅であって、思考の深さではない。

  • ヘッドは学習時に固定。「位置をまたいだ思考」とは、アテンションが残差ストリームに書き戻すもののこと。
  • ヘッド次元(例:128)× ヘッド数(例:32)= 隠れ次元(4096)。ヘッドは同じコンベアベルトの並列スライスで、別々のモデルではない。

FFN:パラメータの居場所

各レイヤーの後半は、すべてのトークンに独立適用される2行列ネットワーク。ベクトルを拡張し(約4倍)、非線形をかけ、射影して戻す。典型的な密モデルでは、全パラメータの約3分の2はここにあり、アテンションではない。役立つ直感はキーバリューメモリ——1つ目の行列は検出すべきパターンを、2つ目はパターンが発火したときベルトに加えるものを保持する。人が「モデルの事実」と呼ぶものの多くはFFN重みに格納されている(パラメータを参照)。

コンポーネント パラメータ比率(典型的な7–9B密モデル)
アテンション(Q、K、V、O) 約10〜15%
FFN 約60〜70%
エンベディング+出力ヘッド 約10〜25%(語彙サイズで増加)

パラメータを自分で数える

モデルカードは5つの数値を公表している。掛ければパラメータ数に到達する。実際の8B級オープンモデル(32レイヤー、隠れ次元4096、32ヘッド+8 KVヘッド、FFN幅14336、語彙約12.8万)では。

attention/layer:  q: 4096×4096 + k,v: 2×(4096×1024) + o: 4096×4096
                  ≈ 42M per layer × 32 layers            ≈ 1.3B
FFN/layer:        3 × (4096×14336), gated ≈ 176M × 32     ≈ 5.6B
embeddings:       2 × (128k × 4096), input + output head  ≈ 1.1B
total                                                     ≈ 8.0B

この計算はモデルカードの「8B」とほぼ一致する。得られる教訓は2つ。FFNがパラメータ数(したがってメモリ予算)を支配すること。そして大きな語彙は最初のレイヤーが動く前に約10億パラメータを要すること——多言語大語彙モデルが密モデル兄弟より重く見える理由の一部。

GQA:アテンションのコスト対策

生成中、各新トークンは過去全トークンのキーとバリュー——KVキャッシュに格納——を読む必要がある。オリジナルのマルチヘッドアテンションはヘッドごと・トークンごとに1組のKとVを格納する。グループ化クエリアテンション(GQA)は少数のKVヘッドを多数のクエリヘッドで共有し(例:32クエリヘッド、8 KVヘッド)、品質低下を無視できるレベルでキャッシュを4分の1に縮める。マルチクエリアテンション(MQA)はKVヘッド1つを共有する。実質的にすべての現代オープンモデルがGQAを採用。この節約が、長いコンテキストが実用になる大きな理由(KVキャッシュ)。

コンテキスト長=アテンションの射程

アテンションにより各トークンは過去の全トークンを見られるので、プリフィルの計算量はプロンプト長の2乗で増え、キャッシュは生成トークンごとに線形に増える。「128kコンテキスト」モデルは位置のトリックと拡張学習でそこに到達するが、ウィンドウの遠端の品質は通常、始点近くより弱い。長いウィンドウは必要なときだけ埋めること。

自分で試すには、ウィンドウの先頭に事実を置き、中間を埋め草で満たし、その事実を問う。大半のモデルはウィンドウの始端と終端では成功し、中間で落ちる——有名な「lost in the middle」パターン。うたい文句のコンテキストは収容能力と見なし、品質保証とは見なすな。

なぜこれで十分か

この構造だけから実用的事実が導ける。必要メモリ=重み+KVキャッシュ(VRAM計算)。デコード速度=重みを再読み取りできる速さ(プリフィルとデコード)。能力はパラメータ数に従う(パラメータ)。コンテキストのコスト=アテンションの射程。アーキテクチャは単純——その中の学習済み重み数十億こそ、誰も手書きできない部分。

関連: LLMとは · KVキャッシュ · プリフィルとデコード · パラメータ