このチュートリアルでは、変換モデルを Open Neural Network Exchange(ONNX)形式でエクスポートし、ONNX モデルを BigQuery データセットにインポートして、SQL クエリからエンベディングを生成する方法について説明します。
このチュートリアルでは、sentence-transformers/all-MiniLM-L6-v2 モデルを使用します。この文変換モデルは、文エンベディングの生成において高速かつ効果的なパフォーマンスを発揮することで知られています。文エンベディングは、テキストの根本的な意味を捉えることで、セマンティック検索、クラスタリング、文の類似性などのタスクを可能にします。
ONNX は、機械学習(ML)フレームワークを統一された形式で表現するためのフォーマットです。ONNX に対する BigQuery ML サポートにより、次のことが可能になります。
- 使い慣れたフレームワークを使用してモデルをトレーニングします。
- モデルを ONNX 形式に変換します。
- ONNX モデルを BigQuery にインポートし、BigQuery ML を使用して予測を行う。
トランスフォーマー モデルファイルを ONNX に変換する
必要に応じて、このセクションの手順に沿って、sentence-transformers/all-MiniLM-L6-v2 モデルとトークナイザーを ONNX に手動で変換できます。それ以外の場合は、すでに変換されている公開 gs://cloud-samples-data Cloud Storage バケットのサンプルファイルを使用できます。
ファイルを手動で変換する場合は、Python がインストールされたローカル コマンドライン環境が必要です。Python のインストールについて詳しくは、Python のダウンロードをご覧ください。
Transformer モデルを ONNX にエクスポートする
Hugging Face Optimum CLI を使用して、sentence-transformers/all-MiniLM-L6-v2 モデルを ONNX にエクスポートします。Optimum CLI を使用したモデルのエクスポートの詳細については、optimum.exporters.onnx を使用してモデルを ONNX にエクスポートするをご覧ください。
モデルをエクスポートするには、コマンドライン環境を開いて次の操作を行います。
- Optimum CLI をインストールします。 - pip install optimum[onnx]
- モデルをエクスポートします。 - --model引数で Hugging Face モデル ID を指定します。- --opset引数は ONNXRuntime ライブラリのバージョンを指定します。BigQuery でサポートされている ONNXRuntime ライブラリとの互換性を維持するために、- 17に設定されています。- optimum-cli export onnx \ --model sentence-transformers/all-MiniLM-L6-v2 \ --task sentence-similarity \ --opset 17 all-MiniLM-L6-v2/
モデルファイルは all-MiniLM-L6-v2 ディレクトリに model.onnx としてエクスポートされます。
Transformer モデルに量子化を適用する
Optimum CLI を使用して、エクスポートされた Transformer モデルに量子化を適用し、モデルサイズを縮小して推論を高速化します。詳細については、量子化をご覧ください。
モデルに量子化を適用するには、コマンドラインで次のコマンドを実行します。
optimum-cli onnxruntime quantize \
  --onnx_model all-MiniLM-L6-v2/ \
  --avx512_vnni -o all-MiniLM-L6-v2_quantized
