ネイティブ OpenVINO で LLM 推論を実行 (非推奨)#
ネイティブ OpenVINO API を使用して生成 AI モデルを実行するには、簡略化された通常の変換 -> 最適化 -> デプロイ パスに従う必要があります。
Hugging Face からモデルを変換するには、トランスフォーメーション API とツールを直接呼び出さずに OpenVINO 形式でモデルをエクスポートできる Optimum-Intel エクスポート機能を使用できます。この場合、変換プロセスは少し簡素化されます。モデルが Hugging Face エコシステムの外部 (ソース・フレームワーク形式の PyTorch など) から取得された場合でも、通常の変換パスを使用できます。
モデルの最適化は、Hugging Face 内で実行することも、重み圧縮で説明されているように NNCF を直接使用して実行することもできます。
注
モデルを元の精度で維持するとパフォーマンスが大幅に低下する可能性があるため、4 ビット精度のモデルを使用することを推奨します。
ネイティブ API を使用する推論コードは、Hugging Face パイプラインの恩恵を受けられません。カスタムコードを記述するか、利用可能なサンプルからコードを流用する必要があります。以下は、一般的な生成 AI シナリオの例です:
テキスト生成 LLM では、トークン化、推論とトークン選択ループ、およびトークン解除を処理する必要があります。トークン選択にビーム検索が含まれる場合は、それも記述する必要があります。
画像生成モデルでは、ソース (テキストなど) エンコーダー・モデルの推論、拡散プロセスの推論ループ、デコードの推論など、複数のモデル推論を含むパイプラインを作成する必要があります。スケジューラー・コードも必要です。
このようなパイプラインを記述するには、OpenVINO で提供される例に従ってください:
推論を実行するには、最初に Hugging Face Optimum-Intel API を使用してモデルを OpenVINO IR 形式に変換する必要があります。
テキスト生成 LLM の推論パイプラインは、次のステージで設定されます:
OpenVINO IR でモデルを読み取ってコンパイルします。
トークナイザーを使用してテキストプロンプトを前処理し、結果をモデル入力として設定します。
トークン生成ループを実行します。
出力のトークン化解除します。
必要条件#
Linux* オペレーティング・システム (現在のバージョン)。
インストール
仮想環境の作成
python -m venv openvino_llm
openvino_llm
は例の名前です。環境に合わせて任意の名前を選択できます。仮想環境のアクティブ化
source openvino_llm/bin/activate
OpenVINO トークナイザーと依存関係をインストール
pip install optimum[openvino]
Hugging Face トークナイザーとモデルを OpenVINO IR 形式に変換#
トークナイザーを変換
OpenVINO トークナイザーには、Hugging Face Hub またはローカルに保存されたトークナイザーを OpenVINO IR 形式に変換する CLI ツールが装備されています:
convert_tokenizer microsoft/Llama2-7b-WhoIsHarryPotter --with-detokenizer -o openvino_tokenizer
この例では、microsoft/Llama2-7b-WhoIsHarryPotter tokenizer
トークナイザーが Hugging Face hub から変換されます。このトークナイザーを任意のトークナイザーに置き換えることもできます。出力ディレクトリー (openvino_tokenizer
) の名前を変更することもできます。
モデルの変換
optimum-cli コマンドを使用して、Hugging Face モデルを OpenVINO IR モデル形式に変換できます。詳細については、OpenVINO を使用した LLM のロードを参照してください。
optimum-cli export openvino --convert-tokenizer --model TinyLlama/TinyLlama-1.1B-Chat-v1.0 openvino_model
完全な OpenVINO テキスト生成パイプライン#
1. モデルのインポートとコンパイル#
前の手順で変換したモデルとトークナイザーを使用します:
import numpy as np
from openvino import compile_model
# OpenVINO を使用してトークナイザー、モデル、およびデトークナイザーをコンパイル。これらのファイルは OpenVINO 用に最適化されたモデルの XML 表現です
compiled_tokenizer = compile_model("openvino_tokenizer.xml")
compiled_model = compile_model("openvino_model.xml")
compiled_detokenizer = compile_model("openvino_detokenizer.xml")
2. 入力をトークン化して変換#
トークン化は、LLM を使用してテキストを生成するプロセスの必須のステップです。トークン化は、入力テキストをトークンのシーケンスに変換します。トークンは基本的に、モデルが理解して処理できる形式です。推論を実行する前に、入力テキスト文字列をトークン化し、モデルが想定する構造に設定する必要があります。
text_input = ["Quick brown fox was"]
ov_input = compiled_tokenizer(text_input)
3. トークンを生成#
テキスト生成のコアは推論とトークン選択のループにあります。このループの各反復で、モデルは入力シーケンスに対して推論を実行し、新しいトークンを生成して選択し、それを既存のシーケンスに追加します。
# 生成する新しいトークンの数を定義
new_tokens_size = 10
# 既存のプロンプトのサイズを決定
prompt_size = ov_input["input_ids"].shape[-1]
# モデルの入力辞書を準備
# 既存のトークンと新しいトークン用の追加スペースを組み合わせる
input_dict = {
output.any_name: np.hstack([tensor, np.zeros(shape=(1, new_tokens_size), dtype=np.int_)])
for output, tensor in ov_input.items()
}
# 新しいトークンを反復的に生成
for idx in range(prompt_size, prompt_size + new_tokens_size):
# モデルからの出力を取得
output = compiled_model(input_dict)["token_ids"]
# 新しく生成されたトークンで input_ids を更新
input_dict["input_ids"][:, idx] = output[:, idx - 1]
# 新しいトークンを含めるようにアノテーション・マスクを更新
input_dict["attention_mask"][:, idx] = 1
4. デコードと表示出力#
プロセスの最後のステップはトークン化解除です。ここでは、モデルによって生成されたトークン ID のシーケンスが、可読可能なテキストに変換されます。このステップは、モデルの出力を解釈するために不可欠です。
# 最終出力のトークン ID を抽出
ov_token_ids = input_dict["input_ids"]
# モデル出力を文字列にデコード
ov_output = compiled_detokenizer(ov_token_ids)["string_output"]
print(f"OpenVINO output string: `{ov_output}`")
# 出力例: ['<s> Quick brown fox was walking through the forest. He was looking for something']