亚马逊AWS官方博客

化繁为简:一键部署多模型网关,助力 Role-play 最佳实践

引言

随着生成式 AI 技术的兴起,Role-play 应用正在成为业界关注的热点。Role-play 应用是指基于大语言模型(LLM)构建的具有个性化特征的 AI 助手或虚拟人物,能够在客服、教育、娱乐等领域提供智能化的人机交互服务。为提升 Role-play 应用体验,多模型成为必然的趋势,然而多模型也带来了模型路由、多模型并发、弹性扩缩等挑战,这就需要一套灵活、高效、经济的流量调度机制。本文将探讨如何利用 Amazon ECS(Elastic Container Service)以及 Amazon Graviton 配合 LiteLLM 实现这一目标。

挑战

Role-play 模型网关在线提供服务,访问时面临以下挑战:

  • 多模型:不同 Role-play 角色需要使用多样化的 LLM 模型,在知识领域、语言风格、交互方式上各有侧重,因此流量网关需要支持不同模型实例的路由。
  • 多区域/账号:流量调度网关需要在多个区域或者多账号间实现负载均衡,将请求合理分发,避免过载,同时还要具备一定的容错能力,规避单区域故障,提升可用性
  • 高可用:大模型推理是关键路径,计算资源消耗大,单个网关实例无法支撑高流量请求。需要能够根据流量压力调整到多个实例配置,在高峰期自动扩容,闲时缩容,以平衡性能和成本。
  • 安全:为了模型调用的可靠,避免模型 API 的直接暴露,我们还需要实现 API 调用的鉴权机制。

解决方案

针对上述挑战,我们提出了基于容器化方案和开源 LiteLLM 来构建大模型流量调度网关的解决方案。整体架构如下图所示:

将流量动态路由到 Claude、Mistral 等不同的大语言模型上,或者负载到不同的账号上, 实现大模型的负载均衡和智能调度。

关键特性

  • 容器化封装:每个 AI Character 对应的 LLM 模型分配和调度策略被封装为 Docker 容器镜像,内置推理运行时环境和模型参数文件。利用 ECS 的任务定义(Task Definition)描述容器的资源需求和配置属性。
  • 服务化部署:通过服务描述文件指定使用的任务定义、期望运行的任务数量等配置 Auto Scaling 策略,根据 CPU 利用率等指标自动调整任务数,实现服务的弹性伸缩。ECS 将确保运行中的任务数量符合期望值,发生故障时自动替换。
  • 分层负载均衡:引入 Application Load Balancer(ALB)作为流量网关的入口。ALB 支持基于内容的路由规则,可根据请求的特征(如路径、查询参数等)将流量分发到不同的目标组(Target Group)。每个 ECS 服务注册为一个目标组,ALB 将请求动态转发到服务内的多个任务实例,实现负载均衡。同时在 ECS 服务内部,每个任务实例运行一个 LiteLLM 容器,使用 Round-Robin 策略处理分发到本实例的请求,避免单个容器过载。

部署方式

基于 ECS 的部署

步骤:

1. 根据账号和模型使用情况编写 Proxy Config 文件:

  • 为相同的 model_name 配置不同的区域或者账号信息,实现相同模型的流量分配。
  • 为不同的模型,包括 Bedrock 托管模型和在 SageMaker 上部署的模型,配置不同的 model_name,实现为不同用户、角色和任务的灵活选择。
## proxy_config.yaml
model_list:
  - model_name: bedrock-claude-v3-sonnet
    litellm_params:
      model: bedrock/anthropic.claude-3-sonnet-20240229-v1:0
      aws_region_name: "us-west-2"
      aws_access_key_id: "<replace_with_your_access_key>"
      aws_secret_access_key: "<replace_with_your_secret_key>"
  - model_name: bedrock-claude-v3-sonnet
    litellm_params:
      model: bedrock/anthropic.claude-3-sonnet-20240229-v1:0
      aws_region_name: "us-east-1"
      aws_access_key_id: "<replace_with_your_access_key>"
      aws_secret_access_key: "<replace_with_your_secret_key>"
  - model_name: bedrock-claude-v3-haiku
    litellm_params:
      model: bedrock/anthropic.claude-3-haiku-20240307-v1:0
      aws_region_name: "us-west-2"
      aws_access_key_id: "<replace_with_your_access_key>"
      aws_secret_access_key: "<replace_with_your_secret_key>"
  - model_name: sagemaker-llama2-7b
    litellm_params:
      model: sagemaker/jumpstart-dft-meta-textgeneration-l-2024xxxx-0642 # replace with your endpoint
      aws_region_name: "us-west-2"
      aws_access_key_id: "<replace_with_your_access_key>"
      aws_secret_access_key: "<replace_with_your_secret_key>"
  - model_name: sagemaker-Yi-1.5-9b
    litellm_params:
      model: sagemaker/jumpstart-dft-hf-llm-yi-1-5-9b-chat-2024xxxx-070517 # replace with your endpoint
      aws_region_name: "us-west-2"
      aws_access_key_id: "<replace_with_your_access_key>"
      aws_secret_access_key: "<replace_with_your_secret_key>"
