Amazon SageMaker 提供了一個無縫的體驗,讓使用者可以在大規模上建立、訓練和部署機器學習 (ML) 模型。雖然 SageMaker 提供了許多內建的演算法和預訓練模型,透過 Amazon SageMaker JumpStart,但在某些情況下,您可能需要使用自訂模型或特定的軟體依賴,這些在 SageMaker 管理的容器映像中並不存在。例如,這可能包括地理空間分析、生物資訊研究或量子機器學習等應用。在這種情況下,SageMaker 允許您透過創建自訂容器映像和定義自訂模型定義來擴展其功能。這種方法使您能夠將模型工件、依賴項和推論代碼打包到一個容器映像中,然後將其部署為 SageMaker 端點,以進行實時推論。這篇文章將帶您了解如何使用 NASA 的 Prithvi 模型在 SageMaker 上部署單一自訂模型的完整過程。Prithvi 模型是由 IBM 和 NASA 團隊在美國連續的 Harmonised Landsat Sentinel 2 (HLS) 數據上預訓練的首個時間視覺變壓器。它可以使用 mmsegmentation 庫進行圖像分割的微調,適用於燒傷疤痕檢測、洪水映射和多時期作物分類等用例。由於其獨特的架構和對 MMCV 庫的微調依賴,它是一個有效的範例,展示如何將複雜的自訂模型部署到 SageMaker。我們將展示如何利用 SageMaker 的靈活性來部署您自己的自訂模型,以滿足您的特定用例和需求。無論您是使用獨特的模型架構、專門的庫,還是特定的軟體版本,這種方法都能讓您在保持對模型環境和依賴的控制的同時,充分利用 SageMaker 的可擴展性和管理能力。
解決方案概述
要在 SageMaker 端點上運行需要獨特套件的自訂模型,您需要遵循以下步驟:
如果您的模型需要額外的套件或在 SageMaker 管理的容器映像中不可用的套件版本,您需要擴展其中一個容器映像。通過擴展 SageMaker 管理的容器,而不是從頭開始創建一個,您可以專注於您的特定用例和模型開發,而不是容器基礎設施。
使用 SageMaker inference.py 文件格式編寫 Python 模型定義。
在特定的文件結構中定義您的模型工件和推論文件,將模型文件打包為 tar.gz 文件,並將文件上傳到 Amazon Simple Storage Service (Amazon S3)。
使用您的模型代碼和擴展的 SageMaker 容器,使用 Amazon SageMaker Studio 創建模型、端點配置和端點。
查詢推論端點以確認您的模型是否正確運行。
以下圖示說明了解決方案架構和工作流程:
前置條件
在您可以繼續之前,您需要滿足以下前置條件。本篇文章使用 us-east-1 AWS 區域:
擁有訪問 POSIX 基礎 (Mac/Linux) 系統或 SageMaker 筆記本的權限。這篇文章不涵蓋設置 SageMaker 訪問,假設有一個可以訪問互聯網的筆記本。然而,這不是安全的最佳實踐,不應在生產環境中這樣做。要了解如何在虛擬私有雲 (VPC) 中創建 SageMaker 筆記本,請參見在您的 VPC 中連接到 SageMaker AI。
確保您擁有 SageMaker 訪問的 AWS 身份和訪問管理 (IAM) 權限;S3 存儲桶的創建、讀取和 PutObject 訪問權限;AWS CodeBuild 訪問權限;Amazon Elastic Container Registry (Amazon ECR) 存儲庫訪問權限;以及創建 IAM 角色的能力。
下載 Prithvi 模型工件和洪水數據微調:
curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | sudo bash
sudo apt-get install git-lfs
git lfs install
git clone https://huggingface.co/ibm-nasa-geospatial/Prithvi-100M
git clone https://huggingface.co/ibm-nasa-geospatial/Prithvi-100M-sen1floods11
擴展 SageMaker 容器映像以適應您的模型
雖然 AWS 提供了針對深度學習優化的預建容器映像,這些映像在 AWS Deep Learning Containers (DLCs) GitHub 上可用於 PyTorch 和 TensorFlow 用例,但在某些情況下,模型需要額外的庫,而這些庫並不包含在這些容器中。安裝這些依賴項可能需要幾分鐘或幾個小時,因此將這些依賴項預先構建到自訂容器映像中會更有效率。在這個例子中,我們部署的 Prithvi 模型依賴於 MMCV 庫,用於高級計算機視覺技術。這個庫在任何 SageMaker DLC 中都不可用,因此您必須創建一個擴展容器來添加它。MMC和 Prithvi 都是第三方模型,尚未經過 AWS 安全審查,因此請自行檢查這些模型或自行承擔風險。這篇文章使用 CodeBuild 和 Docker Dockerfile 來構建擴展容器。
完成以下步驟:
CodeBuild 需要一個包含源代碼的來源位置。使用以下命令創建一個 S3 存儲桶作為此來源位置:
# 生成唯一的後綴
BUCKET_POSTFIX=$(python3 -S -c “import uuid; print(str(uuid.uuid4().hex)[:10])”)
echo “export BUCKET_POSTFIX=$BUCKET_POSTFIX” >> ~/.bashrc
echo “您的存儲桶名稱將是 customsagemakercontainer-codebuildsource-$BUCKET_POSTFIX”
# 創建您的存儲桶
aws s3 mb s3://customsagemakercontainer-codebuildsource-$BUCKET_POSTFIX
創建一個 ECR 存儲庫來存儲 CodeBuild 項目生成的自訂容器映像。將存儲庫 URI 記錄為環境變量。
CONTAINER_REPOSITORY_NAME=”prithvi”
aws ecr create-repository –repository-name $CONTAINER_REPOSITORY_NAME
export REPOSITORY_URI=$(aws ecr describe-repositories –repository-names $CONTAINER_REPOSITORY_NAME –query ‘repositories[0].repositoryUri’ –output text)
為自訂容器創建一個 Dockerfile。您使用 AWS Deep Learning SageMaker 框架容器作為基礎映像,因為它包含所需的依賴項,如 SageMaker 庫、PyTorch 和 CUDA。
這個 Docker 容器安裝了 Prithvi 模型和 MMCV v1.6.2。這些模型是第三方模型,並非由 AWS 生產,因此可能存在安全漏洞。請自行承擔風險。
cat > Dockerfile << EOF
FROM 763104351884.dkr.ecr.us-east-1.amazonaws.com/pytorch-inference:1.13.1-gpu-py39-cu117-ubuntu20.04-sagemaker
WORKDIR /root
RUN DEBIAN_FRONTEND=noninteractive apt-get update -y
RUN DEBIAN_FRONTEND=noninteractive apt-get upgrade -y
RUN git clone https://github.com/NASA-IMPACT/hls-foundation-os.git
RUN wget https://github.com/open-mmlab/mmcv/archive/refs/tags/v1.6.2.tar.gz
RUN tar xvzf v1.6.2.tar.gz
WORKDIR /root/hls-foundation-os
RUN pip install -e .
RUN pip install -U openmim
WORKDIR /root/mmcv-1.6.2
RUN MMCV_WITH_OPS=1 pip install -e . -v
EOF
創建一個 buildspec 文件,以定義 CodeBuild 項目的構建過程。這個 buildspec 文件將指示 CodeBuild 安裝 nvidia-container-toolkit,以確保 Docker 容器可以訪問 GPU,運行 Dockerfile 構建,並將構建的容器映像推送到您的 ECR 存儲庫。
cat > buildspec.yml << EOF
version: 0.2
phases:
pre_build:
commands:
– echo 正在登錄到 Amazon ECR…
– IMAGE_TAG=sagemaker-gpu
– curl -s -L https://nvidia.github.io/libnvidia-container/stable/rpm/nvidia-container-toolkit.repo | sudo tee /etc/yum.repos.d/nvidia-container-toolkit.repo
– sudo yum install -y nvidia-container-toolkit
– sudo nvidia-ctk runtime configure –runtime=docker
– |
cat > /etc/docker/daemon.json << EOF
“runtimes”:
“nvidia”:
“args”: [],
“path”: “nvidia-container-runtime”
,
“default-runtime”: “nvidia”
EOF
– kill \$(ps aux | grep -v grep | grep “/usr/local/bin/dockerd –host” | awk ‘print \$2’)
– sleep 10
– nohup /usr/local/bin/dockerd –host=unix:///var/run/docker.sock –host=tcp://127.0.0.1:2375 –storage-driver=overlay2 &
– sleep 10
– aws ecr get-login-password –region \$AWS_REGION | docker login –username AWS –password-stdin \$REPOSITORY_URI_AWSDL
– docker pull \$REPOSITORY_URI_AWSDL/pytorch-inference:1.13.1-gpu-py39-cu117-ubuntu20.04-sagemaker
build:
commands:
– echo 構建於 \$(date) 開始
– echo 正在構建 Docker 映像…
– aws ecr get-login-password –region \$AWS_REGION | docker login –username AWS –password-stdin \$REPOSITORY_URI
– DOCKER_BUILDKIT=0 docker build -t \$REPOSITORY_URI:latest .
– docker tag \$REPOSITORY_URI:latest \$REPOSITORY_URI:\$IMAGE_TAG
post_build:
commands:
– echo 構建於 \$(date) 完成
– echo 正在推送 Docker 映像…
– docker push \$REPOSITORY_URI:latest
– docker push \$REPOSITORY_URI:\$IMAGE_TAG
EOF
將 Dockerfile 和 buildspec.yml 文件壓縮並上傳到 S3 存儲桶。這個 zip 文件將作為 CodeBuild 項目的源代碼。
要在 SageMaker 筆記本上安裝 zip,請運行以下命令:
安裝 zip 後,運行以下命令:
zip prithvi_container_source.zip Dockerfile buildspec.yml
aws s3 cp prithvi_container_source.zip s3://customsagemakercontainer-codebuildsource-$BUCKET_POSTFIX/
創建一個 CodeBuild 服務角色,以便 CodeBuild 可以訪問構建所需的 AWS 服務。
首先,創建一個文件來定義角色的信任策略:
cat > create-role.json << EOF
“Version”: “2012-10-17”,
“Statement”: [
“Effect”: “Allow”,
“Principal”:
“Service”: “codebuild.amazonaws.com”
,
“Action”: “sts:AssumeRole”
]
EOF
創建一個文件來定義服務角色的權限。這個角色有一些通配符權限 (/* 或 *)。這些可能會給予比所需更多的權限,並破壞最小權限的規則。要了解有關為生產用例定義最小權限的更多信息,請參見授予最小權限。
cat > put-role-policy.json << EOF
“Version”: “2012-10-17”,
“Statement”: [
“Sid”: “CloudWatchLogsPolicy”,
“Effect”: “Allow”,
“Action”: [
“logs:CreateLogGroup”,
“logs:CreateLogStream”,
“logs:PutLogEvents”
],
“Resource”: “arn:aws:logs:us-east-1:*:log-group:/aws/codebuild/*:*”
,
“Sid”: “S3GetObjectPolicy”,
“Effect”: “Allow”,
“Action”: [
“s3:GetObject”,
“s3:GetObjectVersion”
],
“Resource”: [
“arn:aws:s3:::customsagemakercontainer-codebuildsource-$BUCKET_POSTFIX”,
“arn:aws:s3:::customsagemakercontainer-codebuildsource-$BUCKET_POSTFIX/*”
]
,
“Sid”: “S3BucketIdentity”,
“Effect”: “Allow”,
“Action”: [
“s3:GetBucketAcl”,
“s3:GetBucketLocation”
],
“Resource”: “arn:aws:s3:::customsagemakercontainer-codebuildsource-$BUCKET_POSTFIX”
,
“Sid”: “ECRAccess”,
“Effect”: “Allow”,
“Action”: [
“ecr:GetImage”,
“ecr:BatchGetImage”,
“ecr:BatchCheckLayerAvailability”,
“ecr:CompleteLayerUpload”,
“ecr:UploadLayerPart”,
“ecr:GetDownloadUrlForLayer”,
“ecr:InitiateLayerUpload”,
“ecr:PutImage”,
“ecr:ListImages”,
“ecr:DescribeRepositories”,
“ecr:DescribeImages”,
“ecr:DescribeRegistry”,
“ecr:TagResource”
],
“Resource”: [“arn:aws:ecr:*:*:repository/prithvi”,
“arn:aws:ecr:*:763104351884:repository/*”]
,
“Sid”: “ECRAuthToken”,
“Effect”: “Allow”,
“Action”: [
“ecr:GetAuthorizationToken”
],
“Resource”: “*”
]
EOF
創建 CodeBuild 服務角色:
aws iam create-role –role-name CodeBuildServiceRole –assume-role-policy-document file://create-role.json
從 CLI 命令響應中捕獲角色的 Amazon 資源名稱 (ARN),並記錄為環境變量:
export CODEBUILD_SERVICE_ROLE_ARN=$(aws iam get-role –role-name CodeBuildServiceRole –query ‘Role.Arn’ –output text)
將權限策略附加到服務角色:
aws iam put-role-policy –role-name CodeBuildServiceRole –policy-name CodeBuildServiceRolePolicy –policy-document file://put-role-policy.json
使用構建專案 JSON 規範定義 CodeBuild 構建專案的配置:
cat > codebuild-project.json << EOF
“name”: “prithvi-container-build”,
“description”: “修改 AWS SageMaker 深度學習容器以包含 HLS/Prithvi 的構建過程”,
“source”:
“type”: “S3”,
“location”: “customsagemakercontainer-codebuildsource-$BUCKET_POSTFIX/prithvi_container_source.zip”,
“buildspec”: “buildspec.yml”,
“insecureSsl”: false
,
“artifacts”:
“type”: “NO_ARTIFACTS”
,
“cache”:
“type”: “NO_CACHE”
,
“environment”:
“type”: “LINUX_GPU_CONTAINER”,
“image”: “aws/codebuild/amazonlinux2-x86_64-standard:5.0”,
“computeType”: “BUILD_GENERAL1_SMALL”,
“environmentVariables”: [
“name”: “REPOSITORY_URI_AWSDL”,
“value”: “763104351884.dkr.ecr.us-east-1.amazonaws.com”,
“type”: “PLAINTEXT”
,
“name”: “AWS_REGION”,
“value”: “us-east-1”,
“type”: “PLAINTEXT”
,
“name”: “REPOSITORY_URI”,
“value”: “$REPOSITORY_URI”,
“type”: “PLAINTEXT”
],
“imagePullCredentialsType”: “CODEBUILD”,
“privilegedMode”: true
,
“serviceRole”: “$CODEBUILD_SERVICE_ROLE_ARN”,
“timeoutInMinutes”: 60,
“queuedTimeoutInMinutes”: 480,
“logsConfig”:
“cloudWatchLogs”:
“status”: “ENABLED”
EOF
使用前一步中定義的 codebuild-project.json 規範創建 CodeBuild 專案:
aws codebuild create-project –cli-input-json file://codebuild-project.json
為 CodeBuild 專案運行構建:
aws codebuild start-build –project-name prithvi-container-build
構建大約需要 30 分鐘完成,運行成本約為 1.50 美元。CodeBuild 計算實例類型 gpu1.small 每分鐘成本為 0.05 美元。
在運行前面的命令後,您可以按 Ctrl+C 退出並運行未來的命令。構建將已在 AWS 上運行,並且關閉命令不會取消它。
使用以下命令監控構建狀態,並等待直到您觀察到 buildStatus=SUCCEEDED 才繼續下一步:
export BUILD_ID=$(aws codebuild list-builds-for-project –project-name prithvi-container-build –query ‘ids[0]’ –output text) aws codebuild batch-get-builds –ids $BUILD_ID | grep buildStatus
在您的 CodeBuild 專案完成後,請確保不要關閉終端。這裡的環境變量將再次使用。
構建您的 inference.py 文件
要在 AWS 上運行自訂模型進行推論,您需要構建一個 inference.py 文件,該文件初始化您的模型,定義輸入和輸出結構,並生成推論結果。在這個文件中,您必須定義四個函數:
model_fn – 初始化您的模型
input_fn – 定義您的數據應如何輸入以及如何轉換為可用格式
predict_fn – 接收輸入數據並生成預測
output_fn – 將預測轉換為 API 調用格式
在這篇文章中,我們使用以下完成的 inference.py 文件作為 SageMaker 端點。下載這個 inference.py 以繼續,因為它包含處理該模型輸入所需的 TIFF 文件的輔助函數。以下代碼包含在 inference.py 中,僅顯示以解釋文件中所做的內容。
model_fn
model_fn 函數構建您的模型,該模型在 predict_fn 函數中被調用和使用。這個函數將模型權重加載到 torch 模型檢查點中,打開模型配置,定義全局變量,實例化模型,將模型檢查點加載到模型中,並返回模型。
def model_fn(model_dir):
# 實現自訂代碼以加載模型
# 加載權重
weights_path = “./code/prithvi/Prithvi_100M.pt”
checkpoint = torch.load(weights_path, map_location=”cpu”)
# 讀取模型配置
model_cfg_path = “./code/prithvi/Prithvi_100M_config.yaml”
with open(model_cfg_path) as f:
model_config = yaml.safe_load(f)
model_args, train_args = model_config[“model_args”], model_config[“train_params”]
global means
global stds
means = np.array(train_args[“data_mean”]).reshape(-1, 1, 1)
stds = np.array(train_args[“data_std”]).reshape(-1, 1, 1)
# 目前只使用 1 幀 (模型是基於 3 幀訓練的)
model_args[“num_frames”] = 1
# 實例化模型
model = MaskedAutoencoderViT(**model_args)
model.eval()
# 將權重加載到模型中
# strict=false 因為我們只使用 1 幀進行加載,但預期會有警告
del checkpoint[‘pos_embed’]
del checkpoint[‘decoder_pos_embed’]
_ = model.load_state_dict(checkpoint, strict=False)
return model
input_fn
這個函數定義了模型的預期輸入以及如何加載輸入以供 predict_fn 使用。端點期望一個指向 TIFF 文件的字符串 URL 路徑,您可以從 Hugging Face 的 Prithvi 演示中找到。這個函數還定義了在請求主體中發送的請求的內容類型(例如 application/json、image/tiff)。
def input_fn(input_data, content_type):
# 解碼輸入數據 (e.g. JSON 字符串 -> dict)
# 用於在傳遞給模型之前對圖像進行標準化的統計數據
raster_data = load_raster(input_data, crop=(224, 224))
return raster_data
predict_fn:
在 predict_fn 中,您從給定的輸入中創建預測。在這種情況下,創建預測圖像使用兩個特定於此端點的輔助函數 (preprocess_image 和 enhance_raster_for_visualization)。您可以在這裡找到這兩個函數。preprocess_image 函數對圖像進行標準化,然後該函數使用 torch.no_grad 禁用模型的梯度計算。這在推論期間是有用的,可以減少推論時間並降低內存使用。接下來,該函數從實例化的模型中收集預測。mask ratio 決定在推論期間圖像上零化的像素數量。兩個 unpatchify 函數將模型生成的較小的 patchified 結果轉換回原始圖像空間。函數 normalized.clone() 克隆標準化的圖像,並用 rec_img 中的區域替換 mask_img 中的區域。最後,該函數將圖像重新塑形回 TIFF 格式,移除標準化並返回以光柵格式的圖像,這對於可視化非常有價值。這樣的結果是一個可以轉換為字節以供用戶使用的圖像,然後在用戶的屏幕上顯示。
def predict_fn(data, model):
normalized = preprocess_image(data)
with torch.no_grad():
mask_ratio = 0.5
_, pred, mask = model(normalized, mask_ratio=mask_ratio)
mask_img = model.unpatchify(mask.unsqueeze(-1).repeat(1, 1, pred.shape[-1])).detach().cpu()
pred_img = model.unpatchify(pred).detach().cpu()#.numpy()
rec_img = normalized.clone()
rec_img[mask_img == 1] = pred_img[mask_img == 1]
rec_img_np = (rec_img.numpy().reshape(6, 224, 224) * stds) + means
print(rec_img_np.shape)
return enhance_raster_for_visualization(rec_img_np, ref_img=data)
output_fn
output_fn 將從 predict_fn 接收到的 TIFF 圖像作為字節數組返回。
def output_fn(prediction, accept):
print(prediction.shape)
return prediction.tobytes()
測試您的 inference.py 文件
現在您已經下載了完整的 inference.py 文件,您有兩個選擇可以在壓縮文件並上傳到 Amazon S3 之前測試您的模型:
在 Amazon Elastic Compute Cloud (Amazon EC2) 實例上測試 inference.py 函數
在本地模式的 SageMaker 端點上測試您的端點(需要 GPU 或基於 GPU 的工作區來運行此模型)
模型文件結構、tar.gz 壓縮和 S3 上傳
在您開始這一步之前,下載 Prithvi 模型工件和 Prithvi 模型的洪水微調。第一個鏈接將提供來自基礎 Prithvi 模型的所有模型數據,而洪水微調模型則基於該模型進行構建,以在衛星圖像上執行洪泛檢測。使用 brew 在 Mac 上安裝 git-lfs,或使用 https://git-lfs.com/ 在 Windows 上安裝 GitHub 倉庫的大文件。
curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | sudo bash
sudo apt-get install git-lfs
git lfs install
git clone https://huggingface.co/ibm-nasa-geospatial/Prithvi-100M
cd Prithvi-100M
git lfs pull
git checkout c2435efd8f92329d3ca79fc8a7a70e21e675a650
git clone https://huggingface.co/ibm-nasa-geospatial/Prithvi-100M-sen1floods11
cd Prithvi-100M-sen1floods11
git lfs pull
git checkout d48937bf588cd506dd73bc4deca543446ca5530d
要在 SageMaker 控制台上創建 SageMaker 模型,您必須將模型數據存儲在 Amazon S3 中,因為您的 SageMaker 端點將直接從 Amazon S3 使用 tar.gz 格式提取模型工件。在您的 tar.gz 文件中,數據必須具有 SageMaker 定義的特定文件格式。以下是 Prithvi 基礎模型的文件結構(我們的要求已安裝在容器中,因此 requirements.txt 被故意留空):
./model
./model/code/inference.py
./model/code/sen1floods11_Prithvi_100M.py (擴展模型配置)
./model/code/sen1floods11_Prithvi_100M.pth (擴展模型權重)
./model/code/requirements.txt
./model/code/prithvi/Prithvi_100M.pt (擴展模型權重)
./model/code/prithvi/Prithvi_100M_config.yaml (模型配置)
./model/code/prithvi/Prithvi.py (模型)
這個文件夾結構對其他模型也適用。/code 文件夾必須包含 inference.py 文件和在 inference.py 中使用的任何文件。這些附加文件通常是模型工件(配置、權重等)。在我們的情況下,這將是整個 Prithvi 基礎模型文件夾以及我們將使用的微調版本的權重和配置。由於我們已經在容器中安裝了這些包,因此不會使用這些包;然而,仍然必須有一個 requirements.txt 文件,否則您的端點將無法構建。所有其他文件都應放在根文件夾中。
在前面的文件結構到位後,打開您的終端並進入模型文件夾。
在終端中運行以下命令:
tar -czvf model.tar.gz ./
該命令將從當前目錄中的文件創建一個名為 model.tar.gz 的模型文件的壓縮版本。您現在可以將此文件上傳到 S3 存儲桶。
如果使用 SageMaker,運行以下命令:
sudo apt-get install uuid-runtime
現在創建一個新的 S3 存儲桶。以下 CLI 命令創建一個 S3 存儲桶並上傳您的 model.tar.gz 文件:
# 生成唯一的後綴
BUCKET_POSTFIX=$(uuidgen –random | cut -d’-‘ -f1)
echo “export BUCKET_POSTFIX=$BUCKET_POSTFIX” >> ~/.bashrc
echo “您的存儲桶名稱將是 customsagemakercontainer-model-$BUCKET_POSTFIX”
# 創建您的存儲桶
aws s3 mb s3://customsagemakercontainer-model-$BUCKET_POSTFIX
# 上傳到您的存儲桶
aws s3 cp model.tar.gz s3://customsagemakercontainer-model-$BUCKET_POSTFIX/model.tar.gz
您上傳的文件將在下一步中用於定義要在端點中創建的模型。
創建 SageMaker 模型、SageMaker 端點配置和 SageMaker 端點
您現在可以使用 CLI 創建 SageMaker 推論端點。創建 SageMaker 端點有三個步驟:創建模型、創建端點配置和創建端點。
在這篇文章中,您將創建一個公共的 SageMaker 端點,因為這將簡化運行和測試端點的過程。要了解如何限制對 SageMaker 端點的訪問,請參見使用 SageMaker Studio 部署模型。
完成以下步驟:
獲取 ECR 存儲庫的 ARN:
export REPOSITORY_ARN=$(aws ecr describe-repositories –repository-names $CONTAINER_REPOSITORY_NAME –query ‘repositories[0].repositoryArn’ –output text)
創建一個角色供 SageMaker 服務使用。創建一個文件來定義角色的信任政策。
cat > create-sagemaker-role.json << EOF
“Version”: “2012-10-17”,
“Statement”: [
“Effect”: “Allow”,
“Principal”:
“Service”: “sagemaker.amazonaws.com”
,
“Action”: “sts:AssumeRole”
]
EOF
創建一個文件來定義服務角色的權限:
cat > put-sagemaker-role-policy.json << EOF
“Version”: “2012-10-17”,
“Statement”: [
“Action”: [
“s3:ListBucket”
],
“Effect”: “Allow”,
“Resource”: [
“arn:aws:s3:::customsagemakercontainer-model-$BUCKET_POSTFIX”
]
,
“Action”: [
“s3:GetObject”,
“s3:PutObject”,
“s3:DeleteObject”
],
“Effect”: “Allow”,
“Resource”: [
“arn:aws:s3:::customsagemakercontainer-model-$BUCKET_POSTFIX/*”
]
,
“Effect”: “Allow”,
“Action”: [
“sagemaker:BatchPutMetrics”,
“ecr:GetAuthorizationToken”,
“ecr:ListImages”
],
“Resource”: “*”
,
“Effect”: “Allow”,
“Action”: [
“ecr:BatchCheckLayerAvailability”,
“ecr:GetDownloadUrlForLayer”,
“ecr:BatchGetImage”
],
“Resource”: [
“$REPOSITORY_ARN”
]
,
“Effect”: “Allow”,
“Action”: “cloudwatch:PutMetricData”,
“Resource”: “*”,
“Condition”:
“StringLike”:
“cloudwatch:namespace”: [
“*SageMaker*”,
“*Sagemaker*”,
“*sagemaker*”
]
,
“Effect”: “Allow”,
“Action”: [
“logs:CreateLogStream”,
“logs:PutLogEvents”,
“logs:CreateLogGroup”,
“logs:DescribeLogStreams”
],
“Resource”: “arn:aws:logs:*:*:log-group:/aws/sagemaker/*”
]
EOF
創建 SageMaker 服務角色:
aws iam create-role –role-name SageMakerInferenceRole –assume-role-policy-document file://create-sagemaker-role.json
export SAGEMAKER_INFERENCE_ROLE_ARN=$(aws iam get-role –role-name SageMakerInferenceRole –query ‘Role.Arn’ –output text)
將權限策略附加到服務角色:
aws iam put-role-policy –role-name SageMakerInferenceRole –policy-name SageMakerInferenceServiceRolePolicy –policy-document file://put-sagemaker-role-policy.json
模型定義將包括您創建的角色、ECR 容器映像和您之前創建的 model.tar.gz 文件的 Amazon S3 位置。
創建一個 JSON 文件來定義模型,並運行創建模型命令:
cat > create_model.json << EOF
“ModelName”: “prithvi”,
“PrimaryContainer”:
“Image”: “$REPOSITORY_URI:latest”,
“ModelDataUrl”: “s3://customsagemakercontainer-model-$BUCKET_POSTFIX/model.tar.gz”
,
“ExecutionRoleArn”: “$SAGEMAKER_INFERENCE_ROLE_ARN”
EOF
aws sagemaker create-model –cli-input-json file://create_model.json
SageMaker 端點配置指定模型將托管的基礎設施。該模型將在 ml.g4dn.xlarge 實例上托管,以實現 GPU 加速。
創建端點配置 JSON 文件並創建 SageMaker 端點配置:
cat > create_endpoint_config.json << EOF
“EndpointConfigName”: “prithvi-endpoint-config”,
“ProductionVariants”: [
“VariantName”: “default-variant”,
“ModelName”: “prithvi”,
“InitialInstanceCount”: 1,
“InstanceType”: “ml.g4dn.xlarge”,
“InitialVariantWeight”: 1.0
]
EOF
aws sagemaker create-endpoint-config –cli-input-json file://create_endpoint_config.json
通過引用在前一步中創建的端點配置來創建 SageMaker 端點:
aws sagemaker create-endpoint –endpoint-name prithvi-endpoint –endpoint-config-name prithvi-endpoint-config
ml.g4dn.xlarge 推論端點運行時每小時成本為 0.736 美元。端點完成部署需要幾分鐘。
使用以下命令檢查狀態,等待其返回 InService:
aws sagemaker describe-endpoint –endpoint-name prithvi-endpoint –query “EndpointStatus” –output text
當端點的狀態為 InService 時,請繼續下一部分。
測試您的自訂 SageMaker 推論端點
要測試您的 SageMaker 端點,您將使用圖像查詢端點並顯示它。以下命令將一個引用 TIFF 圖像的 URL 發送到 SageMaker 端點,模型將返回一個字節數組,該命令將字節數組重新形成為圖像。在本地或 SageMaker Studio JupyterLab 中打開一個筆記本。以下代碼需要在命令行外運行以查看圖像。
from sagemaker.predictor import Predictor
from sagemaker.serializers import JSONSerializer
payload = “https://huggingface.co/ibm-nasa-geospatial/Prithvi-EO-1.0-100M/resolve/main/examples/HLS.L30.T13REN.2018013T172747.v2.0.B02.B03.B04.B05.B06.B07_cropped.tif”
predictor = Predictor(endpoint_name=”prithvi-endpoint”)
predictor.serializer = JSONSerializer()
predictions = predictor.predict(payload)
這段 Python 代碼為您的端點創建了一個預測器對象,並將預測器的序列化器設置為 NumPy,以便在端點上進行轉換。它使用指向 TIFF 圖像的 URL 作為有效負載查詢預測器對象。您可以在這裡找到輔助函數以顯示圖像並增強光柵。添加輔助函數後,顯示圖像:
import numpy as np
import matplotlib.pyplot as plt
NO_DATA_FLOAT = 0.0001
PERCENTILES = (0.1, 99.9)
NO_DATA = -9999
nppred = np.frombuffer(predictions).reshape((224, 224, 3))
def enhance_raster_for_visualization(raster, ref_img=None):
if ref_img is None:
ref_img = raster
channels = []
for channel in range(raster.shape[0]):
valid_mask = np.ones_like(ref_img[channel], dtype=bool)
valid_mask[ref_img[channel] == NO_DATA_FLOAT] = False
mins, maxs = np.percentile(ref_img[channel][valid_mask], PERCENTILES)
normalized_raster = (raster[channel] – mins) / (maxs – mins)
normalized_raster[~valid_mask] = 0
clipped = np.clip(normalized_raster, 0, 1)
channels.append(clipped)
clipped = np.stack(channels)
channels_last = np.moveaxis(clipped, 0, -1)[…, :3]
rgb = channels_last[…, ::-1]
return rgb
raster_for_visualization = enhance_raster_for_visualization(nppred)
plt.imshow(nppred)
plt.show()
您應該能夠看到一張衛星拍攝的圖像。
清理
為了清理這篇文章中的資源並避免產生費用,請遵循以下步驟:
刪除 SageMaker 端點、端點配置和模型。
刪除 ECR 映像和存儲庫。
刪除創建的 S3 存儲桶中的 model.tar.gz 文件。
刪除 customsagemakercontainer-model 和 customsagemakercontainer-codebuildsource S3 存儲桶。
結論
在這篇文章中,我們擴展了 SageMaker 容器以包含自訂依賴,編寫了一個 Python 腳本來運行自訂 ML 模型,並在 SageMaker 端點內的 SageMaker 容器上部署該模型以進行實時推論。這個解決方案生成了一個運行中的 GPU 啟用端點,以進行推論查詢。您可以使用相同的過程來創建自訂模型的 SageMaker 端點,通過擴展其他 SageMaker 容器並為新的自訂模型編寫 inference.py 文件。此外,通過調整,您可以創建多模型的 SageMaker 端點,或運行批處理端點,以便在一次運行中處理大量查詢。這些解決方案使您能夠超越當前最受歡迎的模型,並自訂模型以適應您獨特的用例。
關於作者
Aidan 是一名解決方案架構師,支持美國聯邦政府健康客戶。他通過開發技術架構和提供有關 Amazon Web Services (AWS) 雲的最佳實踐來協助客戶,專注於 AI/ML 服務。在空閒時間,Aidan 喜歡旅行、健身和烹飪。
Nate 是一名解決方案架構師,支持美國聯邦政府科學客戶。他協助客戶在 Amazon Web Services (AWS) 上開發技術架構,專注於數據分析和高性能計算。在空閒時間,他喜歡滑雪和打高爾夫球。
Charlotte 是 Amazon Web Services (AWS) 航空航天和衛星團隊的解決方案架構師,她幫助客戶通過創新的雲解決方案實現其任務目標。Charlotte 專注於機器學習,特別是生成式 AI。在空閒時間,她喜歡旅行、繪畫和跑步。