亚马逊AWS官方博客

通过使用 Amazon SageMaker 多模型终端节点节省推理成本

Original URL:https://thinkwithwp.com/blogs/machine-learning/save-on-inference-costs-by-using-amazon-sagemaker-multi-model-endpoints/

越来越多的企业在开发基于用户的机器学习 (ML) 模型而不是基于群组或细分市场的模型,基于个体用户数据,这些企业能在任何位置训练数百个到数十万个自定义模型。例如,音乐流媒体服务基于单个听众的音乐历史记录训练自定义模型,以实现个性化音乐推荐。出租车服务基于单个城市的交通模式训练自定义模型,以预测乘客等待时间。

虽然构建自定义机器学习模型较好的提高了单个使用案例推理的准确性,但缺点在于部署模型的成本大幅提高,而且在生产中管理如此多的模型很困难。当您不用同时访问所有模型但仍然需要可以随时使用这些模型时,这些问题变得尤为突出。Amazon SageMaker 多模型终端节点可以解决这些痛点,并且能为企业提供一个可扩展但经济高效的解决方案用于部署多个机器学习模型。

Amazon SageMaker 是一项模块化的端到端服务,可用于轻松地大规模构建、训练和部署机器学习模型。在训练得到一个机器学习模型后,您可以将它部署到完全托管的 Amazon SageMaker 终端节点上,该终端节点可以实时提供低延迟的推理。现在,您可以在一个公共终端节点中部署多个模型,并通过一个使用多模型终端节点的服务容器向外提供服务。如此一来,便可以轻松地大规模管理机器学习模型的部署,并通过提高终端节点及其下层的基础计算实例的使用率来降低您的模型部署成本。

本博文介绍了 Amazon SageMaker 多模型终端节点,并演示了如何应用这项新功能通过 XGBoost 来预测各个细分市场的房屋价格。本博文演示了在多模型终端节点上同时部署10个模型,也演示了在 10 个独立的终端节点上分别部署 10 个模型,并对这两种使用情形进行了对比。如下图所示,前者相比后者每月节省了 3000 美金的成本。

多模型终端节点可以轻松扩展到数百至数千个模型。本博文还将讨论终端节点配置和监控需要考虑的因素,并将重点介绍在 1000 个模型规模的部署样例中,如何节省超过 90% 的成本。

Amazon SageMaker 多模型终端节点的概述

Amazon SageMaker 可使您跨多个可用区将您的模型一键式部署到自动扩展的 Amazon 机器学习实例上,以实现高冗余性。您只需指定实例类型及所需的最大数和最小值,剩下的部分都将由 Amazon SageMaker 解决。Amazon SageMaker 将启动实例、部署模型并设置安全的 HTTPS 终端节点。您的应用程序需要包含到此终端节点的API 调用,以实现低延迟和高吞吐量推理。此架构可使您在几分钟内将新模型集成到应用程序中,因为模型更改不再需要应用程序代码同步更改。Amazon SageMaker 是完全托管的服务,可代为管理您的生产计算基础设施,包括执行运行状况检查、应用安全补丁及执行其他的常规维护,这一切都可以使用内置的 Amazon CloudWatch 监控和日志记录来进行。

Amazon SageMaker 多模型终端节点可使您在一个终端节点中部署多个经过训练的模型,并使用一个服务容器向外提供服务。多模型终端节点完全托管,具有高可用性,可实时提供推理服务。您可以在推理请求中通过参数设置目标模型名称来轻松调用指定模型。如果您拥有大量可通过共享服务容器提供服务且不需要同时访问所有模型的相似模型,该项功能是不二之选。例如,法律应用程序可能需要全面覆盖一组广泛的监管辖区,如果有大量不经常访问的模型,那么一个多模型终端节点就可以高效的提供服务,并且显著的降低成本。

