基于请求Header实现LLM Token限流

更新时间:2024-12-27 02:57:24

服务网格 ASM(Service Mesh)支持基于请求属性(如TCP属性、HTTP Header、路径、Host)和路由目标,限制指定客户端的LLM请求Token数。本文将演示如何通过LLM请求Header限制Token消耗量。若超过限额,Proxy将直接返回响应,请求不会被发送到外部。

背景信息

功能概述

ASMLLM Token限流能力基于Wasm插件实现,整体分为两部分:限流插件和限流服务。限流插件负责拦截请求并提取限流的key,然后访问限流服务来获取是否对该请求进行限流。在LLM的响应阶段,再次调用这个限流服务来更新指定key对应的限流记录。

image
说明

如上图所示,⑥返回 LLM 响应与⑥更新限流记录是异步进行的,互不阻塞。

其中限流服务由客户端自行维护,ASM限流插件会使用标准的HTTP接口调用这个服务。您可以根据不同的业务场景选择不同的限流算法(令牌桶、漏桶或者滑动窗口等)来实现特定的限流规则。您也可以根据后端服务的负载,来动态地调节限流规则。同时,ASM提供了默认的基于令牌桶算法的限流实现,该实现依赖Redis数据库存储限流记录。

适用场景

此能力适用于以下两种场景:

  • 客户端调用外部大模型服务:外部的大模型服务通常根据请求消耗的token数来计费。使用LLM token限流可以有效控制客户端的费用消耗。

  • 推流服务提供方:外部客户端调用本集群的推理服务。推理服务要求大量计算资源,使用LLM token限流可以防止某一个客户短时间内占用过量资源,造成其他用户服务不可用。

前提条件

示例说明

本文示例将配置两个用户名为regular-usersubscriber的请求header。当wasm插件读取到请求后,限流插件会读取请求header,提取出最终的限流key,发送给限流服务。限流服务会根据配置的限流规则来对请求进行限流,实现订阅用户可以消耗更多的token,普通用户只能消耗少量。

步骤一:部署限流服务

  1. 使用以下内容,创建token-limit.yaml。

    展开查看YAML内容

    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: asm-llm-token-rate-limit-example
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: asm-llm-token-rate-limit-example
      labels:
        app: asm-llm-token-rate-limit-example
        service: asm-llm-token-rate-limit-example
    spec:
      ports:
      - name: http
        port: 80
        targetPort: 8080
      selector:
        app: asm-llm-token-rate-limit-example
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: asm-llm-token-rate-limit-example
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: asm-llm-token-rate-limit-example
          version: v1
      template:
        metadata:
          labels:
            app: asm-llm-token-rate-limit-example
            version: v1
          annotations:
            sidecar.istio.io/inject: "true"
        spec:
          tolerations:
          - key: "node.kubernetes.io/disk-pressure"
            operator: "Equal"
            value: ""
            effect: "NoSchedule"
          serviceAccountName: asm-llm-token-rate-limit-example
          containers:
          - image: registry-cn-hangzhou.ack.aliyuncs.com/acs/asm-wasm-token-rate-limit-example:v1.23.6.34-g92d6a4b-aliyun
            imagePullPolicy: IfNotPresent
            name: asm-llm-token-rate-limit-example
            ports:
            - containerPort: 8080
            env:
            - name: REDIS_ADDRESS
              value: ${redis-address}:${redis-port}
            - name: REDIS_PASSWORD
              value: "${redis-user}:${password}"
            - name: RATE_LIMIT_CONFIG
              value: |
                [
                  {
                    "rate_limit_key_regex": "regular-user.*",
                    "redis_expired_seconds": 300,
                    "fill_interval_second": 30,
                    "tokens_per_fill": 50,
                    "max_tokens": 200
                  },
                  {
                    "rate_limit_key_regex": "subscriber.*",
                    "redis_expired_seconds": 600,
                    "fill_interval_second": 60,
                    "tokens_per_fill": 100,
                    "max_tokens": 1000
                  }
                ]
            resources:
              limits:
                memory: 256Mi
                cpu: 200m
              requests:
                memory: 64Mi
                cpu: 50m

    上述YAML配置了环境变量RATE_LIMIT_CONFIG,具体作用如下:

    • rate_limit_key_regex成功匹配请求header中的regular-user.*时,限流规则为:Redis存储的过期时间是300秒,每30秒填充一次令牌桶,每次填充50token,令牌桶的最大容量为200。

    • rate_limit_key_regex成功匹配请求header中的subscriber-.*时,限流规则为:Redis存储的过期时间是600秒,每60秒填充一次令牌桶,每次填充100token,令牌桶的最大容量为1000。

  2. 使用数据面集群的kubeconfig,执行以下命令。

    kubectl apply -f token-limit.yaml

    ASM支持自定义限流服务,并且提供了基于Redis精准匹配的默认实现。更多信息,请参见代码仓库。如果您有其他定制化需求,可以仿照该示例自行开发对应的限流服务。

