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

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

準備模型以進行編譯

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

SageMaker Neo 預期哪些輸入資料形狀?

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

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

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

  • 若為一個輸入:{'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 新」PyTorch一節。

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

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

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

使用字典格式為訓練模型指定預期資料輸入的名稱和形狀 (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 TensorFlow 僅支援 Lite 用於邊緣裝置目標。如需支援的 SageMaker Neo 邊緣裝置目標清單,請參閱 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 模型必須儲存為具有 輸入資料類型的定義檔案 (.pt.pthfloat32

若要儲存模型,請先使用 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 時,不需要將資料輸入組態指定為 。

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

如需有關 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.estimator.Estimator類別初始化估算器物件,以使用 SageMaker Python 中的 compile_model方法進行訓練和編譯內建演算法SDK:

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 Python 編譯模型的詳細資訊SDK,請參閱 編譯模型 (Amazon SageMaker SDK)