使用ACS GPU算力构建QwQ-32B模型推理服务

更新时间:2025-03-10 03:16:58

在使用容器计算服务 ACS(Container Compute Service)算力时,您无需深入了解底层硬件,也无需涉及GPU节点管理和配置即可开箱即用。ACS部署简单、支持按量付费,非常适合用于LLM推理任务,可以有效降低推理成本。本文介绍如何使用ACS GPU算力部署生产可用的QwQ-32B模型推理服务。

背景介绍

QwQ-32B模型

阿里云最新发布的QwQ-32B模型,通过强化学习大幅度提升了模型推理能力。QwQ-32B模型拥有320亿参数,其性能可以与DeepSeek-R1 671B参数的满血版媲美。模型数学代码等核心指标(AIME 24/25、livecodebench)以及部分通用指标(IFEval、LiveBench等)达到DeepSeek-R1满血版水平,各指标均显著超过同样基于Qwen2.5-32BDeepSeek-R1-Distill-Qwen-32B。更多模型信息,请参考QwQ-32B

vLLM

vLLM是一个高效易用的大语言模型推理服务框架,vLLM支持包括通义千问在内的多种常见大语言模型。vLLM通过PagedAttention优化、动态批量推理(continuous batching)、模型量化等优化技术,可以取得较好的大语言模型推理效率。更多关于vLLM框架的信息,请参见vLLM GitHub代码库

前提条件

  • 首次使用阿里云容器计算服务 ACS(Container Compute Service)时,需要为服务账号授予系统默认角色。当且仅当该角色被正确授予后,ACS才能正常地调用相关服务(ECS、OSS、NAS、CPFS、SLB等),创建集群以及保存日志等。具体操作,请参见首次使用容器计算服务

  • 已创建ACS集群,配置的地域和可用区支持GPU资源。具体操作,请参见创建ACS集群

  • 已使用kubectl连接Kubernetes集群。具体操作,请参见获取集群kubeconfig并通过kubectl工具连接集群

GPU实例规格和成本预估

在推理阶段主要占用显存的是模型参数,可以通过以下公式计算。

模型参数量为:32B(即320亿),精度数据类型字节数为:默认精度16位浮点数 / 8位每字节 = 2字节。

除了加载模型占用的显存之外,还需要考虑运算时所需的KV Cache大小和GPU利用率,通常会预留一部分buffer,因此推荐使用80 GiB显存以上的资源配置:GPU:1卡,CPU:16 vCPU,内存:128 GiB。您可以参考规格推荐表GPU计算类型卡型规格来选择合适的实例规格。关于如何计算ACS GPU实例产生的费用,请参见计费说明

说明
  • 在使用ACS GPU实例时,实例规格同样遵循ACS Pod规格规整逻辑

  • ACS Pod默认提供30 GiB的免费的临时存储空间(EphemeralStorage),本文中使用的推理镜像registry-cn-hangzhou.ack.aliyuncs.com/ack-demo/vllm:v0.7.2(公网地址)或registry-cn-wulanchabu-vpc.ack.aliyuncs.com/ack-demo/vllm:v0.7.2(VPC地址)占用约9.5 GiB。如果该存储空间大小无法满足您的需求,您可以自定义增加临时存储空间大小。详细操作,请参见增加临时存储空间大小

操作步骤

说明

您可以提交工单,快速获取模型文件和支持的GPU型号

  • 模型文件:QwQ-32B。模型文件大小约120G,通常下载和上传模型文件需要2-3小时,提交工单可以快速将模型文件复制到您的OSS Bucket。

  • GPU型号:请将标签alibabacloud.com/gpu-model-series: <example-model>替换为ACS支持的GPU具体型号。详细内容,请参见指定ACS GPU算力

步骤一:准备QwQ-32B模型数据

