準備模型以進行編譯 - Amazon SageMaker AI

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

準備模型以進行編譯

SageMaker Neo 需要機器學習模型才能滿足特定的輸入資料形狀。編譯所需的輸入形狀取決於您使用的深度學習架構。正確格式化模型輸入形狀後,請根據以下要求儲存模型。儲存模型後,壓縮模型成品。

SageMaker Neo 應有哪些輸入資料形狀?

編譯模型之前,請先確定模型已正確格式化。Neo 應有已訓練模型 (JSON 格式或清單格式) 之預期資料輸入的名稱和形狀。預期輸入有架構限制。

以下是 SageMaker Neo 預期的輸入形狀:

使用訓練模型之字典格式,指定預期資料輸入的名稱和形狀 (NCHW 格式)。請注意,雖然 Keras 模型成品應該以 NHWC (通道最後一個) 格式上傳,但應該以 NCHW (通道第一個) 格式指定 DataInputConfig。所需的字典格式如下:

  • 若為一個輸入:{'input_1':[1,3,224,224]}

  • 若為兩個輸入:{'input_1': [1,3,224,224], 'input_2':[1,3,224,224]}

使用訓練模型之字典格式,指定預期資料輸入的名稱和形狀 (NCHW 格式)。所需的字典格式如下:

  • 若為一個輸入:{'data':[1,3,1024,1024]}

  • 若為兩個輸入:{'var1': [1,1,28,28], 'var2':[1,1,28,28]}

若為 PyTorch 模型,如果您同時符合下列兩個條件,就不需要提供預期資料輸入的名稱和形狀:

  • 您使用 PyTorch 2.0 或更新的版本建立模型定義檔案。如需如何建立定義檔案的更多相關資訊,請參閱儲存 SageMaker Neo 模型PyTorch一節。

  • 您正在編譯雲端執行個體的模型。如需 SageMaker Neo 支援之執行個體類型的更多相關資訊,請參閱支援的執行個體類型和架構

如果符合這些條件,SageMaker Neo 會從您使用 PyTorch 建立的模型定義檔案 (.pt 或 .pth) 取得輸入組態。

否則您必須執行以下操作:

使用訓練模型之字典格式,指定預期資料輸入的名稱和形狀 (NCHW 格式)。或者,您可以僅使用清單格式指定造型。所需的字典格式如下:

  • 字典格式的一個輸入:{'input0':[1,3,224,224]}

  • 清單格式的一個輸入:[[1,3,224,224]]

  • 字典格式的兩個輸入:{'input0':[1,3,224,224], 'input1':[1,3,224,224]}

  • 清單格式的兩個輸入:[[1,3,224,224], [1,3,224,224]]

使用訓練模型之字典格式,指定預期資料輸入的名稱和形狀 (NHWC 格式)。所需的字典格式如下:

  • 若為一個輸入:{'input':[1,1024,1024,3]}

  • 若為兩個輸入:{'data1': [1,28,28,1], 'data2':[1,28,28,1]}

使用訓練模型之字典格式,指定預期資料輸入的名稱和形狀 (NHWC 格式)。所需的字典格式如下:

  • 若為一個輸入:{'input':[1,224,224,3]}

注意

SageMaker Neo 僅針對 Edge 裝置目標支援 TensorFlow Lite。如需支援之 SageMaker Neo Edge 裝置目標的清單,請參閱 SageMaker Neo 裝置 頁面。如需支援之 SageMaker Neo 雲端執行個體目標的清單,請參閱 SageMaker Neo 支援的執行個體類型和架構 頁面。

不需要輸入資料的名稱和形狀。

儲存 SageMaker Neo 的模型

以下程式碼範例顯示如何儲存模型,使其與 Neo 相容。模型必須封裝為壓縮的 tar 檔案 (*.tar.gz)。

Keras 模型需要一個模型定義檔案 (.h5)。

有兩個選項可以儲存 Keras 模型,使其與 SageMaker Neo 相容:

  1. 使用 model.save("<model-name>", save_format="h5") 匯出為 .h5 格式。

  2. 匯出後凍結 SavedModel

以下是如何將 tf.keras 模型匯出為凍結圖形的範例 (選項二):

