生成 AI モデルの最適化とデプロイ

生成 AI は、ニューラル・ネットワークを使用してテキスト、画像、ビデオ、オーディオなどの新しいデータを作成する革新的な技術です。OpenVINO はモデル推論に依存する生成 AI のユースケースを加速し、開発の迅速化とパフォーマンスの向上を可能にします。生成モデルに関して OpenVINO は以下をサポートします。

  • テキスト、画像、オーディオ生成モデルの変換、最適化、推論 (Llama 2、MPT、OPT、Stable Diffusion、Stable Diffusion XL など)。

  • 埋め込みレイヤーの圧縮を含む 8 ビットおよび 4 ビットの重み圧縮。

  • Hugging Face の GPTQ モデルを含む、ストレージ形式の削減 (非圧縮モデルの場合は fp16 精度、圧縮モデルの場合は int8/int4)。

  • 統合されたインテル® プロセッサー・グラフィックス、ディスクリートのインテル® Arc™ A シリーズ・グラフィックス、ディスクリートのインテル® データセンター GPU フレックス・シリーズなどの CPU および GPU プラットフォームでの推論。

  • 融合推論プリミティブ。例えば、スケーリングされたドット積アテンション、ロータリー位置埋め込み、グループ照会アテンション、エキスパートの混合など。

  • インプレース KV キャッシュ、動的量子化、KV キャッシュ量子化およびカプセル化。

  • 動的ビームサイズ構成、投機的サンプリング。

OpenVINO は、生成 AI のユースケースに 2 つの主なパスを提供します。

どちらの場合も、OpenVINO ランタイムとツールが使用されます。主な違いは、優先される API と最終ソリューションのフットプリントにあります。ネイティブ API により、C++ アプリケーションで生成モデルを使用できるようになり、実行時の依存関係を最小限に抑えられるため、アプリケーションのフットプリントを最小限にできます。ネイティブ API アプローチでは、周辺コード (生成ループ、テキストトークン化、またはスケジューラー関数) の実装が必要ですが、開発者の体験を向上させるため、そうしたコードは Hugging Face ライブラリー内に隠されています。

Hugging Face フレームワークから始めることを推奨します。さまざまなモデルやシナリオを試して最適なものを見つけてから、特定の要件に基づいて OpenVINO ネイティブ API への変換を検討してください。

Optimum Intel は、ニューラル・ネットワーク圧縮フレームワーク (NNCF) を使用したモデルの最適化 (重み圧縮) を可能にし、ネイティブ API アプリケーションで使用するため、モデルを OpenVINO モデル形式にエクスポートするインターフェイスを提供します。

以下の表は、Hugging Face アプローチとネイティブ API アプローチの違いをまとめたものです。

OpenVINO を介した Hugging Face

OpenVINO ネイティブ API

モデルのサポート

幅広いモデルのセット

幅広いモデルのセット

API

Python (Hugging Face API)

Python、C++ (OpenVINO API)

モデル形式

ソース・フレームワーク/OpenVINO

OpenVINO

推論コード

Hugging Face ベース

カスタム推論パイプライン

追加の依存関係

多くの Hugging Face 依存関係

軽量 (numpy など)

アプリケーションのフットプリント

大きい

小さい

前処理/後処理と周辺コード

Hugging Face ですぐに利用可能

OpenVINO サンプルとノートブック

パフォーマンス

良い

最良

Hugging Face Optimum Intel を使用した生成 AI モデルの実行

必要条件

  • Python 環境の作成。

  • Optimum Intel のインストール:

pip install optimum[openvino,nncf]

OpenVINO を Hugging Face のバックエンドとして使用するには、オリジナルの Hugging Face コードを 2 カ所変更します。

-from transformers import AutoModelForCausalLM
+from optimum.intel import OVModelForCausalLM

model_id = "meta-llama/Llama-2-7b-chat-hf"
-model = AutoModelForCausalLM.from_pretrained(model_id)
+model = OVModelForCausalLM.from_pretrained(model_id, export=True)

その後、save_pretrained() メソッドを呼び出してモデルを OpenVINO 中間表現のフォルダーに保存して使用することができます。

model.save_pretrained(model_dir)

