Generative AI

NVIDIA NIM で LoRA アダプター群をシームレスにデプロイ

Reading Time: 3 minutes

最新の基盤である最先端の大規模言語モデル (LLM) は、数十億ものパラメーターを持ち、数兆もの入力テキスト トークンで事前学習されています。多くの場合、カスタマイズの必要なく、幅広いユース ケースで著しい成果を上げています。それにもかかわらず、研究では、下流のタスクで最高の精度を達成するためには、高品質でドメイン固有のデータセットで LLM を適合させる必要があることが示されています。

多くの場合、カスタマイズされた小規模モデルは、より大規模な汎用LLM と同等あるいはそれを上回るパフォーマンスを発揮することが可能であり、同時にデプロイにかかるコストを大幅に削減することができます。しかし、特定の下流タスクのためにモデルをカスタマイズする作業は、作成とデプロイの両方に重大な課題をもたらす可能性があります。

非常に大規模な LLM を完全にファインチューニング (つまり、モデルのすべてのパラメーターを更新する作業) するには、モデル全体の学習に必要となる計算インフラの量を考慮すると困難になる可能性があります。学習時のインフラのコストもデプロイ時のインフラのコストも増加し、ユーザーは複数の大規模モデルをメモリにホストするか、またはモデル全体が入れ替えられる間に発生する遅延の増加を許容する必要があります。Low-rank adaptation (LoRA) は、これらの両方の問題を軽減するための技術です。

本投稿では、LoRA の概要について簡単にご紹介し、LoRA でファインチューニングされたモデルをデプロイする 2 つの方法を説明します。また、LoRA アダプター群のヘテロジニアスな LoRA デプロイを可能にして、混合バッチ推論リクエストを可能にするためのアプローチについても説明します。

Low-rank adaptation (LoRA)

近年、LoRA は、フルファインチューニングと比較して非常に少数の追加パラメーターのチューニングを行う技術として人気が高まっています。これらの追加パラメーターは、LoRA アダプターと呼ばれ、ネットワークの密な層における変化の低ランク分解を表します。LoRA は、LLM が過剰にパラメーター化されており、ファインチューニングの間に学習される新しい情報が低い「固有ランク」を持つという観察に基づいています。言い換えれば、モデル パラメーターの効果的な変化は、非常に高次元のパラメーター空間全体の内の、低次元の部分空間に限定されます。LoRA を使用すれば、学習すべきパラメーター数を 10,000 分の 1 に削減することができます。

図1. パラメーター A および B は、新しく追加された情報を表します。画像提供: LoRA: Low-Rank Adaptation of Large Language Models

図 1 は LoRA のコアとなる考え方を示しています。

  • カスタマイズ中、事前学習済みモデルの重み (W) は固定されます。
  • W を更新する代わりに、2 つの小さな学習可能な行列 AB が注入され、タスク固有の情報が学習されます。行列乗算 B*AW と同じ次元の行列を形成するため、W (= W + BA) に加算することができます。

A 行列と B 行列のランクは、8、16 などの小さな値です。累積すると、W と比較して学習可能なパラメーターがはるかに少なくなり、カスタマイズする際の計算とメモリ消費が効率的になります。このランク (r) パラメーターは、通常、学習時にカスタマイズ可能です。

ランク サイズと計算効率性の間にはトレードオフがあります。ランク値が大きいと表現性も向上し、モデルはより多くの下流タスクに関連するパターンを捉えることができます。非常に大きいランク値 (64 など) では、ほぼフルの教師ありファインチューニングに近い情報学習能力を持つことになります。つまり、モデル内のすべてのパラメーターを更新することに相当します。しかしランク値が大きいほど、メモリや計算リソースの面で、学習と推論にかかるコストも高くなります。実際、ランク値を 8 のように小さくしても、 LoRA のファインチューニングは非常に効果的であり、さまざまな下流タスクの良い出発点になります。

