Llama2 のファインチューニングに低ランク適応 (LoRA) を使用

https://www.intel.com/content/www/us/en/developer/articles/training/fine-tuning-llama2-model-with-lora.html 

インテル® Gaudi® 2 AI アクセラレーターに実装する Llama2 ファインチューニングの低ランク適応 (LoRA) による効率化
https://github.com/HabanaAI/Gaudi-tutorials/blob/main/PyTorch/llama2_fine_tuning_inference/llama2_fine_tuning_inference.ipynb

＜概要＞
生成 AI を使用する場合、LLama2 など大規模言語モデル (LLM) のファインチューニングには、ワークロードの演算リソースとメモリー負荷が高くなることから、特有の課題が伴うものです。しかし、最先端の LLM を高速かつコストを抑えながら運用するうえで、インテル® Gaudi® AI アクセラレーターでの低ランク適応 (LoRA) は強力な選択肢となります。この機能によって、リサーチやアプリケーション開発における大規模モデルの可能性はますます広がります。

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3490396/edbd96fb-8696-4535-a40f-9d22320e1398.png)
図 1. インテル® Tiber™ デベロッパー・クラウドを活用し、インテル® Gaudi® 2 AI アクセラレーターに実装した Llama2 モデルのファインチューニングを実行するワークフロー 

このチュートリアルでは、インテル® Tiber™ デベロッパー・クラウドを活用し、6 分未満、約 0.86 ドルで、Llama2-7B-hf のような最先端モデルの LoRA によるファインチューニングを行う手順について詳しく解説します (図 1)。ここで取り上げるトピックは以下のとおりです。
•	インテル® Gaudi® 2 AI アクセラレーター上で行う LoRA ファインチューニングのための開発環境設定
•	Optimum Habana Hugging Face ライブラリーとインテル® Gaudi® 2 AI アクセラレーターを使用する、高品質の会話データを集めた openassistant-guanaco データセットでの LoRA による Llama2 ファインチューニング
•	LoRA によるチューニング済み Llama2–7B-hf の推論実行と、チューニングなし事前学習済み Llama2 ベースラインとの応答品質の比較
このページで紹介するインサイトとサンプルコードを活用することで、LLM モデルの開発プロセスを効率化できるはずです。さまざまなハイパーパラメーター、データセット、事前学習済みモデルをいち早く試してみることができるので、結果的に生成 AI アプリケーション用 LLM の最適化にかかる時間の短縮につながります。

＜低ランク適応 (LoRA) によるパラメーター効率ファインチューニングの導入＞
根本的に、LoRA の理論は、行列因数分解と低ランク近似の原則を中心に展開します。線形代数では、どの行列もいくつかの低ランクの行列に分解することが可能です。この分解は、ニューラル・ネットワークのコンテキストとすれば、密度が高く、高度にパラメーター化されたレイヤーを、情報損失を最小限に抑えた、可能な限りシンプルでコンパクトな構造への分解と見ることができます。こうすることで、LoRA では無関係なパラメーターを排除しながら、最も影響力のあるパラメーター、つまり特徴量の抽出を目指しています。

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3490396/652ecc0e-323e-4e91-bd7f-fb28d9f7dd5a.png)
図 2. LoRA の学習処理経過と学習処理後を図解 — ソースを表示
https://huggingface.co/docs/peft/conceptual_guides/lora

では、この低ランクのアプローチが、特に大規模ニューラル・ネットワークで機能するのはどうしてでしょうか？その答えは、これらのモデルが扱うデータの本質的な構造にあります。ディープラーニング・モデルで処理されるような高次元データは、低次元サブスペースに常駐することが多く、実際のところ、すべての次元や特徴量が等しく重要というわけではありません。LoRA はこの原則をうまく利用して、ニューラル・ネットワークのパラメーターが存在する効果的なサブスペースを作り出します。このプロセスにはタスクに特化した新パラメーターの投入が含まれ、その次元数を (低ランクの行列によって) 抑えることで、新しいタスクを効率的にファインチューニングできるようにしています。この行列因数分解のトリックこそ、ニューラル・ネットワークがパラメーターの全スペースを再学習する必要なく新しいナレッジを取得して、演算効率と新タスクへの素早い適応を可能にしている仕組みです。

＜環境の設定＞
ここでは環境設定の方法を説明します。
1. インテル® Tiber™ デベロッパー・クラウドのアカウントを作成する
インテル® Gaudi® 2 AI アクセラレーターのクラウド・インスタンスは、このサンドボックス内で利用可能です。無償のアカウントを作成すると、インテルが提供するさまざまなコンピューティング・プラットフォームを探索できます。こちらの手順に従って開始してください。
https://developer.habana.ai/intel-developer-cloud/