あるいは、CLI インターフェイスを使用してモデルをダウンロードして変換することもできます: optimum-cli export openvino --model meta-llama/Llama-2-7b-chat-hf llama_openvino。この場合、変換されたモデルを OpenVINO 表現でディスクから直接ロードできます。

model_id = "llama_openvino"
model = OVModelForCausalLM.from_pretrained(model_id)

デフォルトで推論は CPU で実行されます。別の推論デバイス (GPU など) を選択するには、from_pretrained() 呼び出しに device="GPU" を追加します。モデルのロード後に別のデバイスに切り替えるには、.to() メソッドを使用します。デバイスの命名規則は、OpenVINO ネイティブと同じです。

model.to("GPU")

Optimum-Intel API は、NNCF を使用した重み圧縮による容易に使用できるモデルの最適化も提供し、モデルのフットプリントと推論レイテンシーを大幅に削減します。

model = OVModelForCausalLM.from_pretrained(model_id, export=True, load_in_8bit=True)

重み圧縮はデフォルトで 10 億パラメーターを超えるモデルに適用され、--int8 オプションにより CLI インターフェイスでも使用できます。

パラメーターが 10 億を超えるモデルでは、8 ビットの重み圧縮がデフォルトで有効になります。

Optimum Intel は、重み量子化パラメーターを制御する OVWeightQuantizationConfig クラスを使用した 4 ビット重み圧縮も提供します。

from optimum.intel import OVModelForCausalLM, OVWeightQuantizationConfig
import nncf

model = OVModelForCausalLM.from_pretrained(
    model_id,
    export=True,
    quantization_config=OVWeightQuantizationConfig(bits=4, asym=True, ratio=0.8, dataset="ptb"),
)

最適化されたモデルは、save_pretrained() を呼び出すことで通常どおり保存できます。圧縮オプションの詳細については、重み圧縮ガイドを参照してください。

OpenVINO は、GPTQ で最適化された Hugging Face Transformers ライブラリーの 4 ビット・モデルもサポートしています。この場合、モデル変換によって INT4 最適化の結果が自動的に保存されてモデル推論の利点が得られるため、追加のモデル最適化ステップは必要ありません。

以下は、モデルの変換と推論に Optimum Intel を使用する例です。

ステートフル・モデルの最適化

OVModelForCausalLM クラスを使用すると、モデルは最適化のためデフォルトでステートフル形式に変換されます。この変換により、推論パフォーマンスが向上し、長時間実行されるテキスト生成タスクではランタイムメモリーの使用量が減少します。これは、過去の KV キャッシュテンソルを表すモデルの入力と出力を非表示にし、それらをモデル内でさらに効率良い方法で処理することで実現されます。この機能は、サポートされる多くのテキスト生成モデルに対して自動的に有効になりますが、サポートされていないモデルでは通常のステートレス形式のままです。

KV キャッシュは、Transformers ライブラリーのテキスト生成 API によって内部的に処理されるため、Optimum-Intel API を使用するステートフル・モデルとステートレス・モデルの使用法は変わりません。OpenVINO IR モデルが Optimum-Intel からエクスポートされ、ネイティブ OpenVINO API を使用するアプリケーションで使用される場合、モデルの形式が重要になります。これは、ステートフル・モデルとステートレス・モデルでは入力と出力の数が異なるためです。詳細は、「ネイティブ OpenVINO API」セクションを参照してください。

OpenVINO ランタイムの最適化を有効にする

OpenVINO ランタイムは、より効率的な LLM 推論向けの一連の最適化を提供します。これには、4/8 ビット量子化 MatMuls のアクティベーションの動的量子化KV キャッシュ量子化が含まれます。

  • 動的量子化により、4 ビットまたは 8 ビットの量子化された重みを持つ MatMul 操作のアクティベーションの量子化が可能になります (LLM 重み圧縮を参照)。これにより、LLM の推論レイテンシーとスループットが向上しますが、生成の精度にわずかな偏差が生じる可能性があります。量子化は、構成可能なグループサイズを使用して、グループごとに行われます。これは、グループ内の値が量子化パラメーターを共有することを意味します。グループサイズが大きくなると推論は速くなりますが、精度は低くなります。推奨されるグループサイズの値は、3264、または 128 です。動的量子化を有効にするには、対応する推論プロパティーを次のように使用します。