量子化されたモデルファイルは、all-MiniLM-L6-v2_quantized ディレクトリに model_quantized.onnx としてエクスポートされます。
トークナイザーを ONNX に変換する
ONNX 形式の Transformer モデルを使用してエンベディングを生成するには、通常、トークナイザーを使用して、モデルへの 2 つの入力(input_ids と attention_mask)を生成します。
これらの入力を生成するには、onnxruntime-extensions ライブラリを使用して、sentence-transformers/all-MiniLM-L6-v2 モデルのトークナイザーを ONNX 形式に変換します。トークナイザーを変換すると、生のテキスト入力に対して直接トークン化を実行して、ONNX 予測を生成できます。
トークナイザーを変換するには、コマンドラインで次の操作を行います。
- Optimum CLI をインストールします。 - pip install optimum[onnx]
- 任意のテキスト エディタを使用して、 - convert-tokenizer.pyという名前のファイルを作成します。次の例では、nano テキスト エディタを使用しています。- nano convert-tokenizer.py
- 次の Python スクリプトをコピーして - convert-tokenizer.pyファイルに貼り付けます。- from onnxruntime_extensions import gen_processing_models # Load the Huggingface tokenizer tokenizer = AutoTokenizer.from_pretrained("sentence-transformers/all-MiniLM-L6-v2") # Export the tokenizer to ONNX using gen_processing_models onnx_tokenizer_path = "tokenizer.onnx" # Generate the tokenizer ONNX model, and set the maximum token length. # Ensure 'max_length' is set to a value less than the model's maximum sequence length, failing to do so will result in error during inference. tokenizer_onnx_model = gen_processing_models(tokenizer, pre_kwargs={'max_length': 256})[0] # Modify the tokenizer ONNX model signature. # This is because certain tokenizers don't support batch inference. tokenizer_onnx_model.graph.input[0].type.tensor_type.shape.dim[0].dim_value = 1 # Save the tokenizer ONNX model with open(onnx_tokenizer_path, "wb") as f: f.write(tokenizer_onnx_model.SerializeToString())
- convert-tokenizer.pyファイルを保存します。
- Python スクリプトを実行して、トークナイザーを変換します。 - python convert-tokenizer.py
変換されたトークナイザーは、all-MiniLM-L6-v2_quantized ディレクトリに tokenizer.onnx としてエクスポートされます。
変換したモデルファイルを Cloud Storage にアップロードする
変換モデルとトークナイザーを変換したら、次の操作を行います。
- 変換されたファイルを保存する Cloud Storage バケットを作成します。
- 変換された Transformer モデルとトークナイザー ファイルを Cloud Storage バケットにアップロードします。
データセットを作成する
ML モデルを保存する BigQuery データセットを作成します。
コンソール
- Google Cloud コンソールで、[BigQuery] ページに移動します。 
- [エクスプローラ] ペインで、プロジェクト名をクリックします。 
- [アクションを表示] > [データセットを作成] をクリックします。 
- [データセットを作成する] ページで、次の操作を行います。 - [データセット ID] に「 - bqml_tutorial」と入力します。
- [ロケーション タイプ] で [マルチリージョン] を選択してから、[US(米国の複数のリージョン)] を選択します。 
- 残りのデフォルトの設定は変更せず、[データセットを作成] をクリックします。 
 
