在单个端点上托管多个 LLM

原文:towardsdatascience.com/hosting-multiple-llms-on-a-single-endpoint-32eda0201832

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/2c603a8fe76e81bae1c68289871e0a57.png

图片来自Unsplash的**Michael Dziedzic

过去一年,大型语言模型(LLM)领域经历了爆炸式增长,出现了许多新的模型,以及各种技术和工具来帮助训练、托管和评估这些模型。特别是,托管/推理是这些 LLM 和机器学习的一般力量得到认可的地方,因为没有推理,这些模型就没有可视结果或目的。

如我过去所记录的,托管这些 LLM由于模型的大小以及高效利用模型背后的相关硬件,可能会相当具有挑战性。虽然我们已经与模型托管技术如DJL Serving文本生成推理(TGI)Triton合作,并使用如 Amazon SageMaker 之类的模型/基础设施托管平台来托管这些 LLM,但在我们尝试将 LLM 用例投入生产时,又出现了另一个问题。我们如何为多个 LLM 做到这一点?

为什么这个问题甚至会出现?当我们达到生产级用例时,通常会有多个可能被使用的模型。例如,可能有一个 Llama 模型用于你的摘要用例,而 Falcon 模型则用于你的聊天机器人。虽然我们可以将这些模型各自托管在它们自己的持久端点上,但这会导致高昂的成本。需要一个同时考虑成本和性能/资源分配及优化的解决方案。

在本文中,我们将探讨如何利用一种高级托管选项,即SageMaker 推理组件,来解决这个问题,并构建一个示例,其中我们在单个端点上托管了FlanFalcon模型。

注意:本文文章假设您对 Python、LLMs 和 Amazon SageMaker 推理有中级理解。我建议您阅读这篇文章以开始使用 Amazon SageMaker 推理。

免责声明:我是 AWS 的机器学习架构师,我的观点仅代表个人。

目录

  1. 推理组件简介

  2. 其他多模型 SageMaker 推理托管选项

  3. 多个 LLM 托管示例

  4. 其他资源与结论

1. 推理组件简介

SageMaker 推理组件是 SageMaker 实时推理(SageMaker Real-Time Inference)中引入的一种新型多模型托管选项。对于 SageMaker 实时推理,您有一个持久端点,并配备了一组专用硬件,您可以为它启用自动扩展。创建纯 SageMaker 端点的一般流程如下:

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/fff3f4aa55a94e26bf72d84b628990c7.png

纯 SageMaker 端点流程(作者截图)

对于我们新的端点,我们可以添加多个推理组件,我们的创建/编排过程可能如下所示:

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/0e61eee22bff97fdbce78a911d51c1c4.png

推理组件流程(作者截图)

现在什么是推理组件?推理组件与纯 SageMaker 模型对象 非常相似。您可以指定模型数据和您要托管模型的容器。关键区别在于您可以指定托管此模型所需的计算资源。您可以在类似于以下 API 调用中定义它:

"ComputeResourceRequirements": {
   "NumberOfAcceleratorDevicesRequired": 1, 
   "NumberOfCpuCoresRequired": 1, 
   "MinMemoryRequiredInMb": 1024
}

加速器数量可以是 GPU 或基于 Inferentia 的设备,同时您也可以根据需要指定 CPU 核心和内存。另外,在运行时,您可以设置一个初始副本数量。这意味着模型副本已经加载并准备好服务请求(有助于缓解冷启动并保持模型活跃)。

在推理组件中,您还可以根据每个模型副本接收的平均调用次数应用自动扩展。例如,如果您有一个模型副本,并且它达到了您在自动扩展策略中指定的某个调用阈值,您可以根据您指定的限制增加副本数量。请注意,每个副本将保留您指定的计算资源需求,因此您需要确保您在端点后面有适当数量的实例,以便能够托管您可能创建的副本数量。