import os import tensorflow as tf from tensorflow.keras.applications.resnet50 import ResNet50 from tensorflow.keras import backend tf.keras.backend.set_learning_phase(0) model = tf.keras.applications.ResNet50(weights='imagenet', include_top=False, input_shape=(224, 224, 3), pooling='avg') model.summary() # Save as a SavedModel export_dir = 'saved_model/' model.save(export_dir, save_format='tf') # Freeze saved model input_node_names = [inp.name.split(":")[0] for inp in model.inputs] output_node_names = [output.name.split(":")[0] for output in model.outputs] print("Input names: ", input_node_names) with tf.Session() as sess: loaded = tf.saved_model.load(sess, export_dir=export_dir, tags=["serve"]) frozen_graph = tf.graph_util.convert_variables_to_constants(sess, sess.graph.as_graph_def(), output_node_names) tf.io.write_graph(graph_or_graph_def=frozen_graph, logdir=".", name="frozen_graph.pb", as_text=False) import tarfile tar = tarfile.open("frozen_graph.tar.gz", "w:gz") tar.add("frozen_graph.pb") tar.close()
警告

請勿使用 model.save(<path>, save_format='tf')SavedModel 類別匯出模型。這種格式適合訓練,但不適合推論。

MXNet 模型必須儲存為單一符號檔案 *-symbol.json 和單一參數 *.params files

Gluon Models

使用 HybridSequential 類別定義神經網路。這將以符號程式設計的方式執行程式碼 (相對於命令式程式設計)。

from mxnet import nd, sym from mxnet.gluon import nn def get_net(): net = nn.HybridSequential() # Here we use the class HybridSequential. net.add(nn.Dense(256, activation='relu'), nn.Dense(128, activation='relu'), nn.Dense(2)) net.initialize() return net # Define an input to compute a forward calculation. x = nd.random.normal(shape=(1, 512)) net = get_net() # During the forward calculation, the neural network will automatically infer # the shape of the weight parameters of all the layers based on the shape of # the input. net(x) # hybridize model net.hybridize() net(x) # export model net.export('<model_name>') # this will create model-symbol.json and model-0000.params files import tarfile tar = tarfile.open("<model_name>.tar.gz", "w:gz") for name in ["<model_name>-0000.params", "<model_name>-symbol.json"]: tar.add(name) tar.close()

如需混合模型的更多相關資訊,請參閱 MXNet 混合化文件

Gluon Model Zoo (GluonCV)

GluonCV model zoo 模型已預先混合。因此您可以直接匯出這些模型。

import numpy as np import mxnet as mx import gluoncv as gcv from gluoncv.utils import export_block import tarfile net = gcv.model_zoo.get_model('<model_name>', pretrained=True) # For example, choose <model_name> as resnet18_v1 export_block('<model_name>', net, preprocess=True, layout='HWC') tar = tarfile.open("<model_name>.tar.gz", "w:gz") for name in ["<model_name>-0000.params", "<model_name>-symbol.json"]: tar.add(name) tar.close()
Non Gluon Models

所有非 Gluon 模型儲存至磁碟時,使用 *-symbol*.params 檔案。因此,模型已經適用於 Neo 的正確格式。

# Pass the following 3 parameters: sym, args, aux mx.model.save_checkpoint('<model_name>',0,sym,args,aux) # this will create <model_name>-symbol.json and <model_name>-0000.params files import tarfile tar = tarfile.open("<model_name>.tar.gz", "w:gz") for name in ["<model_name>-0000.params", "<model_name>-symbol.json"]: tar.add(name) tar.close()

PyTorch 模型必須以 float32 的輸入資料類型儲存為定義檔案 (.pt.pth)。

若要儲存模型,請先使用 torch.jit.trace 方法再使用 torch.save 方法。這個程序將物件儲存至磁碟檔案,預設使用 python pickle (pickle_module=pickle) 儲存物件和一些中繼資料。接下來,將儲存的模型轉換為壓縮的 tar 檔案。

import torchvision import torch model = torchvision.models.resnet18(pretrained=True) model.eval() inp = torch.rand(1, 3, 224, 224) model_trace = torch.jit.trace(model, inp) # Save your model. The following code saves it with the .pth file extension model_trace.save('model.pth') # Save as a compressed tar file import tarfile with tarfile.open('model.tar.gz', 'w:gz') as f: f.add('model.pth') f.close()

如果您使用 PyTorch 2.0 或更新版本儲存模型,SageMaker Neo 會從定義檔案衍生模型的輸入組態 (其輸入的名稱和形狀)。在這種情況下,當您編譯模型時,不需要將資料輸入組態指定給 SageMaker AI。