要在 Amazon SageMaker 中创建多模型终端节点,请选择多模型选项,提供推理服务容器镜像的路径,然后提供用于存储训练好的模型构件的 Amazon S3 前缀。只要您的模型全部使用相同的前缀,您可以按任何方式在 S3 中组织它们。调用多模型终端节点时,使用 InvokeEndpoint 的新 TargetModel 参数提供特定模型的相对路径。要在多模型终端节点中添加模型,只需将新训练的模型构件存储在与该终端节点关联的S3 前缀下,然后,该模型将立即可用于调用。要更新已在使用的模型,用新名称命名模型,并添加到 S3 中,然后用新模型名称调用终端节点。要停止使用在多模型终端节点上部署的模型,请停止调用该模型,并将它从 S3 中删除。

Amazon SageMaker 多模型终端节点将在调用时从 S3 中动态加载模型,而不是在创建终端节点时将所有模型从 S3 下载到容器中。因此,初次调用模型的推理延迟可能高于后续推理,后续推理将以低延迟返回调用。如果模型在调用时已加载到容器中,则可以跳过下载步骤,模型推理将以低延迟返回调用。例如,假设您有一个一天只使用几次的模型,它将根据需要自动加载;而频繁访问的模型将保留在内存中,并持续以低延迟返回调用。下图显示从 S3 动态加载到多模型终端节点中的模型。

使用 Amazon SageMaker 多模型终端节点预测房价

本博文基于房屋定价领域带您逐步了解多模型终端节点的使用场景示例。有关更多信息,请参阅 GitHub 上的完全工作笔记本。它使用生成的合成数据让您可以使用任意数量的模型进行实验。每个城市都使用随机生成的特征在一定数量的房子上进行了模型训练。

该实验包含以下步骤:

  1. 使您训练好的模型可用于多模型终端节点
  2. 准备容器
  3. 创建和部署多模型终端节点
  4. 调用多模型终端节点
  5. 动态加载新模型

使您训练好的模型可用于多模型终端节点

您可以在不对模型或模型训练过程进行任何更改的情况下利用多模型部署,并继续生成将要保存在 S3 中的模型构件(例如 model.tar.gz 文件)。

在示例笔记本中,将并行训练一组模型,且每个训练作业的模型构件都将复制到 S3 中指定的位置。训练并复制一组模型后,文件夹将拥有以下内容:

  2019-11-15 14:40:04   11.2 KiB Chicago_IL.tar.gz
  2019-11-15 14:40:04   11.9 KiB Houston_TX.tar.gz
  2019-11-15 14:40:04   11.4 KiB LosAngeles_CA.tar.gz

  对象总数:3
     总大小:34.5 KiB

每个文件都根据原有的model.tar.gz 名称进行重命名,以使每个模型都具有唯一的名称。发送请求做预测时,您通过名称指定目标模型。

准备容器

要使用 Amazon SageMaker 多模型终端节点,您可以使用通用型多模型服务器功能在 GitHub 上构建 docker 容器。该容器是一个灵活易用的框架,可托管基于任何框架的机器学习模型并对外提供服务。XGBoost 示例笔记本演示了如何将开源 Amazon SageMaker XGBoost 容器用作基础来构建容器。

创建多模型终端节点

下一步是创建多模型终端节点,该终端节点知道如何在 S3 中查找目标模型。本博文使用 boto3(适用于 Python 的 AWS 开发工具包)创建模型元数据。将其模式设置为 MultiModel 并告知 Amazon SageMaker 包含所有模型构件的 S3 文件夹的位置,而不是指定某个模型。

此外,指定模型用于推理的框架镜像。本博文使用在上一步构建的 XGBoost 容器。您可以在为该框架配置的多模型终端节点中托管使用相同框架构建的模型。请参阅以下代码来创建模型实体:

  container = {
   'Image':        XGB_CONTAINER,
   'ModelDataUrl': ‘s3://my-bucket/path/to/artifacts/’,
   'Mode':         'MultiModel'
  }

  response = sm_client.create_model(
              ModelName        = ‘my-multi-model-name’,
              ExecutionRoleArn = role,
              Containers       = [container])

有了适当的模型定义后,您需要一个终端节点配置,该配置引用您上面创建的模型实体名称。请参阅以下代码:

  response = sm_client.create_endpoint_config(
    EndpointConfigName = ‘my-epc’,
    ProductionVariants=[{
        'InstanceType':        ‘ml.m4.xlarge’,
        'InitialInstanceCount': 2,
        'InitialVariantWeight': 1,
        'ModelName':            ‘my-multi-model-name’,
        'VariantName':          'AllTraffic'}])

