HUOXIU

応用分野における大規模モデルの必須知識(1)主要微調整手法の概要

編集者注:大規模な事前トレーニング済みモデルの開発と応用により、大規模モデルの微調整技術は多くの分野で画期的な進歩を遂げ、人工知能技術の開発と応用を促進しました。

この記事では、インコンテキスト学習の意味を簡単に説明し、LLMをファインチューニングするための様々な実用的な方法を紹介します。また、大規模言語モデルに適したファインチューニング手法の選択方法を理解する上でも役立ちます。

今すぐこの記事を読んで、大規模なモデルを微調整する学習の旅に出かけましょう。

翻訳はこちらです。お楽しみください!

この記事は、原著者の許可を得てBaihai IDPによって翻訳されました。翻訳の転載をご希望の場合は、お問い合わせください。

オリジナルリンク: https://magazine.sebastianraschka.com/p/finetuning-large-language-models

著者 |セバスティアン・ラシュカ博士

編纂者:岳陽

急速に発展する今日の人工知能分野において、大規模言語モデル(LLM)の効率的な活用はますます重要になっています。しかし、大規模言語モデルの活用方法は非常に多く、初心者にとっては戸惑うかもしれません。

本質的には、事前トレーニング済みの大規模言語モデルを新しいタスクに使用するには、主にコンテキスト内学習と微調整という2 つの方法があります。

この記事では、インコンテキスト学習の意味を簡単に紹介し、LLM を微調整するためのさまざまな実行可能な方法を紹介します。

01文脈内学習とインデックス作成

GPT-2 (Radford et al. [1]) とGPT-3 (Brown et al. [2]) の登場以来、一般的なテキストコーパスで事前学習された生成的大規模言語モデル (LLM) はコンテキスト学習を実行できることが分かっています。これは、新しい特定のタスクを実行したい場合、事前学習済みのLLMをさらに学習または微調整する必要はなく、次の例に示すように、プロンプトを入力するだけで、対象タスクの例を直接提供できることを意味します

文脈学習の例

モデルに直接アクセスできない場合 (たとえば、API 経由でモデルを使用する場合)、コンテキスト学習は非常に役立ちます。

コンテキスト学習に関連しているのがハードプロンプトチューニングです。これは、下の図に示すように、入力を変更することで出力を改善しようとします。

(ハード)プロンプトチューニングの図解。ちなみに、この手法では入力単語またはトークンを直接変更するため、ハードプロンプトチューニングと呼びます。後ほど、ソフトプロンプトチューニング(または一般的にプロンプ​​トチューニングと呼ばれる)と呼ばれる別のバージョンの手法について説明します。

前述のプロンプトチューニング法は、パラメータのファインチューニングの代替手段となり、よりリソース効率に優れています。しかし、特定のタスクに対するモデルのパラメータを更新しないため、異なるタスク間の微妙な差異への適応性が制限される可能性があり、一般的にパフォーマンスはファインチューニングよりも劣ります。さらに、プロンプトチューニングは、異なるプロンプトの品質を手動で比較する必要があるため、非常に労力とコストがかかる可能性があります。

ファインチューニングを詳しく検討する前に、純粋な文脈学習を活用する別のアプローチであるインデックス作成について理解しましょう。大規模言語モデルの分野では、インデックス作成は文脈学習の回避策と見なすことができ、 LLM を外部リソースや Web サイトからデータを抽出する情報検索システムに変換できるようにします。このプロセスでは、インデックス作成モジュールがドキュメントまたは Web サイトを小さなフラグメントに分解し、ベクトル データベースに保存できるベクトルに変換します。次に、ユーザーがクエリを送信すると、インデックス作成モジュールは埋め込まれたクエリとデータベース内の各ベクトルとのベクトル類似度を計算します。最後に、インデックス作成モジュールはクエリに最も類似した上位 k 個の埋め込みを取得し、応答を生成します。

インデックスの図解。

02従来の特徴ベース手法と微調整手法

API 経由やユーザー インターフェイスを使用した LLM との対話など、大規模言語モデル (LLM) に直接アクセスできない場合は、コンテキスト学習が価値がありユーザーフレンドリーなアプローチとなります。

しかし、LLMに直接アクセスできる場合は、対象ドメインのデータを使用してLLMを適応・微調整することで、より良い結果が得られることが多いです。では、モデルを対象タスクに適応させるにはどうすればよいでしょうか?次の図は、3つの一般的な手法を概説しています。

従来の3つの特徴ベースの方法と微調整方法

