基于Knative部署vLLM推理应用

传统的基于GPU利用率的弹性伸缩策略无法准确反映大模型推理服务的实际负载情况,即使GPU利用率达到了100%,也不一定表明系统正处在高负荷运行状态。Knative提供的自动扩缩容机制KPA(Knative Pod Autoscaler)能够根据QPS或RPS来调整资源分配,更直接地反映推理服务的性能表现。本文以Qwen-7B-Chat-Int8模型、GPU类型为V100卡为例,介绍如何在Knative中部署一个vLLM推理服务。

vLLM(Vectorized Large Language Model)是一个高性能的大语言模型推理库,支持多种模型格式和后端加速,适用于大规模语言模型的推理服务部署。vLLM通过PagedAttention优化、动态批量推理(Continuous Batching)、模型量化等优化技术,可以取得较好的大语言模型推理效率。更多关于vLLM框架的信息,请参见vLLM GitHub代码库

前提条件

步骤一:准备模型数据并上传OSS Bucket

您可以使用OSS或NAS准备模型数据,具体操作,请参见使用OSS静态存储卷使用NAS静态存储卷。本文以OSS为例说明如何准备模型数据。

  1. 下载模型文件。本文以Qwen-7B-Chat-Int8模型为例。

    1. 执行以下命令,安装Git。

      # 可执行yum install git或apt install git安装。
      sudo yum install git
    2. 执行以下命令,安装Git LFS(Large File Support)插件。

      # 可执行yum install git-lfs或apt install git-lfs安装。
      sudo yum install git-lfs
    3. 执行以下命令,将ModelScope上的Qwen-7B-Chat-Int8仓库克隆到本地。

      GIT_LFS_SKIP_SMUDGE=1 git clone https://www.modelscope.cn/qwen/Qwen-7B-Chat-Int8.git
    4. 执行以下命令,进入Qwen-7B-Chat-Int8目录,下载LFS管理的大文件。

      cd Qwen-7B-Chat-Int8
      git lfs pull
  2. 将下载的Qwen-7B-Chat-Int8文件上传至OSS。

    1. 登录OSS控制台,查看并记录已创建的Bucket名称。

      如何创建Bucket,请参见创建存储空间

    2. 安装和配置ossutil,用于管理OSS资源。具体操作,请参见安装ossutil

    3. 执行以下命令,在OSS创建名为Qwen-7B-Chat-Int8的目录。

      ossutil mkdir oss://<Your-Bucket-Name>/Qwen-7B-Chat-Int8
    4. 执行以下命令,上传模型文件至OSS。

      ossutil cp -r ./Qwen-7B-Chat-Int8 oss://<Your-Bucket-Name>/Qwen-7B-Chat-Int8
  3. 为目标集群配置存储卷PV和存储声明PVC。

    下表仅介绍示例配置项,具体操作,请参见使用OSS静态存储卷

    • 示例PV的配置信息

      配置项

      说明

      存储卷类型

      OSS

      名称

      llm-model

      访问证书

      配置用于访问OSS的AccessKey ID和AccessKey Secret。

      Bucket ID

      选择已创建的OSS Bucket。

      OSS Path

      选择模型所在的路径,如/Qwen-7B-Chat-Int8。

    • 示例PVC的配置信息

      配置项

      说明

      存储声明类型

      OSS

      名称

      llm-model

      分配模式

      选择已有存储卷

      已有存储卷

      单击选择已有存储卷链接,选择已创建的存储卷PV。

步骤二:部署Knative推理服务

  1. 登录容器服务管理控制台,在左侧导航栏选择集群

  2. 集群列表页面,单击目标集群名称,然后在左侧导航栏,选择应用 > Knative

  3. 单击服务管理页签,选择命名空间default,然后单击使用模板创建,将以下YAML示例粘贴至模板,最后单击创建,部署Knative推理服务。

    apiVersion: serving.knative.dev/v1
    kind: Service
    metadata:
      labels:
        release: qwen
      name: qwen
      namespace: default
    spec:
      template:
        metadata:
          annotations:
            autoscaling.knative.dev/metric: "concurrency" # 配置并发数为弹性伸缩指标
            autoscaling.knative.dev/target: "2" # 设置当前最大并发请求数为2
            autoscaling.knative.dev/max-scale: "3" 
          labels:
            release: qwen
        spec:
          containers:
          - command:
            - sh
            - -c
            - python3 -m vllm.entrypoints.openai.api_server --port 8080 --trust-remote-code
              --served-model-name qwen --model /Qwen-7B-Chat-Int8 --gpu-memory-utilization
              0.95 --quantization gptq --max-model-len=6144 # /Qwen-7B-Chat-Int8为模型所在的路径
            image: kube-ai-registry.cn-shanghai.cr.aliyuncs.com/kube-ai/vllm:0.4.1
            imagePullPolicy: IfNotPresent
            name: vllm-container
            readinessProbe:
              tcpSocket:
                port: 8080
              initialDelaySeconds: 5
              periodSeconds: 5
            resources:
              limits:
                cpu: "32"
                memory: 64Gi
                nvidia.com/gpu: "1"
              requests:
                cpu: "8"
                memory: 16Gi
                nvidia.com/gpu: "1"
            volumeMounts:
            - mountPath: /Qwen-7B-Chat-Int8 # 模型所在的路径
              name: llm-model
          volumes:
          - name: llm-model
            persistentVolumeClaim:
              claimName: llm-model

    参数

    说明

    autoscaling.knative.dev/metric

    扩缩容指标,支持concurrencyrps两种指标。默认为concurrency指标。

    target

    扩缩容阈值。

    autoscaling.knative.dev/target

    扩缩容的最小副本数,需要为≥0的整数。KPA支持设置最小值为0。

    max-scale

    扩缩容的最大副本数。

  4. 服务管理页签,查看服务是否已部署成功,并获取默认域名和访问网关IP,以备后续使用。

    image

步骤三:验证推理服务

执行以下命令,向模型推理服务发送一条模型推理请求。

# 命令中的1XX.XX.XX.XXX为已获取的访问网关IP
curl -H "Host: qwen.default.example.com" -H "Content-Type: application/json" http://1XX.XX.XX.XXX:80/v1/chat/completions -d '{"model": "qwen", "messages": [{"role": "user", "content": "杭州西湖"}], "max_tokens": 10, "temperature": 0.7, "top_p": 0.9, "seed": 10}'

预期输出:

{"id":"cmpl-e914ef54331e4a5f9b858425321a82ed","object":"chat.completion","created":1733191642,"model":"qwen","choices":[{"index":0,"message":{"role":"assistant","content":"西湖位于中国浙江省杭州市,是中国著名的风景名"},"logprobs":null,"finish_reason":"length","stop_reason":null}],"usage":{"prompt_tokens":10,"total_tokens":20,"completion_tokens":10}}

输出结果表明,模型可以根据给定的输入生成相应的回复。

(可选)步骤四:清理环境

如果不再使用已创建的资源,请及时清理。执行以下命令,删除已创建的PV和PVC。

kubectl delete pvc llm-model
kubectl delete pv llm-model