

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

# 用於模型自訂的程式碼範例
<a name="model-customization-code-samples"></a>

下列程式碼範例示範如何準備基本資料集、設定許可、建立自訂模型、檢視輸出檔案、購買模型的輸送量，以及在模型上執行推論。您可以將這些程式碼片段修改為特定的使用案例。

1. 準備訓練資料集。

   1. 建立包含以下一行的訓練資料集檔案，並將其命名為 *train.jsonl*。

      ```
      {"prompt": "what is AWS", "completion": "it's Amazon Web Services"}
      ```

   1. 為您的訓練資料建立 S3 儲存貯體，並為輸出資料建立另一個儲存貯體 (名稱必須是唯一的)。

   1. 將 *train.jsonl* 上傳至訓練資料儲存貯體。

1. 建立政策以存取您的訓練，並將其連接至具有 Amazon Bedrock 信任關係的 IAM 角色。選擇您偏好方法的索引標籤，然後遵循下列步驟：

------
#### [ Console ]

   1. 建立 S3 政策。

      1. 導覽至位於 [https://console.aws.amazon.com/iam](https://console.aws.amazon.com/iam) 的 IAM 主控台，然後從左側導覽窗格中選擇**政策**。

      1. 選取**建立政策**，然後選擇 **JSON** 以開啟**政策編輯器**。

      1. 貼上下列政策，將 *\$1\$1training-bucket\$1* 和 *\$1\$1output-bucket\$1* 取代為您的儲存貯體名稱，然後選取**下一步**。

------
#### [ JSON ]

****  

         ```
         {
             "Version":"2012-10-17",		 	 	 
             "Statement": [
                 {
                     "Effect": "Allow",
                     "Action": [
                         "s3:GetObject",
                         "s3:ListBucket"
                     ],
                     "Resource": [
                         "arn:aws:s3:::${training-bucket}",
                         "arn:aws:s3:::${training-bucket}/*"
                     ]
                 },
                 {
                     "Effect": "Allow",
                     "Action": [
                         "s3:GetObject",
                         "s3:PutObject",
                         "s3:ListBucket"
                     ],
                     "Resource": [
                         "arn:aws:s3:::${output-bucket}",
                         "arn:aws:s3:::${output-bucket}/*"
                     ]
                 }
             ]
         }
         ```

------

      1. 將政策命名為 *MyFineTuningDataAccess*，然後選取**建立政策**。

   1. 建立 IAM 角色，並連接該政策。

      1. 在左側導覽窗格中，選擇**角色**，然後選取**建立角色**。

      1. 選取**自訂信任政策**，貼上下列政策，然後選取**下一步**。

------
#### [ JSON ]

****  

         ```
         {
             "Version":"2012-10-17",		 	 	 
             "Statement": [
                 {
                     "Effect": "Allow",
                     "Principal": {
                         "Service": "bedrock.amazonaws.com"
                     },
                     "Action": "sts:AssumeRole"
                 }
             ] 
         }
         ```

------

      1. 搜尋您建立的 *MyFineTuningDataAccess* 政策，接著選取核取方塊，然後選擇**下一步**。

      1. 將角色命名為 *MyCustomizationRole*，然後選取*建立角色*。

------
#### [ CLI ]

   1. 建立名為 *BedrockTrust.json* 的檔案，並將下列政策貼入其中。

------
#### [ JSON ]

****  

      ```
      {
          "Version":"2012-10-17",		 	 	 
          "Statement": [
              {
                  "Effect": "Allow",
                  "Principal": {
                      "Service": "bedrock.amazonaws.com"
                  },
                  "Action": "sts:AssumeRole"
              }
          ] 
      }
      ```

------

   1. 建立另一個名為 *MyFineTuningDataAccess.json* 的檔案，並將下列政策貼入其中，以您的儲存貯體名稱取代 *\$1\$1training-bucket\$1* 和 *\$1\$1output-bucket\$1*。

------
#### [ JSON ]

****  

      ```
      {
          "Version":"2012-10-17",		 	 	 
          "Statement": [
              {
                  "Effect": "Allow",
                  "Action": [
                      "s3:GetObject",
                      "s3:ListBucket"
                  ],
                  "Resource": [
                      "arn:aws:s3:::${training-bucket}",
                      "arn:aws:s3:::${training-bucket}/*"
                  ]
              },
              {
                  "Effect": "Allow",
                  "Action": [
                      "s3:GetObject",
                      "s3:PutObject",
                      "s3:ListBucket"
                  ],
                  "Resource": [
                      "arn:aws:s3:::${output-bucket}",
                      "arn:aws:s3:::${output-bucket}/*"
                  ]
              }
          ]
      }
      ```

------

   1. 在終端中，瀏覽至包含您建立之政策的資料夾。

   1. 提出 [CreateRole](https://docs.aws.amazon.com/IAM/latest/APIReference/API_CreateRole.html) 請求，以建立名為 *MyCustomizationRole* 的 IAM 角色，並連接您建立的 *BedrockTrust.json* 信任政策。

      ```
      aws iam create-role \
          --role-name MyCustomizationRole \
          --assume-role-policy-document file://BedrockTrust.json
      ```

   1. 提出 [CreatePolicy](https://docs.aws.amazon.com/IAM/latest/APIReference/API_CreatePolicy.html) 請求，使用您建立的 *MyFineTuningDataAccess.json* 檔案來建立 S3 資料存取政策。回應會傳回政策的 `Arn`。

      ```
      aws iam create-policy \
          --policy-name MyFineTuningDataAccess \
          --policy-document file://myFineTuningDataAccess.json
      ```

   1. 提出 [AttachRolePolicy](https://docs.aws.amazon.com/IAM/latest/APIReference/API_AttachRolePolicy.html) 請求，將 S3 資料存取政策連接至角色，在上一個步驟的回應中將 `policy-arn` 取代為 ARN：

      ```
      aws iam attach-role-policy \
          --role-name MyCustomizationRole \
          --policy-arn ${policy-arn}
      ```

------
#### [ Python ]

   1. 執行下列程式碼來發出 [CreateRole](https://docs.aws.amazon.com/IAM/latest/APIReference/API_CreateRole.html) 請求，以建立名為 *MyCustomizationRole* 的 IAM 角色，並發出 [CreatePolicy](https://docs.aws.amazon.com/IAM/latest/APIReference/API_CreatePolicy.html) 請求，以建立名為 *MyFineTuningDataAccess* 的 S3 資料存取政策。對於 S3 資料存取政策，請將 *\$1\$1training-bucket\$1* 和 *\$1\$1output-bucket\$1* 取代為您的 S3 儲存貯體名稱。

      ```
      import boto3
      import json
      
      iam = boto3.client("iam")
      
      iam.create_role(
          RoleName="MyCustomizationRole",
          AssumeRolePolicyDocument=json.dumps({
              "Version": "2012-10-17",		 	 	 
              "Statement": [
                  {
                      "Effect": "Allow",
                      "Principal": {
                          "Service": "bedrock.amazonaws.com"
                      },
                      "Action": "sts:AssumeRole"
                  }
              ] 
          })
      )
      
      iam.create_policy(
          PolicyName="MyFineTuningDataAccess",
          PolicyDocument=json.dumps({
              "Version": "2012-10-17",		 	 	 
              "Statement": [
                  {
                      "Effect": "Allow",
                      "Action": [
                          "s3:GetObject",
                          "s3:ListBucket"
                      ],
                      "Resource": [
                          "arn:aws:s3:::${training-bucket}",
                          "arn:aws:s3:::${training-bucket}/*"
                      ]
                  },
                  {
                      "Effect": "Allow",
                      "Action": [
                          "s3:GetObject",
                          "s3:PutObject",
                          "s3:ListBucket"
                      ],
                      "Resource": [
                          "arn:aws:s3:::${output-bucket}",
                          "arn:aws:s3:::${output-bucket}/*"
                      ]
                  }
              ]
          })
      )
      ```

   1. 回應中會傳回 `Arn`。執行下列程式碼片段來提出 [AttachRolePolicy](https://docs.aws.amazon.com/IAM/latest/APIReference/API_AttachRolePolicy.html) 請求，以傳回的 `Arn` 取代 *\$1\$1policy-arn\$1*。

      ```
      iam.attach_role_policy(
          RoleName="MyCustomizationRole",
          PolicyArn="${policy-arn}"
      )
      ```

------

1. 選取語言以查看程式碼範例，以呼叫模型自訂 API 操作。

------
#### [ CLI ]

首先，建立一個名為 *FineTuningData.json* 的文字檔。將 JSON 程式碼從下方複製到文字檔案，將 *\$1\$1training-bucket\$1* 和 *\$1\$1output-bucket\$1* 取代為您的 S3 儲存貯體名稱。

```
{
    "trainingDataConfig": {
        "s3Uri": "s3://${training-bucket}/train.jsonl"
    },
    "outputDataConfig": {
        "s3Uri": "s3://${output-bucket}"
    }
}
```

若要提交模型自訂任務，請導覽至終端中包含 *FineTuningData.json* 的資料夾，並在命令列中執行下列命令，以您設定的模型自訂角色取代 *\$1\$1your-customization-role-arn\$1*。

```
aws bedrock create-model-customization-job \
    --customization-type FINE_TUNING \
    --base-model-identifier arn:aws:bedrock:us-east-1::foundation-model/amazon.titan-text-express-v1 \
    --role-arn ${your-customization-role-arn} \
    --job-name MyFineTuningJob \
    --custom-model-name MyCustomModel \
    --hyper-parameters epochCount=1,batchSize=1,learningRate=.0001,learningRateWarmupSteps=0 \
    --cli-input-json file://FineTuningData.json
```

回應會傳回 *jobArn*。讓任務有時間完成。您可以使用下列命令來檢查其狀態。

```
aws bedrock get-model-customization-job \
    --job-identifier "jobArn"
```

當 `status` 為 `COMPLETE` 時，您可以在回應中看到 `trainingMetrics`。您可以執行下列命令，將 *aet.et-bucket* 取代為輸出儲存貯體名稱，並將 *jobId* 取代為自訂任務的 ID (`jobArn` 中最後一個斜線後面的序列)，以將成品下載至目前的資料夾。

```
aws s3 cp s3://${output-bucket}/model-customization-job-jobId . --recursive
```

使用下列命令為您的自訂模型購買無承諾佈建輸送量。

**注意**  
您將需要按小時支付此購買的費用。使用主控台查看不同選項的預估價格。

```
aws bedrock create-provisioned-model-throughput \
    --model-id MyCustomModel \
    --provisioned-model-name MyProvisionedCustomModel \
    --model-units 1
```

回應會傳回 `provisionedModelArn`。預留一些時間來建立佈建輸送量。若要檢查其狀態，請在下列命令中提供佈建模型的名稱或 ARN 作為 `provisioned-model-id`。

```
aws bedrock get-provisioned-model-throughput \
    --provisioned-model-id ${provisioned-model-arn}
```

當 `status` 為 `InService` 時，您可以使用下列命令，使用自訂模型執行推論。您必須提供佈建模型的 ARN 作為 `model-id`。輸出會寫入目前資料夾中名為 *output.txt* 的檔案。

```
aws bedrock-runtime invoke-model \
    --model-id ${provisioned-model-arn} \
    --body '{"inputText": "What is AWS?", "textGenerationConfig": {"temperature": 0.5}}' \
    --cli-binary-format raw-in-base64-out \
    output.txt
```

------
#### [ Python ]

執行下列程式碼片段以提交微調任務。將 *\$1\$1your-customization-role-arn\$1* 取代為您設定的 *MyCustomizationRole* ARN，並將 *\$1\$1training-bucket\$1* 和 *\$1\$1output-bucket\$1* 取代為您的 S3 儲存貯體名稱。

```
import boto3

bedrock = boto3.client(service_name='bedrock')
    
# Set parameters
customizationType = "FINE_TUNING"
baseModelIdentifier = "arn:aws:bedrock:us-east-1::foundation-model/amazon.titan-text-express-v1"
roleArn = "${your-customization-role-arn}"
jobName = "MyFineTuningJob"
customModelName = "MyCustomModel"
hyperParameters = {
        "epochCount": "1",
        "batchSize": "1",
        "learningRate": ".0001",
        "learningRateWarmupSteps": "0"
    }
trainingDataConfig = {"s3Uri": "s3://${training-bucket}/myInputData/train.jsonl"}
outputDataConfig = {"s3Uri": "s3://${output-bucket}/myOutputData"}

# Create job
response_ft = bedrock.create_model_customization_job(
    jobName=jobName, 
    customModelName=customModelName,
    roleArn=roleArn,
    baseModelIdentifier=baseModelIdentifier,
    hyperParameters=hyperParameters,
    trainingDataConfig=trainingDataConfig,
    outputDataConfig=outputDataConfig
)

jobArn = response_ft.get('jobArn')
```

回應會傳回 *jobArn*。讓任務有時間完成。您可以使用下列命令來檢查其狀態。

```
bedrock.get_model_customization_job(jobIdentifier=jobArn).get('status')
```

當 `status` 為 `COMPLETE` 時，您可以在 [GetModelCustomizationJob](https://docs.aws.amazon.com/bedrock/latest/APIReference/API_GetModelCustomizationJob.html) 回應中看到 `trainingMetrics`。您也可以遵循[下載物件](https://docs.aws.amazon.com/AmazonS3/latest/userguide/download-objects.html)的步驟來下載指標。

使用下列命令為您的自訂模型購買無承諾佈建輸送量。

```
response_pt = bedrock.create_provisioned_model_throughput(
    modelId="MyCustomModel",
    provisionedModelName="MyProvisionedCustomModel",
    modelUnits="1"
)

provisionedModelArn = response_pt.get('provisionedModelArn')
```

回應會傳回 `provisionedModelArn`。預留一些時間來建立佈建輸送量。若要檢查其狀態，請在下列命令中提供佈建模型的名稱或 ARN 作為 `provisionedModelId`。

```
bedrock.get_provisioned_model_throughput(provisionedModelId=provisionedModelArn)
```

當 `status` 為 `InService` 時，您可以使用下列命令，使用自訂模型執行推論。您必須提供佈建模型的 ARN 作為 `modelId`。

```
import json
import logging
import boto3

from botocore.exceptions import ClientError


class ImageError(Exception):
    "Custom exception for errors returned by the model"

    def __init__(self, message):
        self.message = message


logger = logging.getLogger(__name__)
logging.basicConfig(level=logging.INFO)


def generate_text(model_id, body):
    """
    Generate text using your provisioned custom model.
    Args:
        model_id (str): The model ID to use.
        body (str) : The request body to use.
    Returns:
        response (json): The response from the model.
    """

    logger.info(
        "Generating text with your provisioned custom model %s", model_id)

    brt = boto3.client(service_name='bedrock-runtime')

    accept = "application/json"
    content_type = "application/json"

    response = brt.invoke_model(
        body=body, modelId=model_id, accept=accept, contentType=content_type
    )
    response_body = json.loads(response.get("body").read())

    finish_reason = response_body.get("error")

    if finish_reason is not None:
        raise ImageError(f"Text generation error. Error is {finish_reason}")

    logger.info(
        "Successfully generated text with provisioned custom model %s", model_id)

    return response_body


def main():
    """
    Entrypoint for example.
    """
    try:
        logging.basicConfig(level=logging.INFO,
                            format="%(levelname)s: %(message)s")

        model_id = provisionedModelArn

        body = json.dumps({
            "inputText": "what is AWS?"
        })

        response_body = generate_text(model_id, body)
        print(f"Input token count: {response_body['inputTextTokenCount']}")

        for result in response_body['results']:
            print(f"Token count: {result['tokenCount']}")
            print(f"Output text: {result['outputText']}")
            print(f"Completion reason: {result['completionReason']}")

    except ClientError as err:
        message = err.response["Error"]["Message"]
        logger.error("A client error occurred: %s", message)
        print("A client error occured: " +
              format(message))
    except ImageError as err:
        logger.error(err.message)
        print(err.message)

    else:
        print(
            f"Finished generating text with your provisioned custom model {model_id}.")


if __name__ == "__main__":
    main()
```

------