最后,使用以下代码创建终端节点:

  response = sm_client.create_endpoint(
              EndpointName       = ‘my-endpoint’,
              EndpointConfigName = ‘my-epc’)

调用多模型终端节点

要调用多模型终端节点,您只需要传递一个新参数,该参数表示要调用的目标模型。以下示例代码为使用 boto3 的预测请求:

  response = runtime_sm_client.invoke_endpoint(
                        EndpointName = ’my-endpoint’,
                        ContentType  = 'text/csv',
                        TargetModel  = ’Houston_TX.tar.gz’,
                        Body         = body)

针对单一终端节点后托管的多个目标模型,示例笔记本通过一组随机调用进行迭代。它显示了终端节点如何按需动态加载目标模型。请参阅以下输出:

Using model Houston_TX.tar.gz to predict price of this house:

[1994, 3188, 5, 1.5, 1.62, 3]

486551.41 USD,took 1375 ms

Using model Chicago_IL.tar.gz to predict price of this house:

[1990, 3047, 5, 1.0, 1.11, 2]

428404.88 USD,took 850 ms

Using model Chicago_IL.tar.gz to predict price of this house:

[1995, 3514, 6, 2.0, 0.79, 2]

512149.66 USD,took 17 ms

Using model Houston_TX.tar.gz to predict price of this house:

[1978, 2973, 2, 1.5, 0.99, 1]

328904.12 USD,took 17 ms

由于要从 S3 下载给定模型并将其加载到内存中,针对该模型完成第一次请求的时间有更多延迟(称为冷启动)。后续,因为该模型已加载完成,调用不会产生额外的开销。

动态加载新模型到现有终端节点中

将新模型部署到现有的多模型终端节点中很简单。在终端节点已在运行的情况下,将一组新的模型构件复制到您早前设置的相同的 S3 位置,然后,客户端应用程序可以自由地请求来自于该目标模型的预测,剩余工作则交由 Amazon SageMaker 处理。下面的示例代码为纽约创建了一个可以立即投入使用的新模型:

  !aws s3 cp NewYork_NY.tar.gz s3://my-bucket/path/to/artifacts/

  response = runtime_sm_client.invoke_endpoint(
                        EndpointName=endpoint_name,
                        ContentType='text/csv',
                        TargetModel=’NewYork_NY.tar.gz’,
                        Body=body)

使用多模型终端节点,您无需进行完整的终端节点更新,只需部署新模型(即一个 S3 副本),并且可以避免为每个新模型单独设置终端节点的成本开销。

为大量模型扩展多模型终端节点

随着捆绑模型的规模增大,Amazon SageMaker 多模型终端节点的好处也随之增加。使用一个终端节点托管两个模型时,可以为您节省成本,对于具有数百个甚至数千个模型的使用案例,节省幅度会更高。

例如,假定有 1000 个小型 XGBoost 模型,每个模型本身都可以由 ml.c5.large 终端节点(4 GiB 内存)提供服务,在 us-east-1 每实例小时的成本为 0.119 USD。如果为全部 1000 个模型各自提供终端节点,每月将花费 171,360 USD。如果使用 Amazon SageMaker 多模型终端节点,使用 ml.r5.2xlarge 实例的单个终端节点(64 GiB 内存)即可以托管全部 1000 个模型。这可以将生产推理成本降低 99%,使每个月的成本仅为 1,017 USD。下表总结了本示例中单个终端节点与多模型终端节点之间的区别。请注意,对每个目标模型进行冷启动调用后,多模型案例实现了 7 毫秒的第 90 个百分位延迟。假定终端节点配置为您的目标模型提供了足够的内存,所有模型都加载后的稳态调用延迟将与单模型终端节点的延迟相似。

 

单模型
终端节点
多模型
终端节点
每月的终端节点总价格 171360 USD 1017 USD
终端节点实例类型 ml.c5.large ml.r5.2xlarge
内存容量 (GiB) 4 64
每小时的终端节点价格 0.119 USD 0.706 USD
每个终端节点的实例数量 2 2
1000 个模型所需的终端节点                1000 1
终端节点第 90 个百分位延迟 (ms) 7 7