大语言模型因其庞大的参数量,需要占用大量的磁盘空间来存储模型文件。建议您使用NAS存储卷或OSS存储卷来持久化存储模型文件,以下步骤以使用OSS存储QwQ-32B模型文件作为示例。

  1. 执行以下命令从ModelScope下载QwQ-32B模型。

    说明

    请确认是否已安装git-lfs插件,如未安装可执行yum install git-lfs或者apt-get install git-lfs安装。更多的安装方式,请参见安装git-lfs

    git lfs install
    GIT_LFS_SKIP_SMUDGE=1 git clone https://www.modelscope.cn/Qwen/QwQ-32B.git
    cd QwQ-32B
    git lfs pull
  2. OSS中创建目录,将模型上传至OSS。

    说明

    关于ossutil工具的安装和使用方法,请参见安装ossutil

    ossutil mkdir oss://<your-bucket-name>/models/QwQ-32B
    ossutil cp -r ./QwQ-32B oss://<your-bucket-name>/models/QwQ-32B
  3. 创建PVPVC。为目标集群配置名为llm-model的存储卷PV和存储声明PVC。具体操作,请参见静态挂载OSS存储卷

    控制台操作示例
    kubectl操作示例

    以下为示例PV的基本配置信息:

    配置项

    说明

    存储卷类型

    OSS

    名称

    llm-model

    访问证书

    配置用于访问OSSAccessKey IDAccessKey Secret。

    Bucket ID

    选择上一步所创建的OSS Bucket。

    OSS Path

    选择模型所在的路径,如/models/QwQ-32B

    以下为示例PVC的基本配置信息:

    配置项

    说明

    存储声明类型

    OSS

    名称

    llm-model

    分配模式

    选择已有存储卷。

    已有存储卷

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

    以下为示例YAML:

    apiVersion: v1
    kind: Secret
    metadata:
      name: oss-secret
    stringData:
      akId: <your-oss-ak> # 配置用于访问OSS的AccessKey ID
      akSecret: <your-oss-sk> # 配置用于访问OSS的AccessKey Secret
    ---
    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: llm-model
      labels:
        alicloud-pvname: llm-model
    spec:
      capacity:
        storage: 30Gi 
      accessModes:
        - ReadOnlyMany
      persistentVolumeReclaimPolicy: Retain
      csi:
        driver: ossplugin.csi.alibabacloud.com
        volumeHandle: llm-model
        nodePublishSecretRef:
          name: oss-secret
          namespace: default
        volumeAttributes:
          bucket: <your-bucket-name> # bucket名称
          url: <your-bucket-endpoint> # Endpoint信息,如oss-cn-hangzhou-internal.aliyuncs.com
          otherOpts: "-o umask=022 -o max_stat_cache_size=0 -o allow_other"
          path: <your-model-path> # 本示例中为/models/QwQ-32B/
    ---
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: llm-model
    spec:
      accessModes:
        - ReadOnlyMany
      resources:
        requests:
          storage: 30Gi
      selector:
        matchLabels:
          alicloud-pvname: llm-model

步骤二:部署模型

  1. 执行下列命令,基于vLLM模型推理框架部署QwQ-32B模型的推理服务。

    该推理服务暴露与OpenAI兼容的HTTP API。下列命令将模型参数文件视作是一种特殊类型的数据集合,挂载到推理服务容器的指定位置(/model/QwQ-32B)。--max-model-len设置了该模型最大可处理的Token长度,增大该配置项可获得更好的模型对话效果,但是可能会占用更多GPU显存资源。

    kubectl apply -f- <<EOF
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        app: qwq-32b
        alibabacloud.com/compute-class: gpu
        alibabacloud.com/gpu-model-series: <example-model>
      name: qwq-32b
      namespace: default
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: qwq-32b
      template:
        metadata:
          labels:
            app: qwq-32b
            alibabacloud.com/compute-class: gpu
            alibabacloud.com/gpu-model-series: <example-model>
        spec:
          volumes:
            - name: model
              persistentVolumeClaim:
                claimName: llm-model
            - name: dshm
              emptyDir:
                medium: Memory
                sizeLimit: 30Gi
          containers:
          - command:
            - sh
            - -c
            - vllm serve /models/QwQ-32B --port 8000 --trust-remote-code --served-model-name qwq-32b --max-model-len 32768 --gpu-memory-utilization 0.95 --enforce-eager
            image: registry-cn-wulanchabu-vpc.ack.aliyuncs.com/ack-demo/vllm:v0.7.2
            name: vllm
            ports:
            - containerPort: 8000
            readinessProbe:
              tcpSocket:
                port: 8000
              initialDelaySeconds: 30
              periodSeconds: 30
            resources:
              limits:
                nvidia.com/gpu: "1"
                cpu: "16"
                memory: 128G
            volumeMounts:
              - mountPath: /models/QwQ-32B
                name: model
              - mountPath: /dev/shm
                name: dshm
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: qwq-32b-v1
    spec:
      type: ClusterIP
      ports:
      - port: 8000
        protocol: TCP
        targetPort: 8000
      selector:
        app: qwq-32b
    EOF

步骤三:部署OpenWebUI

  1. 执行以下命令,创建OpenWebUI应用及服务。

    kubectl apply -f- << EOF 
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: openwebui
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: openwebui
      template:
        metadata:
          labels:
            app: openwebui
        spec:
          containers:
          - env:
            - name: ENABLE_OPENAI_API
              value: "True"
            - name: ENABLE_OLLAMA_API
              value: "False"
            - name: OPENAI_API_BASE_URL
              value: http://qwq-32b-v1:8000/v1
            - name: ENABLE_AUTOCOMPLETE_GENERATION
              value: "False"
            - name: ENABLE_TAGS_GENERATION
              value: "False"
            image: kube-ai-registry.cn-shanghai.cr.aliyuncs.com/kube-ai/open-webui:main
            name: openwebui
            ports:
            - containerPort: 8080
              protocol: TCP
            volumeMounts:
            - mountPath: /app/backend/data
              name: data-volume
          volumes:
          - emptyDir: {}
            name: data-volume
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: openwebui
      labels:
        app: openwebui
    spec:
      type: ClusterIP
      ports:
      - port: 8080
        protocol: TCP
        targetPort: 8080
      selector:
        app: openwebui
    EOF