LoRA でチューニングされたモデルのデプロイ

LoRA によるファインチューニングは、以下の方法でデプロイすることができます。

オプション 1: LoRA アダプターのマージ

追加される LoRA の重みを事前学習済みモデルとマージして、前モデルと構造的に同等の専用バリアントを作成することができます。これにより、アダプターを個別に管理することで生じる、推論の待ち時間を回避することができます。重みをマージするのは比較的シンプルなアプローチですが、柔軟性は低くなります。このアプローチの欠点は、モデル全体が「カスタムメイド」になり、一度に 1 つのタスク、つまりこのモデルがファインチューニングされたタスクにしか対応できなくなる点です。このため、デプロイを効率化するために、異なるタスクの入力をバッチ化することが困難になります。この方法は、デプロイごとに 1 つのタスクのみを対応させる場合にのみ推奨されます。

オプション 2: LoRA アダプターを動的に読み込む

LoRAアダプター (図 1 の AB) は、ベース モデル (W) から分離されています。推論時に、ランタイムは入ってくるリクエストに対応するアダプターの重みを動的に読み込みます。これにより、様々なタスクからの入力を同時に提供およびバッチ処理する柔軟性が得られ、利用可能な計算能力を最大限に活用することができ、別のカスタム モデルを維持する必要がありません。

ユース ケースによっては、同じベース モデルに対して、複数の、あるいは数百、数千の LoRA が必要となる場合があります。このような場合には、動的 LoRA アダプターを選択するのがよい方法です。以下はその一例です。

  • パーソナライズされたモデルを顧客に提供したり、レコメンデーションを提供したり、または特定のペルソナや嗜好を適応する、などをしている企業。
  • 同じユース ケースの様々な LoRA のファインチューニングを比較するための A/B テスト。
  • 同じ基盤モデルに基づいて、複数の下流ユース ケースに対するサービスを提供する企業。例えば、バグの要約、チケットのルーティングと分類、チャットボットの実装、特定の文書資料に対する知識検索の実装、根本原因分析などのために、マルチ LoRA セットアップをデプロイする IT サービスチームなど。

NVIDIA NIM は、このような LoRA アダプターの動的な読み込みをサポートし、混合バッチ リクエストを送信可能な最適化された推論マイクロサービスを提供します。以下のセクションでは、NVIDIA のアプローチについてより詳しく見ていきます。

NVIDIA NIM による異種、マルチ LoRA のデプロイ

NIM では、各推論マイクロサービスが単一の基盤モデルに関連付けられています。このモデルでは、モデルに関連付けられた低ランクのアダプターという形で、いくつでも「カスタマイズ」を持つことができます。

  1. NVIDIA NeMo フレームワークまたは Hugging Face PEFT ライブラリを使用して学習されたアダプターは、アダプター ストアに配置され、一意の名前が与えられます。
  2. NIM にリクエストする際には、クライアントは、LoRA モデル名を含めることで、特定のカスタマイズを指定することができます。
  3. NIM はカスタマイズされたモデルに対するリクエストを受け取ると、関連するアダプターをアダプター ストアから多層キャッシュに引き出します。アダプターによっては、 GPU メモリやホスト メモリに常駐されているものもあり、保存場所は最近どのように使用されたのかに応じて異なります。
  4. 処理中、NIM は特殊な GPU カーネルを実行し、基礎モデルと複数の異なる低ランクのアダプターの両方にデータが同時に流れることができるようにします。これにより、複数の異なるカスタム モデルに対するリクエストに同時に応答することができます。
図 2. NVIDIA NIM の動的 LoRA アーキテクチャ。同じ基盤モデルで混合した入力バッチを送信することが可能。

複数のリクエスト バッチを処理