使用 Amazon CloudWatch 指标监控多模型终端节点

为了在价格与性能之间进行权衡,您要使用您自己应用程序的模型和代表性流量对多模型终端节点进行测试。Amazon SageMaker 在 CloudWatch 中为多模型终端节点提供额外的指标,以便您可以确定终端节点的使用情况和缓存命中率,并对您的终端节点进行优化。指标如下:

  • ModelLoadingWaitTime – 调用请求等待目标模型被下载或加载以执行推理的时间间隔。
  • ModelUnloadingTime – 通过容器的 UnloadModel API 调用卸载模型所需要的时间间隔。
  • ModelDownloadingTime – 从 S3 中下载模型所需要的时间间隔。
  • ModelLoadingTime – 通过容器的 LoadModel API 调用加载模型所需要的时间间隔。
  • ModelCacheHit – 发送至已加载模型的终端节点的 InvokeEndpoint 请求数量。取平均统计值将显示模型已加载的请求的比率。
  • LoadedModelCount – 已加载到终端节点的容器中的模型数量。每个实例都会发出该指标。1 分钟内的平均(Average)统计量将向您显示每个实例已加载的模型平均数量,总(Sum)统计量向您显示在终端节点的所有实例中加载的模型总数量。因为您可以将一个模型加载到终端节点的多个容器中,此指标跟踪的模型不一定是唯一的。

您可以使用 CloudWatch 图表帮助持续作出决策,选择出最佳的实例类型、实例计数和某个给定终端节点应托管的模型数量。例如,下面的图表显示加载的模型数量在不断增加,缓存命中率也在相应增加。

在本例中,缓存命中率的起始值为 0,当时没有加载模型。随着加载的模型数量增加,缓存命中率最终达到 100%。

将您的终端节点配置与您的使用案例匹配

为 Amazon SageMaker 终端节点选择适当的终端节点配置,尤其是实例类型和实例数量,这在很大程度上取决于您的特定使用案例要求。对于多模型终端节点也是如此。您可以在内存中保存的模型数量取决于您的终端节点配置(如实例类型和计数)、您的模型配置文件(如模型大小和模型延迟)及您的推理流量模式。您应该综合考虑上述因素来配置您的多模型终端节点并适当调整实例的大小,并且还应该为您的终端节点设置自动缩放。

Amazon SageMaker 多模型终端节点完全支持自动缩放。调用速率用于触发自动缩放事件,该速率基于终端节点服务之完整模型集的聚合预测集。

有些情形下,您可以通过选择不能同时在内存中保存所有目标模型的实例类型来降低成本。Amazon SageMaker 将在内存用完时动态卸载模型,从而为新目标模型腾出空间。对于不经常请求的模型,动态加载可以节省成本,延迟尚可接受。对延迟敏感的情形,您可能需要选择更大的实例类型或更多实例。对于特定使用案例,预先投入时间使用多模型终端节点进行测试和分析,将有助于优化成本,同时满足您的应用程序的性能需求。

结论

Amazon SageMaker 多模型终端节点可帮助您以尽可能低的成本提供高性能机器学习解决方案。通过将一组类似的模型捆绑到单个终端节点后面,可以显著降低推理成本,您可以使用单个共享服务容器提供服务。同样地,Amazon SageMaker 为您提供托管的 Spot 训练以帮助降低训练成本,并针对深度学习工作负载为 Amazon Elastic Inference 提供集成支持。最重要的是,它们将助力于 Amazon SageMaker 改进生产力,并有助于提高机器学习团队的影响力。

试用一下多模型终端节点,在评论中分享您的反馈和问题。


关于作者

Mark Roy 是机器学习专家解决方案架构师,致力于帮助客户实现大规模良好架构的机器学习解决方案。在业余时间,Mark 喜欢打球、教练和篮球。

 

 

 

Urvashi Chowdhary 是 Amazon SageMaker 的首席产品经理。她热衷于与客户合作,使机器学习更容易实现。业余时间,她喜欢帆船、桨板和皮划艇运动。