在本质上,在推理组件中,我们需要牢记的主要特性如下:

  • 每个推理组件都有自己的容器和模型数据,它是模型服务器/容器无关的。例如,您可以在同一个端点上有一个使用 TGI 容器的 IC 和一个使用 DJL Serving 容器的 IC。

  • 您可以将 n 个推理组件添加到您的端点,这是此托管选项的多模型角度。

  • 您可以为每个推理组件/模型指定计算资源需求。

  • 您可以为正在处理的推理组件/模型指定一个初始副本数量。

  • 您可以按推理组件/模型进行扩展,为您的 IC 配置应用程序自动扩展以配置副本数量。使用此功能,您还可以将您的 IC 扩展到 0 个副本。

在今天的示例中,我们不会探索扩展部分,但我们将看看如何将两个独立的 LLM 作为推理组件添加到 SageMaker 端点。在那之前,让我们了解 SageMaker 推理中的其他多模型选项,以避免在使用哪个选项时产生混淆。

2. 其他多模型 SageMaker 推理托管选项

虽然推理组件引入了在 SageMaker 实时推理上托管多个模型的新方法,但根据您的用例,已经有一些先前选项也可以使用。

要了解这两种选项之间的全部差异,请参考我的入门文章这里。在本质上,当您有多个类似口味的模型时,可以使用 MME,这意味着相同的容器/模型框架。使用 MME,您可以在专用端点上为单个容器挂载多个模型。当您有不同的容器/模型框架时,可以使用 MCE。使用 MCE,您在单个端点上拥有多个容器。推理组件可以被视为这两种选项之间的一种结合,但对于特定的用例,最好利用这两种现有选项之一。

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/97a637433851b18180d6b104f4d536c5.png

多模型选项(作者截图)

在每个高级推理选项中,您还需要考虑一些特定的注意事项。例如,在 MME 中,根据流量自动加载和卸载模型。在 MCE 中,有选项将这些容器链接在一起形成一个单一的 推理管道在您确实想要控制每个模型背后的硬件并在每个模型级别进行扩展的使用案例中,最好利用推理组件

每个选项都有其自身的优缺点,因此评估您的性能要求和模型推理模式,以做出 正确的托管决策 非常重要。

3. 多个 LLM 托管示例

在我们的示例中,我们将使用推理组件在单个端点上托管 FlanT5XXLFalcon7B 模型。对于我们的编排,我们将使用 SageMaker Python SDK 和 AWS Python SDK (Boto3) 中的某些相同工具。

import boto3
import sagemaker
import time
from time import gmtime, strftime

#Setup
client = boto3.client(service_name="sagemaker")
runtime = boto3.client(service_name="sagemaker-runtime")
boto_session = boto3.session.Session()
s3 = boto_session.resource('s3')
region = boto_session.region_name
sagemaker_session = sagemaker.Session()
role = sagemaker.get_execution_role()
print(f"Role ARN: {role}")
print(f"Region: {region}")

传统的 SageMaker 模型对象是 SageMaker 实时推理创建的第一步。在这种情况下,我们跳过这个步骤,因为我们创建推理组件时已经定义了模型数据和容器工件。我们直接进入 SageMaker 端点配置 的创建,其中有一些关键变化。

# Container Parameters, increase health check for LLMs: 
variant_name = "AllTraffic"
instance_type = "ml.g5.24xlarge"
model_data_download_timeout_in_seconds = 3600
container_startup_health_check_timeout_in_seconds = 3600

# Setting up managed AutoScaling
initial_instance_count = 1
max_instance_count = 2
print(f"Initial instance count: {initial_instance_count}")
print(f"Max instance count: {max_instance_count}")

