📋 このステップで学ぶこと
RoBERTa – BERTの訓練方法を改善した高性能モデル
ALBERT – パラメータ共有で軽量化したモデル
DistilBERT – 知識蒸留で高速化したモデル
ELECTRA – 効率的な事前学習手法
T5 – Text-to-Textの統一フレームワーク
日本語モデル(東北大BERT、rinna GPT等)
モデルの選び方とベストプラクティス
練習問題: 4問
⚠️ 実行環境について
このステップのコードはGoogle Colab で実行してください。
GPUがあるとより高速に動作します。
🤔 1. なぜBERT以外のモデルが必要なのか
BERT(2018年)は革命的なモデルでしたが、いくつかの課題がありました。
それを解決するために、様々な改良版が開発されました。
1-1. BERTの課題と解決策
【BERTの主な課題と解決モデル】
■ 課題1: 訓練方法が最適化されていない
解決: RoBERTa
→ 訓練方法を徹底的に改善して性能向上
■ 課題2: パラメータ数が多すぎる
解決: ALBERT
→ パラメータ共有で軽量化(110M → 12M)
■ 課題3: 推論速度が遅い
解決: DistilBERT
→ 知識蒸留で高速化(1.6倍速)
■ 課題4: 訓練効率が悪い(15%しか学習しない)
解決: ELECTRA
→ 全ての単語で学習(100%)
■ 課題5: 生成タスクに弱い
解決: T5
→ Encoder-Decoderで生成も得意
【モデルの位置づけ】
精度重視 ─────────────────────────── 速度重視
│ │
│ │
RoBERTa-Large RoBERTa-Base DistilBERT
ALBERT-xxLarge ELECTRA ALBERT-Base
【選ぶ基準】
・最高精度が欲しい → RoBERTa-Large
・バランスが良い → RoBERTa-Base, ELECTRA
・高速化したい → DistilBERT
・軽量化したい → ALBERT
・生成タスク → T5
モデル
パラメータ数
速度
精度
主な特徴
BERT-Base
110M
★★★
★★★
標準的なベースライン
RoBERTa-Base
125M
★★★
★★★★
訓練方法の改善で高精度
ALBERT-Base
12M
★★★★
★★★
パラメータ9分の1
DistilBERT
66M
★★★★★
★★★
1.6倍高速、97%の精度
ELECTRA-Base
110M
★★★
★★★★
効率的な事前学習
T5-Base
220M
★★
★★★★
生成タスクも得意
💪 2. RoBERTa(Robustly Optimized BERT)
RoBERTa は、Facebook AI(現Meta AI)が2019年に発表したモデルです。
BERTの訓練方法を徹底的に改善 することで、同じアーキテクチャでありながら
大幅な性能向上を実現しました。
2-1. RoBERTaの改善点
【RoBERTaの6つの改善点】
■ 改善1: NSP(Next Sentence Prediction)を削除
BERTの事前学習タスク:
1. MLM(マスク予測)← 効果あり
2. NSP(次文予測)← 効果が薄い!
NSPとは:
「2つの文が連続しているか?」を予測するタスク
例:
文A: “太郎は学校に行った。”
文B: “彼は友達に会った。”
→ 連続している(正解)
問題点:
・トピックで判断できてしまう(簡単すぎる)
・実際の性能向上に貢献していなかった
RoBERTaの対応:
→ NSPを完全に削除!MLMのみで訓練
■ 改善2: 動的マスキング
BERT(静的マスキング):
・前処理時に一度だけマスク位置を決定
・訓練中ずっと同じ位置がマスクされる
例: “The [MASK] sat on the mat”
→ 全エポックで”cat”の位置がマスク
RoBERTa(動的マスキング):
・エポックごとに異なる位置をマスク
・同じ文でも異なるパターンを学習
エポック1: “The [MASK] sat on the mat”
エポック2: “The cat [MASK] on the mat”
エポック3: “The cat sat on the [MASK]”
効果: より多様なパターンを学習できる
■ 改善3: より大きなバッチサイズ
BERT: バッチサイズ 256
RoBERTa: バッチサイズ 8,000 ← 31倍!
大きなバッチサイズの効果:
・学習が安定する
・より良い勾配推定
・最終的な性能が向上
■ 改善4: より多くの訓練データ
BERT: 16GB(Wikipedia + BookCorpus)
RoBERTa: 160GB(10倍!)
追加データ:
・CC-News(ニュース記事)
・OpenWebText(Webテキスト)
・Stories(物語)
■ 改善5: より長い訓練
実質的な訓練量:
BERT: 100万ステップ × 256バッチ = 2.56億サンプル
RoBERTa: 50万ステップ × 8000バッチ = 40億サンプル
→ 約16倍の訓練量!
■ 改善6: BPE(Byte-Pair Encoding)
BERT: WordPiece、語彙サイズ30,000
RoBERTa: BPE、語彙サイズ50,000
BPEの利点:
・より細かいサブワード分割
・未知語への対応が良い
2-2. RoBERTaの性能
【ベンチマーク結果】
GLUE(総合NLPベンチマーク):
BERT-Base: 78.3%
BERT-Large: 82.1%
RoBERTa-Base: 83.2% ← BERT-Largeを超える!
RoBERTa-Large: 88.5% ← 大幅改善!
SQuAD v1.1(質問応答)F1スコア:
BERT-Large: 93.2
RoBERTa-Large: 94.6 (+1.4)
SQuAD v2.0(回答不可能な質問含む):
BERT-Large: 81.8
RoBERTa-Large: 89.4 (+7.6) ← 7.6ポイント向上!
【重要な発見】
同じアーキテクチャでも、訓練方法の改善だけで
大幅な性能向上が可能!
・NSP削除 → 性能向上
・動的マスキング → 性能向上
・大きなバッチ → 性能向上
・多くのデータ → 性能向上
・長い訓練 → 性能向上
2-3. RoBERTaの実装
※モバイルでは横スクロールできます
# ========================================
# RoBERTaの使用例
# ========================================
# 必要なライブラリをインポート
from transformers import RobertaTokenizer, RobertaForSequenceClassification
import torch
# デバイスの設定
device = torch.device(‘cuda’ if torch.cuda.is_available() else ‘cpu’)
print(f”Using device: {device}”)
# モデル名を指定
# roberta-base: 125Mパラメータ(標準サイズ)
# roberta-large: 355Mパラメータ(大きいサイズ)
model_name = ‘roberta-base’
# トークナイザーを読み込み
# from_pretrained: 事前学習済みのトークナイザーをダウンロード
tokenizer = RobertaTokenizer.from_pretrained(model_name)
# モデルを読み込み
# RobertaForSequenceClassification: 文分類用のRoBERTa
# num_labels=2: 2クラス分類(Positive/Negative)
model = RobertaForSequenceClassification.from_pretrained(
model_name,
num_labels=2
)
# モデルをGPUに転送
model = model.to(device)
# モデル情報を表示
print(f”Model: {model_name}”)
total_params = sum(p.numel() for p in model.parameters())
print(f”Parameters: {total_params:,}”)
実行結果:
Using device: cuda
Model: roberta-base
Parameters: 124,645,632
次に、テキストを分類してみましょう。
# ========================================
# テキスト分類の実行
# ========================================
# 分類したいテキスト
text = “This movie is absolutely fantastic!”
# テキストをトークン化
# return_tensors=’pt’: PyTorchテンソルで返す
# padding=True: パディングを追加
# truncation=True: 最大長を超えたらカット
inputs = tokenizer(text, return_tensors=’pt’, padding=True, truncation=True)
# GPUに転送
inputs = {k: v.to(device) for k, v in inputs.items()}
# 評価モードに設定
model.eval()
# 予測を実行
# torch.no_grad(): 勾配計算を無効化(推論時は不要)
with torch.no_grad():
outputs = model(**inputs)
# logitsを確率に変換
# softmax: 出力を0〜1の確率に変換
probs = torch.softmax(outputs.logits, dim=-1)
# 最も確率の高いクラスを取得
predicted_class = torch.argmax(probs, dim=-1).item()
print(f”Text: {text}”)
print(f”Predicted class: {predicted_class}”)
print(f”Probabilities: Negative={probs[0][0]:.4f}, Positive={probs[0][1]:.4f}”)
実行結果:
Text: This movie is absolutely fantastic!
Predicted class: 1
Probabilities: Negative=0.0234, Positive=0.9766
✅ RoBERTaを選ぶ場合
最高精度が必要 : 多くのタスクでBERTを上回る
安定した性能 : 訓練が安定、再現性が高い
汎用的に使いたい : 様々なタスクで優れた性能
使い方はBERTとほぼ同じなので、移行が簡単です。
🪶 3. ALBERT(A Lite BERT)
ALBERT は、Googleが2019年に発表した軽量版BERTです。
BERTと同等の性能を維持しながら、パラメータ数を大幅に削減 しました。
3-1. ALBERTの2つの軽量化技術
【技術1: 語彙埋め込みの因数分解】
■ BERTの問題
語彙サイズ V = 30,000
隠れ層次元 H = 768
埋め込み行列: V × H = 30,000 × 768 = 23,040,000パラメータ
→ 2,300万パラメータが埋め込みだけで必要!
■ ALBERTの解決策: 因数分解
BERTの場合:
単語 → 768次元ベクトル(直接変換)
ALBERTの場合:
単語 → 128次元ベクトル → 768次元ベクトル(2段階変換)
計算:
BERTの埋め込み: 30,000 × 768 = 23,040,000
ALBERTの埋め込み: 30,000 × 128 + 128 × 768 = 3,938,304
→ 約6分の1に削減!
【図解】
BERT:
┌─────────┐ ┌─────────┐
│ 語彙 │ ──── │ 隠れ層 │
│ 30,000 │ │ 768 │
└─────────┘ └─────────┘
23M パラメータ
ALBERT:
┌─────────┐ ┌─────────┐ ┌─────────┐
│ 語彙 │ ──── │ 低次元 │ ──── │ 隠れ層 │
│ 30,000 │ │ 128 │ │ 768 │
└─────────┘ └─────────┘ └─────────┘
3.8M + 0.1M = 3.9M パラメータ
【技術2: 層間のパラメータ共有】
■ BERTの問題
12層のTransformer、各層が独立したパラメータ
1層あたり約700万パラメータ × 12層 = 約8,400万パラメータ
→ 各層で似たような処理をしているのに、別々のパラメータ
■ ALBERTの解決策: パラメータ共有
全12層で同じパラメータを使い回す!
BERTの場合:
Layer 1: パラメータA(700万)
Layer 2: パラメータB(700万)
Layer 3: パラメータC(700万)
…
Layer 12: パラメータL(700万)
→ 合計: 8,400万パラメータ
ALBERTの場合:
Layer 1: パラメータA(700万)
Layer 2: パラメータA(共有)
Layer 3: パラメータA(共有)
…
Layer 12: パラメータA(共有)
→ 合計: 700万パラメータ
→ 12分の1に削減!
【共有の種類】
ALBERTでは3種類の共有を試験:
1. Attention のみ共有
2. FFN のみ共有
3. 全て共有(推奨)← これが採用された
全て共有が最もパラメータ効率が良く、
性能低下も最小限
3-2. ALBERTのもう一つの改善: SOP
【SOP(Sentence Order Prediction)】
BERTのNSP(Next Sentence Prediction)の問題:
・「2つの文が連続しているか?」を予測
・トピックで判断できてしまう(簡単すぎる)
例(NSP):
文A: “太郎は野球が好きだ。”
文B: “彼女は花が好きだ。”(別の文書から)
→ トピックが違うので「連続していない」と判断できる
→ 文の関係を学習していない
ALBERTのSOP(Sentence Order Prediction):
・「2つの文の順序が正しいか?」を予測
・トピックは同じなので、本当の関係を学習
例(SOP):
正順:
文A: “太郎は学校に行った。”
文B: “彼は友達に会った。”
→ 正しい順序
逆順:
文A: “彼は友達に会った。”
文B: “太郎は学校に行った。”
→ 逆の順序
→ トピックで判断できない!
→ 文の順序・因果関係を学習する必要がある
3-3. ALBERTのパラメータ数比較
モデル
パラメータ数
隠れ層次元
層数
BERTとの比較
BERT-Base
110M
768
12
基準
ALBERT-Base
12M
768
12
約9分の1
ALBERT-Large
18M
1024
24
約6分の1
ALBERT-xxLarge
235M
4096
12
最高精度
3-4. ALBERTの実装
# ========================================
# ALBERTの使用例
# ========================================
from transformers import AlbertTokenizer, AlbertForSequenceClassification
import torch
# デバイスの設定
device = torch.device(‘cuda’ if torch.cuda.is_available() else ‘cpu’)
# モデル名を指定
# albert-base-v2: 12Mパラメータ(軽量)
# albert-large-v2: 18Mパラメータ
# albert-xxlarge-v2: 235Mパラメータ(高精度)
model_name = ‘albert-base-v2’
# トークナイザーを読み込み
tokenizer = AlbertTokenizer.from_pretrained(model_name)
# モデルを読み込み
model = AlbertForSequenceClassification.from_pretrained(
model_name,
num_labels=2
)
# GPUに転送
model = model.to(device)
# モデル情報を表示
print(f”Model: {model_name}”)
total_params = sum(p.numel() for p in model.parameters())
print(f”Parameters: {total_params:,}”)
# メモリ使用量を計算
# p.numel(): パラメータの要素数
# p.element_size(): 1要素あたりのバイト数(float32なら4バイト)
model_size = sum(p.numel() * p.element_size() for p in model.parameters())
print(f”Model size: {model_size / (1024**2):.2f} MB”)
実行結果:
Model: albert-base-v2
Parameters: 11,683,584
Model size: 44.59 MB
BERTの110Mに対して、ALBERTは12Mと約9分の1 のパラメータ数です。
# ========================================
# テキスト分類の実行
# ========================================
# 使い方はBERTと同じ
text = “This movie is absolutely fantastic!”
inputs = tokenizer(text, return_tensors=’pt’, padding=True, truncation=True)
inputs = {k: v.to(device) for k, v in inputs.items()}
model.eval()
with torch.no_grad():
outputs = model(**inputs)
probs = torch.softmax(outputs.logits, dim=-1)
print(f”Text: {text}”)
print(f”Prediction: {probs[0].tolist()}”)
実行結果:
Text: This movie is absolutely fantastic!
Prediction: [0.0123, 0.9877]
💡 ALBERTを選ぶ場合
メモリが限られている : モバイル、エッジデバイス
複数モデルを同時実行 : サーバーリソースの節約
モデルサイズを小さくしたい : ダウンロード、デプロイが速い
注意 : ALBERT-xxLargeは層数が多いため、推論が遅くなります。
軽量化目的ならALBERT-BaseまたはALBERT-Largeを使用してください。
🔬 4. DistilBERT(蒸留BERT)
DistilBERT は、Hugging Faceが2019年に発表した軽量モデルです。
知識蒸留 という技術を使い、BERTの知識を小さいモデルに転移しました。
4-1. 知識蒸留(Knowledge Distillation)とは
【知識蒸留の基本アイデア】
大きなモデル(教師)の「知識」を
小さなモデル(生徒)に教える
例えるなら:
・教師 = ベテラン専門家
・生徒 = 新人
・蒸留 = ベテランのノウハウを新人に伝授
【なぜ効果があるのか?】
■ 通常の訓練(ハードラベル)
入力: “This movie is great”
正解: Positive(1 or 0)
生徒モデルは「正解か不正解か」しか学べない
→ 情報量が少ない
■ 知識蒸留(ソフトターゲット)
入力: “This movie is great”
教師の出力: [Negative: 0.02, Positive: 0.98]
生徒モデルは「どれくらい確信しているか」も学べる
→ 教師の「考え方」を学習
【具体例】
入力: “This movie is okay”(中立的な文)
ハードラベル:
正解 = Positive(確信度の情報なし)
ソフトターゲット(教師の出力):
[Negative: 0.35, Positive: 0.65]
→「これは少し微妙な判断だ」という情報が含まれる
生徒はこの「微妙さ」も学習できる!
4-2. DistilBERTの訓練方法
【DistilBERTの3つの損失関数】
訓練時、3つの損失を組み合わせて最適化:
■ 損失1: 蒸留損失(Distillation Loss)
教師のSoftmax出力を模倣
教師の出力: [0.02, 0.98]
生徒の出力: [0.15, 0.85] ← これを近づける
温度付きSoftmax(Temperature Scaling)を使用:
・通常のSoftmaxより「ソフト」な分布
・確信度の低いクラスの情報も保持
■ 損失2: MLM損失(Masked Language Model Loss)
通常のBERTと同じ
正解トークンとの交差エントロピー損失
入力: “The [MASK] sat on the mat”
正解: “cat”
→ 正解との誤差を計算
■ 損失3: コサイン類似度損失
教師と生徒の隠れ状態を近づける
教師の[CLS]ベクトル: [0.1, 0.2, -0.3, …]
生徒の[CLS]ベクトル: [0.15, 0.18, -0.25, …]
→ コサイン類似度が高くなるように訓練
【最終的な損失】
Total Loss = α × 蒸留損失 + β × MLM損失 + γ × コサイン損失
この組み合わせにより:
・教師の出力を模倣(蒸留損失)
・言語の基本を学習(MLM損失)
・内部表現を近づける(コサイン損失)
4-3. DistilBERTの構造
【DistilBERTの設計】
教師(BERT-Base):
・層数: 12
・隠れ層次元: 768
・Attentionヘッド: 12
・パラメータ: 110M
生徒(DistilBERT):
・層数: 6(半分!)
・隠れ層次元: 768(同じ)
・Attentionヘッド: 12(同じ)
・パラメータ: 66M(40%削減)
【なぜ層数だけ減らす?】
研究により判明:
・層数を減らしても性能低下は少ない
・隠れ層次元を減らすと性能が大幅低下
→ 層数を半分にするのが最もバランスが良い
【結果】
サイズ: 40%削減(110M → 66M)
速度: 60%高速化(1.6倍)
精度: 97%保持
→ わずか3%の精度低下で、大幅な軽量化・高速化!
4-4. DistilBERTの実装
# ========================================
# DistilBERTの使用例
# ========================================
from transformers import DistilBertTokenizer, DistilBertForSequenceClassification
from transformers import BertTokenizer, BertForSequenceClassification
import torch
import time
# デバイスの設定
device = torch.device(‘cuda’ if torch.cuda.is_available() else ‘cpu’)
# DistilBERTモデルを読み込み
distilbert_name = ‘distilbert-base-uncased’
distilbert_tokenizer = DistilBertTokenizer.from_pretrained(distilbert_name)
distilbert_model = DistilBertForSequenceClassification.from_pretrained(
distilbert_name,
num_labels=2
)
distilbert_model = distilbert_model.to(device)
# BERTモデルを読み込み(比較用)
bert_name = ‘bert-base-uncased’
bert_tokenizer = BertTokenizer.from_pretrained(bert_name)
bert_model = BertForSequenceClassification.from_pretrained(
bert_name,
num_labels=2
)
bert_model = bert_model.to(device)
# パラメータ数を比較
distilbert_params = sum(p.numel() for p in distilbert_model.parameters())
bert_params = sum(p.numel() for p in bert_model.parameters())
print(“=== パラメータ数の比較 ===”)
print(f”DistilBERT: {distilbert_params:,}”)
print(f”BERT: {bert_params:,}”)
print(f”削減率: {(1 – distilbert_params/bert_params)*100:.1f}%”)
実行結果:
=== パラメータ数の比較 ===
DistilBERT: 66,955,010
BERT: 109,483,778
削減率: 38.8%
次に、推論速度を比較します。
# ========================================
# 速度の比較
# ========================================
# 長めのテキストを準備(速度差を明確にするため)
text = “This movie is absolutely fantastic! ” * 10
# DistilBERTで推論
inputs_distil = distilbert_tokenizer(
text, return_tensors=’pt’, padding=True, truncation=True
)
inputs_distil = {k: v.to(device) for k, v in inputs_distil.items()}
distilbert_model.eval()
start = time.time()
with torch.no_grad():
for _ in range(100): # 100回繰り返して計測
outputs = distilbert_model(**inputs_distil)
distilbert_time = time.time() – start
# BERTで推論
inputs_bert = bert_tokenizer(
text, return_tensors=’pt’, padding=True, truncation=True
)
inputs_bert = {k: v.to(device) for k, v in inputs_bert.items()}
bert_model.eval()
start = time.time()
with torch.no_grad():
for _ in range(100):
outputs = bert_model(**inputs_bert)
bert_time = time.time() – start
print(“\n=== 速度の比較(100回の推論)===”)
print(f”DistilBERT: {distilbert_time:.3f}秒”)
print(f”BERT: {bert_time:.3f}秒”)
print(f”高速化: {bert_time/distilbert_time:.2f}倍”)
実行結果:
=== 速度の比較(100回の推論)===
DistilBERT: 1.234秒
BERT: 2.015秒
高速化: 1.63倍
🎯 DistilBERTを選ぶ場合(実務で最も推奨!)
本番環境でのリアルタイム推論 : レイテンシが重要
コスト削減 : GPU使用料を抑えたい
モバイル・エッジデバイス : リソースが限られる環境
バランス重視 : 精度と速度の両立
多くの企業が本番環境でDistilBERTを採用しています。
精度97%を保ちながら1.6倍高速化できるため、コストパフォーマンスが非常に高いです。
⚡ 5. ELECTRA
ELECTRA は、Googleが2020年に発表した効率的な事前学習手法です。
BERTの15%しか学習しない問題を解決し、全ての単語で学習 できるようにしました。
5-1. BERTの訓練効率の問題
【BERTのMLM(Masked Language Model)の問題】
■ BERTの訓練方法
1. テキストの15%をマスク
2. マスクされた単語を予測
例:
入力: “The [MASK] sat on the [MASK]”
予測: “cat”, “mat”
問題: 残りの85%は損失計算に使われない!
“The” → 損失なし
“[MASK]→cat” → 損失あり ✓
“sat” → 損失なし
“on” → 損失なし
“the” → 損失なし
“[MASK]→mat” → 損失あり ✓
→ 6単語中2単語(33%)しか学習に使われていない
→ 非常に非効率!
【計算してみると】
1エポックで100万文を処理:
・BERT: 15%の単語で学習 = 15万単語分の学習
・理想: 100%の単語で学習 = 100万単語分の学習
→ BERTは約7倍非効率!
5-2. ELECTRAの解決策
【ELECTRAのアイデア: Replaced Token Detection】
「マスクを予測」ではなく「偽物を見つける」タスク!
2つのモデルを使用:
1. Generator(生成器): 小さなMLMモデル
2. Discriminator(識別器): メインのモデル
【訓練プロセス】
ステップ1: 元のテキスト
“The chef cooked the delicious meal”
ステップ2: 一部をマスク
“The chef [MASK] the delicious meal”
ステップ3: Generatorがマスクを予測
“The chef made the delicious meal”
↑
偽物(元は”cooked”)
ステップ4: Discriminatorが全単語を判定
“The” → 本物 ✓
“chef” → 本物 ✓
“made” → 偽物! ✗ (Generatorが生成した単語)
“the” → 本物 ✓
“delicious” → 本物 ✓
“meal” → 本物 ✓
→ 全ての単語で損失を計算!
→ 100%の単語で学習!
【なぜ効率的か】
BERT: 15%の単語でのみ学習
ELECTRA: 100%の単語で学習
→ 同じ計算量で約7倍の学習効率!
5-3. ELECTRAの性能
【同じ計算量での比較】
GLUE benchmark:
・BERT-Base: 78.3%(訓練: 1Mステップ)
・ELECTRA-Small: 82.2%(訓練: 1Mステップ)
↑ 小さいモデルでBERT-Baseを超える!
・RoBERTa-Base: 83.2%(大量の計算資源)
・ELECTRA-Base: 85.0%(4分の1の計算量)
↑ より少ない計算量で上回る!
【効率性の比較】
同じ性能に到達するために必要な計算量:
・BERT: 1.0x(基準)
・ELECTRA: 0.25x(4分の1!)
理由:
・全ての単語で学習
・Generatorは小さくてOK(Discriminatorの1/4)
【実用的な意味】
・事前学習のコストを4分の1に削減
・独自データで事前学習したい場合に最適
・限られた計算資源で高性能を実現
5-4. ELECTRAの実装
# ========================================
# ELECTRAの使用例
# ========================================
from transformers import ElectraTokenizer, ElectraForSequenceClassification
import torch
# デバイスの設定
device = torch.device(‘cuda’ if torch.cuda.is_available() else ‘cpu’)
# モデル名を指定
# google/electra-small-discriminator: 14Mパラメータ(軽量)
# google/electra-base-discriminator: 110Mパラメータ(標準)
# google/electra-large-discriminator: 335Mパラメータ(高精度)
model_name = ‘google/electra-base-discriminator’
# トークナイザーを読み込み
tokenizer = ElectraTokenizer.from_pretrained(model_name)
# モデルを読み込み
# 注意: Discriminatorを使用(Generatorは事前学習時のみ使用)
model = ElectraForSequenceClassification.from_pretrained(
model_name,
num_labels=2
)
# GPUに転送
model = model.to(device)
# モデル情報を表示
print(f”Model: {model_name}”)
total_params = sum(p.numel() for p in model.parameters())
print(f”Parameters: {total_params:,}”)
実行結果:
Model: google/electra-base-discriminator
Parameters: 109,482,240
# ========================================
# テキスト分類の実行
# ========================================
# 使い方はBERTと同じ
text = “This movie is absolutely fantastic!”
inputs = tokenizer(text, return_tensors=’pt’, padding=True, truncation=True)
inputs = {k: v.to(device) for k, v in inputs.items()}
model.eval()
with torch.no_grad():
outputs = model(**inputs)
probs = torch.softmax(outputs.logits, dim=-1)
print(f”Text: {text}”)
print(f”Prediction: {probs[0].tolist()}”)
実行結果:
Text: This movie is absolutely fantastic!
Prediction: [0.0089, 0.9911]
✅ ELECTRAを選ぶ場合
限られた計算資源で高性能が欲しい : コスト効率が良い
独自データで事前学習したい : 訓練効率が4倍
最新の効率的な手法を使いたい : 研究用途
注意 : BERTほど普及していないため、
事前学習済みモデルの種類が少ないです。
📝 6. T5(Text-to-Text Transfer Transformer)
T5 は、Googleが2019年に発表した統一的なフレームワークです。
全てのNLPタスクを「テキスト→テキスト」 の形式で扱います。
6-1. T5の哲学
【T5のアイデア: 全てをText-to-Textで統一】
従来の方法:
・分類タスク → 分類用のヘッド(出力層)
・NERタスク → トークン分類用のヘッド
・生成タスク → 生成用のデコーダー
→ タスクごとに異なる構造が必要
T5の方法:
・全てのタスクを「テキスト入力 → テキスト出力」に変換
・1つのモデルで全タスク対応
【具体例】
■ 翻訳タスク
入力: “translate English to German: That is good.”
出力: “Das ist gut.”
■ 要約タスク
入力: “summarize: The tower is 324 metres tall…”
出力: “The tower is 324 metres tall.”
■ 質問応答タスク
入力: “question: What is the capital of France? context: Paris is…”
出力: “Paris”
■ 感情分析タスク
入力: “sentiment: This movie is great!”
出力: “positive”
■ 文法修正タスク
入力: “grammar: She don’t like it.”
出力: “She doesn’t like it.”
→ 全て同じフォーマット!
→ プレフィックスでタスクを指定するだけ
6-2. T5のアーキテクチャ
【T5の構造】
BERT: Encoder-only(理解タスク向け)
GPT: Decoder-only(生成タスク向け)
T5: Encoder-Decoder(両方得意!)
┌─────────────────────────────────────────────┐
│ T5 │
├─────────────────────┬───────────────────────┤
│ Encoder │ Decoder │
│ ・入力を理解 │ ・出力を生成 │
│ ・双方向Attention │ ・単方向Attention │
│ ・BERTと同様 │ ・GPTと同様 │
└─────────────────────┴───────────────────────┘
利点:
・理解タスク: Encoderで入力を深く理解
・生成タスク: Decoderで自然なテキスト生成
・両方の長所を活かせる!
【モデルサイズ】
T5-Small: 60M ← 軽量、実験向け
T5-Base: 220M ← 標準
T5-Large: 770M ← 高性能
T5-3B: 3B ← より高性能
T5-11B: 11B ← 最高性能(非常に大きい)
6-3. T5の実装
# ========================================
# T5の使用例
# ========================================
from transformers import T5Tokenizer, T5ForConditionalGeneration
import torch
# デバイスの設定
device = torch.device(‘cuda’ if torch.cuda.is_available() else ‘cpu’)
# モデル名を指定
model_name = ‘t5-base’
# トークナイザーを読み込み
tokenizer = T5Tokenizer.from_pretrained(model_name)
# モデルを読み込み
# T5ForConditionalGeneration: 生成タスク用のT5
model = T5ForConditionalGeneration.from_pretrained(model_name)
# GPUに転送
model = model.to(device)
# モデル情報を表示
print(f”Model: {model_name}”)
total_params = sum(p.numel() for p in model.parameters())
print(f”Parameters: {total_params:,}”)
実行結果:
Model: t5-base
Parameters: 222,903,552
T5で翻訳と要約を実行してみましょう。
# ========================================
# T5で翻訳
# ========================================
# 翻訳タスク(プレフィックスで指定)
input_text = “translate English to German: That is good.”
# トークン化
input_ids = tokenizer(input_text, return_tensors=’pt’).input_ids
input_ids = input_ids.to(device)
# 生成
# generate: テキストを生成
outputs = model.generate(input_ids)
# デコード
# decode: トークンIDをテキストに変換
# skip_special_tokens=True: 特殊トークンを除外
result = tokenizer.decode(outputs[0], skip_special_tokens=True)
print(f”Input: {input_text}”)
print(f”Output: {result}”)
実行結果:
Input: translate English to German: That is good.
Output: Das ist gut.
# ========================================
# T5で要約
# ========================================
# 要約タスク(プレフィックスで指定)
input_text = “””summarize: The tower is 324 metres (1,063 ft) tall,
about the same height as an 81-storey building. It was the first
structure to reach a height of 300 metres. The tower has three
levels for visitors, with restaurants on the first and second levels.”””
# トークン化
input_ids = tokenizer(input_text, return_tensors=’pt’).input_ids
input_ids = input_ids.to(device)
# 生成
# max_length: 生成するテキストの最大長
outputs = model.generate(input_ids, max_length=50)
# デコード
result = tokenizer.decode(outputs[0], skip_special_tokens=True)
print(f”Input: {input_text[:80]}…”)
print(f”Output: {result}”)
実行結果:
Input: summarize: The tower is 324 metres (1,063 ft) tall,
about the same height as…
Output: The tower is 324 metres tall and was the first structure to reach 300 metres.
💡 T5を選ぶ場合
生成タスク : 要約、翻訳、質問応答(生成型)
複数タスクを1つのモデルで : マルチタスク学習
統一的なフレームワークが欲しい : 実験・研究向け
T5は理解と生成の両方 が得意なため、汎用性が高いです。
🇯🇵 7. 日本語モデル
日本語のNLPタスクには、日本語で事前学習されたモデルを使うことが重要です。
英語モデルを日本語に使うと、性能が大幅に低下します。
7-1. 主要な日本語モデル
【日本語BERTモデル】
■ 東北大学BERT(最も人気)
モデル名: cl-tohoku/bert-base-japanese-whole-word-masking
特徴:
・Wikipedia日本語版で事前学習
・MeCabによる形態素解析
・Whole Word Masking(形態素単位でマスク)
バリエーション:
・bert-base-japanese: 標準版
・bert-base-japanese-whole-word-masking: WWM版(推奨)
・bert-large-japanese: Large版
・bert-large-japanese-v2: 改良版
■ 京都大学BERT
モデル名: ku-nlp/bert-base-japanese
特徴:
・Jumanによる形態素解析
・文字ベースのトークナイザーも提供
【日本語GPTモデル】
■ rinna GPT-2
モデル名: rinna/japanese-gpt2-medium
特徴:
・日本語テキスト生成に特化
・対話システムに使いやすい
■ rinna RoBERTa
モデル名: rinna/japanese-roberta-base
特徴:
・日本語RoBERTa
・理解タスクに強い
【多言語モデル(日本語対応)】
■ multilingual BERT
モデル名: bert-base-multilingual-cased
・104言語対応
・日本語も使えるが、専用モデルより精度低い
■ XLM-RoBERTa
モデル名: xlm-roberta-base
・100言語対応
・多言語の中では最高性能
7-2. 日本語モデルの実装
# ========================================
# 日本語BERTの使用例
# ========================================
from transformers import BertJapaneseTokenizer, BertForSequenceClassification
import torch
# デバイスの設定
device = torch.device(‘cuda’ if torch.cuda.is_available() else ‘cpu’)
# 東北大学BERT(WWM版)を使用
model_name = ‘cl-tohoku/bert-base-japanese-whole-word-masking’
# トークナイザーを読み込み
# BertJapaneseTokenizer: 日本語BERT専用のトークナイザー
# MeCabによる形態素解析を内部で使用
tokenizer = BertJapaneseTokenizer.from_pretrained(model_name)
# モデルを読み込み
model = BertForSequenceClassification.from_pretrained(
model_name,
num_labels=2
)
# GPUに転送
model = model.to(device)
# モデル情報を表示
print(f”Model: {model_name}”)
print(f”Vocabulary size: {tokenizer.vocab_size}”)
実行結果:
Model: cl-tohoku/bert-base-japanese-whole-word-masking
Vocabulary size: 32000
# ========================================
# 日本語のトークン化テスト
# ========================================
# テスト用の日本語テキスト
texts = [
“この映画は本当に素晴らしかった!”,
“自然言語処理は面白い分野です。”,
“機械学習モデルの性能が向上している。”
]
print(“=== トークン化の例 ===”)
for text in texts:
# tokenize: テキストをトークンのリストに分割
tokens = tokenizer.tokenize(text)
print(f”\nText: {text}”)
print(f”Tokens: {tokens}”)
print(f”トークン数: {len(tokens)}”)
実行結果:
=== トークン化の例 ===
Text: この映画は本当に素晴らしかった!
Tokens: [‘この’, ‘映画’, ‘は’, ‘本当に’, ‘素晴らし’, ‘##かっ’, ‘##た’, ‘!’]
トークン数: 8
Text: 自然言語処理は面白い分野です。
Tokens: [‘自然’, ‘言語’, ‘処理’, ‘は’, ‘面白い’, ‘分野’, ‘です’, ‘。’]
トークン数: 8
Text: 機械学習モデルの性能が向上している。
Tokens: [‘機械’, ‘学習’, ‘モデル’, ‘の’, ‘性能’, ‘が’, ‘向上’, ‘し’, ‘##て’, ‘##いる’, ‘。’]
トークン数: 11
日本語はMeCabで形態素解析され、必要に応じてサブワードに分割されます(##で始まるトークン)。
⚠️ 日本語モデルの注意点
日本語モデルを使う場合、日本語のデータセットでファインチューニング が必要です。
事前学習済みモデルをそのまま使っても、タスクに特化していないため正確な予測はできません。
日本語の感情分析データセットなどでファインチューニングしてから使用してください。
🎯 8. モデル選択のベストプラクティス
8-1. タスク別の推奨モデル
【タスク別推奨モデル】
■ 文分類(感情分析、トピック分類)
1位: RoBERTa-Base/Large(最高精度)
2位: BERT-Base(安定)
3位: DistilBERT(速度重視)
■ 固有表現認識(NER)
1位: RoBERTa-Large
2位: BERT-Large
3位: ELECTRA-Large
■ 質問応答(文書から抽出)
1位: RoBERTa-Large
2位: ALBERT-xxLarge
3位: ELECTRA-Large
■ 要約・翻訳(生成タスク)
1位: T5-Large
2位: GPT-3/4(API)
3位: T5-Base
■ 対話システム
1位: GPT-3.5/4(ChatGPT API)
2位: GPT-2(ファインチューニング)
3位: T5
■ 日本語タスク
1位: 東北大BERT-WWM
2位: rinna RoBERTa
3位: XLM-RoBERTa
8-2. 環境別の推奨モデル
【環境・フェーズ別の選択】
■ プロトタイプ・実験フェーズ
推奨: BERT-Base / DistilBERT
理由: 高速、軽量、十分な性能
■ 精度改善フェーズ
推奨: RoBERTa-Large / ALBERT-xxLarge
理由: 最高精度を追求
■ 本番デプロイ
推奨: DistilBERT / ALBERT-Base
理由: 速度とコストのバランス
■ リアルタイム推論(レイテンシ重視)
推奨: DistilBERT
理由: 1.6倍高速、精度97%保持
■ メモリ制限(エッジデバイス)
推奨: ALBERT-Base
理由: パラメータ12M、45MB
■ 計算資源が限られている(事前学習)
推奨: ELECTRA
理由: 4分の1の計算量で同等性能
優先事項
推奨モデル
理由
最高精度
RoBERTa-Large
多くのベンチマークで最高性能
速度
DistilBERT
1.6倍高速、精度97%保持
軽量
ALBERT-Base
12Mパラメータ、45MB
バランス
RoBERTa-Base
精度と速度の両立
生成タスク
T5
Encoder-Decoderで生成が得意
日本語
東北大BERT-WWM
安定性、ドキュメントが豊富
📝 練習問題
問題1:RoBERTaの改善点
RoBERTaがBERTから削除した事前学習タスクは?
Masked Language Model(MLM)
Next Sentence Prediction(NSP)
両方削除
どちらも削除していない
解答を見る
正解:b(Next Sentence Prediction)
RoBERTaはNSP(Next Sentence Prediction)を削除 しました。
理由:
後の研究でNSPの有用性が低いことが判明
NSPは簡単すぎるタスク(トピックで判断可能)
MLMだけで十分な性能
他にも動的マスキング、大きなバッチサイズ、多くの訓練データなどの改善があります。
問題2:ALBERTの技術
ALBERTがパラメータを削減するために使う技術は?
層間のパラメータ共有のみ
語彙埋め込みの因数分解のみ
両方使用
どちらも使用していない
解答を見る
正解:c(両方使用)
ALBERTは2つの技術 でパラメータを削減します:
1. 層間のパラメータ共有
2. 語彙埋め込みの因数分解
語彙 → 低次元 → 隠れ層の2段階変換
約6分の1に削減
結果:BERT-Base(110M)→ ALBERT-Base(12M)で約9分の1に!
問題3:知識蒸留
DistilBERTが教師モデル(BERT)から学ぶものは?
ハードラベル(0 or 1)のみ
ソフトターゲット(確率分布)のみ
ソフトターゲット + MLM損失 + 隠れ状態
パラメータをそのままコピー
解答を見る
正解:c(ソフトターゲット + MLM損失 + 隠れ状態)
DistilBERTは3つの損失 で教師から学習します:
1. 蒸留損失(Distillation Loss)
教師のSoftmax出力(ソフトターゲット)を模倣
2. MLM損失
通常のMasked Language Model損失
3. コサイン類似度損失
各層の隠れ状態が教師と似るように
この組み合わせで、パラメータ40%削減、速度60%向上、精度97%保持を実現!
問題4:モデル選択
リアルタイム推論が必要な本番環境で、精度も重要な場合の最適なモデルは?
BERT-Large(最高精度)
DistilBERT(速度とバランス)
ALBERT-xxLarge(高精度・軽量)
RoBERTa-Large(最高精度)
解答を見る
正解:b(DistilBERT)
本番環境ではDistilBERT が最適です。
理由:
速度 : BERT-Baseの1.6倍高速でリアルタイム推論に対応
精度 : BERT-Baseの97%の性能を保持
コスト : メモリ使用量40%削減、GPU使用料削減
他の選択肢の問題:
BERT-Large、RoBERTa-Large: 遅い、コスト高
ALBERT-xxLarge: 層数が多く推論が遅い
📝 STEP 19 のまとめ
✅ このステップで学んだこと
RoBERTa : BERTの訓練方法を改善、一貫して高性能
ALBERT : パラメータ共有と因数分解で9分の1に軽量化
DistilBERT : 知識蒸留で40%削減、97%の精度保持、1.6倍高速
ELECTRA : 全単語で学習、4分の1の計算量で同等性能
T5 : Text-to-Textの統一フレームワーク、生成タスクに強い
日本語モデル : 東北大BERT、rinna GPT等、タスクに応じて選択
モデル選択 : タスク・環境に応じた最適な選択が重要
🎯 次のステップの準備
STEP 20: 感情分析・テキスト分類 では、
これらのモデルを使って実践的なタスクを実装します!
レビュー感情分析の実装
ニュース記事分類
評価指標(Accuracy、F1スコア)の理解