使用 ONNX 格式的 PyTorch 模型进行预测


开放神经网络交换 (ONNX) 提供了一种用于表示任何机器学习框架的统一格式。BigQuery ML 对 ONNX 的支持让您可以:

  • 使用您偏好的框架训练模型。
  • 将模型转换为 ONNX 模型格式。
  • 将 ONNX 模型导入 BigQuery 并使用 BigQuery ML 进行预测。

本教程介绍了如何将使用 PyTorch 训练的 ONNX 模型导入 BigQuery 数据集,并使用这些模型通过 SQL 查询进行预测。

目标

费用

在本文档中,您将使用 Google Cloud 的以下收费组件:

您可使用价格计算器根据您的预计使用情况来估算费用。 Google Cloud 新用户可能有资格申请免费试用

完成本文档中描述的任务后,您可以通过删除所创建的资源来避免继续计费。如需了解详情,请参阅清理

准备工作

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  3. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  4. Make sure that billing is enabled for your Google Cloud project.

  5. Enable the BigQuery, BigQuery Connection, and Cloud Storage APIs.

    Enable the APIs

  6. 确保您拥有必要的权限,以便执行本文档中的任务。

所需的角色

如果您创建新项目,则您是该项目的所有者,并且会获得完成本教程所需的所有 Identity and Access Management (IAM) 权限。

如果您要使用现有项目,请执行以下操作。

Make sure that you have the following role or roles on the project:

Check for the roles

  1. In the Google Cloud console, go to the IAM page.

    Go to IAM
  2. Select the project.
  3. In the Principal column, find all rows that identify you or a group that you're included in. To learn which groups you're included in, contact your administrator.

  4. For all rows that specify or include you, check the Role column to see whether the list of roles includes the required roles.

Grant the roles

  1. In the Google Cloud console, go to the IAM page.

    进入 IAM
  2. 选择项目。
  3. 点击 授予访问权限
  4. 新的主账号字段中,输入您的用户标识符。 这通常是 Google 账号的电子邮件地址。

  5. 选择角色列表中,选择一个角色。
  6. 如需授予其他角色,请点击 添加其他角色,然后添加其他各个角色。
  7. 点击 Save(保存)。
  8. 如需详细了解 BigQuery 中的 IAM 权限,请参阅 IAM 权限

可选:训练模型并将其转换为 ONNX 格式

以下代码示例展示了如何将预训练分类模型导入 PyTorch,以及如何将生成的模型转换为 ONNX 格式。本教程使用存储在 gs://cloud-samples-data/bigquery/ml/onnx/resnet18.onnx 的预构建示例模型。如果您使用的是示例模型,则无需完成这些步骤。

创建用于图片分类的 PyTorch 视觉模型

使用以下代码示例导入 PyTorch 预训练的 resnet18 模型,以接受 BigQuery ML ML.DECODE_IMAGEML.RESIZE_IMAGE 函数返回的解码图片数据。

import torch
import torch.nn as nn

# Define model input format to match the output format of
# ML.DECODE_IMAGE function: [height, width, channels]
dummy_input = torch.randn(1, 224, 224, 3, device="cpu")

# Load a pretrained pytorch model for image classification
model = torch.hub.load('pytorch/vision:v0.10.0', 'resnet18', pretrained=True)

# Reshape input format from [batch_size, height, width, channels]
# to [batch_size, channels, height, width]
class ReshapeLayer(nn.Module):
    def __init__(self):
        super().__init__()

    def forward(self, x):
        x = x.permute(0, 3, 1, 2)  # reorder dimensions
        return x

class ArgMaxLayer(nn.Module):
    def __init__(self):
        super().__init__()

    def forward(self, x):
       return torch.argmax(x, dim=1)

final_model = nn.Sequential(
    ReshapeLayer(),
    model,
    nn.Softmax(),
    ArgMaxLayer()
)

将模型转换为 ONNX 格式

使用以下示例通过 torch.onnx 导出 PyTorch 视觉模型。导出的 ONNX 文件名为 resnet18.onnx

torch.onnx.export(final_model,            # model being run
                  dummy_input,            # model input
                  "resnet18.onnx",        # where to save the model
                  opset_version=10,       # the ONNX version to export the model to
                  input_names = ['input'],         # the model's input names
                  output_names = ['class_label'])  # the model's output names

将 ONNX 模型上传到 Cloud Storage

保存模型后,请执行以下操作:

创建数据集

