大規模言語モデル(LLM)のファインチューニング入門ガイド

LLMのファインチューニング入門ガイド

はじめに

人工知能の進化と自然言語処理(NLP)の驚異的な進歩をたどる旅に出ましょう。AIは一瞬で急速に進化し、私たちの世界を形作っています。大規模言語モデルの微調整の地殻変動的な影響は、NLPを完全に変革し、私たちの技術的な相互作用を革命化しました。2017年にさかのぼり、「Attention is all you need」という画期的な「Transformer」アーキテクチャが生まれたという節目の瞬間を思い起こしてみてください。このアーキテクチャは現在、NLPの基盤となるものであり、有名なChatGPTを含むすべての大規模言語モデルのレシピに欠かせない要素です。

GPT-3のようなモデルを使って、連続性のある文脈豊かなテキストを簡単に生成することを想像してみてください。チャットボット、翻訳、コンテンツ生成のためのパワーハウスとして、その輝きはアーキテクチャと事前学習と微調整の緻密なダンスによって生まれます。私たちの今回の記事では、これらの変革的な手法の魅力に迫り、大規模言語モデルをタスクに活用するための事前学習と微調整のダイナミックなデュエットを巧みに扱う芸術を明らかにします。一緒にこれらの変革的な手法を解き明かす旅に出ましょう!

学習目標

  • LLMアプリケーションを構築するさまざまな方法を理解する。
  • 特徴抽出、レイヤーの微調整、アダプターメソッドなどの技術を学ぶ。
  • Huggingface transformersライブラリを使用して、下流タスクでLLMを微調整する。

LLMの始め方

LLMは大規模言語モデルの略です。LLMは、人間のようなテキストの意味を理解し、感情分析、言語モデリング(次の単語の予測)、テキスト生成、テキスト要約など、さまざまなタスクを実行するために設計されたディープラーニングモデルです。これらのモデルは膨大なテキストデータで訓練されます。

私たちは、これらのLLMをベースにしたアプリケーションを日常的に使っていますが、それに気づいていないことがあります。GoogleはBERT(Bidirectional Encoder Representations for Transformers)を使用して、クエリの補完、クエリの文脈の理解、より関連性の高く正確な検索結果の出力、言語翻訳など、さまざまなアプリケーションで使用しています。

これらのモデルは、深層学習の手法、複雑なニューラルネットワーク、セルフアテンションなどの高度な技術を基に構築されています。これらのモデルは、言語のパターン、構造、意味を学ぶために膨大なテキストデータで訓練されます。

これらのモデルは広範なデータセットで訓練されているため、それらを訓練するには多くの時間とリソースがかかり、ゼロから訓練することは合理的ではありません。特定のタスクにこれらのモデルを直接使用する方法があります。それでは、詳細について説明しましょう。

LLMアプリケーションを構築するさまざまな方法の概要

私たちは日常生活で興味深いLLMアプリケーションをよく見ます。LLMアプリケーションを構築する方法について知りたいですか?以下はLLMアプリケーションを構築するための3つの方法です:

  1. ゼロからLLMを訓練する
  2. 大規模言語モデルの微調整
  3. プロンプティング

ゼロからLLMを訓練する

人々はしばしば訓練と微調整のLLMの間で混乱します。これらの2つの手法は、モデルのパラメータを変更するという点では似ていますが、訓練の目的は異なります。

ゼロからLLMを訓練することは、事前学習とも呼ばれます。事前学習は、大量の未ラベルのテキストデータで大規模言語モデルを訓練する手法です。しかし、問題は、「ラベルのないデータでモデルを訓練し、そのモデルにデータを正確に予測させることができるのか?」という点です。ここで「セルフサービス学習」という概念が登場します。セルフサービス学習では、モデルが単語をマスキングし、前の単語の助けを借りて次の単語を予測しようとします。例えば、次のような文があるとします。「私はデータサイエンティストです」。

モデルは、次のようなラベル付きデータを作成できます:

これは、マスクされた言語モデル(MLM)によって行われる次の単語の予測として知られています。BERTは、このテクニックを使用してマスクされた単語を予測します。私たちは、MLMを「空欄埋め」の概念と考えることができます。モデルは、空欄に何の単語が適合するかを予測します。次の単語を予測するさまざまな方法がありますが、この記事ではBERTというMLMについてのみ説明します。BERTは、文の前後の単語をどちらも見ることで文脈を理解し、マスクされた単語を予測します。

さて、事前学習の高レベルな概要としては、モデルがテキストの次の単語を予測することを学習する技術です。

大規模言語モデルのファインチューニング

