Level 1概要役割と処理の流れ
何をする機能か
Encoder の N 層すべてを通過したあとに残る、[B, S, D] のベクトル列です。
新しい計算をする層ではなく、Encoder スタックの最終的な出力を指します。
入力トークン 1 個につき 1 本のベクトルが対応し、その本数は最初から最後まで変わりません。 変わったのは中身で、各ベクトルは「文全体を踏まえたうえでの、その位置の意味」を表すようになっています。
なぜ必要か
入力埋め込み の時点では、 同じトークンはどこに出てきても同じベクトルでした。 Encoder を通ることで、同じ語でも文脈によって異なるベクトルになります。
この表現は 2 通りに使われます。
- Decoder が Cross Attention で参照する Key・Value として
- 分類や検索など、下流タスクの入力特徴として(Encoder-only モデルの使い方)
全体の中でいつ呼ばれるか
Encoder の最終層の Add & Norm を終えた時点です。 以降、Encoder 側の計算は行われません。 推論時、この結果は1 回だけ計算して使い回します(Decoder が 1 トークン生成するたびに再計算はしません)。
Level 2内部処理Tensor形状・内部ステップ・設計上の意味
前段から受け取るもの
Encoder 最終層の 残差接続 + LayerNorm の出力 [B, S, D]。
後段へ渡すもの
encoder_states [B, S, D]。Decoder の各層の
Cross Attention へ、Key と Value の材料として渡されます。
Decoder は N 層すべてで同じ encoder_states を参照します。
あわせて、入力側のパディング位置を示す encoder_mask [B, S] も渡します。
パディングを参照しないようにするためです。
例文での処理
共通例文
The keys on the table are lost.
概念上のトークン列(S = 8): [The, keys, on, the, table, are, lost, .]
- The
- keys
- on
- the
- table
- are
- lost
- .
Encoder 出力の段階で、各位置のベクトルはおおむね次のような情報を含みます。
| 位置 | トークン | 含まれるようになった情報の例 |
|---|---|---|
| 1 | keys | 複数形である/on the table に修飾されている/lost の主語である |
| 4 | table | on に続く名詞で、keys の場所を説明する句の一部である |
| 5 | are | 主語 keys に対応する be 動詞である |
Embedding 直後
keys = 「keys という語」のベクトル(文脈なし)Encoder 出力
keys = 「テーブルの上にあった、失くした複数の鍵」のベクトル重要なのは、ベクトルの本数は S 本のままという点です。
文全体を 1 本のベクトルに要約するわけではありません。
文全体を 1 本で表したい場合は、平均を取る、[CLS] のような特別な位置を使う、
といった追加の操作が必要です。
EncoderとDecoderでの違い
これは Encoder 固有の出力です。Decoder 側の対応物は、
Decoder 最終層の出力 [B, T, D] で、そちらは
Linear(語彙数へ変換) へ渡されます。
- Encoder 出力
[B, S, D]→ Cross Attention の Key・Value になる - Decoder 出力
[B, T, D]→ 語彙上の確率へ変換される
Decoder-only の LLM には Encoder がないため、この表現自体が存在しません。 入力(プロンプト)も同じ 1 本の系列として Decoder が処理します。
入力と出力
入力
| 項目名 | データの意味 | データ型 | Tensor形状 | 記号の意味 | 具体例 | 次の渡し先 |
|---|---|---|---|---|---|---|
hidden_states | Encoder 最終層の出力 | float32 Tensor | [B, S, D] | B = バッチサイズ(同時に処理する文の数) / S = 入力系列長(Encoder側のトークン数) / D = モデル内部のベクトル次元(d_model) | [1, 8, 512] | そのまま Encoder 出力になる |
出力
| 項目名 | データの意味 | データ型 | Tensor形状 | 記号の意味 | 具体例 | 次の渡し先 |
|---|---|---|---|---|---|---|
encoder_states | 入力トークンごとの文脈込みベクトル | float32 Tensor | [B, S, D] | B = バッチサイズ(同時に処理する文の数) / S = 入力系列長(Encoder側のトークン数) / D = モデル内部のベクトル次元(d_model) | [1, 8, 512] | Decoder 各層の Cross Attention(Key・Value) |
encoder_mask | 入力側のパディング位置(参照させない位置) | bool / int64 Tensor | [B, S] | B = バッチサイズ(同時に処理する文の数) / S = 入力系列長(Encoder側のトークン数) | [[1, 1, 1, 1, 1, 1, 1, 1]] | Cross Attention のマスク |
B- バッチサイズ(同時に処理する文の数)
S- 入力系列長(Encoder側のトークン数)
D- モデル内部のベクトル次元(d_model)
このサイトでは Tensor 形状を PyTorch の `batch_first=True` 相当、つまり `[B, S, D]`(バッチ次元が先頭)で統一しています。実装によっては `[S, B, D]` を採用するものもあります。
よくある誤解
Level 3数式・Python数式・疑似実装・計算量・実装差
Pythonで表したインターフェース
from dataclasses import dataclass
from typing import Optional
import torch
from torch import Tensor, nn
@dataclass
class EncoderOutput:
encoder_states: Tensor # [B, S, D] 文脈込みの表現
encoder_mask: Optional[Tensor] # [B, S] パディング位置
class TransformerEncoder(nn.Module):
"""Encoder 層を N 個積み重ねたスタック。"""
def __init__(self, layers: nn.ModuleList) -> None:
super().__init__()
# 各層は別々のパラメータを持つ。同じ層を N 回ループするのではない。
self.layers = layers
def forward(
self,
hidden_states: Tensor,
encoder_mask: Optional[Tensor] = None,
) -> EncoderOutput:
"""
Args:
hidden_states: [B, S, D]。位置情報を加算済みの埋め込み。
encoder_mask: [B, S]。1 が実トークン、0 がパディング。
Returns:
encoder_states [B, S, D]。Decoder が Key/Value として参照する。
"""
for layer in self.layers:
hidden_states = layer(hidden_states, encoder_mask) # 形は [B, S, D] のまま
return EncoderOutput(encoder_states=hidden_states, encoder_mask=encoder_mask)
# 最小使用例(層の中身はダミー)
B, S, D = 1, 8, 512
identity_layers = nn.ModuleList([nn.Identity() for _ in range(6)])
class _DummyLayer(nn.Module):
def forward(self, x: Tensor, mask: Optional[Tensor] = None) -> Tensor:
return x
encoder = TransformerEncoder(nn.ModuleList([_DummyLayer() for _ in range(6)]))
out = encoder(torch.randn(B, S, D), torch.ones(B, S, dtype=torch.long))
print(out.encoder_states.shape) # torch.Size([1, 8, 512]) == [B, S, D]
print(out.encoder_mask.shape) # torch.Size([1, 8]) == [B, S]この例で単純化している点
- Encoder 層の中身(Attention・FFN)は既出のため省略し、スタックの入出力だけを示しています。
- Post-Norm 構成を前提にしています(Pre-Norm では最後にもう一度 LayerNorm が入ります)。
- パディングマスクの生成は呼び出し側の責務としています。
型と Tensor 形状の見え方を掴むための擬似実装です。そのまま学習・推論に使えるものではありません。
「N回反復」の意味
図に描かれた「N回反復」は、同じ重みの層を N 回ループするという意味ではありません。 通常は、それぞれ異なるパラメータを持つ層を N 個積み重ねることを指します (原典 base モデルでは N = 6)。
- 1 層目は表層的な特徴(隣接関係、品詞など)を扱う傾向
- 上の層ほど、構文や意味に関わる抽象的な特徴を扱う傾向
が観察されることがありますが、層ごとの役割が設計で決められているわけではありません。
下流での使われ方
- Cross Attention の Key・Value: 原典 Transformer の用法
- 文分類:
[CLS]位置のベクトル、または全位置の平均に分類ヘッドを付ける(BERT 系) - 系列ラベリング: 各位置のベクトルにタグ分類ヘッドを付ける(固有表現抽出など)
- 埋め込み検索: 平均プーリングして 1 本のベクトルにし、 ベクトル DB に格納する(RAG の検索側)