STEP 19:その他の事前学習モデル

🌐 STEP 19: その他の事前学習モデル

BERT・GPT以外の重要モデル群とモデル選択のベストプラクティス

📋 このステップで学ぶこと

  • 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から削除した事前学習タスクは?

  1. Masked Language Model(MLM)
  2. Next Sentence Prediction(NSP)
  3. 両方削除
  4. どちらも削除していない
正解:b(Next Sentence Prediction)

RoBERTaはNSP(Next Sentence Prediction)を削除しました。

理由:

  • 後の研究でNSPの有用性が低いことが判明
  • NSPは簡単すぎるタスク(トピックで判断可能)
  • MLMだけで十分な性能

他にも動的マスキング、大きなバッチサイズ、多くの訓練データなどの改善があります。

問題2:ALBERTの技術

ALBERTがパラメータを削減するために使う技術は?

  1. 層間のパラメータ共有のみ
  2. 語彙埋め込みの因数分解のみ
  3. 両方使用
  4. どちらも使用していない
正解:c(両方使用)

ALBERTは2つの技術でパラメータを削減します:

1. 層間のパラメータ共有

  • 全12層で同じパラメータを使用
  • 12分の1に削減

2. 語彙埋め込みの因数分解

  • 語彙 → 低次元 → 隠れ層の2段階変換
  • 約6分の1に削減

結果:BERT-Base(110M)→ ALBERT-Base(12M)で約9分の1に!

問題3:知識蒸留

DistilBERTが教師モデル(BERT)から学ぶものは?

  1. ハードラベル(0 or 1)のみ
  2. ソフトターゲット(確率分布)のみ
  3. ソフトターゲット + MLM損失 + 隠れ状態
  4. パラメータをそのままコピー
正解:c(ソフトターゲット + MLM損失 + 隠れ状態)

DistilBERTは3つの損失で教師から学習します:

1. 蒸留損失(Distillation Loss)

教師のSoftmax出力(ソフトターゲット)を模倣

2. MLM損失

通常のMasked Language Model損失

3. コサイン類似度損失

各層の隠れ状態が教師と似るように

この組み合わせで、パラメータ40%削減、速度60%向上、精度97%保持を実現!

問題4:モデル選択

リアルタイム推論が必要な本番環境で、精度も重要な場合の最適なモデルは?

  1. BERT-Large(最高精度)
  2. DistilBERT(速度とバランス)
  3. ALBERT-xxLarge(高精度・軽量)
  4. 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スコア)の理解
📝

学習メモ

自然言語処理(NLP) - Step 19

📋 過去のメモ一覧
#artnasekai #学習メモ
LINE