# Endpoint Config Creation
endpoint_config_response = client.create_endpoint_config(
    EndpointConfigName=epc_name,
    ExecutionRoleArn=role,
    ProductionVariants=[
        {
            "VariantName": variant_name,
            "InstanceType": instance_type,
            "InitialInstanceCount": 1,
            "ModelDataDownloadTimeoutInSeconds": model_data_download_timeout_in_seconds,
            "ContainerStartupHealthCheckTimeoutInSeconds": container_startup_health_check_timeout_in_seconds,
            "ManagedInstanceScaling": {
                "Status": "ENABLED",
                "MinInstanceCount": initial_instance_count,
                "MaxInstanceCount": max_instance_count,
            },
            # can set to least outstanding or random: https://aws.amazon.com/blogs/machine-learning/minimize-real-time-inference-latency-by-using-amazon-sagemaker-routing-strategies/
            "RoutingConfig": {"RoutingStrategy": "LEAST_OUTSTANDING_REQUESTS"},
        }
    ],
)

传统的端点配置中,我们只需定义初始实例数量和类型。然而,在这种情况下,我们添加了一些关键参数:

  • 托管实例自动扩展:使用推理组件,您可以在模型/容器级别进行扩展。在这里,您可以根据接收到的流量调整模型副本的数量。然而,您端点背后的硬件也必须扩展,以便有足够的资源来托管这些额外的副本。SageMaker 根据这些推理组件的扩展情况提供托管实例自动扩展,我们在端点配置中启用了这一功能。

  • 路由策略:此外,我们还可以配置请求的 路由策略。这里的默认值是随机路由,但我们启用了 Least Outstanding Requests (LOR) 路由。在这种情况下,请求会被路由到具有最多容量来处理请求的实例,这是监控每个实例上的推理组件数量和流量的组合/公式。

一旦我们定义了端点配置,我们就可以以常规方式 创建一个端点

#Endpoint Creation
endpoint_name = "ic-ep" + strftime("%Y-%m-%d-%H-%M-%S", gmtime())
create_endpoint_response = client.create_endpoint(
    EndpointName=endpoint_name,
    EndpointConfigName=epc_name,
)

一旦端点被创建,我们就专注于添加推理组件的新流程。再次将推理组件视为与 SageMaker 模型对象非常相似。你需要定义相同的模型数据和容器规范。在这种情况下,我们甚至可以直接创建一个 SageMaker 模型对象,并让我们的推理组件继承所需的元数据。

对于我们的 Flan 和 Falcon 模型,我们使用 文本生成推理(TGI)容器 直接获取这些模型工件(TGI 将作为模型服务器)。

from sagemaker.huggingface import HuggingFaceModel, get_huggingface_llm_image_uri
import json

# utilizing huggingface TGI container
image_uri = get_huggingface_llm_image_uri("huggingface",version="1.1.0")
print(f"TGI Image: {image_uri}")

# Flan T5 TGI Model
flant5_model = {"Image": image_uri, "Environment": {"HF_MODEL_ID": "google/flan-t5-xxl"}}
flant5_model_name = "flant5-model" + strftime("%Y-%m-%d-%H-%M-%S", gmtime())
print(f"Flan Model Name: {flant5_model_name}")

#note: falcon 7b takes just one GPU, sharding is not supported
falcon7b_model = {"Image": image_uri, "Environment": {'HF_MODEL_ID':'tiiuae/falcon-7b'}}
falcon7b_model_name = "falcon7b-model" + strftime("%Y-%m-%d-%H-%M-%S", gmtime())
print(f"Falcon Model Name: {falcon7b_model_name}")

我们随后创建一个 SageMaker 模型对象,并将模型元数据传递给我们的 推理组件

# create model object for flan t5
create_flan_model_response = client.create_model(
    ModelName=flant5_model_name,
    ExecutionRoleArn=role,
    Containers=[flant5_model],
)
print("Flan Model Arn: " + create_flan_model_response["ModelArn"])

