PythonでTransformerを実装する方法:基本構造と実装例をやさしく解説!

こんにちは。ゆうせいです。
今回は「TransformerをPythonで実装するにはどうすればいい?」というテーマでお話しします。
Transformerは、自然言語処理(NLP)を一変させた革命的なアーキテクチャですが、
実装となると「難しそう」「数式が多い」「どこから手をつければ…?」と感じる人も多いはず。
そこで今回は、
- Transformerの構造を簡単におさらい
- 実装に必要な要素を分解して解説
- PyTorchでの実装例(シンプルなミニ版)
という流れで、Transformerを自力で動かすための基本をやさしくご紹介していきます!
1. Transformerの全体構造をざっくり把握しよう
Transformerは以下のようなEncoder-Decoder構造でできています:
入力系列 → [エンコーダ] → 中間表現 → [デコーダ] → 出力系列
でも、翻訳以外(分類・生成など)ではEncoderだけを使うケースが多いです。
Encoderの構造
- 入力の埋め込み(Embedding)
- 位置エンコーディング(Positional Encoding)
- 複数の「エンコーダ層」
- Multi-Head Attention
- 残差接続+LayerNorm
- FeedForward Network
2. Pythonで実装する前の準備(必要な知識)
Transformer実装には次の概念が必要になります。
概念 | 説明 |
---|---|
ベクトルの埋め込み(Embedding) | 単語などを数値ベクトルに変換 |
位置エンコーディング | 入力の順序情報を加える |
Self-Attention | 各単語が他の単語をどれだけ重視するかを計算 |
Multi-Head Attention | 複数の視点からAttentionを同時に行う |
Feed Forward | 各位置のベクトルを非線形で変換 |
LayerNorm / 残差接続 | 学習の安定化と深層化の補助 |
3. 実装例(PyTorch)
以下は、Encoderの最小構成をPyTorchで実装する例です。
import torch
import torch.nn as nn
import math
class PositionalEncoding(nn.Module):
def __init__(self, d_model, max_len=5000):
super().__init__()
pe = torch.zeros(max_len, d_model)
position = torch.arange(0, max_len).unsqueeze(1)
div_term = torch.exp(
torch.arange(0, d_model, 2) * (-math.log(10000.0) / d_model)
)
pe[:, 0::2] = torch.sin(position * div_term)
pe[:, 1::2] = torch.cos(position * div_term)
self.pe = pe.unsqueeze(0)
def forward(self, x):
return x + self.pe[:, :x.size(1)].to(x.device)
class TransformerEncoderLayer(nn.Module):
def __init__(self, d_model, nhead, dim_feedforward=2048):
super().__init__()
self.attn = nn.MultiheadAttention(d_model, nhead, batch_first=True)
self.ff = nn.Sequential(
nn.Linear(d_model, dim_feedforward),
nn.ReLU(),
nn.Linear(dim_feedforward, d_model),
)
self.norm1 = nn.LayerNorm(d_model)
self.norm2 = nn.LayerNorm(d_model)
def forward(self, x):
attn_output, _ = self.attn(x, x, x)
x = self.norm1(x + attn_output)
ff_output = self.ff(x)
x = self.norm2(x + ff_output)
return x
class SimpleTransformerEncoder(nn.Module):
def __init__(self, vocab_size, d_model=512, nhead=8, num_layers=6, max_len=5000):
super().__init__()
self.embedding = nn.Embedding(vocab_size, d_model)
self.pos_encoder = PositionalEncoding(d_model, max_len)
self.layers = nn.ModuleList([
TransformerEncoderLayer(d_model, nhead) for _ in range(num_layers)
])
def forward(self, src):
x = self.embedding(src)
x = self.pos_encoder(x)
for layer in self.layers:
x = layer(x)
return x
4. 学習部分(簡易版)
# 入力(例:単語ID列)
sample_input = torch.randint(0, 10000, (8, 32)) # batch=8, length=32
model = SimpleTransformerEncoder(vocab_size=10000)
# 出力ベクトル
output = model(sample_input) # shape: [8, 32, 512]
5. HuggingFace Transformersを使うならもっと簡単!
from transformers import BertTokenizer, BertModel
tokenizer = BertTokenizer.from_pretrained("bert-base-uncased")
model = BertModel.from_pretrained("bert-base-uncased")
inputs = tokenizer("Transformers are powerful!", return_tensors="pt")
outputs = model(**inputs)
こんなに簡単に、実用的なモデルが使えます!
まとめ
- TransformerはSelf-Attentionを使った「並列処理可能な系列モデル」
- 実装では Embedding → Positional Encoding → Multi-Head Attention → FFN の構造
- PyTorchで簡易的に書くこともできるし、HuggingFaceなら一瞬で本格モデルが使える
- 数式を丁寧に追えば、自作実装も理解できるようになる!
今後の学習の指針
- Attentionの数式(クエリ・キー・バリューの関係)を数式レベルで理解
- マスク(Transformer Decoder)やCross-Attentionの実装に挑戦
- トークナイザや語彙の扱い方(BPEやWordPiece)を調べてみよう
- Transformerから派生した構造(BERT、GPT、ViT、T5など)も実験してみよう!
自分でTransformerを動かせると、最新のAI技術がぐっと身近になりますよ!
生成AI研修のおすすめメニュー
投稿者プロフィール

- 代表取締役
-
セイ・コンサルティング・グループ株式会社代表取締役。
岐阜県出身。
2000年創業、2004年会社設立。
IT企業向け人材育成研修歴業界歴20年以上。
すべての無駄を省いた費用対効果の高い「筋肉質」な研修を提供します!
この記事に間違い等ありましたらぜひお知らせください。