2. コンテナを起動する
インテル® Gaudi® AI アクセラレーター上での推奨方法は、コンフィグレーション済み Docker コンテナ内でモデルを実行することです。コンテナ化された開発環境の設定手順については、事前ビルト済みのコンテナを参照してください。
https://docs.habana.ai/en/latest/Installation_Guide/Bare_Metal_Fresh_OS.html#事前ビルト済みのベアメタル用コンテナ

3. サンプルコードにアクセスする
インテル® Gaudi® 2 AI アクセラレーター搭載マシンに接続したら、以下のコマンドを実行し、Gaudi-tutorials リポジトリーのクローンを作成します。

![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3490396/ab50597d-b5e4-44f5-ac72-0257c95a39d0.png)

このデモは Jupyter Notebook 内で実行します。インテル® Gaudi® 2 AI アクセラレーターのインスタンスで Jupyter Notebook を開始するには、以下のいずれかの方法を選んでください。
• Microsoft Visual Studio Code や PyCharm などの統合開発環境 (IDE) から SSH 経由でインスタンスのリモートホストに接続し、IDE 内で Jupyter Lab を実行する。
• ローカルマシンからインスタンスに SSH トンネルを作成し、ローカルのブラウザーで直接 Jupyter Lab を開く。
ファイルツリーで Gaudi-tutorials/PyTorch/llama2_fine_tuning_inference/ フォルダーに移動し、Notebook llama2_fine_tuning_inference.ipynb を開いてください。

＜PEFT (LoRA) による Llama-2-7B-hf のファインチューニング＞
これで環境設定は整いました。以下の手順でサンプルを実行します。
1. モデルにアクセスする
まずは Hugging Face から基本の Llama-2–7B-hf モデルを取得し、これを因果言語モデルのテキスト生成用に openassistant-guanaco データセットでファインチューニングするところから始めます。
• openassistant-guanaco データセットは、Open Assistant データセットのサブセット。このサブセットには、会話ツリーの最も評価の高いパスのみが含まれ、サンプル数は合計 9,846。
• Llama2 を使用するには、Transformers ライブラリーを通じてアクセスする前に、ユーザーが Meta のライセンス条件に同意する必要があります。事前学習済みモデルの使用は、サードパーティー・ライセンスの遵守が求められます。詳細については、「Llama 2 Community License Agreement」を参照してください。
https://ai.meta.com/llama/license/

2. トークン命令用に Hugging Face アカウントを作成する
Hugging Face アカウントを作成するには、以下のコマンドを実行して Hugging Face にログインします。
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3490396/47f5155d-e0f5-4dc3-ac33-07dce02bbafc.png)

3. 追加の依存関係を設定する
ファインチューニングを実行する前に、インテル® Gaudi® 2 AI アクセラレーターで最高のパフォーマンスを発揮するよう設計された 3 つのライブラリーをインストールする必要があります。以下のコマンドはすべて、サンプル Notebook で確認できます。
• Habana Deepspeed: インテル® Gaudi® AI アクセラレーターでの ZeRO-1/ZeRO-2 最適化を有効にする。インストールするには、以下のコマンドを実行します。

![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3490396/3f466907-fe2f-4b47-9945-07b66ae2d06d.png)

• パラメーター効率ファインチューニング (PEFT): 数個のパラメーターをチューニングするだけで、事前学習モデルを適応可能。LoRA を有効にする、PEFT のサブセット。インストールするには、以下のコマンドを実行します。

![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3490396/f140a7c4-77d5-426d-9f48-d34e61b17c1d.png)

• Optimum-Habana: 低レベル・ライブラリーを分離することで、インテル® Gaudi® AI アクセラレーターと Hugging Face の最も広く利用されている API の間を簡単に接続。インストールするには、以下のコマンドを実行します。

![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3490396/7001126e-d325-42a6-a5a1-1261fe080437.png)

4. 言語モデル用の要件ファイルにアクセスする
optimum-habana/examples/language-modeling/requirements.txt 内にある要件ファイルにアクセスし、Notebook の指示に従って独自の開発環境にインストールします。

![8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3490396/10a17d56-68fe-4c97-92fe-e29de525e4e4.png)