# flan inference component reaction, inherit SageMaker Model object
create_flan_ic_response = client.create_inference_component(
    InferenceComponentName=flant5_ic_name,
    EndpointName=endpoint_name,
    VariantName=variant_name,
    Specification={
        "ModelName": flant5_model_name,
        "ComputeResourceRequirements": {
            # enables tensor parallel via TGI, reserving 2 GPUs (g5.24xlarge has 4 GPUs)
            "NumberOfAcceleratorDevicesRequired": 2,
            "NumberOfCpuCoresRequired": 1,
            "MinMemoryRequiredInMb": 1024,
        },
    },
    # can setup autoscaling for copies
    RuntimeConfig={"CopyCount": 1},
)

print("IC Flan Arn: " + create_flan_ic_response["InferenceComponentArn"])

注意,我们将包含容器和模型数据信息的 SageMaker 模型名称传递给我们的推理组件。我们的推理组件(IC)将继承这些信息,然后我们定义使 IC 与我们的传统 SageMaker 实时推理流程不同的组件。

推理组件的关键差异在于我们定义的硬件和扩展参数。注意,我们定义了 NumberOfAcceleratorDevicesRequired,此参数可以指代 GPU 或 Inferentia 基于的实例。请注意,你需要考虑你有多少硬件可用。在我们的案例中,我们使用 ml.g5.24xlarge 实例作为我们的端点,这个实例有 4 个 GPU 可用。通过说我们需要 2 个设备,我们 为每个创建的模型副本分配 2 个 GPU。再次强调,我们也在运行时配置中定义了 CopyCount。在这种情况下,我们定义了 2 个 GPU,因为与 Flan 一样,我们希望通过 TGI 容器启用 Tensor Parallel。对于某些模型,可能甚至不需要多个加速器。例如,对于我们的 Falcon 推理组件,Tensor Parallel 对于 Falcon 7B 没有启用,所以我们只定义了 1 个 GPU 的需求,如下所示:

# create falcon model object
create_falcon_model_response = client.create_model(
    ModelName=falcon7b_model_name,
    ExecutionRoleArn=role,
    Containers=[falcon7b_model],
)
print("Falcon Model Arn: " + create_falcon_model_response["ModelArn"])

falcon_ic_name = "falcon-ic" + strftime("%Y-%m-%d-%H-%M-%S", gmtime())
variant_name = "AllTraffic"

# falcon inference component requirement
create_falcon_ic_response = client.create_inference_component(
    InferenceComponentName=falcon_ic_name,
    EndpointName=endpoint_name,
    VariantName=variant_name,
    Specification={
        "ModelName": falcon7b_model_name,
        "ComputeResourceRequirements": {
            # For falcon 7b only one GPU is needed: https://github.com/huggingface/text-generation-inference/issues/418#issuecomment-1579186709
            "NumberOfAcceleratorDevicesRequired": 1,
            "NumberOfCpuCoresRequired": 1,
            "MinMemoryRequiredInMb": 1024,
        },
    },
    # can setup autoscaling for copies
    RuntimeConfig={"CopyCount": 1},
)
print("IC Falcon Arn: " + create_falcon_ic_response["InferenceComponentArn"])

一旦你的推理组件被创建,你可以在 Studio UI 中看到你的端点上启用了多个模型:

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/6a723ef8b661aa74258cdd56d5f75cac.png

推理组件(创建)

调用这些推理组件与调用传统的 MME 或 MCE 端点非常相似,我们指定推理组件名称作为其自己的参数。

import json

# sample request
payload = "What is the capitol of the United States?"
response = runtime.invoke_endpoint(
    EndpointName=endpoint_name,
    InferenceComponentName=falcon_ic_name, #specify IC name
    ContentType="application/json",
    Accept="application/json",
    Body=json.dumps(
        {
            "inputs": payload,
            "parameters": {
                "early_stopping": True,
                "length_penalty": 2.0,
                "max_new_tokens": 50,
                "temperature": 1,
                "min_length": 10,
                "no_repeat_ngram_size": 3,
                },
        }
    ),
)
result = json.loads(response["Body"].read().decode())
result

4. 其他资源与结论

