mcpField
H
hf-cloud-sagemaker-production-defaults

hf-cloud-sagemaker-production-defaults

github.com/huggingfaceクラウド・DevOps11.2k555 回インストール5 日前に更新
リポジトリ

hf-cloud-sagemaker-production-defaults について

hf-cloud-sagemaker-production-defaultsは、本番運用向けの既定値でAmazon SageMakerのリアルタイム推論エンドポイントをデプロイするスキルです。エンドポイント関連リソース、自動スケーリング、CloudWatchアラームを作成し、実際の呼び出しとログを確認してから完了を報告します。

主な機能

  1. 01SageMakerモデルとエンドポイントを作成
  2. 02自動スケーリングを設定
  3. 03CloudWatchアラームを追加
  4. 04推論コンポーネントのデプロイに対応
  5. 05呼び出しと診断用スクリプトを提供
  6. 06デプロイ情報をJSONで出力

活用シーン

  1. 01SageMakerにLLMまたは埋め込みモデルをデプロイ
  2. 02呼び出し量に応じてエンドポイントを拡縮
  3. 03エンドポイントのスモークテストと障害調査
  4. 04推論コンポーネントでゼロスケールを実行

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/huggingface/skills --skill hf-cloud-sagemaker-production-defaults

インストール後、Claude Code で/hf-cloud-sagemaker-production-defaultsを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
deployment-template.md
scripts/
_common.py
deploy_async.py
deploy_ic.py
deploy.py
invoke_endpoint.py
teardown.py

詳細

SageMaker の本番環境向けデフォルト設定

デモ用エンドポイントと、稼働し続けられるエンドポイントの違いは、トラフィックに応じてスケールし、障害発生時に通知し、後からデバッグできることです。このスキルでは、この3つを任意の追加機能ではなく、デフォルトで有効にします。

このスキルが実行される時点で、プランナーはリアルタイムエンドポイントを選択済みで、IAM には使用可能なロールがあり、イメージ選択ではコンテナ URI と AMI バージョンが決定済みです。このスキルはそれらを実際のデプロイに変換します。

作成されるもの

各エンドポイントについて、このスキルは次のリソースをひとまとまりで作成します。

  1. SageMaker モデル — イメージ + 環境変数 + 実行ロール + S3 アーティファクト
  2. エンドポイント設定 — インスタンスタイプ、初期数、任意のデータキャプチャ
  3. エンドポイント — 推論を提供するリアルタイムエンドポイント
  4. オートスケーリングのターゲット + ポリシー — インスタンスあたりの呼び出し数に基づくターゲット追跡
  5. CloudWatch アラーム — レイテンシー、エラー、プラットフォームのオーバーヘッド

推論コンポーネントのデプロイ(deploy_ic.py)では、2つの変更を加えて同じリソース一式を作成します。エンドポイント設定に実行ロールと ManagedInstanceScaling を含め、推論コンポーネントにモデルを含めます。オートスケーリングのターゲットはバリアントではなく、コンポーネントです。

データキャプチャ(リクエストとレスポンスを S3 に記録する機能)は、デフォルトではオフです。デバッグには便利ですが、ユーザーが必ずしも求めていない継続的な S3 コストが発生します。--enable-data-capture で有効にできます。

後でクリーンアップできるよう、すべてのリソースには CreatedBy=agentic-deploy-skills を含む一貫したタグ一式が付与されます。

デフォルト設定とその理由については、references/deployment-template.md を参照してください。

デプロイの実行

テキスト生成 LLM(vLLM)の場合、まず固定したモデルスナップショットを SageMaker の model.tar.gz アーティファクトとしてパッケージ化し、アカウント管理下の S3 バケットにアップロードします。SageMaker はこれを /opt/ml/model に展開するため、デプロイ時にリポジトリのコードを取得したり実行したりする必要はありません。

python scripts/deploy.py \
    --model-name qwen3-medical \
    --image-uri "$IMAGE_URI" \
    --inference-ami-version "$AMI" \
    --role-arn "$ROLE_ARN" \
    --model-s3-uri "s3://<your-model-bucket>/qwen3-medical/model.tar.gz" \
    --instance-type ml.g5.xlarge \
    --region "$REGION" \
    --env SM_VLLM_MODEL=/opt/ml/model \
    --env SM_VLLM_HOST=0.0.0.0 \
    --env SM_VLLM_TRUST_REMOTE_CODE=false \
    --env SM_VLLM_MAX_MODEL_LEN=4096