创建 BigQuery 数据集以存储机器学习模型。

控制台

  1. 在 Google Cloud 控制台中,转到 BigQuery 页面。

    转到 BigQuery 页面

  2. 探索器窗格中,点击您的项目名称。

  3. 点击 查看操作 > 创建数据集

    “创建数据集”菜单选项。

  4. 创建数据集 页面上,执行以下操作:

    • 数据集 ID 部分,输入 bqml_tutorial

    • 位置类型部分,选择多区域,然后选择 US (multiple regions in United States)(美国[美国的多个区域])。

    公共数据集存储在 US 多区域中。为简单起见,请将数据集存储在同一位置。

    • 保持其余默认设置不变,然后点击创建数据集

    填充了值的“创建数据集”页面。

bq

如需创建新数据集,请使用带有 --location 标志的 bq mk 命令。 如需查看完整的潜在参数列表,请参阅 bq mk --dataset 命令参考文档。

  1. 创建一个名为 bqml_tutorial 的数据集,并将数据位置设置为 US,说明为 BigQuery ML tutorial dataset

    bq --location=US mk -d \
     --description "BigQuery ML tutorial dataset." \
     bqml_tutorial

    该命令使用的不是 --dataset 标志,而是 -d 快捷方式。如果省略 -d--dataset,该命令会默认创建一个数据集。

  2. 确认已创建数据集:

    bq ls

API

使用已定义的数据集资源调用 datasets.insert 方法。

{
  "datasetReference": {
     "datasetId": "bqml_tutorial"
  }
}

将 ONNX 模型导入 BigQuery

以下步骤介绍了如何使用 CREATE MODEL 语句将示例 ONNX 模型从 Cloud Storage 导入到数据集中。

控制台

  1. 在 Google Cloud 控制台中,转到 BigQuery Studio 页面。

    进入 BigQuery Studio

  2. 在查询编辑器中,输入以下 CREATE MODEL 语句:

    CREATE OR REPLACE MODEL `bqml_tutorial.imported_onnx_model`
     OPTIONS (MODEL_TYPE='ONNX',
      MODEL_PATH='BUCKET_PATH')

    BUCKET_PATH 替换为您上传到 Cloud Storage 的模型的路径。如果您使用的是示例模型,请将 BUCKET_PATH 替换为以下值:gs://cloud-samples-data/bigquery/ml/onnx/resnet18.onnx

    操作完成后,您会看到类似于以下内容的消息:Successfully created model named imported_onnx_model

    您的新模型会显示在资源面板中。模型由模型图标表示:“资源”面板中的模型图标。 如果您在资源面板中选择新模型,则模型相关信息会显示在查询编辑器旁边。

    “imported_onnx_model”的信息面板

bq

  1. 通过输入以下 CREATE MODEL 语句,从 Cloud Storage 导入 ONNX 模型。

    bq query --use_legacy_sql=false \
    "CREATE OR REPLACE MODEL
      `bqml_tutorial.imported_onnx_model`
    OPTIONS
      (MODEL_TYPE='ONNX',
       MODEL_PATH='BUCKET_PATH')"

    BUCKET_PATH 替换为您上传到 Cloud Storage 的模型的路径。如果您使用的是示例模型,请将 BUCKET_PATH 替换为以下值:gs://cloud-samples-data/bigquery/ml/onnx/resnet18.onnx

  2. 导入模型后,请验证该模型是否显示在数据集中。

    bq ls bqml_tutorial

    输出内容类似如下:

    tableId               Type
    --------------------- -------
    imported_onnx_model  MODEL

如需详细了解如何将 ONNX 模型导入 BigQuery,包括格式和存储要求,请参阅用于导入 ONNX 模型的 CREATE MODEL 语句

在 BigQuery 中创建对象表以分析图片数据

对象表是位于 Cloud Storage 中的非结构化数据对象上的只读表。借助对象表,您可以分析 BigQuery 中的非结构化数据。

在本教程中,您将使用 ML.PREDICT 函数输出存储在 Cloud Storage 存储桶中的输入图片的预测类别标签。

创建对象表需要您执行以下操作:

  • 创建一个 Cloud Storage 存储桶,并上传一张金鱼的图片。
  • 创建用于访问对象表的 Cloud 资源连接。
  • 向资源连接的服务账号授予访问权限。

创建存储桶并上传图片

请按照以下步骤创建 Cloud Storage 存储桶并上传金鱼图片。