5. ファインチューニングの処理を開始する
ここから、最小セットのモデル・パラメーターのみを調整し、演算とメモリーの負荷を大幅に軽減する、PEFT メソッドによるファインチューニングに取りかかります。最近 PEFT 手法のパフォーマンスは、完全なファインチューニングに匹敵するほどになりました。この手順には、run_lora_clm.py コマンドを介した LoRA による言語モデリングが含まれます。

![9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3490396/82082e78-a2c1-44f1-91bf-5bb5684c7c3f.png)

上記のコマンドラインでいくつかのパラメーターを詳しく見ていきましょう。
--use_deepspeed: DeepSpeed を有効化。
--world_size 8: 分散システムのワーカー数。各インテル® Gaudi® 2 AI アクセラレーター搭載ノードには 8 枚のインテル® Gaudi® AI アクセラレーター・カードが実装されるため、このパラメーターを 8 に設定し、ノード上のすべてのカードを有効にします。
--bf16 True: 16 ビット Brain 浮動小数点形式で半精度の学習処理を有効化。
--num_train_epochs 2: エポック数を 2 に設定。このデモの開発中に、損失が 1.5 エポックで収束すると気付いたため、2 のままにしました。この設定は、ほかのハイパーパラメーター、データセット、事前学習モデルによって変わることがあります。
--use_habana: インテル® Gaudi® AI アクセラレーターでの学習処理を有効化。
驚くべきことに、膨大な 70 億パラメーターのうち調整されたものはわずか 0.06% にとどまり、DeepSpeed のおかげでメモリー使用容量は 94.61GB から 31.03GB まで制限されました。この効率的なプロセスで要するのは 2 エポックのみ、6 分未満で処理が完了します。

＜Llama2 での推論＞
ファインチューニングの処理が完了した後は、PEFT メソッドの LoRA によってチューニングされた重み付けを使用して、サンプルのプロンプトで推論を実行します。
1. ベースラインを規定する
ベースラインを定めるために、LoRA チューニング済みパラメーターを使用していない、チューニングなし基本モデルの応答スニペットを解析します。

![10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3490396/0f740e91-2a08-40f7-90d8-437fac37fd42.png)

このコマンドラインを見て、以下のパラメーターの値に注目してください。
--max_new_tokens: 最大トークン数を 500 に制限。
--bf16: bf16 精度での推論を有効化。
--prompt: モデルに送るプロンプトを指定。
2. チューニングなし事前学習済みモデルからの応答
「このビデオでは、新しい Dell のノートブック PC をインストールして設定する方法を紹介します。これはインストールの手順をステップ・バイ・ステップで説明するビデオです。数週間前、サンディエゴへ短期間の旅行に行く機会がありました。都市部に数日間滞在した後、山間部で数日間過ごし...」
ご覧のとおり、出力結果には一貫性がありません。パーティー計画の提案を求めたところ、ノートブック PC やサンディエゴへの旅行に関する情報が返されました。
3. LoRA によるチューニング済みモデルで推論を実行する
では今度は同じプロンプトですが、LoRA チューニング済みレイヤーで送り、応答を確認してみましょう。

![11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3490396/aed7f73c-2a7a-47da-acdc-56326119ec54.png)

このコマンドラインでは、以下のパラメーターの値に注目してください。
--peft_model: (ファインチューニングの処理中に生成される) モデルのファインチューニング済みコンポーネントへのパスを指定。これにより、既存モデルへ小規模セットのレイヤーが追加されます。
以下は、ファインチューニング後のモデルからの応答スニペットです。
「申し訳ありませんが、私は犬ではなく、誕生日のサプライズパーティーをどのように計画すればよいか分かりません。でも、人間の皆さんが楽しめるようなアクティビティーやゲームのアイデアをお伝えできます。こちらに、楽しいアクティビティーとゲームをいくつか挙げてみました。パズルゲーム: ジグソーパズルやロジックパズルのようなパズルゲームを楽しめるのではないでしょうか。何かを作るような、例えばプラモデルの飛行機や LEGO を組み立てるような遊びも喜んでもらえるかもしれません …」
お気づきのとおり、出力結果の精度はずっとよくなり、6 分未満、約 0.86 ドルと、インテル® Gaudi® 2 AI アクセラレーターが LLM の応答品質に大きく影響していることが分かります。

＜補足資料＞
インテル® Gaudi® アクセラレーターに最適化済みの全モデルをまとめたリストは、https://huggingface.co/docs/optimum/habana/index を参照してください。

インテル® Gaudi® 2 AI アクセラレーターの公式ベンチマークを確認してください。
https://developer.habana.ai/resources/habana-models-performance/