如果要防止 SageMaker Neo 衍生輸入組態,可以將 torch.jit.trace_store_inputs 參數設定為 False。如果您這樣做,則必須在編譯模型時將資料輸入組態指定給 SageMaker AI。

如需 torch.jit.trace 方法的更多相關資訊,請參閱 PyTorch 文件中的 TORCH.JIT.TRACE

TensorFlow 需要一個 .pb 或一個 .pbtxt 檔案,以及一個包含變數的變數目錄。若為凍結模型,只需要一個 .pb.pbtxt 檔案。

以下程式碼範例顯示如何使用 tar Linux 命令壓縮模型。在終端機或 Jupyter 筆記本中執行下列命令 (如果您使用 Jupyter 筆記本,請在陳述式的開頭插入 ! magic 命令):

# Download SSD_Mobilenet trained model !wget http://download.tensorflow.org/models/object_detection/ssd_mobilenet_v2_coco_2018_03_29.tar.gz # unzip the compressed tar file !tar xvf ssd_mobilenet_v2_coco_2018_03_29.tar.gz # Compress the tar file and save it in a directory called 'model.tar.gz' !tar czvf model.tar.gz ssd_mobilenet_v2_coco_2018_03_29/frozen_inference_graph.pb

此範例中使用的命令旗標可完成下列作業:

  • c:建立封存

  • z:使用 gzip 壓縮存檔

  • v:顯示存檔進度

  • f:指定存檔的檔案名稱

內建估算器是由特定架構的容器或特定演算法的容器製作。使用內建的 .fit 方法訓練模型時,內建演算法和特定架構估算器的估算器物件會以正確的格式儲存模型。

例如,您可以使用 sagemaker.TensorFlow 定義 TensorFlow 估算器:

from sagemaker.tensorflow import TensorFlow estimator = TensorFlow(entry_point='mnist.py', role=role, #param role can be arn of a sagemaker execution role framework_version='1.15.3', py_version='py3', training_steps=1000, evaluation_steps=100, instance_count=2, instance_type='ml.c4.xlarge')

然後使用 .fit 內建方法訓練模型:

estimator.fit(inputs)

最後用 compile_model 方法中的組建編譯模型之前:

# Specify output path of the compiled model output_path = '/'.join(estimator.output_path.split('/')[:-1]) # Compile model optimized_estimator = estimator.compile_model(target_instance_family='ml_c5', input_shape={'data':[1, 784]}, # Batch size 1, 3 channels, 224x224 Images. output_path=output_path, framework='tensorflow', framework_version='1.15.3')

使用 SageMaker Python SDK 中的 compile_model 方法訓練及編譯內建演算法時,您也可以使用 sagemaker.estimator.Estimator 類別初始化預估器物件:

import sagemaker from sagemaker.image_uris import retrieve sagemaker_session = sagemaker.Session() aws_region = sagemaker_session.boto_region_name # Specify built-in algorithm training image training_image = retrieve(framework='image-classification', region=aws_region, image_scope='training') training_image = retrieve(framework='image-classification', region=aws_region, image_scope='training') # Create estimator object for training estimator = sagemaker.estimator.Estimator(image_uri=training_image, role=role, #param role can be arn of a sagemaker execution role instance_count=1, instance_type='ml.p3.8xlarge', volume_size = 50, max_run = 360000, input_mode= 'File', output_path=s3_training_output_location, base_job_name='image-classification-training' ) # Setup the input data_channels to be used later for training. train_data = sagemaker.inputs.TrainingInput(s3_training_data_location, content_type='application/x-recordio', s3_data_type='S3Prefix') validation_data = sagemaker.inputs.TrainingInput(s3_validation_data_location, content_type='application/x-recordio', s3_data_type='S3Prefix') data_channels = {'train': train_data, 'validation': validation_data} # Train model estimator.fit(inputs=data_channels, logs=True) # Compile model with Neo optimized_estimator = estimator.compile_model(target_instance_family='ml_c5', input_shape={'data':[1, 3, 224, 224], 'softmax_label':[1]}, output_path=s3_compilation_output_location, framework='mxnet', framework_version='1.7')

如需使用 SageMaker SDK 編譯模型的更多相關資訊,請參閱編譯模型 (Amazon SageMaker AI SDK)