異なるタスクをサポートするために、1 つのバッチ内のリクエストに異なる LoRA アダプターが使用されていることがあります。そのため、従来の 1 つの GEMM (General Matrix Multiplication) を使用して、すべてのリクエストをまとめて計算することはできません。各リクエストを一つずつ順番に計算すると、大量の追加のオーバーヘッドが発生します。この問題を解決するために、NVIDIA では NVIDIA CUTLASS を使用してバッチ処理された GEMM を実装し、バッチ処理された異種リクエスト処理を単一のカーネルに融合しています。これにより、GPU の使用率とパフォーマンスが向上します。

さらに、バッチ処理された GEMM の GPU 使用率は、各アダプターの最初の行列構成要素に対して十分に高いものではないことが判明しました。これは、最初の行列は、入力次元が非常に大きく、出力次元が小さいからです。各アダプターには、図 1 に示すように、A (dr の形状) とB (rd の形状) の 2 つの行列要素があります。通常、d は LoRA ランクの r よりもはるかに大きいため、splitK メソッドを適用して、より多くのストリーミング マルチプロセッサ (SM) 上の複数のタイルに GEMM を分割することで GPU の利用率を改善し、splitK でバッチ化した GEMM の後には追加の削減カーネルを使用して部分的な結果を削減しています。

性能ベンチマークのベスト プラクティス

このようなマルチ LoRA デプロイの遅延とスループットの性能を評価することは簡単ではありません。このセクションでは、LLM LoRA 推論フレームワークのパフォーマンスをベンチマークする際に、一般的に注目すべきいくつかの主要な考慮事項について説明します。

  • ベース モデル: 小規模モデルと大規模モデルの両方とも、Llama 3 8BLlama 3 70B などの LoRA のファインチューニングや推論のためのベース モデルとして使用できます。小規模なモデルは多くのタスク、特にテキスト分類などの従来の非生成型の NLP タスクに優れている一方で、大規模なモデルは複雑な推論タスクに優れています。LoRA の利点の 1 つは、大型の 70B モデルでも、単一の NVIDIA DGX H100 または FP16 を備えた A100 ノード、または 4 ビット量子化を使用した単一の NVIDIA H100 または NVIDIA A100 GPU でファインチューニングできる点です。
  • アダプター: 実際のエンドユーザーの立場からすると、最高の精度が取得できるサイズを試し、選択できる柔軟性がある方が望ましいです。一方で、システム オペレーターは、均一な LoRA によってバッチ処理が向上し、ひいてはパフォーマンスも向上するため、ある一定の固定サイズを均一に実施したい場合があります。LoRA ランクでよく使用されているのは 8/16/32/64 です。
  • テスト パラメーター: ベンチマークする際に考慮すべき他のテスト パラメーターは次の通りです。
    • 出力長の制御: ignore_eos パラメーターは、max_token_length の上限に達するまで、推論フレームワークにテキストを生成し続けるように指示します。これにより、ユース ケースの OSL (出力シーケンス長) 仕様を確実に満たすことができます。このパラメーターをサポートする LLM 推論フレームワークは増えており、ベンチマークのセットアップを大幅に簡素化します。注目すべきことは、ignore_eos を使用すると、パフォーマンス プロファイリングをする際に「実際の」タスクで学習する必要がなくなる点です。
    • システム負荷: コンカレンシ (同時ユーザーの数) は、システムへの負荷を高めるために一般的によく使用されます。これは実際のユース ケースを反映し、システムが効果的に同時に処理できる最大の「バッチサイズ」も考慮に入れたものである必要があります。1 基の GPU で 8B モデルを使用する場合、現実的なサーバー負荷としては最大 250 の同時ユーザーを想定してください。
    • タスク タイプ: 生成型と非生成型の両方のタスクを考慮する必要があります。これらは、ISL (入力シーケンス長) と OSL で異なります。[200, 2000] トークン範囲の ISL と [1, 2000] トークン範囲の OSL は、テキスト分類や要約から翻訳やコード生成にいたるまでの、幅広い LLM アプリケーションを反映しています。
  • ツール: ベンチマーク ツールは、LoRA モデルの呼び出しをサポートするものである必要があります。GenAI-Perf は LoRA をサポートするように設計された LLM ベンチマーク ツールです。アダプターは、ランダムかつ均一に、またはラウンドロビン方式で、または実際の使用パターンを反映する分布に従って呼び出されます。例えば、20% のアダプター がリクエストの 80% を占めるような形です。
  • メトリクス: LLM 分野の主なメトリクスは遅延です。TTFT (最初のトークンまでにかかる時間)、ITL (トークン間の遅延)、スループット、TPS (1 秒あたりの総システム トークン数)。