控制台

  1. 在 Google Cloud 控制台中,进入 Cloud Storage 存储桶页面。

    进入“存储桶”

  2. 点击 创建

  3. 创建存储分区页面上,输入您的存储分区信息。

    1. 开始使用部分中,执行以下操作:

      1. 在框中输入 bqml_images

      2. 点击继续

    2. 选择数据存储位置部分中,执行以下操作:

      1. 对于位置类型,请选择多区域

      2. 从位置类型菜单中,选择美国(美国的多个区域)

      3. 点击继续

    3. 选择数据的存储类别部分中:

      1. 选择设置默认类别

      2. 选择标准

      3. 点击继续

    4. 在其余部分中,保留默认值。

  4. 点击创建

命令行

输入以下 gcloud storage buckets create 命令:

gcloud storage buckets create gs://bqml_images --location=us

如果请求成功,该命令将返回以下消息:

Creating gs://bqml_images/...

将一张图片上传到您的图片 Cloud Storage 存储桶

创建存储桶后,下载金鱼的图片,然后将其上传到 Cloud Storage 存储桶。

如需上传该图片,请完成以下步骤:

控制台

  1. 在 Google Cloud 控制台中,进入 Cloud Storage 存储桶页面。

    进入“存储桶”

  2. 在存储桶列表中,点击 bqml_images

  3. 在存储桶的对象标签页中,执行以下任一操作:

    • 将文件从桌面或文件管理器拖动到 Google Cloud 控制台的主窗格中。

    • 点击上传 > 上传文件,在随即显示的对话框中选择要上传的图片文件,然后点击打开

命令行

输入以下 gcloud storage cp 命令:

gcloud storage cp OBJECT_LOCATION gs://bqml_images/IMAGE_NAME

替换以下内容:

  • OBJECT_LOCATION:图片文件的本地路径。例如 Desktop/goldfish.jpg
  • IMAGE_NAME:映像的名称。 例如 goldfish.jpg

如果成功,响应类似于以下示例:

Completed files 1/1 | 164.3kiB/164.3kiB

创建 BigQuery Cloud 资源连接

您必须具有 Cloud 资源连接才能连接到本教程后面部分创建的对象表

借助云资源连接,您可以查询存储在 BigQuery 以外的 Google Cloud Cloud Storage 或 Spanner 等服务中的数据或第三方来源(如 AWS 或 Azure)中的数据。这些外部连接使用 BigQuery Connection API。

请按照以下步骤创建 Cloud 资源连接。

控制台

  1. 转到 BigQuery Studio 页面。

    进入 BigQuery Studio

  2. 如需创建连接,请点击 添加,然后点击与外部数据源的连接

  3. 连接类型列表中,选择 Vertex AI 远程模型、远程函数和 BigLake(Cloud 资源)

  4. 连接 ID 字段中,输入 bqml_tutorial

  5. 确认已选择多区域 - 美国

  6. 点击创建连接

  7. 在窗口底部,点击前往连接。或者,在探索器窗格中,展开外部连接,然后点击 us.bqml_tutorial

  8. 连接信息窗格中,复制服务账号 ID。为连接配置权限时,您需要使用此 ID。当您创建连接资源时,BigQuery 会创建一个唯一的系统服务账号,并将其与该连接相关联。

bq

  1. 创建连接:

    bq mk --connection --location=US --project_id=PROJECT_ID \
        --connection_type=CLOUD_RESOURCE bqml_tutorial

    PROJECT_ID 替换为您的 Google Cloud 项目 ID。 --project_id 参数会替换默认项目。

    当您创建连接资源时,BigQuery 会创建一个唯一的系统服务账号,并将其与该连接相关联。

    问题排查:如果您收到以下连接错误,请更新 Google Cloud SDK

    Flags parsing error: flag --connection_type=CLOUD_RESOURCE: value should be one of...
    
  2. 检索并复制服务账号 ID 以在后续步骤中使用:

    bq show --connection PROJECT_ID.us.bqml_tutorial

    输出内容类似如下:

    name                          properties
    1234.REGION.CONNECTION_ID {"serviceAccountId": "connection-1234-9u56h9@gcp-sa-bigquery-condel.iam.gserviceaccount.com"}
    

设置连接访问权限

向 Cloud 资源连接的服务账号授予 Storage Object Admin 角色。您必须在您创建远程模型端点的项目中授予此角色。