ファインチューニングは、モデルのパラメータを微調整して特定のタスクに適したものにする技術です。モデルが事前学習された後、特定のタスク(感情分析、テキスト生成、文書の類似性の検出など)を実行するようにファインチューニングされます。大量のテキストでモデルを再トレーニングする必要はありません。代わりに、トレーニング済みのモデルを使用して実行したいタスクを実行します。本記事では、大規模言語モデルのファインチューニング方法について後ほど詳しく説明します。

プロンプティング

プロンプティングは、3つの技術の中で最も簡単ですが、少しトリッキーです。この技術では、モデルにタスクを実行するための文脈(プロンプト)を与えます。それは、本の章を詳しく教えて子供に問題を解かせるようなものです。

LLMの文脈に関して、例えばChatGPTを取り上げましょう。私たちは適切な文脈を設定し、モデルに与えられた問題を解決するよう指示します。

例えば、私はChatGPTにトランスフォーマーモデルに関する面接の質問をしてもらいたいとします。より良い体験と正確な結果を得るためには、適切な文脈を設定し、詳細なタスクの説明を与える必要があります。

例: 私は2年のデータサイエンティストの経験を持ち、現在○○社の仕事面接の準備をしています。問題解決が好きで、最新のNLPモデルを使用しています。最新のトレンドや技術にも詳しいです。この会社の過去の経験に基づいて、面接官が聞く可能性のあるトランスフォーマーモデルに関する非常に難しい質問を10個聞いて、その答えも教えてください。

より詳細かつ具体的にプロンプトを設定すれば、結果はより良くなります。最も楽しい部分は、モデル自体からプロンプトを生成し、個人的なタッチや必要な情報を追加できることです。

さまざまなファインチューニング技術の理解

モデルを従来の方法でファインチューニングするためにはさまざまな方法があり、異なるアプローチは解決したい具体的な問題に依存します。モデルをファインチューニングする技術について説明しましょう。

LLMを従来の方法でファインチューニングする3つの方法があります。

特徴抽出

この技術は、与えられたテキストから特徴を抽出するために使用されますが、なぜテキストから埋め込みを抽出したいのでしょうか?その答えは簡単です。コンピュータはテキストを理解しないため、さまざまなタスクを実行するために使用できるテキストの表現が必要です。埋め込みを抽出した後、感情分析や文書の類似性の識別などのタスクを実行することができます。特徴抽出では、モデルのバックボーン層をロックし、これらの層のパラメータを更新しません。パラメータの更新は、完全に接続された層(fully connected layers)に関連します。

完全モデルのファインチューニング

その名前が示す通り、この技術では各モデル層をカスタムデータセットで特定のエポック数だけトレーニングします。新しいカスタムデータセットに応じて、モデルのすべての層のパラメータを調整します。これにより、モデルのデータと実行したい特定のタスクの精度が向上する可能性があります。ファインチューニングの大規模言語モデルには数十億ものパラメータがあるため、モデルのトレーニングには計算コストがかかり、時間がかかります。

アダプターベースのファインチューニング

アダプターベースのファインチューニングは、比較的新しい概念であり、ネットワークに追加のランダムに初期化されたレイヤーまたはモジュールを追加し、特定のタスクに対してトレーニングします。この技術では、モデルのパラメータは変更されず、アダプターレイヤーのパラメータのみがトレーニングされます。この技術は計算効率的にモデルをチューニングするのに役立ちます。

実装:ダウンストリームタスクでのBERTのファインチューニング

ファインチューニングの技術を知ったところで、IMDBの映画レビューを使用してBERTによる感情分析を行いましょう。BERTは、トランスフォーマーレイヤーを組み合わせた大規模言語モデルで、エンコーダーオンリーです。Googleが開発し、さまざまなタスクで非常に優れた性能を発揮することが証明されています。BERTにはBERT-base-uncased、BERT Large、RoBERTa、LegalBERTなど、さまざまなサイズとバリエーションがあります。

BERTモデルを使用して感情分析を行う

IMDB映画レビューに対してBERTモデルを使用して感情分析を行いましょう。GPUの無料提供を利用するために、Google Colabを使用することをおすすめします。トレーニングを始める前に、いくつかの重要なライブラリをロードしましょう。

BERT(Bidirectional Encoder Representations for Encoders)はTransformersに基づいているため、まず環境にtransformersをインストールする必要があります。

!pip install transformers

BERTモデルが要求するようにデータをロードし、データをトークン化し、分類に使用するモデルをロードし、トレーニングとテストの分割を行い、CSVファイルをロードし、その他の関数をいくつかロードしましょう。

import pandas as pd
import numpy as np
import os
from sklearn.model_selection import train_test_split
import torch
import torch.nn as nn
from transformers import BertTokenizer, BertModel

より高速な計算のために、デバイスをCPUからGPUに変更する必要があります。

device = torch.device("cuda")