その他の補足メトリクスには、1 秒あたりの総リクエスト数やエンド ツー エンド リクエストの遅延などがあります。

ベース モデル (またはマージされた LoRA モデル) を提供する場合と比べて、動的 LoRA (単一の LoRA、同じランクの複数の LoRA、または異なるランクの複数の LoRA) を追加した場合、これらすべてにおいて遅延とスループットの両方の面でコストが増加します。このコストが、動的 LoRA から得られる精度と柔軟性の向上と引き換えるのに妥当なものであるのが理想的です。

LoRA を使用した場合の NIM のパフォーマンス特性については、今後数週間および数か月のうちに、さらに多くの情報をお知らせできると思います。

次のステップ

研究では、ファインチューニングされたモデルの効率性や精度を向上させることを目的とした、LoRA の新しい機能強化が行われています。NVIDIA では将来的に、これらの機能を NIM に組み込む予定です。

Tied-LoRA

Tied-LoRA は、LoRA のパラメーター効率を高めるための NVIDIA Research の新たな技術です。LoRA では、LLM の各層の重み更新を近似するタスク固有の低ランク行列が追加されます。Tied-LoRA では、これらの低ランク行列が様々な層間で共有され (「結合 (Tied)」) 、学習可能なパラメーターの数がさらに削減されます。さらに、この技術は LoRA (低ランク行列およびスケーリングベクトル) の異なるコンポーネントを選択的に学習またはフリーズできるようにするため、ユーザーはパフォーマンスとパラメーター効率のトレードオフを試すことができます。

NVIDIA NIM の今後のリリースで、この技術をサポートする予定です。

DoRA

DoRA は、NVIDIA Research が開発したもう一つの技術で、完全にファインチューニングされたモデルと LoRA チューニングの間のパフォーマンス ギャップを埋めます。これは、事前に訓練された重みを、大きさ (Magnitude) と方向 (Direction) という 2 つの要素に分解することで実現します。ファインチューニングでは、DoRA は LoRA を方向の更新に使用し、そうすることで効率的に学習可能なパラメーター数を最小限に抑えます。このアプローチにより、推論オーバーヘッドを増やすことなく、LoRA の学習能力と学習の安定性を高めることができます。DoRA は、LLAMA、LLAMA、VL-BART などのモデルのファインチューニングにおいて、コモンセンス知識 (Commonsense Reasoning)、視覚指示学習 (Visual Instruction Tuning)、画像およびビデオ-テキスト理解などのさまざまな下流タスクで一貫して LoRA を上回っています。

まとめ

NVIDIA NIM により、複数の LoRA アダプターをシームレスにデプロイおよびスケーリングすることができます。NIM は現在利用可能であり、Meta Llama 3 8B および Llama 3 70B のサポートをはじめ、NVIDIA NeMoHugging Face の両方のモデル形式の LoRA アダプターもサポートしています。今後のリリースでは、最新のコミュニティ モデルへのサポートも追加する予定です。

NIM でマルチ LoRA を始めるには、NVIDIA NeMo を使用した Llama 3 モデルの LoRA チューニング、NIM によりファインチューニングされたアダプターのデプロイ、および混合推論リクエストの送信に関する Jupyter Notebook チュートリアルを参照してください。NIM の詳細については、こちらの関連資料をご覧ください。


関連情報

Tags