如需授予该角色,请按以下步骤操作:

  1. 前往 IAM 和管理页面。

    转到“IAM 和管理”

  2. 点击 授予访问权限

  3. 新建主账号字段中,输入您之前复制的 Cloud 资源连接的服务账号 ID。

  4. 选择角色字段中,选择 Cloud Storage,然后选择 Storage Object Admin

  5. 点击保存

创建对象表

按照以下步骤,使用您上传到 Cloud Storage 的金鱼图片创建名为 goldfish_image_table 的对象表。

控制台

  1. 转到 BigQuery Studio 页面。

    进入 BigQuery Studio

  2. 在查询编辑器中,输入以下查询以创建对象表。

    CREATE EXTERNAL TABLE `bqml_tutorial.goldfish_image_table`
    WITH CONNECTION `us.bqml_tutorial`
    OPTIONS(
    object_metadata = 'SIMPLE',
    uris = ['gs://bqml_images/IMAGE_NAME'],
    max_staleness = INTERVAL 1 DAY,
    metadata_cache_mode = 'AUTOMATIC');

    IMAGE_NAME 替换为图片文件的名称,例如 goldfish.jpg

    操作完成后,您会看到类似 This statement created a new table named goldfish_image_table 的消息。

bq

  1. 通过输入以下 CREATE EXTERNAL TABLE 语句来创建对象表。

    bq query --use_legacy_sql=false \
    "CREATE EXTERNAL TABLE `bqml_tutorial.goldfish_image_table`
    WITH CONNECTION `us.bqml_tutorial`
    OPTIONS(
    object_metadata = 'SIMPLE',
    uris = ['gs://bqml_images/IMAGE_NAME'],
    max_staleness = INTERVAL 1 DAY,
    metadata_cache_mode = 'AUTOMATIC')"

    IMAGE_NAME 替换为图片文件的名称,例如 goldfish.jpg

  2. 创建对象表后,请验证它是否显示在数据集中。

    bq ls bqml_tutorial

    输出内容类似如下:

    tableId               Type
    --------------------- --------
    goldfish_image_table  EXTERNAL

如需了解详情,请参阅创建对象表

使用导入的 ONNX 模型进行预测

您可以使用包含 ML.PREDICT 函数的以下查询,根据输入对象表 goldfish_image_table 中的图片数据进行预测。此查询会根据 ImageNet 标签字典输出输入图片的预测类标签。

在查询中,您必须使用 ML.DECODE_IMAGE 函数来解码图片数据,以便 ML.PREDICT 可对其进行解释。系统会调用 ML.RESIZE_IMAGE 函数来调整图片大小,使其适合模型输入的大小 (224*224)。

如需详细了解如何对图片对象表运行推断,请参阅对图片对象表运行推断

如需根据图片数据进行预测,请执行以下操作。

控制台

  1. 转到 BigQuery Studio 页面。

    进入 BigQuery Studio

  2. 在查询编辑器中输入以下 ML.PREDICT 查询。

     SELECT
       class_label
     FROM
       ML.PREDICT(MODEL bqml_tutorial.imported_onnx_model,
         (
         SELECT
           ML.RESIZE_IMAGE(ML.DECODE_IMAGE(DATA),
             224,
             224,
             FALSE) AS input
         FROM
           bqml_tutorial.goldfish_image_table))
     

    查询结果类似于以下内容:

    ML.PREDICT 查询的结果

bq

输入以下 bq query 命令:

bq query --use_legacy_sql=false \
'SELECT
  class_label
FROM
  ML.PREDICT(MODEL `bqml_tutorial.imported_onnx_model`,
    (
    SELECT
      ML.RESIZE_IMAGE(ML.DECODE_IMAGE(DATA),
        224,
        224,
        FALSE) AS input
    FROM
      bqml_tutorial.goldfish_image_table))'

清理

为避免因本教程中使用的资源导致您的 Google Cloud 账号产生费用,请删除包含这些资源的项目,或者保留项目但删除各个资源。

删除项目

控制台

  1. In the Google Cloud console, go to the Manage resources page.

    Go to Manage resources

  2. In the project list, select the project that you want to delete, and then click Delete.
  3. In the dialog, type the project ID, and then click Shut down to delete the project.

gcloud

    Delete a Google Cloud project:

    gcloud projects delete PROJECT_ID

删除各个资源

或者,如需移除本教程中使用的各个资源,请执行以下操作:

  1. 删除导入的模型

  2. (可选)删除数据集

  3. 删除 Cloud 资源连接

  4. 删除 Cloud Storage 存储桶

后续步骤