general_settings: 
  master_key: "<replace_with_your_master_key>"

2. 在方案部署账号中准备一个 S3 桶,上传上述 yaml 文件到 s3://<bucket_name>/litellm/proxy_config.yaml

3. 一键部署 CloudFormation 模版,需要输入上一步的 S3 桶名 bucket_name。该方案会部署的资源包括:

  • 新的 VPC、公有和私有 Subnets、安全组、Internet Gateway。方案默认为实现 Virtual Key 和用户资源使用管理部署 PostgreSQL,为实现负载均衡的路由规则管理部署 Redis。
  • ECS 集群和 Litellm ECS Service,该服务支持根据 CPU utilization 使用量自动扩缩,日志会进入 CloudWatch LogGroup。
  • Application Load Balancer,Litellm Service 通过 ALB 暴露在 80 端口。

部署完成后,CloudFormation 的 Output 会显示 ALB 的 DNS。

即可开始使用模型网关,以下为 Postman 示例:

除了适用于生产环境的基于 ECS 的高可用弹性部署,此方案也提供基于 EC2 和 docker-compose 的快速部署方案,方便进行功能快速验证。

基于 EC2 的部署

步骤:

1. 准备 proxy_config.yaml 并将文件到 s3://<bucket_name>/litellm/proxy_config.yaml

2. 上传 docker-compose.yml 和 prometheus.yml 到同一路径 s3://<bucket_name>/litellm/

services:
  litellm:
    image: ghcr.io/berriai/litellm:main-stable
    ports:
      - "80:4000"
    ...
    
  redis:
    image: redis:6.2-alpine
    ports:
      - '6379:6379'
    ...
      
  db:
    image: postgres
    ports:
      - '5432:5432'
    ...
    
  prometheus:
    image: prom/prometheus
    ports:
      - '9090:9090'

基于 docker-compose 的部署默认添加了 Prometheus 组件,因只有 LiteLLM 企业版提供譬如根据 user,key,model,team 等维度指标来跟踪 spend 和 token 的使用情况,开源版本中默认的 prometheus 组件仅上报基础的 python 和 process 资源使用指标。可根据实际需要选择使用企业版或移除 prometheus 组件。

3. 一键部署 CloudFormation 模版 ,需要输入上一步的 S3 桶名 bucket_name。该方案会部署的资源包括:

  • 新的 VPC、公有和私有 Subnets、安全组、Internet Gateway
  • EC2 MultiLLM server,服务端点为 http:// <MultiLLM_Server_PublicIP>:80

此方案的部署基于 LiteLLM 项目,以上两种方式都可通过 admin 面板 http://<MultiLLM_DNS_or_IP>/ui 进行后续管理,登录信息为 admin/<master_key>

基础功能测试

1. OpenAPI 兼容性

  • rest call 调用(支持 streaming 功能)
    curl -i http://$litellm_ip:80/v1/chat/completions \
        -H "Content-Type: application/json" \
        -H "Authorization: Bearer <master_key>" \
        -d '{
            "model": "bedrock-claude-v3-haiku",
            "messages": [
                {
                    "role": "user",
                    "content": "Hello"
                }
            ],
            "stream": True
    }'
    
  • SDK 集成
    import openai
    client = openai.OpenAI(
        api_key="<your_master_key or virtual_key>",
        base_url="http://$litellm_ip:80"
    )
    
    # request sent to model set on litellm proxy, `litellm --model`
    response = client.chat.completions.create(model="bedrock-claude-v3-haiku", messages = [
        {
            "role": "user",
            "content": "this is a test request, write a short poem"
        }
    ])
    print(response)
    

