人工知能
大規模言語モデルを微調整するための包括的なガイド

著者
Aayush Mittal ミッタル
大規模言語モデル (LLM) である GPT-4、LaMDA、PaLM などのモデルは、その豊富な言語理解能力と、広範なトピックについて人間のようなテキストを生成する能力で世界を驚かせています。これらのモデルは、インターネット、書籍、その他のソースからなる巨大なデータセットで事前トレーニングされています。
この事前トレーニング段階で、モデルは言語、トピック、推論能力、トレーニングデータに含まれる特定の偏見についての広範な知識を習得します。ただし、これらの事前トレーニングされた LLM は、特定のドメインまたはタスクについての専門知識が不足しています。
ここで、微調整が重要な役割を果たします。微調整とは、事前トレーニングされた LLM を特定のアプリケーションまたはユースケースに適合させるプロセスです。モデルをタスク固有のデータセットでさらにトレーニングすることで、その能力をそのドメインのニュアンスと要件に合わせることができます。
微調整は、広範な知識を持つ総合的な専門家を特定の分野の専門家に育てることに似ています。このガイドでは、LLM の微調整の何、何故、そして方法について探ります。
微調整とは何か
本質的に、微調整 とは、事前トレーニングされた大規模モデルを、ターゲットタスクまたはドメインに合わせて更新するパラメータを使用することです。これにより、モデルはその狭い分野のニュアンス、パターン、目的を学習し、内部化することができます。
事前トレーニングでは、モデルは広範な言語理解を獲得しますが、微調整ではその一般的な能力を特化させます。これは、ルネサンス人を業界の専門家に育てることに似ています。
事前トレーニングされたモデルの重みは、一般的な知識を符号化したもので、微調整プロセスの開始点または初期化として使用されます。モデルはさらにトレーニングされますが、この場合はターゲットアプリケーションに直接関連する例を使用してトレーニングされます。
モデルをこの特化されたデータ分布に公開し、モデルのパラメータをそれに応じて調整することで、LLM をターゲットユースケースに合わせてより正確で効果的なものにすることができます。これは、事前トレーニングされた能力を基盤として使用しながら行われます。
なぜ LLM を微調整するのか
LLM を微調整する主な理由は以下のとおりです:
- ドメインカスタマイズ:各分野、法律、医療、ソフトウェアエンジニアリングなどには、それぞれ独自の言語規則、用語、コンテキストがあります。微調整により、一般的なモデルを特定のドメインに合わせてカスタマイズすることができます。
- タスク特化:LLM は、テキスト要約、機械翻訳、質問回答などのさまざまな自然言語処理タスクに微調整できます。これにより、ターゲットタスクのパフォーマンスが向上します。
- データコンプライアンス:高度に規制された業界、ヘルスケアや金融などには、厳格なデータプライバシーの要件があります。微調整により、機密情報を保護しながら、LLM を企業独自のデータでトレーニングすることができます。
- ラベル付きデータの制限:スクラッチからモデルをトレーニングするためのラベル付きデータセットを取得することは困難な場合があります。微調整により、事前トレーニングされたモデルの能力を活用して、限られた監督例から強力なタスクパフォーマンスを実現することができます。
- モデル更新:ドメインで新しいデータが利用可能になると、モデルをさらに微調整して最新の知識と機能を取り込むことができます。
- 偏見の軽減:LLM は、広範な事前トレーニングデータから社会的な偏見を取得する可能性があります。微調整により、カーソルデータセットを使用してこれらの不適切な偏見を軽減または修正することができます。
本質的に、微調整は、一般的なモデルと特定のアプリケーションの焦点された要件の間のギャップを埋め、モデル出力の精度、安全性、関連性をターゲットユースケース向上させます。
提供された図は、大規模言語モデル (LLM) の実装と利用のプロセスを概説しています。事前トレーニングされたモデル (T5 など) に、構造化された会社データと非構造化された会社データ (CSV、JSON など) が入力されます。このデータは、教師あり、教師なし、または転移学習の微調整プロセスを経て、会社の特定のニーズに合わせてモデルを適応させます。
モデルが会社データで微調整されると、その重みが更新されます。トレーニングされたモデルは、さらに会社データでトレーニングを繰り返し、反復的に新しい会社データで学習し、応答を改善します。このプロセスは反復的で、モデルは新しいデータパターンに適応するために学習し、再トレーニングされます。
トレーニングされたモデルの出力 (ワードや埋め込みを表すトークン) は、さまざまな企業アプリケーションに展開されます。これらのアプリケーションは、チャットボット、ヘルスケアなど、業界固有のクエリに応答するモデルを必要とします。金融分野では、アプリケーションには、不正検出や脅威分析が含まれます。ヘルスケアでは、モデルは患者への問い合わせや診断を支援できます。
トレーニングされたモデルの能力は、新しい会社データで継続的に学習し、応答を改善することで、時間の経過とともに維持され、成長します。結果として、企業ユーザーは、アプリケーションを介してモデルとやり取りし、モデルがトレーニングと微調整を受けたドメイン固有のデータを反映した情報に基づいた回答を受け取ります。
このインフラストラクチャは、幅広い企業アプリケーションをサポートし、ビジネスコンテキストで適切に実装および維持された場合の LLM の多様性と適応性を示しています。
微調整アプローチ
大規模言語モデルを微調整する主な戦略は 2 つあります:
1) フルモデル微調整
フル微調整アプローチでは、事前トレーニングされたモデルのすべてのパラメータ (重みとバイアス) が 2 番目のトレーニング段階で更新されます。モデルはタスク固有のラベル付きデータセットに公開され、標準的なトレーニングプロセスでモデルの全体的な最適化が行われます。
これにより、モデルはターゲットタスクまたはドメインに合わせて包括的な調整を行うことができます。ただし、フル微調整にはいくつかの欠点があります:
- 事前トレーニング段階と同様に、トレーニングに大量の計算リソースと時間が必要です。
- ストレージ要件が高く、各タスクのためにモデルを個別にコピーして維持する必要があります。
- 「カタストロフィック忘却」のリスクがあり、微調整によってモデルが事前トレーニングで学習した一部の一般的な能力を失う可能性があります。
これらの制限にもかかわらず、フル微調整は、リソースが許容される場合やターゲットタスクが一般的な言語から大きく異なる場合に、広く使用される有力なテクニックです。
2) 効率的な微調整方法
フル微調整の計算上の課題を克服するために、研究者は、微調整中にモデルのパラメータの小さなサブセットのみを更新する効率的な戦略を開発しました。これらのパラメータ効率的なテクニックは、特化とリソース要件の削減のバランスをとります。
人気のある効率的な微調整方法には以下のものがあります:
Prefix-Tuning:ここでは、タスク固有のベクトルまたは「プレフィックス」が導入され、ターゲットタスクのために事前トレーニングされたモデルの注意を条件付けるようにトレーニングされます。プレフィックスのみが微調整中に更新されます。
LoRA (Low-Rank Adaptation):LoRA は、事前トレーニングされたモデルの各層に、トレーニング可能な低ランク行列を微調整中に挿入します。これらの小さなランク調整により、フル微調整よりもはるかに少ないトレーニング可能なパラメータでモデルを特化させることができます。
LoRA (Low-Rank Adaptation) について詳細な説明を提供できます。LoRA は、大規模言語モデルの適応性を向上させるために、事前トレーニングされたモデルに少数のトレーニング可能なパラメータを導入する微調整方法です。LoRA では、事前トレーニングされたモデルの重み行列に低ランク行列を追加します。これにより、微調整プロセス中に計算とメモリの要件が大幅に削減されます。
LoRA とは
LoRA は、事前トレーニングされたモデルの重み行列に低ランク更新を導入する微調整方法です。事前トレーニングされたモデルの重み行列 0∈W0∈Rd×k, LoRA は低ランク行列 BA, A∈Rr×k および B∈Rd×r を追加します。ここで、r はランクです。このアプローチにより、タスクの適応に必要なトレーニング可能なパラメータの数が大幅に削減され、計算リソースが制約された状況でもタスクに適応することができます。更新された重み行列は、W=W0+B⋅A として与えられます。
この低ランク更新は、元の重み行列 $W_{0}$ を低ランク行列 $BA$ で修正するものと解釈できます。LoRA の主な利点は、$d \times k$ のパラメータをすべて更新するのではなく、$A$ と $B$ の $r \times (d + k)$ のパラメータのみを最適化する必要があることです。これにより、トレーニング可能なパラメータの数が大幅に削減されます。
ここでは、peft ライブラリを使用して、事前トレーニングされた LLM に LoRA を適用する Python の例を示します:
</div> <div> <div class="code-block__code !my-0 !rounded-t-lg !text-sm !leading-relaxed" data-darkreader-inline-bgimage="" data-darkreader-inline-bgcolor="" data-darkreader-inline-color=""><code class="language-python" data-darkreader-inline-bgimage="" data-darkreader-inline-bgcolor="" data-darkreader-inline-color=""><span class="token" data-darkreader-inline-color="">from</span> transformers <span class="token" data-darkreader-inline-color="">import</span> AutoModelForSequenceClassification </code></div> <div class="code-block__code !my-0 !rounded-t-lg !text-sm !leading-relaxed" data-darkreader-inline-bgimage="" data-darkreader-inline-bgcolor="" data-darkreader-inline-color=""><code class="language-python" data-darkreader-inline-bgimage="" data-darkreader-inline-bgcolor="" data-darkreader-inline-color=""><span class="token" data-darkreader-inline-color="">from</span> peft <span class="token" data-darkreader-inline-color="">import</span> get_peft_model<span class="token" data-darkreader-inline-color="">,</span> LoraConfig<span class="token" data-darkreader-inline-color="">,</span> TaskType </code></div> <div data-darkreader-inline-bgimage="" data-darkreader-inline-bgcolor="" data-darkreader-inline-color=""></div> <div class="code-block__code !my-0 !rounded-t-lg !text-sm !leading-relaxed" data-darkreader-inline-bgimage="" data-darkreader-inline-bgcolor="" data-darkreader-inline-color=""><code class="language-python" data-darkreader-inline-bgimage="" data-darkreader-inline-bgcolor="" data-darkreader-inline-color=""><span class="token" data-darkreader-inline-color=""># 事前トレーニング済みモデルをロード</span> </code></div> <div class="code-block__code !my-0 !rounded-t-lg !text-sm !leading-relaxed" data-darkreader-inline-bgimage="" data-darkreader-inline-bgcolor="" data-darkreader-inline-color=""><code class="language-python" data-darkreader-inline-bgimage="" data-darkreader-inline-bgcolor="" data-darkreader-inline-color="">model <span class="token" data-darkreader-inline-color="">=</span> AutoModelForSequenceClassification<span class="token" data-darkreader-inline-color="">.</span>from_pretrained<span class="token" data-darkreader-inline-color="">(</span><span class="token" data-darkreader-inline-color="">"bert-base-uncased"</span><span class="token" data-darkreader-inline-color="">,</span> num_labels<span class="token" data-darkreader-inline-color="">=</span><span class="token" data-darkreader-inline-color="">2</span><span class="token" data-darkreader-inline-color="">)</span> </code></div> <div data-darkreader-inline-bgimage="" data-darkreader-inline-bgcolor="" data-darkreader-inline-color=""></div> <div class="code-block__code !my-0 !rounded-t-lg !text-sm !leading-relaxed" data-darkreader-inline-bgimage="" data-darkreader-inline-bgcolor="" data-darkreader-inline-color=""><code class="language-python" data-darkreader-inline-bgimage="" data-darkreader-inline-bgcolor="" data-darkreader-inline-color=""><span class="token" data-darkreader-inline-color=""># LoRA 構成を定義</span> </code></div> <div class="code-block__code !my-0 !rounded-t-lg !text-sm !leading-relaxed" data-darkreader-inline-bgimage="" data-darkreader-inline-bgcolor="" data-darkreader-inline-color=""><code class="language-python" data-darkreader-inline-bgimage="" data-darkreader-inline-bgcolor="" data-darkreader-inline-color="">peft_config <span class="token" data-darkreader-inline-color="">=</span> LoraConfig<span class="token" data-darkreader-inline-color="">(</span>task_type<span class="token" data-darkreader-inline-color="">=</span>TaskType<span class="token" data-darkreader-inline-color="">.</span>SEQ_CLS<span class="token" data-darkreader-inline-color="">, </span>r<span class="token" data-darkreader-inline-color="">=</span><span class="token" data-darkreader-inline-color="">8</span><span class="token" data-darkreader-inline-color="">,</span> <span class="token" data-darkreader-inline-color=""># 低ランク更新のランク</span> lora_alpha<span class="token" data-darkreader-inline-color="">=</span><span class="token" data-darkreader-inline-color="">16</span><span class="token" data-darkreader-inline-color="">,</span></code><code class="language-python" data-darkreader-inline-bgimage="" data-darkreader-inline-bgcolor="" data-darkreader-inline-color=""><span class="token" data-darkreader-inline-color=""># 低ランク更新のスケーリング係数</span> </code></div> <div data-darkreader-inline-bgimage="" data-darkreader-inline-bgcolor="" data-darkreader-inline-color="">
この例では、シーケンス分類のための事前トレーニング済み BERT モデルをロードし、LoRA 構成を定義します。パラメータ r は低ランク更新のランクを指定し、lora_alpha は更新のスケーリング係数です。パラメータ target_modules は、LoRA 更新を受けるモデルの層を示します。LoRA 有効なモデルを作成した後、標準的なトレーニングプロセスを使用して微調整プロセスを実行できます。
アダプタ層:LoRA と同様ですが、低ランク更新ではなく、事前トレーニング済みモデルの各トランスフォーマーブロック内に薄い「アダプタ層」が挿入されます。新しいコンパクト層のパラメータのみがトレーニングされます。
プロンプト微調整:このアプローチでは、事前トレーニング済みモデルは完全に凍結されます。代わりに、ターゲットタスクのために事前トレーニング済み知識を活性化するために、トレーニング可能な「プロンプト」埋め込みが入力として導入されます。
これらの効率的な方法は、フル微調整と比較して最大 100 倍の計算削減を提供しながら、多くのタスクで競合するパフォーマンスを実現します。また、フルモデルの複製を避けることで、ストレージ要件も削減されます。
ただし、一般的な言語や全体的な特化が必要なタスクでは、フル微調整のパフォーマンスに及ばない可能性があります。
微調整プロセス
どの微調整戦略を使用するかに関係なく、大規模言語モデルの特化プロセスは一般的なフレームワークに従います:
- データの準備:ターゲットタスクの入力 (プロンプト) と望ましい出力の間のマッピングが含まれるラベル付きデータセットを取得または作成する必要があります。テキスト生成タスクの場合は、入力テキストと要約出力のペアになります。
- データの分割:ベストプラクティスに従って、ラベル付きデータセットをトレーニング、検証、テストセットに分割します。これにより、モデルトレーニング、ハイパーパラメーターの調整、最終評価用のデータが分離されます。
- ハイパーパラメーターの調整:学習率、バッチサイズ、トレーニングスケジュールなどのパラメータは、データに対する最も効果的な微調整のために調整する必要があります。これには通常、少量の検証セットが必要です。
- モデルトレーニング:調整されたハイパーパラメータを使用して、トレーニングセットで微調整最適化プロセスを実行します。モデルが検証セットでパフォーマンスを向上させなくなる (早期終了) まで、フルトレーニングセットで実行します。
- 評価:微調整されたモデルのパフォーマンスを、実際の例で構成されるテストセットで評価します。ターゲットユースケースの現実世界の有効性を推定するために、理想的にはこれらの例が含まれている必要があります。
- 展開と監視:満足のいくパフォーマンスを示した後、モデルの展開と新しい入力に対する推論を実行できます。概念のドリフトに対するモデルのパフォーマンスと精度を時間の経過とともに監視することは重要です。
このプロセスは概要ですが、特定の LLM またはタスクの微調整の成功に影響を与える多くのニュアンスがあります。カリキュラム学習、多タスク微調整、少数ショットプロンプティングなどの戦略により、さらにパフォーマンスを向上させることができます。
さらに、効率的な微調整方法には追加の考慮が必要です。たとえば、LoRA では、事前トレーニングされたモデルの出力を結合レイヤーを介して条件付けるテクニックが必要です。プロンプト微調整では、適切な動作を活性化するように慎重に設計されたプロンプトが必要です。
高度な微調整: 人間のフィードバックの組み込み
ラベル付きデータセットを使用した標準的な教師あり微調整は効果的ですが、人間の好みやフィードバックを直接使用して LLM をトレーニングするという分野は興味深いものです。この人間がループ内にあるアプローチでは、強化学習のテクニックが使用されます:
PPO (近接方策最適化):ここでは、LLM は強化学習エージェントとして扱われ、出力は「アクション」と見なされます。人間の評価またはスコアを予測するための報酬モデルがトレーニングされ、PPO は LLM を報酬モデルのスコアを最大化する出力を生成するように最適化します。
RLHF (人間のフィードバックからの強化学習):このアプローチは PPO を拡張し、微調整プロセス中に人間のフィードバックを直接組み込みます。固定された報酬モデルではなく、微調整中に LLM の出力に対する人間の評価から報酬が得られます。
計算コストが高くなる可能性はありますが、これらの方法により、静的なデータセットで捉えることができない特性に基づいて LLM の動作をより精密に形成することができます。Anthropic のような企業は、Claude のような言語モデルに真実性、倫理、安全性の認識を高めるために RLHF を使用しました。
潜在的なリスクと制限
大規模言語モデルの微調整は非常に強力ですが、慎重に管理する必要があるリスクもあります:
偏見の増幅:微調整データに社会的な偏見が含まれている場合、モデルはこれらの不適切な偏見を増幅する可能性があります。代表的なデバイアスを除去したデータセットのカーソルが重要です。
事実のドリフト:高品質のデータで微調整した後でも、モデルは長い会話やプロンプトで不正確な事実やトレーニング例と一致しない出力を「妄想」する可能性があります。事実の取得方法が必要になる場合があります。
スケーラビリティの課題:GPT-3 のような大きなモデルのフル微調整には、多くの組織にとって実行不可能なほど大量の計算リソースが必要です。効率的な微調整はこれを部分的に緩和しますが、トレードオフがあります。
カタストロフィック忘却:フル微調整中に、モデルは事前トレーニング中に学習した一部の一般的な能力を失う「カタストロフィック忘却」を経験する可能性があります。多タスク学習が必要になる場合があります。
知的財産およびプライバシーのリスク:微調整に使用される独自のデータは、公開された言語モデルの出力に漏洩する可能性があり、リスクをもたらします。差分プライバシーと情報ハザード緩和テクニックが活発な研究分野です。
全体として、微調整は、データの品質、アイデンティティの考慮、リスクの軽減、およびパフォーマンスと効率のトレードオフのバランスを取る必要がある、微妙なプロセスです。
将来: 大規模言語モデルのカスタマイズ
今後、微調整とモデル適応テクニックの進歩は、大規模言語モデルの潜在的な可能性を解き放つために不可欠です。
PaLM のようなより大きなモデルを制約されたリソースで微調整できるより効率的な方法の開発により、アクセスが民主化されます。データセット作成パイプラインとプロンプトエンジニアリングの自動化により、特化を容易にします。
ラベルなしの生データから微調整する自己教師ありテクニックは、新しいフロンティアを開拓する可能性があります。また、異なるタスクまたはデータでトレーニングされたサブモデルの組み合わせを使用して、高度にカスタマイズされたモデルを需要に応じて構築することができます。
最終的に、大規模言語モデルの汎用性と安全性を確保しながら、すべての想定されるユースケースに合わせてそれらをシームレスにカスタマイズおよび特化できる能力が、人間の能力を各ドメインと取り組み全体で拡大する強力で柔軟な AI アシスタントとしての役割を果たすために不可欠です。
私は過去5年間、機械学習とディープラーニングの魅力的世界に没頭してきました。私の情熱と専門知識は、AI/MLに特に焦点を当てた50以上の多様なソフトウェアエンジニアリングプロジェクトに貢献することになりました。私の継続的な好奇心は、自然言語処理という分野にも私を引き付け、さらに探求したいと思っています。