步骤二:部署限流插件

  1. 使用以下内容,创建wasm.yaml。

    apiVersion: extensions.istio.io/v1alpha1
    kind: WasmPlugin
    metadata:
      name: llm-token-ratelimit
      namespace: default
    spec:
      failStrategy: FAIL_OPEN
      imagePullPolicy: IfNotPresent
      selector:
        matchLabels:
          app: sleep
      match:
      - mode: CLIENT
        ports:
        - number: 80
      phase: STATS
      pluginConfig:
        matches:
        - host:
            exact: "dashscope.aliyuncs.com"
        rateLimitKeys:
        - "{{request.headers.user-type}}"
        rateLimitService:
          service: asm-llm-token-rate-limit-example.default.svc.cluster.local
          port: 80
      priority: 10
      url: registry-cn-hangzhou.ack.aliyuncs.com/acs/asm-wasm-llm-token-ratelimit:v1.23.6.34-g92d6a4b-aliyun

    部分配置项说明如下:

    配置项

    说明

    配置项

    说明

    .spec.pluginConfig.matches

    匹配要执行限流逻辑的请求,未命中请求直接放行。

    .spec.pluginConfig.rateLimitKeys

    生成限流key的规则。更多信息,请参见Attributes。本示例为{{request.headers.user-type}}

    .spec.pluginConfig.rateLimitService

    限流服务的信息,Service需要填写服务的全称。

  2. 使用控制面集群的kubeconfig,执行以下命令。

    kubectl apply -f wasm.yaml

步骤三:测试

使用数据面集群的kubeconfig,分别以regular-usersubscriber身份多次执行以下命令。

kubectl exec deployment/sleep -it -- curl 'http://dashscope.aliyuncs.com' \
--header 'Content-Type: application/json' \
--header "user-type: regular-user" \
--data '{
    "messages": [
        {"role": "user", "content": "介绍一下你自己"}
    ]
}'
kubectl exec deployment/sleep -it -- curl 'http://dashscope.aliyuncs.com' \
--header 'Content-Type: application/json' \
--header "user-type: subscriber" \
--data '{
    "messages": [
        {"role": "user", "content": "介绍一下你自己"}
    ]
}'

预期输出:

{"choices":[{"message":{"role":"assistant","content":"我是来自阿里云的大规模语言模型,我叫通义千问。我是一个能够回答问题、创作文字,还能表达观点、撰写代码的超大规模语言模型。我的知识来自于互联网上的文本,经过多轮迭代和优化,我的能力不断提升,现在已经能够回答各种问题,比如科技、文化、历史、娱乐等各类话题的问题,也可以进行连续的对话。如果您有任何问题或需要帮助,请随时告诉我,我会尽力提供支持。"},"finish_reason":"stop","index":0,"logprobs":null}],"object":"chat.completion","usage":{"prompt_tokens":10,"completion_tokens":95,"total_tokens":105},"created":1735103573,"system_fingerprint":null,"model":"qwen1.5-72b-chat","id":"chatcmpl-7de0bd64-341a-9196-b676-99b5644ec111"}%
regular-user is being rate-limited
{"choices":[{"message":{"role":"assistant","content":"我是来自阿里云的大规模语言模型,我叫通义千问。我是一个能够回答问题、创作文字,还能表达观点、撰写代码的超大规模语言模型。我的知识来自于互联网上的文本,经过多轮迭代和优化,我的能力不断提升,现在已经能够回答各种问题,比如科技、文化、历史、娱乐等各类话题的问题,也可以进行连续的对话。如果您有任何问题或需要帮助,请随时告诉我,我会尽力提供支持。"},"finish_reason":"stop","index":0,"logprobs":null}],"object":"chat.completion","usage":{"prompt_tokens":10,"completion_tokens":95,"total_tokens":105},"created":1735103890,"system_fingerprint":null,"model":"qwen1.5-72b-chat","id":"chatcmpl-1b284b71-f850-95f5-9a7e-12678812763c"}%
{"choices":[{"message":{"role":"assistant","content":"我是来自阿里云的大规模语言模型,我叫通义千问。我是一个能够回答问题、创作文字,还能表达观点、撰写代码的超大规模语言模型。我的知识来自于阿里云的海量文本数据,包含各种书籍、文档、网页、论文等,旨在使我能够理解和回答各种主题。如果您有任何问题或需要帮助,请随时告诉我,我会尽力提供支持。"},"finish_reason":"stop","index":0,"logprobs":null}],"object":"chat.completion","usage":{"prompt_tokens":10,"completion_tokens":81,"total_tokens":91},"created":1735103895,"system_fingerprint":null,"model":"qwen1.5-72b-chat","id":"chatcmpl-0d29d820-c9c5-9e94-9a5a-d054233ed35a"}
subscriber is being rate-limited
  • 本页导读 (1)
  • 背景信息
  • 功能概述
  • 适用场景
  • 前提条件
  • 示例说明
  • 步骤一:部署限流服务
  • 步骤二:部署限流插件
  • 步骤三:测试
AI助理

点击开启售前

在线咨询服务

你好,我是AI助理

可以解答问题、推荐解决方案等