埋め込みモデル(TEI。多くの場合 CPU で実行)の場合:

python scripts/deploy.py \
    --model-name bge-large-embeddings \
    --image-uri "$IMAGE_URI" \
    --role-arn "$ROLE_ARN" \
    --instance-type ml.c6i.2xlarge \
    --region "$REGION" \
    --env HF_MODEL_ID=BAAI/bge-large-en-v1.5

注:TEI のデプロイでは --inference-ami-version は不要です。このフラグは vLLM 固有です。TEI の環境変数もよりシンプルで、SM_VLLM_* ではなく HF_MODEL_ID を使用し、ホストや trust-remote-code の設定も不要です。

各値の取得元:

パラメーター取得元
--image-urihf-cloud-serving-image-selection — エージェントが AWS DLC カタログページから読み取ります
--inference-ami-versionhf-cloud-serving-image-selection — cu130 以上を含む vLLM タグで必須です
--role-arnhf-cloud-sagemaker-iam-preflight(check_role.py)
--regionhf-cloud-aws-context-discovery
--instance-typeユーザー入力またはプランナーの推奨
--envモデル固有。必須の SM_VLLM_* 変数については hf-cloud-serving-image-selection を参照してください
--model-s3-uri本番環境ではこちらを推奨 — 固定したモデルアーティファクトを /opt/ml/model に展開するための S3 URI。Hub を実行時に利用する例外を除き、省略しないでください

スクリプトはエラー処理を行いながら順番にリソースを作成し、InService になるまで待機します(最大30分)。失敗理由を表示し、オートスケーリングとアラームを登録したうえで、削除コマンドを含む概要を出力します。また、後続のスクリプトで使用できるよう、エンドポイント名、設定名、モデル名を含む JSON データを標準出力に出力します。

スクリプトはこのスキルに同梱されています。インストール済みのコピーに scripts/ ディレクトリがない場合(一部のハーネスではインストール時に SKILL.md しかコピーされません)は、この説明から再実装するのではなく、ソースリポジトリから取得してください。

モデル読み込みのデフォルト設定:固定した重みをあらかじめ S3 に配置し、--model-s3-uri を指定します。コンテナは実行時に Hub に依存せず、/opt/ml/model から重みを読み込みます。Hub からの読み込みは明示的な例外です。エンドポイント起動後のダウンロードに5〜15分以上かかることを想定し、ゲート付きモデルではトークンを指定してください。また、アーキテクチャ固有の要件でレビュー済みのカスタムコードが必要な場合を除き、SM_VLLM_TRUST_REMOTE_CODE=false を維持してください。deploy.py は30分間待機します。

InService は成功ではありません — 成功と判断する前にスモークテストを実行してください

InService が示すのは、コンテナが /ping に応答したことだけです。MMS ベースのコンテナ(HF Inference Toolkit)では、Python ワーカーがクラッシュループしていても、Java フロントエンドは ping に応答します。そのため、エンドポイントが InService でも何も提供できない場合があります。必ず次の 2 つを確認してください。

  1. 実際に 1 回呼び出します。

    • リアルタイム:最小限のペイロードで、以下の invoke_endpoint.py を実行します。妥当な本文を含む HTTP 200 を必須とします。
    • 非同期:入力を 1 つ S3 にアップロードし、invoke-endpoint-async を呼び出して、出力 URI を数分間ポーリングします(「非同期エンドポイントの呼び出し」を参照)。結果オブジェクトがあれば成功です。失敗 URI にオブジェクトがある場合、または何も現れない場合は、正常に動作していません。
  2. エンドポイントのログをスキャンして、ワーカークラッシュの兆候を確認します — スモークリクエストがタイムアウトするだけの場合でも、クラッシュループを検出できます。

    aws logs filter-log-events \
        --log-group-name /aws/sagemaker/Endpoints/<endpoint-name> \
        --filter-pattern '?"Worker died" ?"Load model failed" ?"ImportError"' \
        --region <region> --max-items 5
    

推論コンポーネントのデプロイでは、代わりに /aws/sagemaker/InferenceComponents/<component-name> にログが記録されます。deploy_ic.py は待機中にこのロググループを自動的にスキャンします。

