OpenVINO トークナイザー#

トークン化は、LLM によるテキスト生成を含む各種モデルを使用したテキスト処理に必要なステップです。トークナイザーは、入力テキストを対応する ID を持つトークンのシーケンスに変換し、モデルが推論中にそれを理解して処理できるようにします。一連の数字を文字列に変換することをデトークン化と呼びます。

../../_images/tokenization.svg

トークナイザーとモデルの関係には、2 つの重要なポイントがあります:

  • テキスト入力を伴うすべてのモデルはトークナイザーとペアになっており、トークナイザーなしでは使用できません。

  • 特定のタスクでモデルの精度を再現するには、モデルのトレーニング中に使用されたものと同じトークナイザーを使用することが不可欠です。

OpenVINO トークナイザーは、トークナイザー変換を効率化してプロジェクトにシームレスに統合できるように設計された OpenVINO 拡張機能および Python ライブラリーです。OpenVINO トークナイザーを使用すると、次のことが可能になります:

  • OpenVINO にテキスト処理操作を追加します。トークナイザーとデトークナイザーはどちらも OpenVINO モデルであるため、読み取り、コンパイル、保存などの操作を他のモデルと同様に行うことができます。

  • サードパーティーに依存せずトークン化とデトークン化を実行します。

  • さまざまな環境で効率的にデプロイできるように、Hugging Face トークナイザーを OpenVINO トークナイザーおよびデトークナイザーに変換します。詳細については 変換の例を参照してください。

  • OpenVINO モデルを単一モデルに結合します。分類子や RAG エンベッダーなど、各パイプライン推論でトークナイザーとモデルの両方が 1 度使用される特定のモデルに推奨されます。詳細は、OpenVINO トークナイザーのノートブックを参照してください。

  • テキスト生成モデルに貪欲な (greedy) デコード・パイプラインを追加します。

  • TensorFlow Text MUSE モデルなどの TensorFlow モデルを使用します。詳細な手順については、MUSE モデル推論の例を参照してください。TensorFlow 統合では、StringSplit、StaticRexexpReplace、StringLower などの文字列テンソル操作を実行するため追加の変換拡張機能が必要になることに注意してください。

OpenVINO トークナイザーは CPU デバイス上でのみ推論できます。

サポートされるトークナイザー#

Hugging Face トークナイザー・タイプ

トークナイザー・モデル・タイプ

トークナイザー

デトークナイザー

高速

WordPiece

はい

いいえ

BPE

はい

はい

Unigram

いいえ

いいえ

レガシー

SentencePiece.model

はい

はい

カスタム

tiktoken

はい

はい

RWKV

Trie

はい

はい

変換されたトークナイザーと元のトークナイザーの出力は異なる場合があり、特定のタスクでモデルの精度が低下または向上する可能性があります。これらの変更を軽減するためにプロンプトを変更することができます。OpenVINO トークナイザー・リポジトリーでは、元のトークナイザー/デトークナイザーと変換されたトークナイザー/デトークナイザーの出力が一致するテストのパーセンテージを確認できます。

Python* のインストール#

  1. 仮想環境を作成してアクティブ化します。

    python3 -m venv venv 
    
    source venv/bin/activate
  2. OpenVINO トークナイザーをインストールします。

    インストールのオプションには、変換された OpenVINO トークナイザーの使用、Hugging Face トークナイザーの OpenVINO トークナイザーへの変換、最新の変更を試すプレリリース・バージョンのインストール、ソースからのビルドとインストールなどがあります。Conda ディストリビューションを使用して OpenVINO トークナイザーをインストールすることもできます。詳細については、OpenVINO トークナイザー・リポジトリーを参照してください。

    pip install openvino-tokenizers
    pip install openvino-tokenizers[transformers]
    pip install --pre -U openvino openvino-tokenizers --extra-index-url https://storage.openvinotoolkit.org/simple/wheels/nightly
    source path/to/installed/openvino/setupvars.sh 
    
          git clone https://github.com/openvinotoolkit/openvino_tokenizers.git 
    
    cd openvino_tokenizers 
    
    pip install --no-deps .

C++ インストール#