以下のセクションでは、エンコーダースタイルのインターフェースを持つ大規模言語モデル(BERTなど)のファインチューニングを例に、具体的なファインチューニング手法の原理とサンプルコードを分析します。以下のファインチューニングタスクの例は、映画レビューの感情が肯定的か否定的かを予測する分類器タスクです。エンコーダースタイルのLLMのファインチューニングに加えて、GPTのようなデコーダースタイルのLLMにも同じ手法が適用できることに注意することが重要です。この点については、今後の記事で例を挙げて説明します。

さらに、デコーダー型LLMを微調整することで、単なるテキスト分類ではなく、特定の指示に対して複数文の回答を生成することも可能になります。今後の記事でこの実例を紹介する予定ですので、どうぞお楽しみに。

2.1特徴ベースの手法

特徴量ベースのアプローチでは、事前学習済みのLLMを読み込み、対象データセットに適用する必要があります。このアプローチでは、特に学習セットの出力埋め込みを生成することに興味があります。この埋め込みは、分類モデルの学習に入力特徴量として使用できます。このアプローチはBERTのような埋め込みに重点を置いたモデルで非常に一般的ですが、生成GPTスタイルのモデルからも埋め込みを抽出できます。

次に、分類モデルとして、ロジスティック回帰、ランダムフォレスト、XGBoostなど、任意のモデルを使用できます。(ただし、私の経験では、この場合、ロジスティック回帰のような線形分類器の方がパフォーマンスが優れています。)

理論的には、次のコードを使用して機能ベースの方法を説明することができます。

モデル = AutoModel.from_pretrained("distilbert-base-uncased")
# ...
# データセットをトークン化
# ...
# 埋め込みを生成する
@torch.推論モード()
def get_output_embeddings(バッチ):
出力 = モデル(
バッチ["input_ids"],
attention_mask=バッチ["attention_mask"]
).last_hidden_​​state[:, 0]
{"features": 出力}を返す
データセットの特徴 = データセットトークン化マップ(
get_output_embeddings、バッチ処理=True、バッチサイズ=10)
X_train = np.array(imdb_features["train"]["features"])
y_train = np.array(imdb_features["train"]["label"])
X_val = np.array(imdb_features["検証"]["機能"])
y_val = np.array(imdb_features["検証"]["ラベル"])
X_test = np.array(imdb_features["テスト"]["機能"])
y_test = np.array(imdb_features["テスト"]["ラベル"])
# 分類器を訓練する
sklearn.linear_modelからLogisticRegressionをインポートする
clf = ロジスティック回帰()
clf.fit(X_train, y_train)
print("トレーニング精度", clf.score(X_train, y_train))
print("検証精度", clf.score(X_val, y_val))
print("テスト精度", clf.score(X_test, y_test))

(興味のある読者は完全なコードをここで見つけることができます[4])

2.2 微調整法I - 出力層の更新

上述の特徴量ベースのアプローチに類似したアプローチの一つに、出力層のファインチューニング(本稿ではファインチューニング法Iと呼ぶ)と呼ばれるものがあります。特徴量ベースのアプローチと同様に、この手法では事前学習済みのLLMのパラメータは変更せず、新たに追加された出力層のみを学習します。これは、ロジスティック回帰分類器や小規模な多層パーセプトロンを埋め込み特徴量で学習するのと似ています。

関連するコードは次のとおりです。

モデル = AutoModelForSequenceClassification.from_pretrained(
「ディスティルバートベースアンケース」
ラベル数=2
)
# すべてのレイヤーをフリーズ
model.parameters() の param について:
    param.requires_grad = False

# 最後の2つのレイヤー(出力レイヤー)を解凍します
model.pre_classifier.parameters() の param について:
param.requires_grad = True
model.classifier.parameters() の param について:
param.requires_grad = True

# モデルの微調整
lightning_model = CustomLightningModule(モデル)
トレーナー = L.トレーナー(
最大エポック数=3,
...
)
トレーナー.フィット(
モデル=lightning_model、
train_dataloaders=train_loader、
val_dataloaders=val_loader)
# モデルを評価する
trainer.test(lightning_model、データローダー=test_loader)

(興味のある読者は完全なコードをここで見つけることができます[4])

理論的には、この方法のモデリング性能と速度は、特徴ベースの方法と同程度になるはずです。なぜなら、どちらもバックボーンモデルを凍結するからです(注:バックボーンモデルを凍結することで、重みを変更せずにタスクモジュールのみをトレーニングできます。これにより、更新する必要のあるパラメータの数が減り、トレーニング効率が向上し、元のバックボーンモデルの特徴抽出機能がある程度保持されます)。ただし、特徴ベースの方法では、トレーニングデータセットに埋め込まれた特徴を事前に計算して保存することが少し簡単になるので、特定のシナリオではより便利な場合があります

2.3 微調整法 II - すべてのレイヤーを更新する

