关于 hf-cloud-sagemaker-production-defaults
hf-cloud-sagemaker-production-defaults 用于在 Amazon SageMaker 部署实时推理端点,并采用面向生产的默认配置。它创建端点资源、自动扩缩和 CloudWatch 警报,并通过实际调用和日志检查验证部署。
主要功能
- 01创建 SageMaker 模型和端点
- 02配置自动扩缩
- 03添加 CloudWatch 警报
- 04支持推理组件部署
- 05提供端点调用与诊断脚本
- 06以 JSON 输出部署信息
适用场景
- 01在 SageMaker 部署 LLM 或嵌入模型
- 02根据调用量扩缩端点
- 03执行端点冒烟测试并排查故障
- 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.mdscripts/_common.pydeploy_async.pydeploy_ic.pydeploy.pyinvoke_endpoint.pyteardown.py详细介绍
SageMaker 生产默认配置
演示端点与可长期运行的端点之间的区别在于:它能随流量扩缩,在发生故障时发出通知,并且之后可以调试。本技能将这三项设为默认配置,而非可选项。
运行本技能时,规划器已选择实时端点,IAM 已有可用角色,镜像选择也已确定容器 URI 和 AMI 版本。本技能会将这些内容转化为实际部署。
创建的内容
对于每个端点,本技能都会创建以下资源:
- SageMaker Model — 镜像、环境变量、执行角色和 S3 构件
- 端点配置 — 实例类型、初始数量、可选的数据捕获
- 端点 — 用于提供推理服务的实时端点
- 自动扩缩目标和策略 — 根据每个实例的调用次数进行目标跟踪
- CloudWatch 警报 — 延迟、错误和平台开销
推理组件部署(deploy_ic.py)会创建相同的一组资源,但有两处不同:端点配置包含执行角色和 ManagedInstanceScaling,并且由推理组件承载模型。其自动扩缩目标是组件,而不是变体。
默认情况下,数据捕获(将请求/响应记录到 S3)处于关闭状态——它有助于调试,但会产生用户未必需要的持续 S3 费用。使用 --enable-data-capture 启用。
所有资源都会获得一组统一标签,其中包括 CreatedBy=agentic-deploy-skills,以便之后清理。
默认配置及其理由见 references/deployment-template.md。
运行部署
对于文本生成大模型(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 环境变量也更简单(使用 HF_MODEL_ID 而非 SM_VLLM_*,且无需配置主机或 trust-remote-code)。
各参数的来源:
| 参数 | 来源 |
|---|---|
--image-uri | hf-cloud-serving-image-selection — Agent 从 AWS DLC 目录页面读取 |
--inference-ami-version | hf-cloud-serving-image-selection — 对包含 cu130+ 的 vLLM 标签,此项为必需 |
--role-arn | hf-cloud-sagemaker-iam-preflight(check_role.py) |
--region | hf-cloud-aws-context-discovery |
--instance-type | 用户输入或规划器建议 |
--env | 因模型而异;所需的 SM_VLLM_* 变量见 hf-cloud-serving-image-selection |
--model-s3-uri | 生产环境首选 — 固定版本模型构件的 S3 URI;该构件会解压到 /opt/ml/model;仅在 Hub 运行时加载这一例外情况下省略 |
脚本会按顺序创建资源并处理错误,等待端点达到 InService 状态(最长 30 分钟),显示失败原因,注册自动扩缩和警报,并打印包含拆除命令的摘要。脚本会在 stdout 输出一个 JSON 数据块,其中包含供下游脚本使用的端点、配置和模型名称。
这些脚本随本技能一同提供。如果已安装的副本缺少 scripts/ 目录(某些运行环境安装时只会复制 SKILL.md),请从源代码仓库获取脚本,而不要根据本说明重新实现。
模型加载默认方式:将固定版本的权重预先暂存到 S3,并传入 --model-s3-uri;容器会从 /opt/ml/model 加载权重,不依赖运行时访问 Hub。通过 Hub 加载属于明确的例外情况:预计端点启动后还需下载 5–15 分钟或更久;对于受限模型,请提供令牌;除非特定架构需要经过审核的自定义代码,否则应保持 SM_VLLM_TRUST_REMOTE_CODE=false。deploy.py 会等待 30 分钟。
InService 并不代表成功 — 宣布完成前先进行烟雾测试
InService 只表示容器对 /ping 作出了响应。对于基于 MMS 的容器(HF Inference Toolkit),即使 Python 工作进程不断崩溃重启,Java 前端仍会响应 ping — 端点可能处于 InService 状态,却无法提供任何服务。始终进行以下两项检查:
-
进行一次真实调用。
- 实时:使用
invoke_endpoint.py(见下文)发送最小载荷;要求返回 HTTP 200,且响应正文合理。 - 异步:将一个输入上传到 S3,调用
invoke-endpoint-async,并轮询输出 URI 几分钟(参见“调用异步端点”)。出现结果对象 = 成功;失败 URI 上出现对象,或始终没有对象 = 故障。
- 实时:使用
-
扫描端点日志,查找工作进程崩溃标记 — 即使烟雾测试请求只是超时,也能发现崩溃重启的情况:
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 等权限),请用一行说明,然后继续执行可行的检查。绝不要因为缺少仅用于诊断的权限而阻止部署,也绝不要将调用遭拒视为没有问题的证据。
只有两项检查都通过后,才能报告部署完成。如果日志扫描发现问题,应从 CloudWatch 中提供实际的回溯信息 — 而不是 InService 状态。
测试实时端点
端点进入 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 重新运行),并重试一次,然后再判定端点或模型发生故障。
调用生成式重排器(vLLM)
生成式重排器(如 Qwen3-Reranker — 由 hf-cloud-serving-image-selection 路由至 HuggingFace vLLM DLC)是通过生成的第一个 token 进行评分的因果语言模型,而不是聊天模型。请使用带原始 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 后缀至关重要:它会预先填入一个空的思考块,确保生成的第一个 token 是是/否判断。根据返回的 logprobs 计算分数:P("yes") / (P("yes") + P("no"))。使用一个相关配对(预期 >0.9)和一个不相关配对(预期 <0.05)对端点进行合理性检查 — 如果不同配对的分数几乎相同,说明提示词模板有误,而不是模型发生故障。
同样的规则也适用于其他情况:对于任何要求提示词逐字节精确的思考模式模型,优先使用原始 completions API,而不要使用 chat。
选择镜像 URI
Agent 从 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 注册的变体级目标实例数不能低于一个。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) |
|---|---|---|
| 执行角色 | 位于 Model 上 | 位于端点配置上(ExecutionRoleArn) |
| 模型引用 | ProductionVariants[].ModelName | InferenceComponent.Specification.ModelName;变体没有 ModelName |
| 实例下限 | InitialInstanceCount,最小值为 1 | ManagedInstanceScaling {Status: ENABLED, MinInstanceCount: 0} |
| 扩缩目标 | endpoint/<ep>/variant/AllTraffic,sagemaker:variant:DesiredInstanceCount | inference-component/<ic>,sagemaker:inference-component:DesiredCopyCount |
| 扩缩指标 | SageMakerVariantInvocationsPerInstance(20 次/分钟) | SageMakerInferenceComponentConcurrentRequestsPerCopyHighResolution(每个副本 5 个并发请求) |
| 从零唤醒 | 不适用 | 步进策略 + NoCapacityInvocationFailures 警报 |
| 调用 | 端点名称 | 端点名称加上 InferenceComponentName |
InferenceAmiVersion 仍应设置在变体上,并且可以与 ManagedInstanceScaling 共存(已在 cu130 + ml.g5.xlarge 上验证)。
要实现缩容至零,需要四个部分,缺一不可。目标跟踪无法从零扩容,因为它无法除以零个副本。移除步进策略或其警报后,端点会缩容至零,然后再也无法响应。deploy_ic.py 会配置这四个部分。
实测行为
从 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 的组件运行 vLLM 时,即使主机内存占用达到数 GB,也不会有问题。
可调度资源池远小于实例内存。在 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 开始,仅在多个组件共享一个实例时才调高。
对于多 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 s 重试,直到有副本处理请求。不使用时,冷启动端点看起来总像是坏了。
拆除顺序
teardown.py 可处理这两种形式,但顺序至关重要:
- 告警(
<endpoint>-*和<component>-*) - 扩缩策略和可扩缩目标,针对组件资源 ID
- 推理组件
- 端点、端点配置、模型
以下两种情况使这一顺序不可或缺:
delete-endpoint不会删除组件。 这些组件会继续存在,持续报告InService,并阻止创建同名的新组件。务必先删除组件。- 处于临时状态时无法删除组件——容器启动期间的
CREATE_IN_PROGRESS,以及扩缩操作更改副本数量期间的UPDATE_RC_IN_PROGRESS。脚本每隔 15 s 重试一次,最长 15 min;扩缩事件刚发生后立即拆除,确实可能需要几分钟。
TargetTracking-inference-component/<ic>-AlarmHigh|Low 告警属于 Application Auto Scaling。删除策略会移除这些告警,因此脚本不会处理它们(已验证:拆除后不会残留告警)。
异步推理部署
对于运行时间较长(>60s)的推理、大型负载,或足够突发/稀疏、适合缩容至零的工作负载,请使用 deploy_async.py,而不是 deploy.py。异步部署支持在变体本身设置 MinCapacity=0。实时端点也能缩容至零,但只能通过推理组件实现——请参阅下文的“实时端点缩容至零”。当单次推理超过 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
缩容至零的工作原理
异步脚本会在变体上注册两个自动扩缩策略:
- 对
ApproximateBacklogSizePerInstance使用目标跟踪——负责在最小值和最大值之间持续扩缩 - 由
HasBacklogWithoutCapacityCloudWatch 告警触发的步进扩缩——负责在0→1时从零唤醒
两者缺一不可。仅靠目标跟踪无法从零转换(因为零个实例时无法进行除法运算),因此没有步进策略的话,端点启动后会在第一个批次处理完毕时缩容至零,此后再也不会唤醒。脚本会自动完成配置。
异步告警
该脚本会创建 3 个 CloudWatch 告警:
ApproximateBacklogSize > 50— 队列积压速度超过处理能力InvocationsFailed > 5— 处理反复失败HasBacklogWithoutCapacity— 用于触发从零唤醒策略(这不是通知告警;其操作是阶梯扩缩策略,而不是 SNS 主题)
如果传入 --sns-alarm-topic <arn>,前两个告警会向该主题发送通知。唤醒告警始终指向阶梯策略。
调用异步端点
异步端点不能同步调用。你需要先将输入上传到 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 秒的大模型工作负载进行了调优。对于嵌入部署(TEI),每个请求快得多(CPU 上通常 <100ms,GPU 上通常 <20ms),因此单个实例可以处理高得多的吞吐量。对于嵌入部署,请根据实例和模型大小将目标提高到 100–500。 默认值 20 会导致嵌入部署过于频繁地触发自动扩缩,造成资金浪费。
经验法则:目标值 ≈ 60 /(典型请求延迟,单位为秒)。延迟为 3s 的大模型 → 目标值为 20。延迟为 100ms 的嵌入模型 → 目标值为 600。生成式重排器介于两者之间——每个请求只生成一个令牌,因此目标值设为约 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 令牌或内存溢出。
“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 中的“已知有问题的镜像”)。问题发生在容器内部,因此更改环境变量、AMI、实例类型或同系列标签都无法修复。请切换到 DJL Inference。
状态为 InService,但调用超时 / 从未出现异步输出 — 存活的 MMS 前端后有一个失效的 Python 工作进程。运行上方“InService 不代表成功”中的日志扫描;CloudWatch 中的回溯才是真正的错误。
启动期间从 HF Hub 下载权重时出现 403 Forbidden — 容器中捆绑的 huggingface_hub 版本早于 HF 的 XET CDN 身份验证支持。请添加 --env HF_HUB_ENABLE_HF_TRANSFER=0,或将权重预先暂存到 S3。注意:这可能会掩盖更深层的问题(下载成功后,工作进程仍可能崩溃)——修复后请重新检查日志。
诊断规则:当多个配置(不同镜像、角色、实例类型)出现相同故障,且从未生成任何日志时,原因几乎总是在容器之外——主机 AMI、网络或账户级别问题,而非部署配置。请停止反复调整配置;检查 AMI 版本和账户状态。
组件卡在 Creating,没有 FailureReason — 容器陷入崩溃循环,supervisord 会重启它,因此状态始终不会改变。组件会保持 Creating,直到 ContainerStartupHealthCheckTimeoutInSeconds 超时,最长可达一小时。请查看 /aws/sagemaker/InferenceComponents/<component-name>,查找 exited: app、not expected 或 api_server.py: error:。deploy_ic.py 会在每次轮询时执行此扫描,并在约一分钟内中止。
There is not enough hardware resources on the instances for this endpoint — 组件的 ComputeResourceRequirements 超出了可调度资源池,而该资源池远小于实例内存。请降低 --min-memory-mb(ml.g5.xlarge 上 1024 可用;4096 会被拒绝)。不要增加实例:即使实例运行正常,也会出现此消息。
Cannot delete inference component ... while it is in state CREATE_IN_PROGRESS / UPDATE_RC_IN_PROGRESS — 这是正常情况,不是错误。请重试;teardown.py 会重试 15 分钟。UPDATE_RC_IN_PROGRESS 表示扩缩容操作正在更改副本数量。
组件的生命周期长于其端点 — delete-endpoint 会留下组件,它们仍会报告 InService,从而阻止重用名称。请先删除组件;teardown.py 就是这样处理的。
不要盲目重试。脚本会打印 describe-endpoint 返回的具体 FailureReason——请先修复根本原因,再重试。