ONNX 형식의 PyTorch 모델로 예측

개요

Open Neural Network Exchange(ONNX)는 어떤 머신러닝 프레임워크이든 나타내도록 설계된 균일한 형식을 제공합니다. ONNX에 대한 BigQuery ML 지원을 통해 다음을 수행할 수 있습니다.

  • 원하는 프레임워크를 사용하여 모델을 학습시키기
  • 모델을 ONNX 모델 형식으로 변환하기. 자세한 내용은 ONNX 형식으로 변환을 참조하세요.
  • ONNX 모델을 BigQuery로 가져오고 BigQuery ML을 사용하여 예측하기

이 튜토리얼에서는 PyTorch로 학습된 ONNX 모델을 BigQuery 데이터 세트로 가져오고 이를 사용해서 SQL 쿼리로부터 예측을 수행하는 방법을 설명합니다. 다음 인터페이스를 사용하여 ONNX 모델을 가져올 수 있습니다.

형식 및 스토리지 요구사항을 포함하여 BigQuery로 ONNX 모델을 가져오는 데 대한 자세한 내용은 ONNX 모델을 가져오기 위한 CREATE MODEL을 참조하세요.

목표

이 튜토리얼에서는 다음 단계를 진행합니다.

  • PyTorch로 모델을 만들고 학습시킵니다.
  • torch.onnx를 사용하여 모델을 ONNX 형식으로 변환합니다.
  • ONNX 모델을 BigQuery로 가져와 예측을 수행합니다.

이미지 분류를 위한 PyTorch 비전 모델 만들기

BigQuery ML ML.DECODE_IMAGEML.RESIZE_IMAGE 함수에서 반환된 디코딩된 이미지 데이터를 수락하는 PyTorch 사전 학습된 resnet18을 가져옵니다.

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 비전 모델을 resnet18.onnx라는 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

Cloud Storage에 ONNX 모델 업로드

ONNX 모델 파일을 저장할 Cloud Storage 버킷을 만들고, 저장된 ONNX 모델 파일을 Cloud Storage 버킷에 업로드합니다. 자세한 내용은 파일 시스템에서 객체 업로드를 참조하세요.

ONNX 모델을 BigQuery로 가져오기

이 단계에서는 ONNX 모델을 Cloud Storage 버킷에 업로드했다고 가정합니다. 예시 모델은 gs://cloud-samples-data/bigquery/ml/onnx/resnet18.onnx에 저장됩니다.

콘솔

  1. Google Cloud 콘솔에서 BigQuery 페이지로 이동합니다.

    BigQuery 페이지로 이동

  2. 쿼리 편집기에서 다음과 같이 CREATE MODEL 문을 입력합니다.

     CREATE OR REPLACE MODEL `mydataset.mymodel`
      OPTIONS (MODEL_TYPE='ONNX',
       MODEL_PATH='gs://bucket/path/to/onnx_model/*')
    

    예를 들면 다음과 같습니다.

     CREATE OR REPLACE MODEL `example_dataset.imported_onnx_model`
      OPTIONS (MODEL_TYPE='ONNX',
       MODEL_PATH='gs://cloud-samples-data/bigquery/ml/onnx/resnet18.onnx')
    

    앞의 쿼리는 gs://cloud-samples-data/bigquery/ml/onnx/resnet18.onnx에 위치한 ONNX 모델을 imported_onnx_model이라는 BigQuery 모델로 가져옵니다.

  3. 새 모델이 리소스 패널에 표시됩니다. 프로젝트의 각 데이터 세트를 확장하면 모델이 데이터 세트의 다른 BigQuery 리소스와 함께 나열됩니다. 모델은 모델 아이콘(모델 아이콘)으로 표시됩니다.

  4. 리소스 패널에서 새 모델을 선택하면 모델에 대한 정보가 쿼리 편집기 아래에 표시됩니다.

    onnx 모델 정보

bq