BERTの論文(Devlinら)では、出力層のみをファインチューニングすることで全層をファインチューニングした場合と同等のモデル性能を達成できると述べられていますが、後者はパラメータ数が多いため、大幅にコストがかかります。例えば、BERTベースモデルは約1億1000万個のパラメータを持っています。しかし、二値分類に使用されるBERTベースモデルの最後の層には、わずか1500個のパラメータしか含まれていません。さらに、BERTベースモデルの最後の2層には合計6万個のパラメータがあり、これはモデル全体の約0.6%に過ぎません。

どちらの方法を選択するかは、対象タスクと対象ドメイン、そしてモデルの事前学習に使用したデータセットの類似性によって異なります。しかし、実際には、すべてのレイヤーを微調整することで、ほぼ確実にモデルのパフォーマンスが向上します。

したがって、モデル性能を最適化する際に、事前学習済みLLMを用いる際のゴールドスタンダードは、全ての層を更新することです(本稿ではファインチューニング法IIと呼びます)。理論的には、ファインチューニング法IIはファインチューニング法Iと非常に似ています。主な違いは、法IIでは事前学習済みLLMのパラメータを固定するのではなく、ファインチューニングを行う点です

モデル = AutoModelForSequenceClassification.from_pretrained(
「ディスティルバートベースアンケース」
ラベル数=2
)
# レイヤーをフリーズする(ここでは行いません)
# model.parameters() 内の param について:
# param.requires_grad = False

# モデルの微調整
lightning_model = LightningModel(モデル)
トレーナー = L.トレーナー(
最大エポック数=3,
...
)
トレーナー.フィット(
モデル=lightning_model、
train_dataloaders=train_loader、
val_dataloaders=val_loader)
# モデルを評価する
trainer.test(lightning_model、データローダー=test_loader)

(興味のある読者は完全なコードをここで見つけることができます[4])

上記のコードは、DistilBERTベースモデルに基づいた映画レビュー分類器をトレーニングするために使用されました(コードノートブック[4]で確認できます)。

1) 特徴ベース手法とロジスティック回帰:テスト精度 83%

2) 方法 I を微調整し、最後の 2 つのレイヤーを更新します。精度は 87% です。

3) 微調整法 II、全レイヤーの更新:92% の精度。

これらの精度の結果は予想と一致しており、つまり、より多くのレイヤーを微調整すると通常はパフォーマンスが向上しますが、コストも高くなります。

この記事では、3 つの異なる方法におけるトレーニング効率とモデル パフォーマンスのトレードオフについて説明します。

上記のシナリオは、ファインチューニングの最も特徴的または極端な3つのケース、つまり最後のレイヤー(またはいくつかのレイヤー)のみをトレーニングする場合と、すべてのレイヤーをトレーニングする場合を例に挙げています。もちろん、具体的な結果はモデルとデータセットによって異なる場合がありますが、その間の様々なシナリオを検討してみる価値はあります。例えば、完全にトレーニングされたモデルと同じパフォーマンスを達成するために、モデルの半分だけをトレーニングするだけで十分な場合もあります(パラメータ効率の高いファインチューニングについては、次のセクションで詳しく説明します)。興味があれば、次の図は、IMDB映画レビューデータセットの20,000のトレーニングインスタンスでファインチューニングされたDistilBERTモデルの予測パフォーマンスとトレーニング時間を示しています。

IMDB映画レビューデータセットを用いて微調整された、事前学習済みのDistilBERTモデルのパフォーマンス。関連コードはGitHub [5]で公開されています。

ご覧のとおり、最後の層のみをトレーニングすると最速ですが、モデルのパフォーマンスは最も低くなります。当然のことながら、より多くの層をトレーニングするとモデルのパフォーマンスは向上しますが、計算コストも増加します。興味深いことに、予測パフォーマンスは、2つの全結合出力層と最後の2つのTransformerブロック(左から3番目のブロック)をトレーニングすると飽和する傾向があります。したがって、この特定のケース(つまり、この特定のモデルとデータセットの組み合わせ)では、これらの層を超えてトレーニングすることは計算リソースの無駄遣いのように思われます。

03軽量ファインチューニング(パラメータ効率の高いファインチューニング)

軽量ファインチューニングにより、計算量とリソース消費を最小限に抑えながら、事前学習済みモデルを再利用できるようになります。全体として、軽量ファインチューニングには以下の5つの利点があります。

1. コンピューティング コストを削減できます (必要な GPU と GPU ランタイムが少なくなります)。

2. トレーニング時間が短くなります(トレーニングがより早く完了します)。

3. ハードウェア要件が低い (ビデオメモリと RAM が少ない GPU に適しています)。