2. Virtual key 使用

  • 为 user 生成 key,配置可以调用的模型
    curl http://$litellm_ip:80/key/generate \
        --header 'Authorization: Bearer <master_key>' \
        --header 'Content-Type: application/json' \
        --data-raw '{
            "models": [
                "bedrock-claude-v3-sonnet",
                "bedrock-claude-v3-haiku"
            ],
            "metadata": {
                "user": "<user_mail>"
            }
    }'
    

    结果返回的 JSON 中含有类似 sk-pyHgYR8Iacc4CLHwjeKu4Q 的 virtual key。

  • 查询 key 的使用情况
    curl http://$litellm_ip:80/key/info?key=sk-pyHgYR8Iacc4CLHwjeKu4Q \
        -X GET \
        -H 'Authorization: Bearer <master_key>'
    

    结果返回的 JSON 内容包含对应 Key 的 spend 使用情况。

3. Routing 功能

  • 在 yaml 文件中将路由策略配置为 simple shuffle
    model_list:
      - model_name: bedrock-claude-v3-sonnet
        litellm_params:
          model: bedrock/anthropic.claude-3-sonnet-20240229-v1:0
          aws_region_name: "us-west-2"
          ...
      - model_name: bedrock-claude-v3-sonnet
        litellm_params:
          model: bedrock/anthropic.claude-3-sonnet-20240229-v1:0
          aws_region_name: "us-east-1"
          ...
    router_settings:
      routing_strategy: simple-shuffle
    

    当多次调用 bedrock-claude-v3-sonnet 时,返回的结果标头会显示不同的 model id ,证明不同的 LLM 实例被调用了。

    #第一次调用 bedrock-claude-v3-sonnet 返回结果标头
    HTTP/1.1 200 OK
    ...
    server: uvicorn
    x-litellm-call-id: ac125673-85ef-466e-ba3f-f26fab463041
    x-litellm-model-id: 2a281c00b23a45934cb6a5cb3929249fb55627923ece219cdbcc2331a7b1855f 
    ...
    
    #第二次调用 bedrock-claude-v3-sonnet 返回结果标头
    HTTP/1.1 200 OK
    ...
    server: uvicorn
    x-litellm-call-id: c24f6b5c-385a-4105-af2f-b4ad2b801371
    x-litellm-model-id: ab933985853f13d8760ccd08d89e500574fd52724a211b24e082936b8d5eb382
    ...
    
  • 在 proxy_config.yaml 文件中将路由策略按以下配置为 rate limit aware 方式
    YAML
    model_list:
      - model_name: bedrock-claude-v3-sonnet
        litellm_params:
          model: bedrock/anthropic.claude-3-sonnet-20240229-v1:0
          aws_region_name: "us-west-2"
          rpm: 10
          ...
      - model_name: bedrock-claude-v3-sonnet
        litellm_params:
          model: bedrock/anthropic.claude-3-sonnet-20240229-v1:0
          aws_region_name: "us-east-1"
          rpm: 10
          ...
    router_settings:
      routing_strategy: usage-based-routing
    

    当调用 bedrock-claude-v3-sonnet 的 rpm 超过 20 时,返回的结果为 “HTTPError(‘429 Client Error: Too Many Requests for url: /v1/chat/completions’)” 。

更多详细功能可参考 LiteLLM 项目。

Locust 压测

运行 locust 脚本,以下是配置 peak users = 100, ramp up = 20 对 haiku 模型进行的压测结果截图:

结论

借助容器化和自动扩缩容特性,以及 LiteLLM 的轻量化优势,我们可以构建一个灵活、高效、经济的大模型调度机制。这不仅能够显著降低应用的运营成本,还能以更敏捷的方式满足不断变化的需求。

代码链接:

https://github.com/chenxqdu/multillm-proxy-on-aws

本篇作者

杜晨曦

亚马逊云科技解决方案架构师,负责基于亚马逊云科技云计算方案架构的咨询和设计,在国内推广亚马逊云科技云平台技术和各种解决方案。

曹镏

亚马逊云科技解决方案架构师,专注于为企业级客户提供信息化以及生成式 AI 方案的咨询与设计,在 AI/ML 领域具有解决实际问题能力以及落地大模型训练项目的经验。