bq
新しいデータセットを作成するには、--location フラグを指定した bq mk コマンドを使用します。使用可能なパラメータの一覧については、bq mk --dataset コマンドのリファレンスをご覧ください。
- データの場所が - USに設定され、- BigQuery ML tutorial datasetという説明の付いた、- bqml_tutorialという名前のデータセットを作成します。- bq --location=US mk -d \ --description "BigQuery ML tutorial dataset." \ bqml_tutorial - このコマンドでは、 - --datasetフラグの代わりに- -dショートカットを使用しています。- -dと- --datasetを省略した場合、このコマンドはデフォルトでデータセットを作成します。
- データセットが作成されたことを確認します。 - bq ls
API
定義済みのデータセット リソースを使用して datasets.insert メソッドを呼び出します。
{ "datasetReference": { "datasetId": "bqml_tutorial" } }
BigQuery DataFrames
このサンプルを試す前に、BigQuery DataFrames を使用した BigQuery クイックスタートの手順に沿って BigQuery DataFrames を設定してください。詳細については、BigQuery DataFrames のリファレンス ドキュメントをご覧ください。
BigQuery に対する認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の ADC の設定をご覧ください。
ONNX モデルを BigQuery にインポートする
変換されたトークナイザーと文変換モデルを BigQuery ML モデルとしてインポートします。
次のオプションのいずれかを選択します。
コンソール
- Google Cloud コンソールで、BigQuery Studio を開きます。 
- クエリエディタで次の - CREATE MODELステートメントを実行して、- tokenizerモデルを作成します。- CREATE OR REPLACE MODEL `bqml_tutorial.tokenizer` OPTIONS (MODEL_TYPE='ONNX', MODEL_PATH='TOKENIZER_BUCKET_PATH') - TOKENIZER_BUCKET_PATHは、Cloud Storage にアップロードしたモデルのパスに置き換えます。サンプルモデルを使用する場合は、- TOKENIZER_BUCKET_PATHを値- gs://cloud-samples-data/bigquery/ml/onnx/all-MiniLM-L6-v2/tokenizer.onnxに置き換えます。- オペレーションが完了すると、[クエリ結果] ペインに - Successfully created model named tokenizerのようなメッセージが表示されます。
- [モデルに移動] をクリックして、[詳細] ペインを開きます。 
- [特徴列] セクションでモデルの入力を確認し、[ラベル列] セクションでモデルの出力を確認します。 ![`tokenizer model の [**詳細**] ペイン](https://cloud.google.com/static/bigquery/images/tokenizer-details.png?hl=ja)  
- クエリエディタで次の - CREATE MODELステートメントを実行して、- all-MiniLM-L6-v2モデルを作成します。- CREATE OR REPLACE MODEL `bqml_tutorial.all-MiniLM-L6-v2` OPTIONS (MODEL_TYPE='ONNX', MODEL_PATH='TRANSFORMER_BUCKET_PATH') - TRANSFORMER_BUCKET_PATHは、Cloud Storage にアップロードしたモデルのパスに置き換えます。サンプルモデルを使用する場合は、- TRANSFORMER_BUCKET_PATHを値- gs://cloud-samples-data/bigquery/ml/onnx/all-MiniLM-L6-v2/model_quantized.onnxに置き換えます。- オペレーションが完了すると、[クエリ結果] ペインに - Successfully created model named all-MiniLM-L6-v2のようなメッセージが表示されます。
- [モデルに移動] をクリックして、[詳細] ペインを開きます。 
- [特徴列] セクションでモデルの入力を確認し、[ラベル列] セクションでモデルの出力を確認します。 ![`all-MiniLM-L6-v2` モデルの [**詳細**] ペイン](https://cloud.google.com/static/bigquery/images/sentence-transformer-model-details.png?hl=ja)  
bq
bq コマンドライン ツールの query コマンドを使用して、CREATE MODEL ステートメントを実行します。
- コマンドラインで、次のコマンドを実行して - tokenizerモデルを作成します。- bq query --use_legacy_sql=false \ "CREATE OR REPLACE MODEL `bqml_tutorial.tokenizer` OPTIONS (MODEL_TYPE='ONNX', MODEL_PATH='TOKENIZER_BUCKET_PATH')"- TOKENIZER_BUCKET_PATHは、Cloud Storage にアップロードしたモデルのパスに置き換えます。サンプルモデルを使用する場合は、- TOKENIZER_BUCKET_PATHを値- gs://cloud-samples-data/bigquery/ml/onnx/all-MiniLM-L6-v2/tokenizer.onnxに置き換えます。- 処理が完了すると、「 - Successfully created model named tokenizer」のようなメッセージが表示されます。
- コマンドラインで、次のコマンドを実行して - all-MiniLM-L6-v2モデルを作成します。- bq query --use_legacy_sql=false \ "CREATE OR REPLACE MODEL `bqml_tutorial.all-MiniLM-L6-v2` OPTIONS (MODEL_TYPE='ONNX', MODEL_PATH='TRANSFORMER_BUCKET_PATH')"- TRANSFORMER_BUCKET_PATHは、Cloud Storage にアップロードしたモデルのパスに置き換えます。サンプルモデルを使用する場合は、- TRANSFORMER_BUCKET_PATHを値- gs://cloud-samples-data/bigquery/ml/onnx/all-MiniLM-L6-v2/model_quantized.onnxに置き換えます。- 処理が完了すると、「 - Successfully created model named all-MiniLM-L6-v2」のようなメッセージが表示されます。
- モデルをインポートしたら、モデルがデータセットに表示されていることを確認します。 - bq ls -m bqml_tutorial - 出力は次のようになります。 - tableId Type ------------------------ tokenizer MODEL all-MiniLM-L6-v2 MODEL 
API
jobs.insert メソッドを使用してモデルをインポートします。リクエスト本文の QueryRequest リソースの query パラメータに CREATE MODEL ステートメントを入力します。
- 次の - queryパラメータ値を使用して、- tokenizerモデルを作成します。- { "query": "CREATE MODEL `PROJECT_ID :bqml_tutorial.tokenizer` OPTIONS(MODEL_TYPE='ONNX' MODEL_PATH='TOKENIZER_BUCKET_PATH')" }- 次のように置き換えます。 - PROJECT_ID: プロジェクト ID。
- TOKENIZER_BUCKET_PATHは、Cloud Storage にアップロードしたモデルのパスに置き換えます。サンプルモデルを使用する場合は、- TOKENIZER_BUCKET_PATHを値- gs://cloud-samples-data/bigquery/ml/onnx/all-MiniLM-L6-v2/tokenizer.onnxに置き換えます。
 
- 次の - queryパラメータ値を使用して、- all-MiniLM-L6-v2モデルを作成します。- { "query": "CREATE MODEL `PROJECT_ID :bqml_tutorial.all-MiniLM-L6-v2` OPTIONS(MODEL_TYPE='ONNX' MODEL_PATH='TRANSFORMER_BUCKET_PATH')" }- 次のように置き換えます。 - PROJECT_ID: プロジェクト ID。
- TRANSFORMER_BUCKET_PATHは、Cloud Storage にアップロードしたモデルのパスに置き換えます。サンプルモデルを使用している場合は、- TRANSFORMER_BUCKET_PATHを値- gs://cloud-samples-data/bigquery/ml/onnx/all-MiniLM-L6-v2/model_quantized.onnxに置き換えます。
 
BigQuery DataFrames
このサンプルを試す前に、BigQuery DataFrames を使用した BigQuery クイックスタートの手順に沿って BigQuery DataFrames を設定してください。詳細については、BigQuery DataFrames のリファレンス ドキュメントをご覧ください。
BigQuery に対する認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の ADC の設定をご覧ください。
ONNXModel オブジェクトを使用して、トークナイザー モデルと文変換モデルをインポートします。
import bigframes from bigframes.ml.imported import ONNXModel bigframes.options.bigquery.project = PROJECT_ID bigframes.options.bigquery.location = "US" tokenizer = ONNXModel( model_path= "TOKENIZER_BUCKET_PATH" ) imported_onnx_model = ONNXModel( model_path="TRANSFORMER_BUCKET_PATH" )
次のように置き換えます。
- PROJECT_ID: プロジェクト ID。
- TOKENIZER_BUCKET_PATHは、Cloud Storage にアップロードしたモデルのパスに置き換えます。サンプルモデルを使用する場合は、- TOKENIZER_BUCKET_PATHを値- gs://cloud-samples-data/bigquery/ml/onnx/all-MiniLM-L6-v2/tokenizer.onnxに置き換えます。
- TRANSFORMER_BUCKET_PATHは、Cloud Storage にアップロードしたモデルのパスに置き換えます。サンプルモデルを使用している場合は、- TRANSFORMER_BUCKET_PATHを値- gs://cloud-samples-data/bigquery/ml/onnx/all-MiniLM-L6-v2/model_quantized.onnxに置き換えます。
インポートした ONNX モデルを使用してエンベディングを生成する
インポートしたトークナイザーと文変換モデルを使用して、bigquery-public-data.imdb.reviews 一般公開データセットのデータに基づいてエンベディングを生成します。
次のオプションのいずれかを選択します。
コンソール
ML.PREDICT 関数を使用して、モデルでエンベディングを生成します。
このクエリでは、ネストされた ML.PREDICT 呼び出しを使用して、次のとおりトークナイザーとエンベディング モデルを介して未加工のテキストを直接処理します。
- トークン化(内部クエリ): 内部 ML.PREDICT呼び出しでbqml_tutorial.tokenizerモデルが使用されます。bigquery-public-data.imdb.reviews一般公開データセットのtitle列をtext入力として使用します。tokenizerモデルは、input_ids入力やattention_mask入力など、メインモデルが必要とする数値トークン入力に未加工のテキスト文字列を変換します。
- エンベディング生成(外部クエリ): 外部 ML.PREDICT呼び出しでbqml_tutorial.all-MiniLM-L6-v2モデルを使用します。このクエリは、内部クエリの出力からinput_ids列とattention_mask列を入力として取得します。
SELECT ステートメントは、テキストのセマンティック エンベディングを表す FLOAT 値の配列である sentence_embedding 列を取得します。
- Google Cloud コンソールで、BigQuery Studio を開きます。 
- クエリエディタで、次のクエリを実行します。 - SELECT sentence_embedding FROM ML.PREDICT (MODEL `bqml_tutorial.all-MiniLM-L6-v2`, ( SELECT input_ids, attention_mask FROM ML.PREDICT(MODEL `bqml_tutorial.tokenizer`, ( SELECT title AS text FROM `bigquery-public-data.imdb.reviews` limit 10)))) - 次のような結果になります。 - +-----------------------+ | sentence_embedding | +-----------------------+ | -0.02361682802438736 | | 0.02025664784014225 | | 0.005168713629245758 | | -0.026361213997006416 | | 0.0655381828546524 | | ... | +-----------------------+ 
bq
bq コマンドライン ツールの query コマンドを使用して、クエリを実行します。このクエリは、ML.PREDICT 関数を使用して、モデルでエンベディングを生成します。
このクエリでは、ネストされた ML.PREDICT 呼び出しを使用して、次のとおりトークナイザーとエンベディング モデルを介して未加工のテキストを直接処理します。
- トークン化(内部クエリ): 内部 ML.PREDICT呼び出しでbqml_tutorial.tokenizerモデルが使用されます。bigquery-public-data.imdb.reviews一般公開データセットのtitle列をtext入力として使用します。tokenizerモデルは、input_ids入力やattention_mask入力など、メインモデルが必要とする数値トークン入力に未加工のテキスト文字列を変換します。
- エンベディング生成(外部クエリ): 外部 ML.PREDICT呼び出しでbqml_tutorial.all-MiniLM-L6-v2モデルを使用します。このクエリは、内部クエリの出力からinput_ids列とattention_mask列を入力として取得します。
SELECT ステートメントは、テキストのセマンティック エンベディングを表す FLOAT 値の配列である sentence_embedding 列を取得します。
コマンドラインで、次のコマンドを実行してクエリを実行します。
bq query --use_legacy_sql=false \ 'SELECT sentence_embedding FROM ML.PREDICT (MODEL `bqml_tutorial.all-MiniLM-L6-v2`, ( SELECT input_ids, attention_mask FROM ML.PREDICT(MODEL `bqml_tutorial.tokenizer`, ( SELECT title AS text FROM `bigquery-public-data.imdb.reviews` limit 10))))'
次のような結果になります。
+-----------------------+ | sentence_embedding | +-----------------------+ | -0.02361682802438736 | | 0.02025664784014225 | | 0.005168713629245758 | | -0.026361213997006416 | | 0.0655381828546524 | | ... | +-----------------------+
BigQuery DataFrames
このサンプルを試す前に、BigQuery DataFrames を使用した BigQuery クイックスタートの手順に沿って BigQuery DataFrames を設定してください。詳細については、BigQuery DataFrames のリファレンス ドキュメントをご覧ください。
BigQuery に対する認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の ADC の設定をご覧ください。
predict メソッドを使用して、ONNX モデルでエンベディングを生成します。
import bigframes.pandas as bpd
df = bpd.read_gbq("bigquery-public-data.imdb.reviews", max_results=10)
df_pred = df.rename(columns={"title": "text"})
tokens = tokenizer.predict(df_pred)
predictions = imported_onnx_model.predict(tokens)
predictions.peek(5)
出力は次のようになります。