4. モデルのパフォーマンスが向上します(過剰適合が削減されます)。

5. 必要な保管スペースが少なくなります (ほとんどの重量はさまざまなタスク間で共有できます)。

前の章では、より多くのレイヤーをファインチューニングすると、一般的により良い結果が得られることを学びました。上記の実験は、比較的小規模なDistilBERTモデルに基づいています。しかし、GPUメモリに収まることがほぼ不可能な大規模なモデル(最先端の生成LLMモデルなど)をファインチューニングしたい場合はどうすればよいでしょうか?もちろん、前述の特徴量ベースの手法やファインチューニング手法を使用できます。しかし、ファインチューニング手法IIと同等のモデル品質を実現したい場合はどうすればよいでしょうか?

長年にわたり、研究者たちはLLMを微調整し、少ないパラメータ数で高いモデル性能を達成するための手法(Lialin et al. [6])を開発してきました。これらの手法は、しばしばパラメータ効率の良い微調整手法(PEFT)と呼ばれます。

より一般的な PEFT テクニックのいくつかを下の画像に示します。

人気の軽量微調整(PEFT)テクノロジーオプション

では、これらの手法はどのように機能するのでしょうか?簡単に言うと、いずれも微調整のための少数の追加パラメータを導入するものです(上記の微調整手法IIのように全層を微調整するのではなく)。ある意味では、微調整手法I(最終層のみを微調整する)は軽量微調整(PEFT)手法とも考えられます。しかし、プレフィックスチューニング、アダプタ、低ランク適応(LoRA)などの手法は、いずれも複数の層を「変更」することで、非常に低コストでより優れた予測性能を実現します。

この記事はすでにかなり長くなっており、いずれも非常に興味深い技術ですので、今後個別に紹介していく予定です。

04人間のフィードバックによる強化学習

人間によるフィードバックを用いた強化学習(RLHF)では、教師あり学習と強化学習を組み合わせた手法を用いて、事前学習済みモデルの微調整を行います。この手法は、InstructGPT(Ouyang et al. [7])をベースにしたChatGPTで広く採用されています。

RLHFでは、人間が異なるモデルの出力をランク付けまたは評価することで人間のフィードバックを収集し、報酬シグナルを生成します。収集された報酬ラベルは報酬モデルのトレーニングに使用され、LLM(言語モデル)が人間の好みに適応するように導きます。

報酬モデル自体は教師あり学習によって学習されます(通常は事前学習済みのLLMをベースモデルとして使用します)。次に、報酬モデルを用いて事前学習済みのLLMを更新し、人間の好みに適応させます。この学習プロセスでは、近似方策最適化(Schulman et al. [8])と呼ばれる強化学習手法が用いられます。

InstructGPT に関連する論文のスクリーンショット。RLHF プロセスの概要を示しています。

人間のフィードバックに基づいて事前学習済みのモデルを直接学習させるのではなく、報酬モデルを使用するのはなぜでしょうか?これは、モデルの学習プロセスに人間を関与させると、リアルタイムでフィードバックを得ることができず、ボトルネックが生じるためです。

この記事はすでにかなり長くなってしまいましたので、詳しい説明は次回の記事に譲ります。どうぞお楽しみに!

05要約

事前学習済みLLMの全層を微調整することは、新しいターゲットタスクへの適応における依然としてゴールドスタンダードです。しかし、事前学習済みTransformerモデルには、効果的な代替手段がいくつか存在します。特徴量ベースのアプローチ、コンテキスト学習、軽量な微調整といった手法は、計算コストとリソースを最小限に抑えながら、 LLMを新しいタスクに効果的に適用できます。

さらに、人間のフィードバックに基づく強化学習 (RLHF) は、教師あり微調整 (SFT) の代替としてモデルのパフォーマンスを向上させることができます。

終わり

参考文献

1.https://d4mucfpksywv.cloudfront.net/better-language-models/language_models_are_unsupervised_multitask_learners.pdf

2.https://arxiv.org/abs/2005.14165

3.https://arxiv.org/abs/1810.04805

4.https://github.com/rasbt/LLM-finetuning-scripts/tree/main/conventional/distilbert-movie-review

5.https://github.com/rasbt/LLM-finetuning-scripts/tree/main/conventional/distilbert-movie-review/layerwise-experiment

6.https://arxiv.org/abs/2303.15647

7.https://arxiv.org/abs/2203.02155

8.https://arxiv.org/abs/1707.06347

この記事は、原著者の許可を得てBaihai IDPによって翻訳されました。翻訳の転載をご希望の場合は、お問い合わせください。

オリジナルリンク:

https://magazine.sebastianraschka.com/p/finetuning-large-language-models