Amazon SageMaker JumpStartでリアルタイム推論エンドポイントにモデルをデプロイしてみた

## はじめに
Amazon Sagemaker AIを触ってみたかったのですが、
機能が豊富すぎて、どこから手をつけていいか分かりませんでした。

そこで入門のための足がかりとしてSageMaker JumpStartを使って、
事前学習済みのモデルを、推論エンドポイントにデプロイしてみました。

## 目次
1. [はじめに](#はじめに)
2. [Amazon SageMaker JumpStartとは?](#Amazon-SageMaker-JumpStartとは？)
3. [事前学習済みモデルをデプロイ](#事前学習済みモデルをデプロイ)
4. [推論エンドポイントにアクセス](#推論エンドポイントにアクセス)
5. [まとめ](#まとめ)


## Amazon SageMaker JumpStartとは？
JumpStartはSageMaker AIの機能の一部です。
事前学習済みの機械学習オープンソースモデルを手軽にデプロイできます。
モデルを一から作成しなくても良い点が魅力的です。
選択するモデルによってはファインチューニングや評価も行うことができます。


## 事前学習済みモデルをデプロイ
### 条件
- IAMユーザーは検証用にadmin権限付与
- 使用リージョンはオレゴン(us-west-2)を選択


#### Amazon SageMaker AI にアクセス
検索バーに「sagemakerAI」と入力し、
サービスにある「Amazon SageMaker AI」 をクリックします。
![コンソールのホーム___コンソールのホーム___us-west-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1053703/96e478d5-813d-7387-eac0-d10548025bb8.png)


#### ドメインとプロファイルを作成する
「シングルユーザー向けの設定」をクリックします。
SageMaker Studioで使用するドメインとプロファイルが作成されます。
![Amazon_SageMaker_AI___us-east-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1053703/372ab46b-9963-13f8-4f18-3e6815957445.png)

#### SageMaker Studioを開く
左のメニューバーから「Studio」をクリックします。
「Studioを開く」をクリックすると、新規タブが立ち上がります。
![0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1053703/8c70b4e8-5c68-02cd-873f-86433f738a26.png)


#### JumpStartから使用するモデルを選択する
SageMaker Studioの左のメニューから「JumpStart」をクリックします。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1053703/c8abacbd-021f-a60a-9b1e-6380e61ed75f.png)

今回はStable diffusionをデプロイします。
検索バーに「stability」と入力し、プロバイダーの「Stability AI」をクリックします。
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1053703/37cd31b8-7d58-0653-fb23-f1b071c897e7.png)

今回検証で使用するモデルは「Stable Diffusion XL 1.0」です。
今回はAWS marketplaceに登録されているモデルを使用します。
![SageMakerPublicHub_-_SageMaker_Studio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1053703/a6498e8c-581f-0920-56f9-83a4b7b8c198.png)

ページ右上の「Deploy」をクリックします。
「Train」「Optimize」、「Evaluate」などは、このモデルでは使用できないようです。
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1053703/267b227e-8012-7ef9-8e3b-dd03903e7b22.png)

#### モデルのサブスクライブ
Stable Diffusion XL 1.0使用するには、
AWS marketplaceでのサブスクリプションが必要となります。
左下の「Subscribe」をクリックすることで、AWS marketplaceの新規タブが開きます。
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1053703/3485cc55-f811-b517-e737-69cb0a60d4a6.png)

Stable Diffusion XL 1.0の「Pricing Terms」を見てみると、
モデルの利用料金はかからないことがわかります。
ページ下部のEULAを確認し、Accept Offerをクリックします。
![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1053703/ba47e407-691d-5c0f-8c93-c76f42a48642.png)

Stable Diffusion XL 1.0のサブスクライブが完了しました。
![AWS_Marketplace__Stable_Diffusion_XL_1_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1053703/e7a3fdcd-d0f0-7802-dcda-41f5e2a9a73e.png)

#### モデルの詳細を確認
[Product Details](https://aws.amazon.com/marketplace/pp/prodview-pe7wqwehghdtm)をクリックすると、モデルの詳細を確認することができます
![product_detail.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1053703/20b59a1b-42fd-58f6-1970-836231408206.png)

概要、料金、使い方などを確認することができます。
![AWS_Marketplace__Stable_Diffusion_XL_1_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1053703/1eb2bbd0-e763-7ae5-5e30-eb9dfeed4c6a.png)





#### モデルを推論エンドポイントにデプロイ
先ほどのタブに戻って、「Deploy」をクリックします。
![Stabilityai_Sdxl_1_0_-_SageMaker_Studio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1053703/21e6dbcd-616f-66ae-f55d-9d7befd588b3.png)

デフォルトの設定のまま、右下の「Deploy」をクリックします。
この推論エンドポイントで使用するインスタンス対しては料金が発生しますので、
推論エンドポイントの消し忘れにはご注意ください。

料金の詳細については、 [SageMaker AI の料金表](https://aws.amazon.com/sagemaker-ai/pricing/)から確認してください。

![Cursor_と_Deploy_-_SageMaker_Studio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1053703/3fc01898-6f32-0eb3-2d6d-12edbfe587d9.png)

推論エンドポイントが作成されました。
作成してすぐは、Statusが「Creating」となっています。
Statusが「In service」に遷移すると、推論エンドポイントを使用することができます。
![https___qiita-image-store_s3_ap-northeast-1_amazonaws_com_0_1053703_9495a3bb-8b1a-a319-7865-a0242561d767.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1053703/171e0df8-e940-4777-aa06-48113b7125b3.png)

Statusが「In service」に変わりました。
「jumpstart-dft-stabilityai-sdxl-1-0-20250209-035558」がエンドポイント名になります。
エンドポイント名はこの後の手順で使用します。
![Jumpstart_Dft_Stabilityai_Sdxl_1_0_20250209_035558_-_SageMaker_Studio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1053703/88da06ec-5bbe-17d5-58ab-1b4afac88a8a.png)




## 推論エンドポイントにアクセス
[モデルの詳細ページ](https://aws.amazon.com/marketplace/pp/prodview-pe7wqwehghdtm)を参考に、推論エンドポイントにアクセスをし、
生成されたイメージを保存するコードを作成してみました。

#### 実行環境
pythonのバージョンは3.12.7を使用しました。
依存関係は以下の通りです。
```requirements.txt
boto3==1.36.16
botocore==1.36.16
jmespath==1.0.1
python-dateutil==2.9.0.post0
s3transfer==0.11.2
six==1.17.0
urllib3==2.3.0
```

#### 実行コード
以下が推論エンドポイント利用検証用のコードになります。
endpoint_nameに先ほど確認したエンドポイント名を格納してください。
プロファイルとして、IAMユーザーのアクセスキーを発行して指定しています。
```invoke_endpoint.py
import boto3
import json
import base64
import os

# SageMakerのエンドポイント名を設定
# 例 endpoint_name = "jumpstart-dft-stabilityai-sdxl-1-0-20250209-035558"
endpoint_name = "YOUR_INFFERENCE_ENDPOINT_NAME"


# リクエストペイロード
payload = {
    "cfg_scale": 7,
    "height": 1024,
    "width": 1024,
    "steps": 50,
    "seed": 42,
    "sampler": "K_DPMPP_2M",
    "text_prompts": [
        {
            "text": "A photograph of fresh pizza with basil and tomatoes, from a traditional oven",
            "weight": 1
        }
    ]
}

# SageMakerランタイムクライアントを初期化
sagemaker_runtime = boto3.client("sagemaker-runtime", region_name="us-west-2")

# エンドポイントにリクエスト送信
response = sagemaker_runtime.invoke_endpoint(
    EndpointName=endpoint_name,
    ContentType="application/json",
    Body=json.dumps(payload)
)

# レスポンスデータの取得
response_body = json.loads(response["Body"].read().decode("utf-8"))

# レスポンスから画像データを保存
if response_body.get("result") == "success" and "artifacts" in response_body:
    # 出力先ディレクトリ
    output_dir = "output_images"
    os.makedirs(output_dir, exist_ok=True)
    
    for index, artifact in enumerate(response_body["artifacts"]):
        # Base64データを取得
        base64_data = artifact.get("base64")
        finish_reason = artifact.get("finishReason", "UNKNOWN")
        seed = artifact.get("seed", "UNKNOWN")
        
        if base64_data:
            # Base64データをデコードしてバイナリ形式に変換
            image_data = base64.b64decode(base64_data)
            
            # ファイル名の作成
            file_name = f"image_{index+1}_seed_{seed}_{finish_reason}.png"
            file_path = os.path.join(output_dir, file_name)
            
            # 画像を保存
            with open(file_path, "wb") as f:
                f.write(image_data)
            print(f"画像が保存されました: {file_path}")
        else:
            print(f"アーティファクト {index+1} に画像データがありません。")
else:
    print("画像生成に失敗しました。レスポンス:", response_body)
```

#### 結果
output_imagesディレクトリ配下に、バジルとトマトが乗ったピザが生成されました。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1053703/65b09f90-5bd8-539d-c30d-667c7f77c8cc.png" width="50%" height="300px">





## まとめ

SageMaker AIを資格などで勉強はすれど、実際に触ったことは無かったので、
JumpStartは入り口としてはとても良かったと思いました。

JumpStartでは使用できるデプロイオプションとして、リアルタイム推論とバッチ変換のみがサポートされていてデプロイオプションが限られているようなので、今後JumpStartを使用したデプロイ以外も試していきたいと思います。