

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

# 使用 ModelBuilder 在 Amazon SageMaker AI 建立模型
<a name="how-it-works-modelbuilder-creation"></a>

準備在 SageMaker AI 端點上部署的模型需要多個步驟，包括選擇模型映像、設定端點組態、編碼序列化和還原序列化函式以在伺服器和用戶端之間傳輸資料、識別模型相依性，以及將它們上傳到 Amazon S3。`ModelBuilder` 可以降低初始設定和部署的複雜性，協助您在單一步驟中建立可部署模型。

`ModelBuilder` 會為您執行以下任務：
+ 在單一步驟中，將使用 XGBoost 或 PyTorch 等各種架構訓練的機器學習模型轉換為可部署模型。
+ 根據模型架構執行自動容器選擇，您不需要手動指定容器。您仍然可以將自有 URI 傳遞至 `ModelBuilder`，以攜帶自有容器。
+ 在將資料傳送至伺服器之前，先處理用戶端的資料序列化，以便伺服器傳回的結果進行推論和還原序列化。資料格式正確，無需手動處理。
+ 啟用相依性自動擷取，並根據模型伺服器期望封裝模型。`ModelBuilder` 的相依性自動擷取是動態載入相依性的最佳方法。(建議您在本機測試自動擷取，並更新相依性以滿足您的需求。)
+ 針對大型語言模型 (LLM) 使用案例，選擇性地對可在 SageMaker AI 端點上託管時部署的服務屬性執行本機參數調校，以獲得更好的效能。
+ 支援多數熱門模型伺服器和容器，例如 TorchServe、Triton、DJLServing 和 TGI 容器。

## 使用 ModelBuilder 建置模型
<a name="how-it-works-modelbuilder-creation-mb"></a>

