本教程介绍了如何将 Transformer 模型导出为开放神经网络交换 (ONNX) 格式,将 ONNX 模型导入 BigQuery 数据集,然后使用该模型通过 SQL 查询生成嵌入。
本教程使用 sentence-transformers/all-MiniLM-L6-v2
模型。此句子转换器模型以其在生成句子嵌入方面的快速高效而闻名。句子嵌入通过捕获文本的潜在含义,实现语义搜索、聚类和句子相似性等任务。
ONNX 提供了一种用于表示任何机器学习 (ML) 框架的统一格式。BigQuery ML 对 ONNX 的支持让您可以执行以下操作:
- 使用您偏好的框架训练模型。
- 将模型转换为 ONNX 模型格式。
- 将 ONNX 模型导入 BigQuery 并使用 BigQuery ML 进行预测。
将 Transformer 模型文件转换为 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 库版本,并设置为17
以保持与 BigQuery 支持的 ONNXRuntime 库的兼容性。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 模型生成嵌入,您通常会使用分词器生成模型的两个输入,即 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
转换 Transformer 模型和分词器后,请执行以下操作:
创建数据集
创建 BigQuery 数据集以存储机器学习模型。
控制台
在 Google Cloud 控制台中,前往 BigQuery 页面。
在探索器窗格中,点击您的项目名称。
点击
查看操作 > 创建数据集在 创建数据集 页面上,执行以下操作:
在数据集 ID 部分,输入
bqml_tutorial
。在位置类型部分,选择多区域,然后选择 US (multiple regions in United States)(美国[美国的多个区域])。
保持其余默认设置不变,然后点击创建数据集。
bq
如需创建新数据集,请使用带有 --location
标志的 bq mk
命令。 如需查看完整的潜在参数列表,请参阅 bq mk --dataset
命令参考文档。
创建一个名为
bqml_tutorial
的数据集,并将数据位置设置为US
,说明为BigQuery ML tutorial dataset
: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 DataFrame
在尝试此示例之前,请按照《BigQuery 快速入门:使用 BigQuery DataFrames》中的 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
。点击前往模型以打开详细信息窗格。
查看特征列部分可了解模型输入,查看标签列可了解模型输出。
在查询编辑器中,运行以下
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
。点击前往模型以打开详细信息窗格。
查看特征列部分可了解模型输入,查看标签列可了解模型输出。
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
方法导入模型。在请求正文中,使用 CREATE MODEL
语句填充 QueryRequest
资源的 query
参数。
使用以下
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 DataFrame
在尝试此示例之前,请按照《BigQuery 快速入门:使用 BigQuery DataFrames》中的 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
语句会检索 sentence_embedding
列,该列是一个 FLOAT
值数组,表示文本的语义嵌入。
在 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
语句会检索 sentence_embedding
列,该列是一个 FLOAT
值数组,表示文本的语义嵌入。
在命令行中,运行以下命令以运行查询。
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 DataFrame
在尝试此示例之前,请按照《BigQuery 快速入门:使用 BigQuery DataFrames》中的 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)
输出类似于以下内容: