「[[.NET 開発基盤部会 Wiki>http://dotnetdevelopmentinfrastructure.osscons.jp]]」は、「[[Open棟梁Project>https://github.com/OpenTouryoProject/]]」,「[[OSSコンソーシアム .NET開発基盤部会>https://www.osscons.jp/dotNetDevelopmentInfrastructure/]]」によって運営されています。 -[[戻る>テキスト生成系(Transformer系)#j2f01d54]] > [[チューニング、拡張系>テキスト生成系(Transformer系)#j2f01d54]] --[[LLMのPE]] --[[LLMのRAG]] --[[OSSのLLM]] > LLMのFT ---[[huggingface/transformers Trainer]] ---[[huggingface/trl SFTTrainer]] --[[LLMエージェント]] *目次 [#u4413184] #contents *概要 [#o6adc09b] LLMのファイン・チューニング(FT)は既存LLMを特定の用途や業界向けに最適化するための手法 -ここでは、SaaS形式のLLMサービスのFTではなく、主に、ローカルにダウンロードしたLLMのFTと、その取り回し方法について言及する。 -モデルのリリースに伴う事前学習とではなく、作成後のLLMの精度を上げるために行われる追加学習(フル・ファインチューニング)や、[[転移学習>深層学習のテクニック#ebe9edcc]](ReFT、PEFT、LoRA)を対象とする。 **基本概念 [#r833f951] -一般的な事前学習済みのLLMが持つ汎用的な知識を特定の専門分野や業務プロセスに特化させるために追加の学習。 -これにより、対象のタスクへ適応させ、より正確で一貫性のある回答が可能になる。 **適用場面 [#mdae5ed6] FTは、以下のような場面で活用される。 |場面|使途|h |カスタマーサポート|自社独自のFAQや業界特有の表現に適応させる。| |医療や法律分野|専門用語や規制対応の正確な知識を学習させる。| |文書生成や翻訳|高精度な自然言語処理を必要とする場面。| **トレードオフ [#oc8b04a2] ***メリット [#xe0713b9] -精度向上~ 特定の用途に特化したモデルを構築できる。 -カスタマイズ性~ 企業独自のデータやノウハウを学習させることで、ブランド固有の表現や業界標準に沿った応答が可能。 ***デメリット [#w03485e7] -コスト~ 高性能な[[GPU>深層学習(deep learning)#f674295b]]やクラウド環境が必要で、運用コストが増加。 -データ量~ 大量の学習データが求められ、データ収集・整理の負担が発生。 **手法の種類 [#sd57dc5f] 主に以下の手法がある。 ***全体・部分の分類 [#n7d28557] -全体:[[Full Fine-Tuning>#b45c9886]]~ LLMのモデル全体のパラメタを再学習させる方法。高いカスタマイズ性があるが、学習に大量のデータと計算リソースが必要。 -部分:[[PEFT(Parameter-Efficient Fine-Tuning)>#t16de86b]]~ 一部のパラメタや特定の層に限定して調整を加える方法。計算コストを抑えつつ高いカスタマイズ性を維持。 ***教師なし/あり学習、強化学習 [#fcd28885] -教師なし学習:CLM(次単語予測)、MLM(マスク単語予測)は「自己教師あり学習(self-supervised learning)」に分類される、教師なし学習の一種。 -教師あり学習:指示チューニング([[Instruction Tuning>#m581916f]])は、データ形式はQ&A形式である必要がある。 -強化学習:[[RLHF>#f617b1df]]は、[[Instruction Tuning>#m581916f]]、[[Reward Fine-Tuning>#ud85a68e]]の2つの手法を組み合わせて使う。 **個々の説明 [#y575a9ad] ***Full Fine-Tuning [#b45c9886] モデルの全パラメタを特定のタスクやドメインに合わせて調整するプロセス -一般的に[[通常のFT>深層学習のテクニック#ea94272b]]の様に元のモデルに対して層(パラメタ)の追加を行わない。 -全体のパラメタを調整することで、特定のタスクに対して高い精度を達成できるが、 大量の計算資源が必要となる。 ***PEFT [#t16de86b] PEFT:Parameter-Efficient Fine-Tuning -モデルの部分(埋め込み層、隠れ層、アテンション機構など既存パラメタの一部)を効率的に調整する手法 -既存のデータセットを使ったモデルの精度向上が目的で、新しい事実を覚えさせることには向いていない。 -[[LoRA, QLoRA, Adapter, Prefix Tuning, BitFit, ReFT>#o17ec824]] ***RLHF [#f617b1df] RLHF:Reinforcement Learning from Human Feedback -人間の好みに基づいてモデルの応答を調整する強化学習ベースのアプローチ -「どちらの応答が望ましいか」という人間の評価のフィードバックを元に学習を行い改善する。 -報酬モデルを用いて、LLMを人間の好みに合うように方策最適化する強化学習。 -以下の3ステップから構成される。 --Supervised Fine-Tuning(SFT)~ 人間のデモに基づいて初期モデルを強化する。 ---[[Instruction Tuning>#m581916f]]で、ベースLLMを教師あり学習で微調整する。 ---「基本的に良い応答を出す」能力を得るが、まだ細かな好みやニュアンスには対応できない。 --Reward Model(報酬モデル)の訓練~ どんな応答が「良い」のかを学習させる。 ---人間が複数の応答候補に「好みの順位付け(ランキング)」を行う。 ---モデルにプロンプトを与え、複数の応答を生成 → 人間がどれが良いかを比較して評価。 ---このランキングデータを用いて、「良い応答には高い報酬を与える」報酬モデル(Reward Model)を学習。 --[[Reward Fine-Tuning>#o361b6ee]](PPOなど)~ ***Instruction Tuning [#m581916f] 指示に基づいてモデルを調整する教師あり学習(Supervised Fine-Tuning, SFT) -モデルに「明示的な指示(instruction)」を与えて、それに従った応答を生成させるように学習させる手法。 -例:指示「以下のテキストを要約してください」「○○について説明してください」と結果「望ましい応答」を学習データとして与える。 -JSON: {"input": "ユーザーの質問", "output": "AIの回答"} ***Reward Fine-Tuning [#o361b6ee] 報酬モデルを使って、モデルを人間の好みに合わせて強化学習。 -報酬モデルを用いて、モデルの出力に対する「報酬」を計算。 -この報酬を最大化するように、主にPPOを使って言語モデルを微調整。 -これにより、モデルは「人間が望むような応答」を出す傾向が強まる。 *PEFT系 [#o17ec824] **差分学習型(元の重みに対する差分を学習) [#u6b3648b] ***LoRA [#edcd5d87] LoRA:Low-Rank Adaptation(低ランク適応) -主に大規模な機械学習モデル(特にLLMや画像生成モデル)に対して、追加の知識やスタイルを効率的に学習させる技術 -[[通常のFT>深層学習のテクニック#ea94272b]]の様に出力層側に層を追加するのではなく、スキップ接続された線形結合層を追加しそこだけ[[転移学習>深層学習のテクニック#ebe9edcc]]する。 -線形結合層は「低ランク近似行列」は元来の行列を二つの小さな行列の積として近似するもので~ ココでは入出力がX次元である場合、XX行列とせず、Xr行列 * rX行列(rは低ランクの次元)とする。 -具体的には、 --W_new = W_old + W_b W_a とした場合、W_b W_a がそれぞれ低ランクの行列で、~ W_b のサイズが (X, r) で W_a のサイズが (r, X) となり、パラメタ数を削減できる。 --例えば、 ---W_old=(768,768) とするとパラメタ数 =768×768=589,824 ---W_a=(8,768)、W_b=(768,8) (r=8)とすると、LoRAによる追加パラメタW_b W_aのパラメタ数 =8*768+768*8=12,288。 --α:スケーリング係数(通常はハイパーパラメタ)を適用すると ---W_new = W_old + α (W_b W_a) ---α=r 通常通り、α > rLoRA の影響を強くし、α < r LoRA の影響を弱くし、α = 2r が推奨値。 -特徴~ 従って、転移学習と同じ特徴を持っている。 --効率性:少ないデータで高い性能を達成できる。 --柔軟性:既存のモデルを様々なタスクに適応させやすい。 --計算資源の節約 ---モデル全体を再学習する必要がないため、計算コストが低い。 ---LLM/SLMに適用する際、LLMの方が学習コストが大きい理由は順/逆伝播のコストが高いため -得意なケース~ 「既存の知識の補強」の目的で使う事に適している。 --特定のドメインに適応させる。 --新しい言葉や概念を学習させる。 --特定の文章スタイルやキャラクターの言い回し。 -不得意なケース --完全に未知の知識をゼロから学習する。 --長大なデータを一度に追加する。 -補足 --HuggingFaceのPEFT(Parameter-Efficient Fine-Tuning)ライブラリで簡単に試すことができる。 --言語モデルだけでなく、画像生成モデル(例:StableDiffusion)にも適用されている。 -手順(簡単な流れ) --学習データの準備(追加したい知識やスタイルのデータセットを作る) --LoRAの適用(ベース・モデルにLoRAを組み込んで学習) --ハイパー・パラメタの設定(r:Rank、α、Targetモジュール) --ファイン・チューニング(追加の知識やスタイルを反映) --モデルの評価・テスト(意図した知識やスタイルが反映されているか確認) ***QLoRA [#iee439a7] QLoRA:量子化 + LoRA、Quantized Low-Rank Adaptation -QLoRAはLoRAのアップグレード版で、[[量子化>深層学習(deep learning)#oea41d77]]手法を取り入れ、さらに[[GPU>深層学習(deep learning)#f674295b]]のメモリ効率を高めている。 -新しいデータ型「4-bit NormalFloat(NF4)」を導入し、メモリ効率、計算速度をも改善。 ***ReLoRA [#qbab85eb] (LoRAの逐次再初期化) **モジュール追加型(新たな層やブロックを追加) [#o0fb9c0f] ***Adapter [#o48215b0] 「スキップ接続された線形結合層」(Adapter)を追加(Adaptation)するような方法、全般。 ***Prefix Tuning [#oc09c52a] -入力にPrefixベクトルを挿入 --入力の先頭に特別なprefixトークンを追加し、元のモデル本体のパラメタは固定 --prefixトークンに対応する少量の追加パラメタのみ学習させる(同様に転移学習的)。 --タスク毎に異なるprefixベクトルを付加することで効率的に適応させることができる。 --Faster Transformerなどの実装に対応している(追加パラメタに効率的に対応する機構を持っているらしい) --[[LoRA>#edcd5d87]]と比較して「学習コストは低い」が「新しい事実を覚えさせるのは苦手」とのこと。 -例えるなら --「この後は医療系の話をします:」のような前置きを付けるイメージ --ただし、これだけの説明だとPrompt Tuning的、~ Prompt Tuningとの違いは、各層のアクティベーション系列のPrefixが学習プロセスを通じて最適化される点。 ---追加トークンの位置: Prompt Tuningは入力系列の先頭に追加トークンを付加するのに対し、Prefix Tuningは各層の入力に追加トークンを付加。 ---追加パラメタの学習: Prefix Tuningは各層にPrefixに対応した学習可能なパラメタを付加し、さらにPrefix付のアクティベーション系列を生成する。 ***Prompt Tuning [#o90041d0] (Embeddingに仮想トークンを追加) ***P-Tuning [#b8aa7b64] (深層プロンプトを最適化) **微小パラメタ更新型 [#lda9061b] (既存パラメタのごく一部を更新) ***BitFit [#j15e942b] BitFit:Bias-only fine-tuning -バイアス項のみ更新する非常に軽量なFT技法 --重み(weight)パラメタは固定 --バイアス(bias)項のみ微調整 -特徴 --バイアス(bias)項のみの微調整なので学習が高速でメモリ消費も少ない。 --テキスト分類などのタスクにおいては、フルファインチューニングに匹敵する性能を示すこともある。 --特別なレイヤ追加や新しい訓練戦略は不要で、既存のモデルのオリジナル性を維持しながら、簡単に調整可能。 ***LayerNorm-tuning [#t337b283] (LayerNormのみ更新) ***ReFT [#c38bbd0f] ReFT:Representation Fine-Tuning -特定のタスクに対する性能を向上させることを目的とする。 -中間層の表現のみに限定して更新 --通常のPEFT(LoRAやAdapter)は追加層や差分重みを挿入するのに対し、 --ReFTは既存のモデルの内部表現(≒埋め込み層)の重みを直接微調整する。 -手法 --初期段階: モデルは通常の教師あり学習(SFT)でウォームアップ --強化学習: その後、オンライン強化学習(例えばPPO)を使用してモデルをさらに微調整。 -結果 --質問に対して複数の推論パスが自動的にサンプリングされ、真の答えから自然に報酬が得られる。 --方策(埋め込みモデルの部分)を最適化する強化学習を採用し、回答精度を上げることができる。 **その他・派生手法 [#z357c706] ***Compacter [#x38f8979] ***Adalora(動的に重要な層だけにLoRA適用) [#c58150a1] ***IA³(Attention/FFNにスカラー重みを掛けて調整) [#ka65eec8] *実地 [#nac49c56] **構築 [#a8ccf18b] ***アウトライン [#g063c912] -[[GPU>深層学習(deep learning)#f674295b]]付きVMの準備 --使用可能なVMサイズを表示 --VMサイズを使用してCreateVM -インストレーション --NVIDIAドライバ --CUDAツールキット --cuDNN(任意だが推奨 → 既定であたる) -Python 環境で確認 -参考 --Llama-3をColabで記事執筆用にファインチューニングしてみた~ https://zenn.dev/carenet/articles/0d2e1100121b0e ***実際の手順 [#l5db1fb1] -[[Standard_NC8as_T4_v3、CUDA Toolkit 12.8>OSSのLLM#aa81fc3e]] の環境を構築 -以下は、上記リンクを参考に、Standard_NV36ads_A10_v5、Ubuntu2004、CUDA Toolkit 11.3の環境を構築~ --[[GPU>深層学習(deep learning)#f674295b]]付きVMを準備する。 ---Standard_NV36ads_A10_v5が利用可能なリージョンを探す。 Get-AzComputeResourceSku | Where-Object { $_.Name -eq "Standard_NV36ads_A10_v5" } | Select-Object Locations ---{japaneast}が確認できたので、料金計算ツールでも再確認する。~ すると{eastasia}の方が安かったので、必要に応じて変更しても良いかも。 ---[[以下の変数を変更>Ubuntu 24.04 on Azure via Bastion 2025/2/27#v3741d2b]]し、 vmSize=Standard_NV36ads_A10_v5 vmOS=Canonical:0001-com-ubuntu-pro-focal:pro-20_04-lts-gen2:latest vmName=GPU-VM2 vmUser=XXXX vmPassword=XXXX ※ Ubuntu2004なのは「NVIDIA GPU Driver Extension」の前提条件のため。~ ※ NVIDIA ... Extensionをデプロイ後、2004アップグレードすると動かなくなる。 ---有償イメージに同意し、VMを作成する。 az vm image terms accept \ --publisher canonical \ --offer 0001-com-ubuntu-pro-focal \ --plan pro-20_04-lts-gen2 ※ 作成後はセキュア ブートと vTPM を無効化する必要がある。 --インストレーション ---NVIDIAドライバ:Linux 用の NVIDIA GPU ドライバー拡張機能~ https://learn.microsoft.com/ja-jp/azure/virtual-machines/extensions/hpccompute-gpu-linux~ ・VMを起動した状態で、VMの「拡張機能とアプリケーション」から、~ 拡張機能 > NVIDIA GPU Driver Extensionをインストールする。~ ・暫く時間がかかるのでBastion Create完了前に実行してしまって良い。~ ・「nvidia-smi」で、以下のようにNVIDIAドライバが確認できる。 $ nvidia-smi Thu Jul 3 03:14:40 2025 +-----------------------------------------------------------------------------------------+ | NVIDIA-SMI 550.144.06 Driver Version: 550.144.06 CUDA Version: 12.4 | |-----------------------------------------+------------------------+----------------------+ | GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. | | | | MIG M. | |=========================================+========================+======================| | 0 NVIDIA A10-24Q On | 00000002:00:00.0 Off | 0 | | N/A N/A P8 N/A / N/A | 1MiB / 24512MiB | 0% Default | | | | N/A | +-----------------------------------------+------------------------+----------------------+ +-----------------------------------------------------------------------------------------+ | Processes: | | GPU GI CI PID Type Process name GPU Memory | | ID ID Usage | |=========================================================================================| | No running processes found | +-----------------------------------------------------------------------------------------+ ---前提に準拠し「[[CUDA Toolkit 11.3の手順>https://developer.nvidia.com/cuda-11.3.0-download-archive?target_os=Linux&target_arch=x86_64&Distribution=Ubuntu&target_version=20.04&target_type=deb_network]]」でインストール(&color(red){ドライバ死亡};)~ 以下、差異のメモ~ ・「NO_PUBKEY A4B469963BF863CC」と怒られた時の~ 対処法(CUDAリポジトリキーのローテーションに起因)~ sudo apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/7fa2af80.pub sudo apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/3bf863cc.pub ・nvcc -Vで実際に入ったバージョンを確認すると、~ 11.3ではなく最新バージョン(12.9)が入っている。 $ nvcc -V nvcc: NVIDIA (R) Cuda compiler driver Copyright (c) 2005-2025 NVIDIA Corporation Built on Tue_May_27_02:21:03_PDT_2025 Cuda compilation tools, release 12.9, V12.9.86 Build cuda_12.9.r12.9/compiler.36037853_0 ・一説によると、バージョン指定しない場合、最新のCUDAが入る[[らしい>https://qiita.com/porizou1/items/74d8264d6381ee2941bd]]。 sudo apt-get -y install cuda ・その後の手順で&color(red){ドライバ死亡};が確認される。 $ nvidia-smi NVIDIA-SMI has failed because it couldn't communicate with the NVIDIA driver. ---nvidia-smiを踏まえ「[[CUDA Toolkit 12.4の手順>https://developer.nvidia.com/cuda-12-4-0-download-archive?target_os=Linux&target_arch=x86_64&Distribution=Ubuntu&target_version=20.04&target_type=deb_network]]」でインストール~ 以下、差異のメモ~ ・nvcc -Vで実際に入ったバージョンを確認~ $ nvcc -V nvcc: NVIDIA (R) Cuda compiler driver Copyright (c) 2005-2024 NVIDIA Corporation Built on Thu_Mar_28_02:18:24_PDT_2024 Cuda compilation tools, release 12.4, V12.4.131 Build cuda_12.4.r12.4/compiler.34097967_0 ・こちらの手順で、CUDA Toolkit 11.3をインストール(&color(red){ドライバ死亡};)~ ・cuda-toolkit-12-4 → cuda-11-3に変更して実行 sudo apt-get -y install cuda-11-3 ・nvcc -Vでインストールは確認できるが、~ $ nvcc -V ... ・その後の手順で&color(red){ドライバ死亡};が確認される。 $ nvidia-smi NVIDIA-SMI has failed because it couldn't communicate with the NVIDIA driver. ---nvidia-smiでNVIDIAドライバの死活を監視~ ・CUDA Toolkitのインストールに成功しても、NVIDIAドライバがお亡くなりになるケースがある。~ nvidia-smi ... ・ココまで成功したのは、CUDA Toolkit 12.4の手順でのみ。 --Python 環境で確認~ 以下、差異のメモ ---Pythonのバージョンアップ(Python 3.8.10 → 3.12.3)~ システム標準の Python 3.8.10 は「/usr/bin/python3」にバインドされており、OSに必要。削除・上書き厳禁。~ 追加インストールした Python 3.12.3 「/usr/local/bin/python3.12」にインストールされ、他のPythonと独立。~ ・依存パッケージをインストール sudo apt update sudo apt install -y build-essential zlib1g-dev libncurses5-dev libgdbm-dev libnss3-dev libssl-dev libreadline-dev libffi-dev libsqlite3-dev libbz2-dev liblzma-dev ・Python 3.12.3 のソースコードをダウンロード cd /usr/src sudo wget https://www.python.org/ftp/python/3.12.3/Python-3.12.3.tgz sudo tar xzf Python-3.12.3.tgz cd Python-3.12.3 ・コンパイルしてインストール sudo ./configure --enable-optimizations sudo make -j$(nproc) sudo make altinstall ※ --enable-optimizations は高速化オプション~ ※ make altinstall で、既存の python3 コマンドを上書きしない~ ・cdしたので元に戻す cd ~ # 再ログインでも良い ・実行とバージョン確認(フルパス) /usr/local/bin/python3.12 --version /usr/local/bin/python3.12 >>> ・実行とバージョン確認(PATHにある) python3.12 --version python3.12 >>> ・pipの扱いはどうなるのか?~ ・インストール結果 installed pip-24.0 WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv ・実行結果(Python3に対応) $ pip Command 'pip' not found, but can be installed with: sudo apt install python3-pip $ pip3 # pip3って訳でもないらしい Command 'pip3' not found, but can be installed with: sudo apt install python3-pip ・実行結果(Python3.12に対応) pip3.12 Usage: pip3.12 <command> [options] Commands: ... General Options: ... ---仮想環境を使う~ ・仮想環境を作成 python3.12 -m venv .python312_venv ・activate source .python312_venv/bin/activate ・deactivate deactivate ---仮想環境外にpipインストール~ ・python3のpipは一先ず不要(だが、入れるなら以下) sudo apt update sudo apt install python3-pip pip3 --version ・python3.12のpipをインストール・アップグレード sudo python3.12 -m ensurepip --upgrade sudo python3.12 -m pip install --upgrade pip ※ sudo を付与した pip 周辺で警告が表示されるが、ココでは問題はない。~ ・pip3.12 のインストールを(再度)確認する。 python3.12 -m pip --version pip3.12 --version ・pip3.12 を使って仮想環境外でパッケージをインストール pip3.12 install --user numpy ※ --user をつけることで、~/.local/ 以下にインストールされ、他環境には影響を与えない。~ ※ sudo pip はシステムパッケージマネージャーと競合する可能性があるので使用しない。 ---仮想環境(.python312_venv)内にpipインストール~ ・仮想環境内で pip 更新~ pip install --upgrade pip ・仮想環境内でパッケージをインストール pip install numpy ※ pipは仮想環境内での使用が推奨:https://pip.pypa.io/warnings/venv ---フレームワークのpipインストール:https://pytorch.org/get-started/previous-versions/~ 仮想環境の「外」でやるか「中」でやるかは要検討だが、「外」に入れても「中」では使えないので基本は「中」かと。~ ・仮想環境外へはpip3.12を使ってやる。 TMPDIR=/mnt/tmp pip3.12 install torch==2.6.0 torchvision==0.21.0 torchaudio==2.6.0 --index-url https://download.pytorch.org/whl/cu124~ ・仮想環境(.python312_venv)内へはpipを使ってやる。 TMPDIR=/mnt/tmp pip install torch==2.6.0 torchvision==0.21.0 torchaudio==2.6.0 --index-url https://download.pytorch.org/whl/cu124 ・実行確認(インタラクティブ実行で) python3.12 >>> import torch >>> print(torch.cuda.is_available()) # TrueならOK True >>> print(torch.cuda.get_device_name(0)) # GPU名表示 NVIDIA A10-24Q **実装 [#fbf52eee] ***アウトライン [#pf4385c1] -[[はじめに参考にしたのは10ヶ月前のMSのphi-3のLORA FTコード>https://github.com/OpenTouryoProject/DxCommon/blob/5af61da777002d809db2a73e35b0c181b68ebc8f/Notebook/Jupyter/path/LLM_Fine-tuning1.ipynb]]だったが既に動作せず。 -以下のように、環境のバージョンを上げるとすぐ動かなくなる~ (また、実績のある環境&コードで実行すると言う手段もあるが、[[環境を合わせるのに苦労する>#l5db1fb1]])。 --ハードウェア:学習資源の準備とCUDA等の環境構築 --ソフトウェア:モデルやライブラリのバージョンの不一致 ---コンフィグレーション系のI/F変更 ---データ系のフォーマット変更 --構造・形式 ---使用するモデルの構造差異でtarget_modulesが異なる。 ---データの正確な形式のDatasetやTokenizer処理が不可欠 --訓練条件(低リソース環境・量子化)との不整合、 ---4bit/8bit量子化(bnb_config)を使うときは、特定のモデルでしか動作しなかったり ---LoRA適用時に特別な設定(例:device_map="auto", gradient_checkpointing=True)が必要だったり --実験コードがプロダクションレベルでない ---GitHubで共有されるコードは、個人の実験コードであることが多く、エラー処理や汎用性がなく、前提条件を明記していない場合がある。 ---ブラックボックスの抽象化レイヤーが多過ぎてエラーメッセージが「根本原因」を教えない(バージョン不一致だがバージョンの明記はない)。 ---ライブラリのエラーメッセージをベースにトラブルシュートしようとしても対応が難しい。下位スタックの情報だけを返すことが多いため。 ***実際のコード [#q95d7ca6] (リンク先の各ライブラリの項に記載) -使い分けまとめ |学習形式|入力形式|ライブラリ|クラス|h |次単語予測(事前学習)|生テキスト|huggingface/transformers|[[Trainer>huggingface/transformers Trainer]]| |SFT / Instruction tuning|JSON形式の会話データ|huggingface/TRL|[[SFTTrainer(Trainerを継承)>huggingface/trl SFTTrainer]]| -選定目安 |プロジェクト内容|推奨トレーナー|h |GPTのような汎用LMの事前学習|Trainer(with Causal LM)| |ChatGPT風の会話モデル|SFTTrainer(またはLoRA + SFTTrainer)| |RLHF(報酬学習やPPO)まで進める |trl 内の SFTTrainer → RewardTrainer → PPOTrainer の流れ| **運用 [#t8bf957d] ***アウトライン [#je919dca] -ファインチューニングしたLoRAモデルをマージ from peft import PeftModel base_model = AutoModelForCausalLM.from_pretrained("meta-llama/Llama-2-7b-hf", device_map="auto") model = PeftModel.from_pretrained(base_model, "path/to/lora_adapter") merged_model = model.merge_and_unload() merged_model.save_pretrained("merged_model") tokenizer.save_pretrained("merged_model") -[[Transformers形式>OSSのLLM#zbe3597d]] → [[GGUF形式>OSSのLLM#sd779976]]への変換 --変換処理に使用するllama.cppの準備 ---llama.cppを取得&ビルド ---Pythonラッパーのパッケージをインストール --変換処理を実行する。 ---BFloat16のGGUF形式モデルに変換:convert_hf_to_gguf.py ---Q4_K_Mで量子化:llama-quantize(CLIっぽい) -ファインチューニングしたLoRAモデルをOllamaで実行 --Ollama用のModelfileを定義~ FROM llama2 # ファインチューニング済み GGUF を追加 PARAMETER_FILE ./llama-2-7b-q4.gguf --GGUF形式をポイントしビルド ollama create my-llama2-qa -f Modelfile --ビルドしたモデルを実行 ollama run my-llama2-qa ***実際のスクリプト [#r5679d6e] *知識付与 [#t5812328] -LLMのファインチューニングでドメイン知識の獲得は可能か。知識付与の限界と可能性 https://zenn.dev/dalab/articles/d41110bfbb120e **記載されている内容 [#i7123f76] ***前提 [#z72ecc36] -Swallow-MS-7b-instruct-v0.1にInstruction Tuning -量子化の設定、16bit(bfloat16)のモデルに対して、8bitの量子化 -LoRAはHugging Faceのpeftライブラリを使用して実装 ***データ [#m66a222c] -同じ事実を記述するテキストの数が重要 -間違った質問文を入れて質問と回答の種類に幅を持たせた。 -train と eval のデータ -- 知識を「正しく記憶できているか」だけを確認したい場合、同じで良い。 -モデルの「汎化能力」や「忘却の程度」を確認したい場合、別にすべき。 --実際の運用に近い評価をしたい場合、両方を混ぜるのが一般的。 ***設定 [#l8c4861e] -16bit(bfloat16)のモデルに対して、8bitの量子化 -r=16、lora_alpha=16、TargetModuleについては、 --PEFTライブラリのデフォルトの設定ではSelf attention層のみが対象 --先行研究によれば、知識付与においては、全結合層も学習の対象にすることが重要 --「Self attention層のみ」「全結合層のみ」「全層」で検証した所「全層」の出力が最も回答の精度が高くなった。 ---「Self attention層のみ」は丸暗記の回答はできるが聞き方が少し変わると回答ができない傾向 ---「全結合層のみ」は同じ回答の繰り返しが出やすい傾向にありました。 -その他、バッチサイズは2、勾配累積は2、エポック数は8 ***定義 [#t29bed25] 学習した知識について、 -学習したQ&Aをそのまま回答できる(暗記) -多少質問の仕方が変わっても正しく答えられる(言い換え耐性) -多少違う回答の仕方を要求されても正しく答えられる(出力柔軟性) -学習した知識を統合して回答(学習知識間の統合) -事前知識を組み合わせて回答(事前知識との統合) ***結果 [#aba33803] -短く簡潔な事実を覚えることは可能。 -知識の組み合わせ回答もある程度可能。 -長文になるほど精度が落ち、ヒントを与えると、逆に誤る場合がある。 ***学習データ [#sbb0826e] -形式に偏りがあると、回答の形式の柔軟性が失われやすくなる。 -100件未満の場合、エポック数が8~10回程度必要になり、過学習で?精度が落ちる。 -データに多様性を与え、回答の形式の柔軟性を向上させることができるが、ハルシネーションの可能性がある。 -長い文章を記憶して、正しく情報を出力するのは、少ない学習データからは難しかった。 **フロンティアモデルに聞く [#qde7873d] ***定義・結果 [#g0d12bc3] 学習した知識について、 -固定知識 --暗記:強い(高い確率で可能) --言換耐性:中〜強(データ多様性で強化可) --出力柔軟性:強(基盤モデルの指示追従能力に依存) --学習知識間の統合:中(比較系QAを追加して強化する必要がある) --事前知識との統合:強(事前知識を壊さない利点がある) -要推論知識 --暗記:弱〜中(そもそも、暗記だけで答えられるケースが少ない) --言換耐性:中(もともと、推論系は言い換え耐性があるため) --出力柔軟性:中〜強(基盤モデルの推論能力に依存) --学習知識間の統合:中(高度でLoRA層だけでは対応できない) --事前知識との統合:強(基盤モデルの推論能力に依存) --★ 推論力(新規問題への適応:弱〜中(CoTなどで推論能力そのものを強化する必要がある) ※ 「固定知識用データセット設計」と「推論知識用データセット設計」で違う ***パラメタ [#va503670] LLMに、固定知識「XXXXはYYYYだ。」と言う100個程度の事実をファインチューニングで学習させる場合、 -r=8〜16, α=16〜32 -3〜6エポック 1万件にデータ拡張 ***学習データ [#p1400eed] LLMに、固定知識「XXXXはYYYYだ。」と言う100個程度の事実をファインチューニングで学習させる場合、 -基本 --質問の言い換え や 異なるプロンプト形式(Alpaca 形式、Dolly 形式)などでデータ拡張 --たとえば、一万件規模にデータ拡張すると、1エポック=各知識100回の学習になる。 --大規模言語モデルのLoRA微調整では、数十回〜数百回見ればほとんど暗記できる傾向がある。 --故に、固定知識の暗記が目的なら、1エポックでも十分に覚える可能性が高い。1〜3エポック程度で十分。 --データ量が少なくなると、ばらつきで一部の知識が完全に暗記されないことがある。 -固定知識用 --暗記:... --言換耐性:言い換えパターンをLLM に自動生成させる(質問・回答パターンの多様化、自然な口頭のQA) --出力柔軟性:スタイル指示、説明生成により、基盤モデルの指示追従性と新知識が結びつく。 --学習知識間の統合:「比較系」「関連付け系」「逆質問(知識逆引き)」の追加 --事前知識との統合:明示的なQA形式、負例の追加 -推論知識用 *参考 [#a6f42034] **LoRA [#w424841e] -LoRAによるSLMのファインチューニングのハイパーパラメータチューニング - target_modules~ https://zenn.dev/headwaters/articles/123f4b68e07ea6 -LoRA(ローラ)とは|今年注目の画像生成AI (Stable Diffusion) のファインチューニングを試してみた | Ledge.ai~ https://ledge.ai/articles/LoRA **環境 [#oe04b9f8] ***[[VM費用見積もり>OSSのLLM#j66a9045]] [#y54fc6ec] ***[[GPU付きVMを準備>OSSのLLM#we26e9ac]] [#m927f83a] ***[[GPUを認識させる>OSSのLLM#p7fc71c4]] [#b74108a5] **実装 [#x681d57e] ***phi3 [#ze2c49d8] -メモ:phi3をLoRaでColab上でファインチューニングしてみる。 - 地平線まで行ってくる。~ https://bwgift.hatenadiary.jp/entry/2024/08/02/200735 -Phi-3のFineTuning方法の違い「通常のファインチューニング」「LoRA」「qLoRA」~ https://zenn.dev/headwaters/articles/55f648399c1820 -https://github.com/microsoft/PhiCookBook/blob/main/code/04.Finetuning/Phi-3-finetune-lora-python.ipynb ***Llama2-3 [#v9d9647c] -Llama2 のファインチューニングに低ランク適応 (LoRA) を使用~ https://zenn.dev/intel_developer/articles/82f74c7e5b80ae -llama.cppで語尾を”ござる”に変えるloraを作る(ELYZA-japanese-Llama-2)~ https://zenn.dev/michy/articles/a79d4a4a501bf9 -【Llama2】ファインチューニング | 7b・13b・70b | 業界最安級GPUクラウド | GPUSOROBAN~ https://soroban.highreso.jp/article/article-057#65954616a3bb513f40eb74c5-4f75fd7cab2ca5595d0fca36 -Google Colab で Llama 3 のファインチューニングを試す |npaka~ https://note.com/npaka/n/n315c0bdbbf00 -MetaのオープンソースLLM「Llama 3」を日本語版にファインチューニング(SFT) #生成AI - Qiita~ https://qiita.com/bostonchou/items/bf4a34dcbaf45828f886 ***その他 [#qd259e50] -ラインの日本語LLM --日本語LLMのファインチューニング入門 – 自作・Hugging Face公開データセット対応 | 子供プログラマー~ https://child-programmer.com/llm-ft-tutorial/ **運用 [#a9b4e516] ***モデル取り回し [#ue84b6b5] -https://x.com/talktoai/status/1836754397340062179 -【llama.cpp】誰でもできるgguf変換~ https://zenn.dev/saldra/articles/2598836233f555 -HuggingFaceのモデルをGGUF変換する|あきら~ https://note.com/mydatastock/n/n0966c7836543 -初心者でもできる!HuggingFaceモデルをGGUF形式に変換しOllamaで使う手順 - uepon日々の備忘録~ https://uepon.hatenadiary.com/entry/2024/09/10/153249 -Qiita --GGUF 変換メモ #llama.cpp~ https://qiita.com/7shi/items/14d24a25aa26dcf97d2d --ファインチューニングしたモデルをGGUFに変換する。 #LLM~ https://qiita.com/hudebakononaka/items/ca295eae60231d7d025f --【Llama.cpp】学習したオリジナルLlama2ベースのLLMを量子化してGGUF形式にするまでの流れ #LLaMA - Qiita~ https://qiita.com/keisuke-okb/items/faeaf4b14d7e581707b9 --ファインチューニングしたモデルでGGUFファイル作成した時に詰まった件について #Python - Qiita~ https://qiita.com/kyotoman/items/5d460708d798a6f26cf0