Hugging Face と Optimum Intel で LLM を実行#

以下の手順は、Optimum Intel を使用して Hugging Face から LLM をロードして推論する方法を示しています。また、モデルを OpenVINO IR 形式に変換して、NNCF で最適化し、他の OpenVINO ツールで使用する方法も示します。

必要条件#

  • OpenVINO PIP のインストールページの指示に従って、Python 環境を作成します。

  • Optimum Intel に必要な依存関係をインストールします:

pip install optimum[openvino,nncf]

Optimum Intel に Hugging Face モデルをロード#

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)

Hugging Face Transformers ライブラリーの AutoModelForCasualLM を使用する代わりに、optimal.intel ライブラリーの OVModelForCasualLM に切り替えます。この変更により、OpenVINO の最適化機能を使用できるようになります。このガイドでは CausalLM に注目しますが、OVModelForSeq2SeqLM などの他の AutoModel タイプを使用することもできます。

export=True パラメーターを設定すると、モデルはすぐに OpenVINO IR 形式に変換されます。

効率を高めるため、変換後に save_pretrained() を使用してモデルをディスクに保存し、デプロイメント時に from_pretrained() を使用してディスクからロードすることを推奨します。

model.save_pretrained("ov_model")

これにより、OpenVINO IR 形式の LLM を含む ov_model という新しいフォルダーが作成されます。フォルダーを変更して、ov_model の代わりに別のモデル・ディレクトリーを提供することもできます。

モデルを保存したら、次のコマンドで読み込むことができます:

model = OVModelForCausalLM.from_pretrained("ov_model")

Hugging Face モデルを OpenVINO IR に変換#

optimum-cli ツールを使用すると、Hugging Face のモデルを OpenVINO IR 形式に変換できます:

optimum-cli export openvino --model <MODEL_NAME> <NEW_MODEL_NAME>

Hugging Face の Llama 2 モデルを OpenVINO IR モデルに変換し、ov_llama_2 という名前を付ける場合、コマンドは次のようになります:

optimum-cli export openvino --model meta-llama/Llama-2-7b-chat-hf ov_llama_2

この場合、変換されたモデルを OpenVINO 表現でディスクから直接ロードできます:

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

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

optimum-cli export openvino --model meta-llama/Llama-2-7b-chat-hf --weight-format int8 ov_llama_2
model = OVModelForCausalLM.from_pretrained(model_id, export=True, load_in_8bit=True) 

# またはモデルがすでに変換されている場合 
model = OVModelForCausalLM.from_pretrained(model_path, load_in_8bit=True) 

# 最適化後にモデルを保存 
model.save_pretrained(optimized_model_path)

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

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

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

optimum-cli export openvino --model meta-llama/Llama-2-7b-chat-hf --weight-format int4 ov_llama_2
from optimum.intel import OVModelForCausalLM, OVWeightQuantizationConfig 
import nncf 

model = OVModelForCausalLM.from_pretrained( 
    model_id, 
    export=True, 
    quantization_config=OVWeightQuantizationConfig(bits=4), 
) 

# またはモデルがすでに変換されている場合 
model = OVModelForCausalLM.from_pretrained( 
    model_path, 
    quantization_config=OVWeightQuantizationConfig(bits=4), 
) 

# 重み量子化にカスタム・パラメーターを使用 
model = OVModelForCausalLM.from_pretrained( 
    model_path, 
    quantization_config=OVWeightQuantizationConfig(bits=4, asym=True, ratio=0.8, dataset="ptb"), 
) 

# 最適化後にモデルを保存 
model.save_pretrained(optimized_model_path)

Optimum-Intel には、meta-llama/Llama-2-7bQwen/Qwen-7B-Chat などの一般的なモデル用の重み量子化パラメーターのセットが事前定義されています。これらのパラメーターは、設定で bits=4 が指定されている場合にのみデフォルトで使用されます。

圧縮オプションの詳細については、重み圧縮ガイドを参照してください。

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

以下は、モデルの変換と推論にインテルによる適用を使用する例です:

Optimum-Intel は他の生成 AI モデルにも使用できます。その他の例については、Optimum-Intel OpenVINO を使用した Stable Diffusion v2.1 および Stable Diffusion XL と OpenVINO を使用したイメージ生成を参照してください。

推論の例#

Hugging Face モデルの場合、AutoTokenizerpipeline 関数を使用して推論パイプラインを作成します。この設定により、テキスト処理とモデルの対話が簡単になります:

from optimum.intel import OVModelForCausalLM 
# 推論向けの新しいインポート 
from transformers import AutoTokenizer 
# モデルをロード 
model_id = "meta-llama/Llama-2-7b-chat-hf" 
model = OVModelForCausalLM.from_pretrained(model_id, export=True) 
# 推論 
prompt = "The weather is:" 
tokenizer = AutoTokenizer.from_pretrained(model_id) 
inputs = tokenizer(prompt, return_tensors="pt") 
outputs = model.generate(**inputs, max_new_tokens=50) 
print(tokenizer.decode(outputs[0], skip_special_tokens=True))

毎回 LLM をオンザフライで OpenVINO IR に変換するタスクは、リソースを大量に消費します。モデルを一度変換し、フォルダーに保存して、推論時に読み込むことを推奨します。

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

model.to("GPU")

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 キャッシュは次の精度に量子化できます: u8bf16f16u8 が使用される場合、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")

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

関連情報#