`ModelBuilder` 是一種 Python 類別，採用 XGBoost 或 PyTorch 等架構模型或使用者指定的推論規格，並將其轉換為可部署模型。`ModelBuilder` 提供建置函式，可產生用於部署的成品。產生的模型成品專屬於模型伺服器，您也可以將其指定為其中一個輸入。如需 `ModelBuilder` 類別的詳細資訊，請參閱 [ModelBuilder](https://sagemaker.readthedocs.io/en/stable/api/inference/model_builder.html#sagemaker.serve.builder.model_builder.ModelBuilder)。

下圖說明使用 `ModelBuilder` 時的整體模型建立工作流程。`ModelBuilder` 接受模型或推論規格以及您的結構描述，以建立可在部署前於本機測試的可部署模型。

![\[使用 ModelBuilder 建立模型和部署流程。\]](http://docs.aws.amazon.com/zh_tw/sagemaker/latest/dg/images/model-builder-flow.png)


`ModelBuilder` 可以處理您想要套用的任何自訂項目。不過，若要部署架構模型，模型建置器至少需要模型、範例輸入和輸出，以及角色。下列程式碼範例會使用架構模型呼叫 `ModelBuilder`，並使用最小引數呼叫 `SchemaBuilder` 執行個體 (以推論用於序列化和還原序列化端點輸入和輸出的對應函式)。未指定容器，也不會傳遞封裝相依性 - 當您建置模型時，SageMaker AI 會自動推論這些資源。

```
from sagemaker.serve.builder.model_builder import ModelBuilder
from sagemaker.serve.builder.schema_builder import SchemaBuilder

model_builder = ModelBuilder(
    model=model,
    schema_builder=SchemaBuilder(input, output),
    role_arn="execution-role",
)
```

下列程式碼範例會使用推論規格 (作為 `InferenceSpec` 執行個體) 和額外的自訂功能調用 `ModelBuilder`，而非使用模型。在此情況下，對模型建置器的呼叫包含儲存模型成品的路徑，並開啟所有可用相依性的自動擷取。如需進一步了解 `InferenceSpec`，請參閱 [自訂模型載入和請求處理](#how-it-works-modelbuilder-creation-is)。

```
model_builder = ModelBuilder(
    mode=Mode.LOCAL_CONTAINER,
    model_path=model-artifact-directory,
    inference_spec=your-inference-spec,
    schema_builder=SchemaBuilder(input, output),
    role_arn=execution-role,
    dependencies={"auto": True}
)
```

## 定義序列化和還原序列化方法
<a name="how-it-works-modelbuilder-creation-sb"></a>

調用 SageMaker AI 端點時，資料會透過具不同 MIME 類型的 HTTP 承載傳送。例如，傳送至端點以進行推論的映像需要在用戶端轉換為位元組，並透過 HTTP 承載傳送至端點。當端點收到承載時，它需要將位元組字串還原序列化回模型預期的資料類型 (也稱為伺服器端還原序列化)。模型完成預測後，也需要將結果序列化為可透過 HTTP 承載傳回給使用者或用戶端的位元組。一旦用戶端收到回應位元組資料，則需要執行用戶端還原序列化，將位元組資料轉換回預期的資料格式，例如 JSON。至少需要為以下任務轉換資料：

1. 推論請求序列化 (由用戶端處理)

1. 推論請求還原序列化 (由伺服器或演算法處理)

1. 針對承載調用模型，並傳回回應承載

1. 推論回應序列化 (由伺服器或演算法處理)

1. 推論回應還原序列化 (由用戶端處理)

下圖顯示調用端點時發生的序列化和還原序列化程序。

![\[用戶端至伺服器資料序列化和還原序列化的圖表。\]](http://docs.aws.amazon.com/zh_tw/sagemaker/latest/dg/images/model-builder-serialization.png)


當您將範例輸入和輸出提供給 `SchemaBuilder` 時，結構描述建置器會產生對應的封送函式，以序列化和還原序列化輸入和輸出。您可以使用 `CustomPayloadTranslator` 進一步自訂序列化函式。但是在多數情況下，如下簡單的序列化程式會運作：

```
input = "How is the demo going?"
output = "Comment la démo va-t-elle?"
schema = SchemaBuilder(input, output)
```

如需進一步了解 `SchemaBuilder`，請參閱 [SchemaBuilder](https://sagemaker.readthedocs.io/en/stable/api/inference/model_builder.html#sagemaker.serve.builder.schema_builder.SchemaBuilder)。

下列程式碼片段範例是您想在用戶端和伺服器端自訂序列化和還原序列化函式的情況。您可以使用 `CustomPayloadTranslator` 定義自己的請求和回應轉譯器，並將這些轉譯器傳遞給 `SchemaBuilder`。

透過以轉譯器包含輸入和輸出，模型建置器可以擷取模型預期的資料格式。例如，假設範例輸入是原始映像，您的自訂轉譯器會裁切映像，並將裁切映像以張量形式傳送至伺服器。`ModelBuilder` 需要原始輸入和任何自訂預處理或後處理程式碼，才能衍生方法，在用戶端和伺服器端轉換資料。

```
from sagemaker.serve import CustomPayloadTranslator

# request translator
class MyRequestTranslator(CustomPayloadTranslator):
    # This function converts the payload to bytes - happens on client side
    def serialize_payload_to_bytes(self, payload: object) -> bytes:
        # converts the input payload to bytes
        ... ...
        return  //return object as bytes

    # This function converts the bytes to payload - happens on server side
    def deserialize_payload_from_stream(self, stream) -> object:
        # convert bytes to in-memory object
        ... ...
        return //return in-memory object

# response translator
class MyResponseTranslator(CustomPayloadTranslator):
    # This function converts the payload to bytes - happens on server side
    def serialize_payload_to_bytes(self, payload: object) -> bytes:
        # converts the response payload to bytes
        ... ...
        return //return object as bytes

    # This function converts the bytes to payload - happens on client side
    def deserialize_payload_from_stream(self, stream) -> object:
        # convert bytes to in-memory object
        ... ...
        return //return in-memory object
```

建立 `SchemaBuilder` 物件時，您會一併傳遞範例輸入和輸出與先前定義的自訂轉譯器，如下範例所示：

```
my_schema = SchemaBuilder(
    sample_input=image,
    sample_output=output,
    input_translator=MyRequestTranslator(),
    output_translator=MyResponseTranslator()
)
```

然後，請將範例輸入和輸出以及先前定義的自訂轉譯器傳遞至 `SchemaBuilder` 物件。

```
my_schema = SchemaBuilder(
    sample_input=image,
    sample_output=output,
    input_translator=MyRequestTranslator(),
    output_translator=MyResponseTranslator()
)
```

下列章節詳細說明如何使用 `ModelBuilder` 建置模型，並使用其支援類別來自訂使用案例的體驗。

**Topics**
+ [使用 ModelBuilder 建置模型](#how-it-works-modelbuilder-creation-mb)
+ [定義序列化和還原序列化方法](#how-it-works-modelbuilder-creation-sb)
+ [自訂模型載入和請求處理](#how-it-works-modelbuilder-creation-is)
+ [建置您的模型和部署](#how-it-works-modelbuilder-creation-deploy)
+ [使用自有容器 (BYOC)](#how-it-works-modelbuilder-creation-mb-byoc)
+ [在本機模式中使用 ModelBuilder](#how-it-works-modelbuilder-creation-local)
+ [ModelBuilder 範例](#how-it-works-modelbuilder-creation-example)

## 自訂模型載入和請求處理
<a name="how-it-works-modelbuilder-creation-is"></a>

透過 `InferenceSpec` 提供您的自有推論程式碼，即可提供額外的自訂層。您可以透過 `InferenceSpec` 自訂模型的載入方式，以及模型處理傳入推論請求的方式，同時略過其預設載入和推論處理機制。使用非標準模型或自訂推論管道時，這種彈性方式格外有用。您可以自訂 `invoke` 方法，以控制模型如何預處理和後處理傳入的請求。`invoke` 方法會確保模型正確處理推論請求。下列範例使用 `InferenceSpec` 來產生具 HuggingFace 管道的模型。如需進一步了解 `InferenceSpec`，請參閱 [InferenceSpec](https://sagemaker.readthedocs.io/en/stable/api/inference/model_builder.html#sagemaker.serve.spec.inference_spec.InferenceSpec)。

```
from sagemaker.serve.spec.inference_spec import InferenceSpec
from transformers import pipeline

class MyInferenceSpec(InferenceSpec):
    def load(self, model_dir: str):
        return pipeline("translation_en_to_fr", model="t5-small")

    def invoke(self, input, model):
        return model(input)

inf_spec = MyInferenceSpec()

model_builder = ModelBuilder(
    inference_spec=your-inference-spec,
    schema_builder=SchemaBuilder(X_test, y_pred)
)
```

下列範例說明先前範例的自訂變化。模型是以具相依性的推論規格定義。在此情況下，推論規格中的程式碼取決於 *lang-segment* 套件。`dependencies` 的引數包含使用 Git 指示建置器安裝 *lang-segment* 的陳述式。由於模型建置器是由使用者指示來自訂安裝相依性，因此 `auto` 關鍵是 `False`，以關閉相依性自動擷取。

```
model_builder = ModelBuilder(
    mode=Mode.LOCAL_CONTAINER,
    model_path=model-artifact-directory,
    inference_spec=your-inference-spec,
    schema_builder=SchemaBuilder(input, output),
    role_arn=execution-role,
    dependencies={"auto": False, "custom": ["-e git+https://github.com/luca-medeiros/lang-segment-anything.git#egg=lang-sam"],}
)
```

## 建置您的模型和部署
<a name="how-it-works-modelbuilder-creation-deploy"></a>

呼叫 `build` 函式來建立可部署模型。此步驟會在您的工作目錄中使用必要程式碼來建立推論程式碼 (作為 `inference.py`)，以建立結構描述、執行輸入和輸出的序列化和還原序列化，以及執行其他使用者指定的自訂邏輯。

作為完整性檢查，SageMaker AI 會封裝並挑選部署所需的檔案，作為 `ModelBuilder` 建置函式的一部分。在此過程中，SageMaker AI 也會為 pickle 檔案建立 HMAC 簽署，並在 `deploy` (或 `create`) 期間將 [CreateModel](https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_CreateModel.html) API 中的私密金鑰新增為環境變數。端點啟動會使用環境變數來驗證 pickle 檔案的完整性。

```
# Build the model according to the model server specification and save it as files in the working directory
model = model_builder.build()
```

使用模型的現有 `deploy` 方法部署模型。在此步驟中，SageMaker AI 會設定端點，在模型開始對傳入請求進行預測時託管模型。雖然 `ModelBuilder` 會推論部署模型所需的端點資源，但您可以使用自有參數值覆寫這些預估值。下列範例指示 SageMaker AI 在單一 `ml.c6i.xlarge` 執行個體上部署模型。由 `ModelBuilder` 建構的模型會在部署期間啟用即時記錄，以作為新增功能。

```
predictor = model.deploy(
    initial_instance_count=1,
    instance_type="ml.c6i.xlarge"
)
```

如果您要更詳盡地控制指派給模型的端點資源，您可以使用 `ResourceRequirements` 物件。您可以使用 `ResourceRequirements` 物件，請求要部署模型的 CPU、加速器和複本數量下限。您也可以請求記憶體下上限 (以 MB 為單位)。若要使用此功能，您需要將端點類型指定為 `EndpointType.INFERENCE_COMPONENT_BASED`。下列範例會請求四個加速器，記憶體大小下限為 1024 MB，以及要部署至端點類型 `EndpointType.INFERENCE_COMPONENT_BASED` 的模型複本。

```
resource_requirements = ResourceRequirements(
    requests={
        "num_accelerators": 4,
        "memory": 1024,
        "copies": 1,
    },
    limits={},
)
predictor = model.deploy(
    mode=Mode.SAGEMAKER_ENDPOINT,
    endpoint_type=EndpointType.INFERENCE_COMPONENT_BASED,
    resources=resource_requirements,
    role="role"
)
```

## 使用自有容器 (BYOC)
<a name="how-it-works-modelbuilder-creation-mb-byoc"></a>

如果您要使用自有容器 (從 SageMaker AI 容器擴充)，您也可以指定映像 URI，如下範例所示。您也需要識別與 `ModelBuilder` 映像對應的模型伺服器，以產生特定於模型伺服器的成品。

```
model_builder = ModelBuilder(
    model=model,
    model_server=ModelServer.TORCHSERVE,
    schema_builder=SchemaBuilder(X_test, y_pred),
    image_uri="123123123123.dkr.ecr.ap-southeast-2.amazonaws.com/byoc-image:xgb-1.7-1")
)
```

## 在本機模式中使用 ModelBuilder
<a name="how-it-works-modelbuilder-creation-local"></a>

您可以使用 `mode` 引數，在本機測試和部署之間切換到端點，以在本機部署模型。您需要將模型成品儲存在工作目錄中，如下程式碼片段所示：

```
model = XGBClassifier()
model.fit(X_train, y_train)
model.save_model(model_dir + "/my_model.xgb")
```

傳遞模型物件、`SchemaBuilder` 執行個體，並將模式設為 `Mode.LOCAL_CONTAINER`。當您呼叫 `build` 函式時，`ModelBuilder` 會自動識別支援的架構容器，並掃描相依性。下列範例示範在本機模式中使用 XGBoost 模型建立模型。

```
model_builder_local = ModelBuilder(
    model=model,
    schema_builder=SchemaBuilder(X_test, y_pred),
    role_arn=execution-role,
    mode=Mode.LOCAL_CONTAINER
)
xgb_local_builder = model_builder_local.build()
```

呼叫 `deploy` 函式以在本機進行部署，如下程式碼片段所示。如果您為執行個體類型或數量指定了參數，則會忽略這些引數。

```
predictor_local = xgb_local_builder.deploy()
```

### 故障診斷本機模式
<a name="how-it-works-modelbuilder-creation-troubleshoot"></a>

根據個別本機設定不同，您可能難以在環境中順暢執行 `ModelBuilder`。請參閱下列清單，了解您可能遇到的問題以及解決方式。
+ **已在使用中**：您可能會遇到 `Address already in use` 錯誤。在此情況下，該連接埠可能正在執行 Docker 容器或受其他程序使用。您可以遵循 [Linux 文件](https://www.cyberciti.biz/faq/what-process-has-open-linux-port/)所述的方法來識別程序，並將本機程序從連接埠 8080 正常重新導向至另一個連接埠或清除 Docker 執行個體。
+ **IAM 許可問題**：嘗試提取 Amazon ECR 映像或存取 Amazon S3 時，您可能會遇到許可問題。在此情況下，請導覽至筆記本或 Studio Classic 執行個體的執行角色，以驗證 `SageMakerFullAccess` 政策或個別 API 許可。
+ **EBS 磁碟區容量問題**：如果您部署大型語言模型 (LLM)，則在本機模式下執行 Docker 時可能會耗盡空間，或遇到 Docker 快取的空間限制。在此情況下，您可以嘗試將 Docker 磁碟區移至空間足夠的檔案系統。若要移動 Docker 磁碟區，請完成下列步驟：

  1. 開啟終端機並執行 `df` 以顯示磁碟用量，如下輸出所示：

     ```
     (python3) sh-4.2$ df
     Filesystem     1K-blocks      Used Available Use% Mounted on
     devtmpfs       195928700         0 195928700   0% /dev
     tmpfs          195939296         0 195939296   0% /dev/shm
     tmpfs          195939296      1048 195938248   1% /run
     tmpfs          195939296         0 195939296   0% /sys/fs/cgroup
     /dev/nvme0n1p1 141545452 135242112   6303340  96% /
     tmpfs           39187860         0  39187860   0% /run/user/0
     /dev/nvme2n1   264055236  76594068 176644712  31% /home/ec2-user/SageMaker
     tmpfs           39187860         0  39187860   0% /run/user/1002
     tmpfs           39187860         0  39187860   0% /run/user/1001
     tmpfs           39187860         0  39187860   0% /run/user/1000
     ```

  1. 將預設 Docker 目錄從 `/dev/nvme0n1p1` 移至 `/dev/nvme2n1`，讓您可以充分利用 256 GB SageMaker AI 磁碟區。如需更多詳細資訊，請參閱如何[移動 Docker 目錄](https://www.guguweb.com/2019/02/07/how-to-move-docker-data-directory-to-another-location-on-ubuntu/)的文件。

  1. 使用下列命令停止 Docker：

     ```
     sudo service docker stop
     ```

  1. 將 `daemon.json` 新增至 `/etc/docker`，或將下列 JSON Blob 附加至現有 JSON Blob。

     ```
     {
         "data-root": "/home/ec2-user/SageMaker/{created_docker_folder}"
     }
     ```

  1. 使用下列命令，將 Docker 目錄從 `/var/lib/docker` 移至 `/home/ec2-user/SageMaker AI`：

     ```
     sudo rsync -aP /var/lib/docker/ /home/ec2-user/SageMaker/{created_docker_folder}
     ```

  1. 使用下列命令啟動 Docker：

     ```
     sudo service docker start
     ```

  1. 使用下列命令清理垃圾桶：

     ```
     cd /home/ec2-user/SageMaker/.Trash-1000/files/*
     sudo rm -r *
     ```

  1. 如果您使用 SageMaker 筆記本執行個體，您可以遵循 [Docker 準備檔案](https://github.com/melanie531/amazon-sagemaker-pytorch-lightning-distributed-training/blob/main/prepare-docker.sh)中的步驟，為本機模式準備 Docker。

## ModelBuilder 範例
<a name="how-it-works-modelbuilder-creation-example"></a>

如需更多使用 `ModelBuilder` 來建置模型的範例，請參閱 [ModelBuilder 範例筆記本](https://github.com/aws-samples/sagemaker-hosting/blob/main/SageMaker-Model-Builder)。