model = OVModelForCausalLM.from_pretrained(
    model_path,
    ov_config={"DYNAMIC_QUANTIZATION_GROUP_SIZE": "32", "PERFORMANCE_HINT": "LATENCY"}
)
  • KV キャッシュ量子化により、LLM のキーおよび値キャッシュの精度を下げることができます。これにより、推論中のメモリー消費が軽減され、レイテンシーとスループットが向上します。KV キャッシュは、u8bf16f16 の精度に量子化できます。u8 が使用される場合、KV キャッシュ量子化もグループごとに適用されます。したがって、定義されている場合は、DYNAMIC_QUANTIZATION_GROUP_SIZE 値を使用できます。それ以外の場合は、グループサイズ 32 がデフォルトで使用されます。KV キャッシュ量子化は次のように有効にできます。

model = OVModelForCausalLM.from_pretrained(
    model_path,
    ov_config={"KV_CACHE_PRECISION": "u8", "DYNAMIC_QUANTIZATION_GROUP_SIZE": "32", "PERFORMANCE_HINT": "LATENCY"}
)

現在、CPU デバイスでは動的量子化と KV キャッシュ量子化の両方を利用可能できます。

LoRA でチューニングされたモデルの操作

低ランク適応 (LoRA) は、生成 AI モデルを下流タスクまたはカスタムデータに合わせて調整する一般的な方法です。ただし、Hugging Face API を使用して効率的にデプロイするには、いくつかの追加手順が必要です。つまり、余分な計算を避けるため、トレーニングされたアダプターをベースライン・モデルに融合する必要があります。これは、大規模言語モデル (LLM) に対する適用方法です。

model_id = "meta-llama/Llama-2-7b-chat-hf"
lora_adaptor = "./lora_adaptor"

model = AutoModelForCausalLM.from_pretrained(model_id, use_cache=True)
model = PeftModelForCausalLM.from_pretrained(model, lora_adaptor)
model.merge_and_unload()
model.get_base_model().save_pretrained("fused_lora_model")

これで、前述の Optimum Intel Python API または CLI インターフェイスを使用してモデルを OpenVINO に変換できるようになりました。

ネイティブ OpenVINO API を使用した生成 AI モデルの実行

ネイティブ OpenVINO API を使用して生成 AI モデルを実行するには、簡略化された通常の変換 -> 最適化 -> デプロイ パスに従う必要があります。

Hugging Face モデルを変換するための推奨される方法は、Optimum-Intel エクスポート機能を使用することです。この機能により、変換 API やツールを直接呼び出すことなく、OpenVINO 形式でモデルをエクスポートできます。Optimum-Intel が必要な変換パラメーターを提供するため、変換プロセスは大幅に簡素化されます。これらのパラメーターは多くの場合モデル固有であり、さまざまなモデル入力プロパティーの知識が求められます。

さらに、Optimum-Intel は、重み圧縮やデフォルトでのステートフル形式の使用など、モデルのエクスポート・フローをさらに簡素化するモデル最適化を適用します。モデルが Hugging Face エコシステムの外部 (ソース・フレームワーク形式の PyTorch、TensorFlow など) から取得された場合でも、通常の変換パスを使用できます。

モデルの最適化は、Hugging Face 内で実行することも、重み圧縮ガイドで説明されているように NNCF を直接使用して実行することもできます。

ネイティブ API を使用する推論コードは、Hugging Face パイプラインの恩恵を受けられません。カスタムコードを記述するか、利用可能なサンプルからコードを流用する必要があります。以下は、一般的な生成 AI シナリオの例です。

  • テキスト生成 LLM では、トークン化、推論とトークンのサンプリング、およびトークン化解除を処理する必要があります。トークン・サンプリングにビーム検索が含まれる場合、それも実装する必要があります。これについては、C++ テキスト生成サンプルで詳しく説明されています。

  • 画像生成モデルでは、ソース (テキストなど) エンコーダー・モデルの推論、拡散プロセスの推論ループ、デコードの推論など、複数のモデル推論を含むパイプラインを作成する必要があります。スケジューラー・コードも必要です。Stable Diffusion の C++ 実装は、良い参照コードです。