変換されたトークナイザーは、ビルド済みのバイナリーを使用して C++ パイプラインで使用できます。

  1. 使用する OS 用の OpenVINO アーカイブ・ディストリビューションをダウンロードし、アーカイブを抽出します。

  2. OpenVINO トークナイザーの事前ビルド・ライブラリーをダウンロードします。互換性を維持するには、OpenVINO トークナイザーのバージョンの最初の 3 つの数字が OpenVINO バージョンおよび OS と一致する必要があります。

  3. OpenVINO トークナイザーのアーカイブを OpenVINO のインストール・ディレクトリーに抽出します:

    <openvino_dir>/runtime/lib/intel64/
    <openvino_dir>/runtime/lib/aarch64/
    <openvino_dir>\runtime\bin\intel64\Release\
    <openvino_dir>/runtime/lib/intel64/Release
    <openvino_dir>/runtime/lib/arm64/Release/

    その後、コードにバイナリー拡張子を追加できます:

    core.add_extension("libopenvino_tokenizers.so")
    core.add_extension("openvino_tokenizers.dll")
    core.add_extension("libopenvino_tokenizers.dylib")

    2023.3.0.0 バージョンを使用する場合、バイナリー拡張ファイルは (lib)user_ov_extension.(dll/dylib/so) になります。

変換されたモデルを読み取ってコンパイルする方法は、モデル準備ガイドを参照してください。

トークナイザーの使い方#

1. トークナイザーを OpenVINO 中間表現 (IR) に変換#

トークナイザーにバンドルされている CLI ツールまたは Python API を使用して、Hugging Face トークナイザーを IR に変換できます。変換された OpenVINO トークナイザーがある場合は、この手順をスキップしてください。

依存関係があるコンポーネントをインストールします:

pip install openvino-tokenizers[transformers]

トークナイザーを変換:

!convert_tokenizer $model_id --with-detokenizer -o tokenizer

トークナイザーを使用するには変換されたモデルをコンパイルします:

from pathlib import Path 
import openvino_tokenizers 
from openvino import Core 

tokenizer_dir = Path("tokenizer/") 
core = Core() 
ov_tokenizer = core.read_model(tokenizer_dir / "openvino_tokenizer") 
ov_detokenizer = core.read_model(tokenizer_dir / "openvino_detokenizer") 

tokenizer, detokenizer = 
core.compile_model(ov_tokenizer), core.compile_model(ov_detokenizer)
from transformers import AutoTokenizer 
from openvino_tokenizers import convert_tokenizer 

hf_tokenizer = AutoTokenizer.from_pretrained(model_id) 
ov_tokenizer, ov_detokenizer = convert_tokenizer(hf_tokenizer, with_detokenizer=True)

変換されたトークナイザーを後で再利用するには、save_model を使用します:

from pathlib import Path 
from openvino import save_model 

tokenizer_dir = Path("tokenizer/") 
save_model(ov_tokenizer, tokenizer_dir / "openvino_tokenizer.xml") 
save_model(ov_detokenizer, tokenizer_dir / "openvino_detokenizer.xml")

トークナイザーを使用するには変換されたモデルをコンパイルします:

from openvino import compile_model 

tokenizer, detokenizer = compile_model(ov_tokenizer), compile_model(ov_detokenizer)

結果として、2 つの OpenVINO モデルが作成されます: ov_tokenizerov_detokenizer。詳細情報とコードについては、OpenVINO トークナイザーのノートブックをご覧ください。

2. 入力をトークナイズして準備#

input numpy as np 

text_input = ["Quick brown fox jumped"] 

model_input = {name.any_name: output for name, output in 
tokenizer(text_input).items()} 

if "position_ids" in (input.any_name for input in infer_request.model_inputs): 
   model_input["position_ids"] = np.arange(model_input["input_ids"].shape[1], 
dtype=np.int64)[np.newaxis, :]
# ビームサーチなし、idx を 0 に設定 
model_input["beam_idx"] = np.array([0], dtype=np.int32) 
# 文末トークンは、モデルがテキスト生成の終了を示す場所です 
# トークナイザー/デトークナイザー ov.Model オブジェクトの rt_info から EOS トークン ID を読み取ります 
eos_token = ov_tokenizer.get_rt_info(EOS_TOKEN_ID_NAME).value

3. テキストを生成#

tokens_result = np.array([[]], dtype=np.int64) 

# 推論前にモデル内の KV キャッシュをリセット 
infer_request.reset_state() 
max_infer = 10 

for _ in range(max_infer): 
    infer_request.start_async(model_input) 
    infer_request.wait() 

    # 最初の推論で最後のトークンの予測を取得 
    output_token = infer_request.get_output_tensor().data[:, -1:] 
    tokens_result = np.hstack((tokens_result, output_token)) 
    if output_token[0, 0] == eos_token: 
        break 

    # 新しい推論の入力を準備 
    model_input["input_ids"] = output_token 
    model_input["attention_mask"] = np.hstack((model_input["attention_mask"].data, [[1]])) 
    model_input["position_ids"] = np.hstack( 
        (model_input["position_ids"].data, [[model_input["position_ids"].data.shape[-1]]]) 
    )

4. デトークナイズの出力#

text_result = detokenizer(tokens_result)["string_output"] 
print(f"Prompt:\n{text_input[0]}") 
print(f"Generated:\n{text_result[0]}")

関連情報#