次のステップは、データセットをロードし、データセットの最初の5つのレコードを確認することです。

df = pd.read_csv('/content/drive/MyDrive/movie.csv')
df.head()

データセットをトレーニングセットと検証セットに分割します。データをトレーニング、検証、テストセットに分割することもできますが、単純化のために、データセットをトレーニングセットと検証セットにのみ分割します。

x_train, x_val, y_train, y_val = train_test_split(df.text, df.label, random_state = 42, test_size = 0.2, stratify = df.label)

BERTモデルのインポートとロード

BERTモデルとトークナイザーをインポートしてロードしましょう。

from transformers.models.bert.modeling_bert import BertForSequenceClassification
# BERT-baseの事前学習モデルをインポートする
BERT = BertModel.from_pretrained('bert-base-uncased')
# BERTトークナイザーをロードする
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')

トークナイザーを使用してテキストをトークンに変換し、最大長250でパディングと切り詰めを行います。

train_tokens = tokenizer.batch_encode_plus(x_train.tolist(), max_length = 250, pad_to_max_length=True, truncation=True)
val_tokens = tokenizer.batch_encode_plus(x_val.tolist(), max_length = 250, pad_to_max_length=True, truncation=True)

トークナイザーは、特定の単語に関連するトークンであるinput_ids、入力のさまざまなセグメントやパーツを区別する整数のリストであるtoken_type_ids、トークンにアテンションを与える必要があるかどうかを示すattention_maskという3つのキーバリューペアを含む辞書を返します。

これらの値をテンソルに変換します

train_ids = torch.tensor(train_tokens['input_ids'])
train_masks = torch.tensor(train_tokens['attention_mask'])
train_label = torch.tensor(y_train.tolist())
val_ids = torch.tensor(val_tokens['input_ids'])
val_masks = torch.tensor(val_tokens['attention_mask'])
val_label = torch.tensor(y_val.tolist())

データをさらに前処理し、モデルに適した形式にするためにTensorDatasetとDataLoaderをロードします。

from torch.utils.data import TensorDataset, DataLoader
train_data = TensorDataset(train_ids, train_masks, train_label)
val_data = TensorDataset(val_ids, val_masks, val_label)
train_loader = DataLoader(train_data, batch_size = 32, shuffle = True)
val_loader = DataLoader(val_data, batch_size = 32, shuffle = True)

私たちのタスクは、BERTのパラメータを私たちの分類器で凍結し、そのレイヤーをカスタムデータセットでファインチューニングすることです。したがって、モデルのパラメータを凍結します。for param in BERT.parameters():param.requires_grad = Falseそして、追加したレイヤーのために前方および後方パスを定義する必要があります。BERTモデルは特徴抽出器として機能し、分類のための前方および後方パスを明示的に定義する必要があります。

class Model(nn.Module):
  def __init__(self, bert):
    super(Model, self).__init__()
    self.bert = bert
    self.dropout = nn.Dropout(0.1)
    self.relu = nn.ReLU()
    self.fc1 = nn.Linear(768, 512)
    self.fc2 = nn.Linear(512, 2)
    self.softmax = nn.LogSoftmax(dim=1)
  def forward(self, sent_id, mask):
    # 入力をモデルに渡す
    outputs = self.bert(sent_id, mask)
    cls_hs = outputs.last_hidden_state[:, 0, :]
    x = self.fc1(cls_hs)
    x = self.relu(x)
    x = self.dropout(x)
    x = self.fc2(x)
    x = self.softmax(x)
    return x

モデルをGPUに移動しましょう

model = Model(BERT)
# モデルをGPUに転送
model = model.to(device)

オプティマイザの定義

# Hugging Face Transformersからのオプティマイザ
from transformers import AdamW
# オプティマイザを定義する
optimizer = AdamW(model.parameters(),lr = 1e-5)

これまでにデータセットの前処理を行い、モデルを定義しました。モデルをトレーニングするためのコードを書く必要があります。トレーニング関数:

def train():
  model.train()
  total_loss, total_accuracy = 0, 0
  total_preds = []
  for step, batch in enumerate(train_loader):
    # 利用可能な場合、バッチをGPUに移動
    batch = [item.to(device) for item in batch]
    sent_id, mask, labels = batch
    # 以前に計算された勾配をクリアする
    optimizer.zero_grad()
    # 現在のバッチに対するモデルの予測を取得
    preds = model(sent_id, mask)
    # 予測とラベルの間の損失を計算する
    loss_function = nn.CrossEntropyLoss()
    loss = loss_function(preds, labels)
    # 総損失に加える
    total_loss += loss.item()
    # 逆伝搬と勾配の更新
    loss.backward()
    optimizer.step()
    # 予測をCPUに移動し、numpy配列に変換する
    preds = preds.detach().cpu().numpy()
    # モデルの予測を追加する
    total_preds.append(preds)
  # 平均損失を計算する
  avg_loss = total_loss / len(train_loader)
  # 予測を連結する
  total_preds = np.concatenate(total_preds, axis=0)
  # 平均損失と予測を返す
  return avg_loss, total_preds