診断が拒否された場合の一般的なルール:ワークフローが診断に使用する読み取り専用の呼び出しが拒否された場合(logs:FilterLogEvents や servicequotas:ListServiceQuotas などを持たない制限付きロールの場合)、その旨を 1 行で伝え、実行できる確認を続けてください。診断にのみ必要な権限を理由にデプロイを止めてはいけません。また、呼び出しが拒否されたことを、問題がない証拠として解釈してはいけません。

両方の確認に合格してから、デプロイ完了を報告してください。ログスキャンで該当箇所が見つかった場合は、InService のステータスではなく、CloudWatch の実際のトレースバックを提示してください。

リアルタイムエンドポイントのテスト

エンドポイントが InService になったら、同梱のヘルパーを使ってテストしてください。これはクロスプラットフォーム対応でBOM セーフです。ペイロードファイルを手動で作成して invoke-endpoint を直接呼び出すのではなく、このヘルパーを使用してください。

# macOS / Linux
python3 scripts/invoke_endpoint.py \
    --endpoint-name <endpoint-name> \
    --payload '{"inputs": "Hello"}' \
    --region "$REGION"
# Windows (PowerShell)
python scripts\invoke_endpoint.py `
    --endpoint-name <endpoint-name> `
    --payload-file payload.json `
    --region $REGION

--payload '<json>'(インライン)または --payload-file <path> を受け付け、JSON を検証し、リクエスト本文をプレーンな UTF-8 として書き込み、エンドポイントを呼び出して、レスポンス本文を標準出力に出力します。

UTF-8 BOM の落とし穴(Windows)

Windows でリクエストペイロードを自分で作成する場合は、Set-Content -Encoding UTF8 を使用しないでください。PowerShell のバージョンによっては、UTF-8 のバイトオーダーマーク(BOM)が先頭に付加されます。SageMaker の JSON パーサーは BOM を含むデータを拒否し、400 ModelError を返します。

Unexpected UTF-8 BOM (decode using utf-8-sig): line 1 column 1 (char 0)

これはモデル、エンドポイントの健全性、またはイメージの問題ではありません。リクエスト本文のファイルエンコーディングだけの問題です。invoke_endpoint.py を使えば、この問題を完全に回避できます(--payload-file に BOM がすでに含まれている場合も取り除きます)。CLI を直接呼び出す必要がある場合は、BOM を含まない UTF-8 として本文を書き込んでください。

# BOM-free UTF-8 — use this
[System.IO.File]::WriteAllText((Resolve-Path "payload.json"), $json, [System.Text.UTF8Encoding]::new($false))

aws sagemaker-runtime invoke-endpoint `
    --endpoint-name <endpoint-name> `
    --content-type application/json `
    --body fileb://payload.json `
    --region $REGION `
    response.json

**フォールバック:**呼び出しが Unexpected UTF-8 BOM で失敗した場合は、エンドポイントやモデルに問題があると判断する前に、ペイロードを BOM を含まない UTF-8 として書き直す(または invoke_endpoint.py で再実行する)などして、1 回再試行してください。

生成型リランカーの呼び出し(vLLM)

生成型リランカー(Qwen3-Reranker など。hf-cloud-serving-image-selection によって HuggingFace vLLM DLC にルーティングされます)は、チャットモデルではなく、最初に生成されるトークンでスコアを付ける因果言語モデルです。生の prompt を指定する completions API を使い、messages/chat API は使わないでください。チャットのテンプレート処理では、{"enable_thinking": false} などの chat_template_kwargs が確実に反映されません。また、誤ったテンプレートを使ってもエラーにならず、すべてのクエリとドキュメントの組み合わせに対してほぼ同じスコアが返されます。

ペイロードの形式(Qwen3-Reranker が期待する形式 — {query} / {document} を置き換えてください):

{
  "prompt": "<|im_start|>system\nJudge whether the Document meets the requirements based on the Query and the Instruct provided. Note that the answer can only be \"yes\" or \"no\".<|im_end|>\n<|im_start|>user\n<Instruct>: Given a web search query, retrieve relevant passages that answer the query\n<Query>: {query}\n<Document>: {document}<|im_end|>\n<|im_start|>assistant\n<think>\n\n</think>\n\n",
  "max_tokens": 1,
  "temperature": 0,
  "logprobs": 20
}

末尾の <|im_start|>assistant\n\n\n サフィックスは不可欠です。空の思考ブロックを事前入力することで、最初に生成されるトークンが yes/no の判定になります。返された logprobs からスコアを計算します:P("yes") / (P("yes") + P("no"))。関連性の高いペア 1 つ(0.9 超を期待)と、関連性のないペア 1 つ(0.05 未満を期待)でエンドポイントを健全性チェックしてください。ペア間でスコアがほぼ同じなら、モデルの不具合ではなく、プロンプトテンプレートが誤っています。

同じルールは一般化できます。プロンプトをバイト単位で正確に一致させる必要がある思考モードのモデルでは、チャット API よりも生の completions API を優先してください。

イメージ URI の選択

エージェントは AWS の Deep Learning Containers カタログ からイメージ URI を読み取ります。モデルファミリーに一致する行(LLM には HuggingFace vLLM、埋め込みには TEI など)を選び、<region> をデプロイ先のリージョンに置き換えて、deploy.py --image-uri に渡します。

特に vLLM イメージ(huggingface-vllm と AWS の vllm フォールバックの両方)では、タグの CUDA バージョンも確認してください。

# Example: HuggingFace vLLM 0.21.0 from the catalog
IMAGE_URI="763104351884.dkr.ecr.eu-west-1.amazonaws.com/huggingface-vllm:0.21.0-transformers5.8.1-gpu-py312-cu130-ubuntu22.04"

# cu130 tag → must pass --inference-ami-version
python deploy.py --image-uri "$IMAGE_URI" \
    --inference-ami-version al2-ami-sagemaker-inference-gpu-3-1 \
    ...

cu129 以下のタグでは、--inference-ami-version を省略してください。vLLM の AMI 全体の参照表と各イメージファミリーの環境変数要件については、hf-cloud-serving-image-selection を参照してください。

リアルタイムエンドポイントをゼロにスケールする

リアルタイムエンドポイントがインスタンス数をゼロにできるのは、推論コンポーネントをホストしている場合に限られます。deploy.py が登録するバリアント単位のターゲットでは、インスタンス数を 1 未満にできません。deploy_ic.py はコンポーネントベースの構成を構築します。

トラフィックが少ない、またはスケジュールされており、クライアントが最初のリクエストに数分かかることを許容できる場合に使用してください。SLA のあるインタラクティブなトラフィックには使用しないでください。起動には数分かかり、その間のリクエストはすべて失敗します。

python scripts/deploy_ic.py \
    --model-name qwen3-scale-to-zero \
    --image-uri "$IMAGE_URI" \
    --inference-ami-version "$AMI" \
    --role-arn "$ROLE_ARN" \
    --model-s3-uri "s3://<your-model-bucket>/qwen3-scale-to-zero/model.tar.gz" \
    --instance-type ml.g5.xlarge \
    --region "$REGION" \
    --env SM_VLLM_MODEL=/opt/ml/model \
    --env SM_VLLM_HOST=0.0.0.0 \
    --env SM_VLLM_TRUST_REMOTE_CODE=false \
    --env SM_VLLM_MAX_MODEL_LEN=4096
deploy.py との違い
項目モデルベース(deploy.py)コンポーネントベース(deploy_ic.py)
実行ロールモデル上エンドポイント設定上(ExecutionRoleArn)
モデル参照ProductionVariants[].ModelNameInferenceComponent.Specification.ModelName。バリアントには ModelName がありません
インスタンス数の下限InitialInstanceCount、最小 1ManagedInstanceScaling {Status: ENABLED, MinInstanceCount: 0}
スケーリングターゲットendpoint/<ep>/variant/AllTraffic、sagemaker:variant:DesiredInstanceCountinference-component/<ic>、sagemaker:inference-component:DesiredCopyCount
スケーリングメトリクスSageMakerVariantInvocationsPerInstance(20/分)SageMakerInferenceComponentConcurrentRequestsPerCopyHighResolution(5 同時リクエスト/コピー)
ゼロからの起動該当なしステップポリシー+NoCapacityInvocationFailures アラーム
呼び出しエンドポイント名エンドポイント名 と InferenceComponentName

InferenceAmiVersion は引き続きバリアントに設定し、ManagedInstanceScaling と併用できます(cu130+ml.g5.xlarge で確認済み)。

ゼロへのスケーリングを機能させるには、4 つの要素が必要であり、すべて必須です。ターゲット追跡ではコピー数をゼロで割ることができないため、ゼロからスケールアウトできません。ステップポリシーまたはそのアラームを外すと、エンドポイントは一度ゼロにスケールした後、二度と応答しなくなります。deploy_ic.py は4つすべてを設定します。

実測した動作

Hub の Qwen/Qwen3-0.6B、ml.g5.xlarge、us-east-1、2026年7月:

ステップ時間
エンドポイントが InService(空の状態で起動し、モデルは読み込まれません)4 分
コンポーネントが InService(Hub からのダウンロード+vLLM の起動+CUDA グラフ)+6 分
アイドル状態からコピー数 0 まで最後のリクエストから 11 分
コピー数 0 からインスタンス数 0 まで+12 分
コピー数 0 の状態で最初のリクエスト → HTTP 400 has no capacity即時
NoCapacityInvocationFailures アラーム → ALARM+67 秒
ステップポリシーが希望コピー数とインスタンス数を 1 に引き上げる+1 分 42 秒
HTTP 200+9 分 24 秒

このスキルではスケールインを調整できません。Application Auto Scaling は AlarmLow を独自に作成し、期間を 10 秒、評価期間を 90 回に設定するため、発火するにはアイドル状態のデータポイントが15分間必要です。

本番環境の重みを事前にステージングし、--model-s3-uri を渡してください。実行時の Hub アクセスを避けられるだけでなく、起動のたびに時間を短縮できます。モデルアーティファクトは起動のたびに再度読み込まれるため、アイドル期間後の最初のリクエストまでのクリティカルパスに取得処理が含まれます。

コンポーネントのサイズ設定

ComputeResourceRequirements はスケジューリング用の予約であり、上限ではありません。1024 MB をリクエストするコンポーネントでも、問題なく数 GB のホストメモリを使用して vLLM を実行できます。

スケジューリング可能なプールは、インスタンスのメモリよりはるかに小さいものです。ml.g5.xlarge(16 GiB)では、スケジューラーは 1024 MB を受け入れ、4096 MB を拒否します。過剰な値をリクエストすると、すぐに原因の分かりにくいエラーが発生します。

There is not enough hardware resources on the instances for this endpoint to
create a copy of the inference component.

このメッセージは、エンドポイントのインスタンスが正常な場合にも表示されます。「インスタンスを追加する」ではなく、「リクエストが大きすぎる」と解釈してください。デフォルトの 1024 MB から始め、1 つのインスタンスで複数のコンポーネントを共有する場合にのみ値を増やしてください。

マルチ GPU モデルでは、--accelerator-devices を SM_VLLM_TENSOR_PARALLEL_SIZE に合わせる必要があります。

呼び出しとテスト

コンポーネント名を渡し、起動を待てるようにします。

python3 scripts/invoke_endpoint.py \
    --endpoint-name <endpoint-name> \
    --inference-component-name <component-name> \
    --payload '{"prompt": "hello", "max_tokens": 16}' \
    --wait-for-capacity 900 --region "$REGION"

400 has no capacity エラーは起動の合図であり、障害ではありません。このエラーによって、ステップポリシーをトリガーするメトリクスが公開されます。--wait-for-capacity を指定すると、コピーがリクエストを処理できるようになるまでヘルパーが 30 秒ごとに再試行します。これを指定しない場合、コールド状態のエンドポイントは常に壊れているように見えます。

ティアダウンの順序

teardown.py はどちらの構成にも対応していますが、順序が重要です。

  1. アラーム(<endpoint>-* と <component>-*)
  2. スケーリングポリシーとスケーラブルターゲット(コンポーネントのリソース ID)
  3. 推論コンポーネント
  4. エンドポイント、エンドポイント設定、モデル

次の 2 つの動作により、この順序が必要になります。

  • delete-endpoint はコンポーネントを削除しません。 コンポーネントは残り、InService の報告を続け、同じ名前の新しいコンポーネントをブロックします。必ず先にコンポーネントを削除してください。
  • 一時的な状態の間はコンポーネントの削除が拒否されます。コンテナの起動中は CREATE_IN_PROGRESS、スケーリングアクションによるコピー数の変更中は UPDATE_RC_IN_PROGRESS になります。スクリプトは 15 分間、15 秒ごとに再試行します。スケーリングイベント直後のティアダウンに数分かかるのは正常です。

TargetTracking-inference-component/<ic>-AlarmHigh|Low アラームは Application Auto Scaling に属します。ポリシーを削除するとこれらのアラームも削除されるため、スクリプトでは処理しません(確認済み:ティアダウン後にアラームは残りません)。

非同期推論のデプロイ

長時間実行される推論(>60s)、大きなペイロード、またはスケール・トゥ・ゼロの恩恵を受けられる、負荷が急増したりまばらになったりするワークロードには、deploy.py ではなく deploy_async.py を使用してください。非同期では、バリアント自体に MinCapacity=0 を設定できます。リアルタイムエンドポイントもゼロまでスケールできますが、推論コンポーネントを通じてのみ可能です。詳しくは、以下の「リアルタイムエンドポイントのスケール・トゥ・ゼロ」を参照してください。1 回の推論が InvokeEndpoint の 60s の応答制限を超える場合も、非同期が適切です。

python scripts/deploy_async.py \
    --model-name flux-text-to-image \
    --image-uri "$IMAGE_URI" \
    --role-arn "$ROLE_ARN" \
    --instance-type ml.g5.2xlarge \
    --region "$REGION" \
    --output-s3-uri s3://amzn-s3-demo-async-output/async-output/ \
    --env HF_MODEL_ID=black-forest-labs/FLUX.1-dev

deploy.py に加えて必須となる項目:

  • --output-s3-uri — 非同期の結果を保存する場所(結果は同期的に返されません)

非同期専用の任意のフラグ:

  • --failure-s3-uri — 失敗した呼び出し用の別パス
  • --success-sns-topic、--error-sns-topic — 非同期結果の準備完了時または失敗時に通知を受け取ります
  • --min-capacity 0(デフォルト)— バッチ間にゼロまでスケールします
  • --backlog-per-instance-target N — インスタンスあたりの目標キュー深度(デフォルト 5)
  • --max-concurrent-invocations-per-instance N — デフォルト 4
スケール・トゥ・ゼロの仕組み

非同期スクリプトは、バリアントに2 つのオートスケーリングポリシーを登録します。

  1. ApproximateBacklogSizePerInstance に基づくターゲット追跡 — 最小値と最大値の間で継続的にスケーリングします
  2. CloudWatch アラーム HasBacklogWithoutCapacity がトリガーするステップスケーリング — 0→1 のゼロからの起動を処理します

どちらも必要です。ターゲット追跡だけではゼロから移行できません(インスタンス数がゼロでは除算できないため)。そのため、ステップポリシーがないと、エンドポイントは起動後、最初のバッチが終わるとゼロまでスケールし、その後二度と起動しません。スクリプトがこれらを自動的に設定します。

非同期アラーム

スクリプトは、次の CloudWatch アラームを3つ作成します。

  • ApproximateBacklogSize > 50 — キューの増加が処理能力を上回っています
  • InvocationsFailed > 5 — 処理が繰り返し失敗しています
  • HasBacklogWithoutCapacity — ゼロからの起動ポリシーを制御します(通知用アラームではありません。アクションの対象は SNS トピックではなく、ステップスケーリングポリシーです)

--sns-alarm-topic <arn> を渡すと、最初の2つのアラームがそのトピックに通知します。起動アラームの通知先は常にステップポリシーです。

非同期エンドポイントの呼び出し

非同期エンドポイントは同期的には呼び出しません。入力を S3 にアップロードし、S3 の入力場所を指定して invoke-endpoint-async を呼び出します。処理が完了すると、SageMaker は結果を --output-s3-uri に書き込みます。

# Upload your input first
aws s3 cp input.json s3://amzn-s3-demo-input/job1/input.json

# Invoke
aws sagemaker-runtime invoke-endpoint-async \
    --endpoint-name <endpoint-name> \
    --input-location s3://amzn-s3-demo-input/job1/input.json \
    --content-type application/json \
    --region <region>

# Poll for the result at your output URI
aws s3 cp s3://amzn-s3-demo-async-output/async-output/<inference-id>.out result.json

アップロードする input.json にも、同じ UTF-8 BOM の注意事項が当てはまります(上記の「UTF-8 BOM の落とし穴」を参照)。Windows で作成する場合は、BOM なしの UTF-8 として書き込んでください。そうしないと、コンテナの JSON パーサーが拒否します。

ティアダウンの手順はリアルタイムの場合と同じです。python3 scripts/teardown.py <endpoint-name> を実行します(ティアダウンスクリプトは名前のプレフィックスでポリシーとアラームを検出するため、どちらのデプロイモードにも対応しています)。

デフォルト設定一覧

設定デフォルト変更方法
初期インスタンス数1--initial-instance-count
オートスケーリングの最小/最大1 / 4--min-capacity、--max-capacity
オートスケーリングのターゲット20 呼び出し/分/インスタンス--target-invocations-per-instance
データキャプチャ無効(オプトイン)--enable-data-capture
CloudWatch アラーム3 個のアラーム--no-alarms
SNS 通知なし(アラームは作成されますが、通知しません)--sns-alarm-topic <arn>
環境タグdev--environment
InferenceAmiVersionなし(SageMaker のデフォルト)--inference-ami-version(vLLM CUDA 13 以降では必須)

デフォルト値が設定されない項目(ユーザー固有の入力が必要):VPC 設定、KMS キー、マルチバリアント、非同期推論。

オートスケーリングのターゲット — モデルの種類に合わせて調整する

デフォルトの --target-invocations-per-instance 20 は控えめな値で、各リクエストに1~5秒かかる LLM ワークロード向けに調整されています。埋め込みのデプロイ(TEI)では、各リクエストの処理がはるかに速いため(CPU では通常 100ms 未満、GPU では 20ms 未満)、1つのインスタンスでより多くのスループットを処理できます。埋め込みをデプロイする場合は、インスタンスとモデルのサイズに応じて、ターゲットを100~500に引き上げてください。 デフォルトの20では埋め込みに対してオートスケーリングが過剰に頻繁に起動し、費用が無駄になります。

目安:ターゲット値 ≈ 60 /(通常のリクエスト遅延時間[秒])。遅延時間が3秒の LLM の場合、ターゲットは20です。遅延時間が100msの埋め込みの場合、ターゲットは600です。生成型リランカーはその中間です。リクエストごとに1トークンだけ生成するため、ターゲットは約40~100が妥当です。

データキャプチャと IAM に関する注意点

ユーザーがデータキャプチャを有効にする場合、実行ロールにはキャプチャ用プレフィックスへの S3 書き込みアクセスが必要です。デフォルトの URI(s3://sagemaker-<region>-<account>/<endpoint>/data-capture/)は、通常、モデルアーティファクト用バケットとは別のバケットを指します。hf-cloud-sagemaker-iam-preflight がインラインポリシーの対象をモデル用バケットだけに限定していると、キャプチャの書き込みはひそかに失敗します。エンドポイントのサービスは継続しますが、データは表示されません。

ユーザーから「データキャプチャが表示されない」と報告された場合は、ロールの S3 アクセスを確認してください。インラインポリシーの範囲を広げるか、ロールが書き込み可能なバケットを指す --data-capture-s3-uri を渡してください。

ティアダウン

python3 scripts/teardown.py <endpoint-name> <region>   # macOS / Linux
python  scripts\teardown.py <endpoint-name> <region>   # Windows

安全な順序で削除します:アラーム → オートスケーリング → エンドポイント(課金を停止)→ エンドポイント設定 → モデル。何度実行しても安全です。

削除されないもの:IAM 実行ロール(共有されている可能性があります)、データキャプチャの S3 オブジェクト(ユーザーが保持したい場合があります)、SNS トピック、元のモデルアーティファクト。

デプロイの概要を伝えた後は、必ずティアダウンコマンドもユーザーに案内してください。ユーザーは忘れがちで、エンドポイントの利用料金が発生し続けるためです。

デプロイに失敗した場合

CannotStartContainerError が発生し、CloudWatch ログが一度も作成されない場合 — InferenceAmiVersion の問題です。イメージタグに cu130 以降が含まれていて、--inference-ami-version al2-ami-sagemaker-inference-gpu-3-1 を渡していない場合は、これが原因です。hf-cloud-serving-image-selection を参照してください。イメージ、IAM ロール、環境変数、インスタンスタイプを追及しないでください — 他の多くの問題でも同じ障害の兆候が見られますが、ここでの原因は AMI です。

「Failed to pass ping health check」 — コンテナは起動してログを出力しましたが、/ping が応答していません。/aws/sagemaker/Endpoints/<endpoint-name> の CloudWatch を確認してください。通常は、モデルアーキテクチャに合わないイメージ、HF トークンの欠落、または OOM が原因です。

「Container failed to start」(ログがある場合) — エントリーポイントが実行された後、終了しました。CloudWatch を確認してください。よくある原因は、必須の環境変数(SM_VLLM_MODEL、SM_VLLM_HOST、SM_VLLM_TRUST_REMOTE_CODE)の欠落、ModelDataUrl の形式の誤り、モデル成果物を読み取れないことです。

ResourceLimitExceeded — このリージョンでは、そのインスタンスタイプのクォータがありません。上限の引き上げを申請するか、別のタイプを選んでください(プランナーは事前にクォータを確認しているはずです — hf-cloud-sagemaker-deployment-planner を参照してください)。

CloudWatch ログに ImportError: libtorch_cuda.so: undefined symbol: ncclCommResume がある場合 — huggingface-pytorch-inference の GPU イメージに既知のパッケージング不具合があります(hf-cloud-serving-image-selection の「Known-broken images」を参照してください)。コンテナ内部の問題なので、環境変数、AMI、インスタンスタイプ、または同系列の別タグでは解決しません。DJL Inference に切り替えてください。

InService だが、呼び出しがタイムアウトする/非同期の出力が現れない場合 — 稼働中の MMS フロントエンドの背後で、Python ワーカーが停止しています。上記の「InService is not success」にあるログスキャンを実行してください。CloudWatch のトレースバックが実際のエラーです。

起動中に HF Hub から重みをダウンロードすると 403 Forbidden が発生する場合 — コンテナにバンドルされた huggingface_hub が HF の XET CDN 認証に対応する前のバージョンです。--env HF_HUB_ENABLE_HF_TRANSFER=0 を追加するか、重みを事前に S3 に配置してください。注意:これによって、より深刻な問題が隠れることがあります(ダウンロードが成功した後もワーカーがクラッシュする可能性があります)。修正後、ログを再確認してください。

診断ルール:異なる複数の構成(異なるイメージ、ロール、インスタンスタイプ)で失敗の兆候が同じで、ログが一度も出力されない場合、原因はほぼ常にコンテナより下の層(ホスト AMI、ネットワーク、アカウントレベル)にあり、デプロイ設定ではありません。設定の変更を繰り返すのはやめて、AMI のバージョンとアカウントの状態を確認してください。

コンポーネントが Creating のまま停止し、FailureReason がない場合 — コンテナがクラッシュループしており、supervisord が再起動するため、ステータスが変わりません。コンポーネントは ContainerStartupHealthCheckTimeoutInSeconds の期限が切れるまで、最大 1 時間 Creating のままです。/aws/sagemaker/InferenceComponents/<component-name> を読み取り、exited: app、not expected、または api_server.py: error: を探してください。deploy_ic.py はポーリングごとにこのスキャンを実行し、約 1 分で中止します。

There is not enough hardware resources on the instances for this endpoint — コンポーネントの ComputeResourceRequirements が、スケジュール可能なリソースプールを超えています。このプールはインスタンスのメモリよりかなり小さいものです。--min-memory-mb を下げてください(ml.g5.xlarge では 1024 は機能しますが、4096 は拒否されます)。インスタンスを追加しないでください。正常なインスタンスがある場合でも、このメッセージは表示されます。

There is not enough hardware resources on the instances for this endpoint — コンポーネントの ComputeResourceRequirements が、スケジュール可能なリソースプールを超えています。このプールはインスタンスのメモリよりかなり小さいものです。--min-memory-mb を下げてください(ml.g5.xlarge では 1024 は機能しますが、4096 は拒否されます)。インスタンスを追加しないでください。正常なインスタンスがある場合でも、このメッセージは表示されます。

CREATE_IN_PROGRESS または UPDATE_RC_IN_PROGRESS の状態にあるため、推論コンポーネント ... を削除できない場合 — 正常な状態であり、エラーではありません。再試行してください。teardown.py は 15 分間再試行します。UPDATE_RC_IN_PROGRESS は、スケーリング操作によってコピー数が変更されていることを意味します。

コンポーネントがエンドポイントより長く残る場合 — delete-endpoint を実行しても、コンポーネントは削除されず、InService と報告されたまま残ります。名前の再利用が妨げられます。先にコンポーネントを削除してください。teardown.py はその順序で処理します。

むやみに再試行しないでください。スクリプトは describe-endpoint の FailureReason を具体的に表示します — 再試行する前に、根本原因を修正してください。

コメント