SageMaker-Deployment/LLM-Hosting/Inference-Components/falcon-flan-tgi-ic.ipynb at master ·…

整个示例的代码可以在上面的链接中找到。有关推理组件的更多资源,请参阅官方 AWS 博客这里SageMaker LLM 研讨会。推理组件提供了一种生产级别的视角,不仅可以帮助您扩展 LLM 模型,还可以以性能和成本最优的方式扩展您可能拥有的任何其他 ML 模型。

请继续关注更多关于 GenAI/AWS 的文章以及对我们上述讨论的主题的深入探讨。一如既往,感谢您的阅读,欢迎留下任何反馈。


如果您喜欢这篇文章,请随意在LinkedIn上与我联系并订阅我的 Medium通讯

内容概要:本文介绍了ENVI Deep Learning V1.0的操作教程,重点讲解了如何利用ENVI软件进行深度学习模型的训练与应用,以实现遥感图像中特定目标(如集装箱)的自动提取。教程涵盖了从数据准备、标签图像创建、模型初始化与训练,到执行分类及结果优化的完整流程,并介绍了精度评价与通过ENVI Modeler实现一键化建模的方法。系统基于TensorFlow框架,采用ENVINet5(U-Net变体)架构,支持通过点、线、面ROI或分类图生成标签数据,适用于多/高光谱影像的单一类别特征提取。; 适合人群:具备遥感图像处理基础,熟悉ENVI软件操作,从事地理信息、测绘、环境监测等相关领域的技术人员或研究人员,尤其是希望将深度学习技术应用于遥感目标识别的初学者与实践者。; 使用场景及目标:①在遥感影像中自动识别和提取特定地物目标(如车辆、建筑、道路、集装箱等);②掌握ENVI环境下深度学习模型的训练流程与关键参数设置(如Patch Size、Epochs、Class Weight等);③通过模型调优与结果反馈提升分类精度,实现高效自动化信息提取。; 阅读建议:建议结合实际遥感项目边学边练,重点关注标签数据制作、模型参数配置与结果后处理环节,充分利用ENVI Modeler进行自动化建模与参数优化,同时注意软硬件环境(特别是NVIDIA GPU)的配置要求以保障训练效率。
内容概要:本文系统阐述了企业新闻发稿在生成式引擎优化(GEO)时代下的全渠道策略与效果评估体系,涵盖当前企业传播面临的预算、资源、内容与效果评估四大挑战,并深入分析2025年新闻发稿行业五大趋势,包括AI驱动的智能化转型、精准化传播、首发内容价值提升、内容资产化及数据可视化。文章重点解析央媒、地方官媒、综合门户和自媒体四类媒体资源的特性、传播优势与发稿策略,提出基于内容适配性、时间节奏、话题设计的策略制定方法,并构建涵盖品牌价值、销售转化与GEO优化的多维评估框架。此外,结合“传声港”工具实操指南,提供AI智能投放、效果监测、自媒体管理与舆情应对的全流程解决方案,并针对科技、消费、B2B、区域品牌四大行业推出定制化发稿方案。; 适合人群:企业市场/公关负责人、品牌传播管理者、数字营销从业者及中小企业决策者,具备一定媒体传播经验并希望提升发稿效率与ROI的专业人士。; 使用场景及目标:①制定科学的新闻发稿策略,实现从“流量思维”向“价值思维”转型;②构建央媒定调、门户扩散、自媒体互动的立体化传播矩阵;③利用AI工具实现精准投放与GEO优化,提升品牌在AI搜索中的权威性与可见性;④通过数据驱动评估体系量化品牌影响力与销售转化效果。; 阅读建议:建议结合文中提供的实操清单、案例分析与工具指南进行系统学习,重点关注媒体适配性策略与GEO评估指标,在实际发稿中分阶段试点“AI+全渠道”组合策略,并定期复盘优化,以实现品牌传播的长期复利效应。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值