評価関数

def evaluate():
  model.eval()
  total_loss, total_accuracy = 0, 0
  total_preds = []
  for step, batch in enumerate(val_loader):
    # 利用可能な場合、バッチをGPUに移動
    batch = [item.to(device) for item in batch]
    sent_id, mask, labels = batch
    # 以前に計算された勾配をクリアする
    optimizer.zero_grad()
    # 現在のバッチに対するモデルの予測を取得
    preds = model(sent_id, mask)
    # 予測とラベルの間の損失を計算する
    loss_function = nn.CrossEntropyLoss()
    loss = loss_function(preds, labels)
    # 総損失に加える
    total_loss += loss.item()
    # 逆伝搬と勾配の更新
    loss.backward()
    optimizer.step()
    # 予測をCPUに移動し、numpy配列に変換する
    preds = preds.detach().cpu().numpy()
    # モデルの予測を追加する
    total_preds.append(preds)
  # 平均損失を計算する
  avg_loss = total_loss / len(val_loader)
  # 予測を連結する
  total_preds = np.concatenate(total_preds, axis=0)
  # 平均損失と予測を返す
  return avg_loss, total_preds

これらの関数を使用してモデルをトレーニングします:

# 初期損失を無限大に設定
best_valid_loss = float('inf')
# エポックの定義
epochs = 5
# 各エポックのトレーニングと検証の損失を格納する空のリスト
train_losses=[]
valid_losses=[]
# 各エポックについて
for epoch in range(epochs):
  print('\n エポック {:} / {:}'.format(epoch + 1, epochs))
  # モデルをトレーニングする
  train_loss, _ = train()
  # モデルを評価する
  valid_loss, _ = evaluate()
  # 最良のモデルを保存する
  if valid_loss < best_valid_loss:
    best_valid_loss = valid_loss
    torch.save(model.state_dict(), 'saved_weights.pt')
    # トレーニングと検証の損失を追加する
  train_losses.append(train_loss)
  valid_losses.append(valid_loss)
  print(f'\n トレーニングの損失: {train_loss:.3f}')
  print(f'検証の損失: {valid_loss:.3f}')

以上です。トレーニングされたモデルを使用して、任意のデータやテキストを推論することができます。

結論

この記事では、大規模な言語モデル(LLM)の微調整と、自然言語処理(NLP)へのその重要な影響について探求しました。自己教師あり学習を用いて、大量の未ラベルテキストでLLMを事前学習するプロセスと、特定のタスクに適応するために事前学習モデルを調整する微調整について説明しました。また、コンテキストを提供して関連する出力を生成するためのプロンプトについても説明しました。さらに、特徴抽出、完全なモデルの微調整、アダプタベースのLLMの微調整など、さまざまな微調整技術についても調査しました。大規模な言語モデルは、NLPの世界を革新し、さまざまなアプリケーションの進展を推進し続けています。

よくある質問

We will continue to update VoAGI; if you have any questions or suggestions, please contact us!

Share:

Was this article helpful?

93 out of 132 found this helpful

Discover more

人工知能

5つの最高のChatGPT SEOプラグイン

SEOの専門家たちは、ChatGPTプラグインがGoogleのランキングを上げるのを助けるすばらしいツールであることに気づき始めています

機械学習

「AIへの恐怖は迷信的なくだらないことだ」

「人工知能が私たちを皆殺しにすると恐れている人々は、200,000年にわたる宗教的な迷信のナンセンスと同じ間違いをしています」

AIニュース

生成AIにおけるプロンプトエンジニアリングの基本原則

導入 この記事では、生成型AIにおけるChatGPTプロンプトエンジニアリングについて説明します。ChatGPTは2022年11月以来、技術...

データサイエンス

「研究データ管理の変革:AIの役割によるデベロッパーのエンパワーメント」

「人工知能(AI)は、開発者にとって便利な友達のような存在ですAIは大量のデータの中から情報を見つけることを簡単にします」

人工知能

私たちの早期警戒システムへのサポート

GoogleのYossi MatiasさんとWMOのインフラストラクチャー部門ディレクターであるAnthony Reaさんが「Early Warnings For All ...

機械学習

自然言語処理における転移学習:テキスト分類のための事前学習済みモデルの活用

この記事では、転移学習の概念について説明し、いくつかの人気のある事前学習済みモデルを探求し、テキスト分類に使用する方...