步骤四:验证推理服务

  1. 使用kubectl port-forward在推理服务与本地环境间建立端口转发。

    说明

    请注意kubectl port-forward建立的端口转发不具备生产级别的可靠性、安全性和扩展性,因此仅适用于开发和调试目的,不适合在生产环境使用。更多关于Kubernetes集群内生产可用的网络方案的信息,请参见Ingress管理

    kubectl port-forward svc/openwebui 8080:8080

    预期输出:

    Forwarding from 127.0.0.1:8080 -> 8080
    Forwarding from [::1]:8080 -> 8080
  2. 访问http://localhost:8080,登录OpenWebUI页面。

    第一次登录需要配置管理员账号和密码。输入提示词,预期输出如下图所示。

    image

(可选)步骤五:压测推理服务

说明

下载压测数据集步骤需要访问公网能力。具体操作,请参见为集群开启公网访问能力Pod挂载独立公网EIP

  1. 执行以下命令创建压测工具。

    kubectl apply -f- <<EOF 
    apiVersion: apps/v1 
    kind: Deployment
    metadata:
      name: vllm-benchmark
      labels:
        app: vllm-benchmark
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: vllm-benchmark
      template:
        metadata:
          labels:
            app: vllm-benchmark
        spec:
          volumes:
          - name: llm-model
            persistentVolumeClaim:
              claimName: llm-model
          containers:
          - name: vllm-benchmark
            image: kube-ai-registry.cn-shanghai.cr.aliyuncs.com/kube-ai/vllm-benchmark:v1
            command:
            - "sh"
            - "-c"
            - "sleep inf"
            volumeMounts:
            - mountPath: /models/QwQ-32B
              name: llm-model
    EOF
  2. 进入压测Pod,下载压测数据集。

    # 执行以下命令进入Benchmark Pod
    PODNAME=$(kubectl get po -o custom-columns=":metadata.name"|grep "vllm-benchmark")
    kubectl exec -it $PODNAME -- bash
    
    # 下载压测数据集
    pip3 install modelscope
    modelscope download --dataset gliang1001/ShareGPT_V3_unfiltered_cleaned_split ShareGPT_V3_unfiltered_cleaned_split.json --local_dir /root/
  3. 执行压测。

    # 执行压测 input_length=4096,tp=4,output_lenght=512,concurrency=8,num_prompts=80
    python3 /root/vllm/benchmarks/benchmark_serving.py \
    --backend vllm \
    --model /models/QwQ-32B \
    --served-model-name qwq-32b \
    --trust-remote-code \
    --dataset-name random \
    --dataset-path /root/ShareGPT_V3_unfiltered_cleaned_split.json \
    --random-input-len 4096 \
    --random-output-len 512 \
    --random-range-ratio 1 \
    --num-prompts 80 \
    --max-concurrency 8 \
    --host qwq-32b-v1 \
    --port 8000 \
    --endpoint /v1/completions \
    --save-result \
    2>&1 | tee benchmark_serving.txt

    预期输出:

    Starting initial single prompt test run...
    Initial test run completed. Starting main benchmark run...
    Traffic request rate: inf
    Burstiness factor: 1.0 (Poisson process)
    Maximum request concurrency: 8
    100%|██████████| 80/80 [07:44<00:00,  5.81s/it]
    ============ Serving Benchmark Result ============
    Successful requests:                     80        
    Benchmark duration (s):                  464.74    
    Total input tokens:                      327680    
    Total generated tokens:                  39554     
    Request throughput (req/s):              0.17      
    Output token throughput (tok/s):         85.11     
    Total Token throughput (tok/s):          790.18    
    ---------------Time to First Token----------------
    Mean TTFT (ms):                          10315.97  
    Median TTFT (ms):                        12470.54  
    P99 TTFT (ms):                           17580.34  
    -----Time per Output Token (excl. 1st token)------
    Mean TPOT (ms):                          71.03     
    Median TPOT (ms):                        66.24     
    P99 TPOT (ms):                           95.95     
    ---------------Inter-token Latency----------------
    Mean ITL (ms):                           71.02     
    Median ITL (ms):                         58.12     
    P99 ITL (ms):                            60.26     
    ==================================================
    

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

如果不再需要使用本文档中部署的模型推理服务,请及时清理环境。

  1. 清理模型推理工作负载和服务。

    kubectl delete deployment qwq-32b
    kubectl delete service qwq-32b-v1
    kubectl delete deployment openwebui
    kubectl delete service openwebui
    kubectl delete deployment vllm-benchmark
  2. 清理PVPVC。

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

    预期输出:

    persistentvolumeclaim "llm-model" deleted
    persistentvolume "llm-model" deleted

相关文档

  • 本页导读 (0)
  • 背景介绍
  • QwQ-32B模型
  • vLLM
  • 前提条件
  • GPU实例规格和成本预估
  • 操作步骤
  • 步骤一:准备QwQ-32B模型数据
  • 步骤二:部署模型
  • 步骤三:部署OpenWebUI
  • 步骤四:验证推理服务
  • (可选)步骤五:压测推理服务
  • (可选)步骤六:清理环境
  • 相关文档