Cloud Storage에서 ONNX 모델을 가져오려면 다음과 같은 명령어를 입력하여 일괄 쿼리를 실행합니다.

bq query \
--use_legacy_sql=false \
"CREATE MODEL
  `mydataset.mymodel`
OPTIONS
  (MODEL_TYPE='ONNX',
   MODEL_PATH='gs://bucket/path/to/onnx_model/*')"

예를 들면 다음과 같습니다.

bq query --use_legacy_sql=false \
"CREATE OR REPLACE MODEL
  `example_dataset.imported_onnx_model`
OPTIONS
  (MODEL_TYPE='ONNX',
   MODEL_PATH='gs://cloud-samples-data/bigquery/ml/onnx/resnet18.onnx')"

모델을 가져오면 bq ls [dataset_name]의 출력에 모델이 나타납니다.

$ bq ls example_dataset

       tableId          Type    Labels   Time Partitioning
 --------------------- ------- -------- -------------------
  imported_onnx_model   MODEL

API

새 작업을 삽입하고 jobs#configuration.query 속성을 다음 요청 본문과 같이 입력합니다.

{
  "query": "CREATE MODEL `project_id:mydataset.mymodel` OPTIONS(MODEL_TYPE='ONNX' MODEL_PATH='gs://bucket/path/to/onnx_model/*')"
}

이미지 데이터 액세스를 위해 BigQuery에서 객체 테이블 만들기

BigQuery에서 구조화되지 않은 데이터에 액세스하려면 객체 테이블을 만들어야 합니다. 자세한 내용은 객체 테이블 만들기를 참조하세요.

gs://mybucket/goldfish.jpg에 저장된 금붕어 이미지에 goldfish_image_table이라는 객체 테이블을 만듭니다.

CREATE EXTERNAL TABLE `example_dataset.goldfish_image_table`
WITH CONNECTION `us.my-connection`
OPTIONS(
  object_metadata = 'SIMPLE',
  uris = ['gs://mybucket/goldfish.jpg'],
  max_staleness = INTERVAL 1 DAY,
  metadata_cache_mode = 'AUTOMATIC');

가져온 ONNX 모델로 예측 수행

콘솔

  1. Google Cloud 콘솔에서 BigQuery 페이지로 이동합니다.

    BigQuery 페이지로 이동

  2. 쿼리 편집기에서 다음과 같이 ML.PREDICT를 사용하여 쿼리를 입력합니다.

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

    앞의 쿼리는 현재 프로젝트에서 example_dataset 데이터 세트에 있는 imported_onnx_model이라는 모델을 사용하여 입력 객체 테이블 goldfish_image_table의 이미지 데이터로부터 예측을 수행합니다. ML.PREDICT로 해석할 수 있도록 ML.DECODE_IMAGE 함수를 사용하여 이미지 데이터를 디코딩해야 합니다. 또한 ML.RESIZE_IMAGE 함수를 호출하여 모델 입력 크기에 맞게 이미지 크기를 조절합니다(224*224). 이미지 객체 테이블에서 추론 실행에 대한 자세한 내용은 이미지 객체 테이블에서 추론 실행을 참조하세요.

    이 쿼리는 ImageNet 라벨 딕셔너리를 기반으로 입력 이미지의 예측 클래스 라벨을 출력합니다.

    쿼리 결과

bq

input_data 테이블의 입력 데이터로 예측하려면 가져온 ONNX 모델 my_model을 사용하여 다음과 같은 명령어를 입력합니다.

bq query \
--use_legacy_sql=false \
'SELECT *
 FROM ML.PREDICT(
   MODEL `my_project.my_dataset.my_model`,
   (SELECT * FROM input_data))'

API

새 작업을 삽입하고 jobs#configuration.query 속성을 다음 요청 본문과 같이 입력합니다.

{
  "query": "SELECT * FROM ML.PREDICT(MODEL `my_project.my_dataset.my_model`, (SELECT * FROM input_data))"
}

다음 단계