You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无需更新配置,如何让AWS SageMaker端点重新加载S3新模型?

问题:AWS SageMaker端点无法重新加载S3中更新的model.tar.gz模型
  • 场景:需将其他训练流水线生成的新model.tar.gz(存储在S3)部署到已有SageMaker端点,该端点由AWS CDK创建,端点配置的model_data_url指向目标S3路径,但SageMaker未自动重新加载新模型。
  • 核心需求:允许数据科学家在训练流水线中选择部署新模型到测试端点,无需创建新模型/端点配置、无需修改CDK基础设施代码。已知SageMaker容器会缓存模型,需强制触发重新加载。
  • 排除方案:官方建议的「同一文件夹用不同文件名存储模型并修改调用代码」不适用,且不希望无TargetModel参数时默认使用旧模型。
  • 当前尝试:上传模型到S3后执行以下代码,端点进入Updating状态,但未触发模型重新加载:
def update_sm_endpoint(endpoint_name: str) -> Dict[str, Any]:
    """Forces the sagemaker endpoint to reload model from s3"""
    sm = boto3.client("sagemaker")
    return sm.update_endpoint_weights_and_capacities(
        EndpointName=endpoint_name,
        DesiredWeightsAndCapacities=[
            {"VariantName": "main", "DesiredWeight": 1},
        ],
    )
可行解决方案

方法1:通过模型版本ID触发端点配置更新

SageMaker会根据S3对象的版本ID判断模型是否更新。上传新模型后,获取其版本ID并更新现有模型的model_data_url,再创建新端点配置并关联到目标端点:

import boto3
import time

def refresh_sagemaker_model(endpoint_name: str, s3_model_path: str):
    sm_client = boto3.client("sagemaker")
    s3_client = boto3.client("s3")
    
    # 解析S3路径获取桶名和对象键
    bucket = s3_model_path.split("//")[1].split("/")[0]
    key = "/".join(s3_model_path.split("//")[1].split("/")[1:])
    
    # 获取新模型的S3版本ID
    s3_response = s3_client.head_object(Bucket=bucket, Key=key)
    model_version_id = s3_response["VersionId"]
    
    # 获取当前端点的配置和模型信息
    endpoint_desc = sm_client.describe_endpoint(EndpointName=endpoint_name)
    current_config_name = endpoint_desc["EndpointConfigName"]
    config_desc = sm_client.describe_endpoint_config(EndpointConfigName=current_config_name)
    variant = config_desc["ProductionVariants"][0]
    current_model_name = variant["ModelName"]
    
    # 更新现有模型的model_data_url,附加版本ID
    updated_model_data_url = f"{s3_model_path}?versionId={model_version_id}"
    sm_client.update_model(
        ModelName=current_model_name,
        ExecutionRoleArn=config_desc["ExecutionRoleArn"],
        PrimaryContainer={
            "Image": variant["Container"]["Image"],
            "ModelDataUrl": updated_model_data_url
        }
    )
    
    # 创建新端点配置(复用原配置参数)
    new_config_name = f"{current_config_name}-refresh-{int(time.time())}"
    sm_client.create_endpoint_config(
        EndpointConfigName=new_config_name,
        ProductionVariants=[{
            "VariantName": variant["VariantName"],
            "ModelName": current_model_name,
            "InitialInstanceCount": variant["InitialInstanceCount"],
            "InstanceType": variant["InstanceType"],
            "InitialVariantWeight": variant["InitialVariantWeight"]
        }],
        DataCaptureConfig=config_desc.get("DataCaptureConfig")
    )
    
    # 更新端点使用新配置
    sm_client.update_endpoint(
        EndpointName=endpoint_name,
        EndpointConfigName=new_config_name
    )

方法2:自定义容器实现热重载

如果使用自定义推理容器,可在容器内添加定时检查逻辑,自动检测S3模型更新并重新加载:

  • 在容器启动脚本中添加定时任务,定期调用S3 API获取model.tar.gz的ETag或版本ID
  • 当检测到ETag/版本ID变化时,下载新模型并重启推理服务(如TensorFlow Serving、FastAPI进程)

方法3:滚动实例强制清除缓存

SageMaker实例会将模型缓存到本地磁盘,通过缩容再扩容的方式替换实例,可强制清除缓存:

def force_instance_refresh(endpoint_name: str, variant_name: str = "main"):
    sm_client = boto3.client("sagemaker")
    
    # 获取当前实例数量
    endpoint_desc = sm_client.describe_endpoint(EndpointName=endpoint_name)
    config_desc = sm_client.describe_endpoint_config(EndpointConfigName=endpoint_desc["EndpointConfigName"])
    variant = next(v for v in config_desc["ProductionVariants"] if v["VariantName"] == variant_name)
    original_count = variant["InitialInstanceCount"]
    
    # 缩容到0
    sm_client.update_endpoint_weights_and_capacities(
        EndpointName=endpoint_name,
        DesiredWeightsAndCapacities=[
            {"VariantName": variant_name, "DesiredInstanceCount": 0}
        ]
    )
    
    # 等待实例销毁完成
    waiter = sm_client.get_waiter("endpoint_in_service")
    waiter.wait(EndpointName=endpoint_name)
    
    # 扩容回原实例数
    sm_client.update_endpoint_weights_and_capacities(
        EndpointName=endpoint_name,
        DesiredWeightsAndCapacities=[
            {"VariantName": variant_name, "DesiredInstanceCount": original_count}
        ]
    )

注意:此方法会导致端点短暂不可用,仅适合测试环境。

内容的提问来源于stack exchange,提问作者Steffenk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 18:40:27