【阅读原文】戳:使用容器服务ACK快速部署QwQ-32B模型并实现推理智能路由
背景介绍
1. QwQ-32B模型
阿里云最新发布的QwQ-32B模型,通过强化学习大幅度提升了模型推理能力。QwQ-32B模型拥有320亿参数,其性能可以与DeepSeek-R1 671B媲美。模型数学代码等核心指标(AIME 24/25、livecodebench)以及部分通用指标(IFEval、LiveBench等)达到DeepSeek-R1满血版水平,各指标均显著超过同样基于Qwen2.5-32B的DeepSeek-R1-Distill-Qwen-32B。更多模型信息请参考QwQ-32B[1]。
2. vLLM
vLLM[2]是一个高效易用的大语言模型推理服务框架,vLLM支持包括通义千问在内的多种常见大语言模型。vLLM通过PagedAttention优化、动态批量推理(continuous batching)、模型量化等优化技术,可以取得较好的大语言模型推理效率。更多关于vLLM框架的信息,请参考vLLM Github代码库[3]。
前提条件
• 已创建包含GPU的Kubernetes集群。具体操作,请参见创建包含GPU的Kubernetes集群[4]。
至少有一个ecs.gn7i-c32g1.32xlarge(4xA10)GPU节点
部署推理服务
步骤一:准备模型数据
1. 下载模型。
GIT_LFS_SKIP_SMUDGE=1 git clone https://www.modelscope.cn/Qwen/QwQ-32B.git cd QwQ-32B git lfs pull
2. 将下载的模型文件上传至OSS。
ossutil mkdir oss://<Your-Bucket-Name>/QwQ-32B ossutil cp -r ./QwQ-32B oss://<Your-Bucket-Name>/QwQ-32B
3. 为目标集群配置存储卷PV和存储声明PVC。具体操作,请参见使用OSS静态存储卷[5]。
以下为示例PV的配置信息:
配置项 | 说明 |
存储卷类型 | OSS |
名称 | llm-model |
访问证书 | 配置用于访问OSS的AccessKey ID和AccessKey Secret。 |
Bucket ID | 选择已创建的OSS Bucket。 |
OSS Path | 选择模型所在的路径,如/models/Qwen1.5-4B-Chat。 |
以下为示例PVC的配置信息:
配置项 | 说明 |
存储声明类型 | OSS |
名称 | llm-model |
分配模式 | 选择已有存储卷。 |
已有存储卷 | 单击选择已有存储卷链接,选择已创建的存储卷PV。 |
步骤二:部署推理服务
1. 执行以下命令,基于vLLM模型推理框架部署QwQ-32B模型的推理服务。
kubectl apply -f- <<EOF apiVersion: apps/v1 kind: Deployment metadata: labels: app: qwq-32b name: qwq-32b namespace: default spec: replicas: 5 # 根据GPU节点数量进行调整 selector: matchLabels: app: qwq-32b template: metadata: labels: app: qwq-32b annotations: prometheus.io/path: /metrics prometheus.io/port: "8000" prometheus.io/scrape: "true" 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 --tensor-parallel=4 --max-model-len 8192 --gpu-memory-utilization 0.95 --enforce-eager image: registry-cn-hangzhou.ack.aliyuncs.com/dev/vllm:v0.7.2 name: vllm ports: - containerPort: 8000 readinessProbe: tcpSocket: port: 8000 initialDelaySeconds: 30 periodSeconds: 30 resources: limits: nvidia.com/gpu: "4" 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 spec: type: ClusterIP ports: - port: 8080 protocol: TCP targetPort: 8080 selector: app: openwebui EOF
步骤四:验证推理服务
1. 执行以下命令,在推理服务与本地环境之间建立端口转发。
请注意kubectl port-forward建立的端口转发不具备生产级别的可靠性、安全性和扩展性,因此仅适用于开发和调试目的,不适合在生产环境使用。更多关于Kubernetes集群内生产可用的网络方案的信息,请参见Ingress概述[6]。
kubectl port-forward svc/openwebui 8080:8080
2. 访问http://localhost:8080,登陆OpenWebUI页面。
第一次登录需要配置管理员账号和密码。输入提示词"0.11和0.9谁大?",预期输出如下图所示。
[可选]步骤五:压测推理服务
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. 下载压测数据集。
# 执行以下命令进入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 [06:27<00:00, 4.84s/it] ============ Serving Benchmark Result ============ Successful requests: 80 Benchmark duration (s): 387.00 Total input tokens: 327680 Total generated tokens: 39432 Request throughput (req/s): 0.21 Output token throughput (tok/s): 101.89 Total Token throughput (tok/s): 948.60 ---------------Time to First Token---------------- Mean TTFT (ms): 4995.48 Median TTFT (ms): 4015.59 P99 TTFT (ms): 12712.06 -----Time per Output Token (excl. 1st token)------ Mean TPOT (ms): 66.59 Median TPOT (ms): 67.21 P99 TPOT (ms): 81.33 ---------------Inter-token Latency---------------- Mean ITL (ms): 66.59 Median ITL (ms): 51.26 P99 ITL (ms): 52.61 ==================================================
智能路由:ACK Gateway with AI Extension
ACK Gateway with AI Extension组件是基于Kubernetes社区 Gateway API及其Inference Extension规范实现的增强型组件,支持生产级的四层/七层路由服务,并提供面向AI大语言模型(LLM)推理场景的智能负载均衡能力。
步骤一:为LLM推理应用配置智能路由
开启ACK Gateway with AI Extension组件,可以使用Gateway API为推理服务提供生产可用的流量入口,同时基于ACK Gateway的推理扩展提升对后端推理服务的负载均衡能力。
1. 在ACK集群的组件管理中开启ACK Gateway with AI Extension组件。具体请参考管理ACK托管集群的相关组件[7]。开启时打开“启用Gateway API推理扩展”选项。
2. 部署网关实例
使用kubectl连接到ACK集群,并使用以下指令来创建一个具有8080和8081端口的网关。其中8080端口将部署一个标准的HTTP路由、路由到后端推理服务,而8081端口则将基于推理服务扩展向后端推理服务进行路由。
kubectl apply -f- <<EOF apiVersion: gateway.networking.k8s.io/v1 kind: GatewayClass metadata: name: inference-gateway spec: controllerName: gateway.envoyproxy.io/gatewayclass-controller --- apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: inference-gateway spec: gatewayClassName: inference-gateway listeners: - name: http protocol: HTTP port: 8080 - name: llm-gw protocol: HTTP port: 8081 --- apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: backend spec: parentRefs: - name: inference-gateway sectionName: http rules: - backendRefs: - group: "" kind: Service name: vllm-llama2-7b-pool port: 8000 matches: - path: type: PathPrefix value: / timeouts: request: "24h" backendRequest: "24h" EOF
3. 在网关8081端口上启用推理扩展
使用以下指令创建InferencePool资源和InferenceModel资源,在推理扩展提供的CRD中:InferencePool资源通过标签选择器声明一组在集群中运行的LLM推理服务工作负载,而InferenceModel指定了InferencePool中具体模型的流量分发策略。
kubectl apply -f- <<EOF apiVersion: inference.networking.x-k8s.io/v1alpha1 kind: InferencePool metadata: annotations: inference.networking.x-k8s.io/attach-to: | name: inference-gateway port: 8081 name: vllm-llama2-7b-pool spec: targetPortNumber: 8000 selector: app: vllm-llama2-7b-pool extensionRef: name: inference-gateway-ext-proc --- apiVersion: inference.networking.x-k8s.io/v1alpha1 kind: InferenceModel metadata: name: inferencemodel-sample spec: modelName: /model/llama2 criticality: Critical poolRef: group: inference.networking.x-k8s.io kind: InferencePool name: vllm-llama2-7b-pool targetModels: - name: /model/llama2 weight: 100 EOF
4. 执行以下命令,验证ACK Gateway的推理服务路由已经生效。
GATEWAY_IP=$(kubectl get gateway/inference-gateway -o jsonpath='{.status.addresses[0].value}') curl -X POST ${GATEWAY_IP}/v1/chat/completions -H 'Content-Type: application/json' -d '{ "model": "qwq-32b", "max_completion_tokens": 8000, "temperature": 0, "messages": [ { "role": "user", "content": "你是谁?" } ] }' -v
此时,已经可以通过ACK Gateway的IP地址对推理服务进行访问。
步骤二:观测推理服务性能和负载均衡效果
1. 通过Prometheus实例默认的服务发现机制采集推理服务相关指标。具体操作,请参见默认服务发现[8] 。
在基于vLLM的推理服务提供的监控指标中,可以通过以下重点指标来直观了解推理服务工作负载的内部状态以及性能表现。
指标名称 | 说明 |
vllm:gpu_cache_usage_perc | vllm的GPU缓存使用百分比。vLLM启动时,会尽可能多地预先占有一块GPU显存,用于进行KV缓存。对于vLLM服务器,缓存利用率越低,代表GPU还有充足的空间将资源分配给新来的请求。 |
vllm:request_queue_time_seconds_sum | 请求在等待状态排队花费的时间。LLM推理请求在到达vLLM服务器后、可能不会被立刻处理,而是需要等待被vLLM调度器调度运行预填充和解码。 |
vllm:num_requests_running vllm:num_requests_waiting vllm:num_requests_swapped |
正在运行推理、正在等待和被交换到内存的请求数量。可以用来评估vLLM服务当前的请求压力。 |
vllm:avg_generation_throughput_toks_per_s vllm:avg_prompt_throughput_toks_per_s |
每秒被预填充阶段消耗的token以及解码阶段生成的token数量。 |
vllm:time_to_first_token_seconds_bucket | 从请求发送到推理服务,到响应第一个token为止的时延水平。该指标通常代表了客户端在输出请求内容后得到首个响应所需的时间、是影响LLM用户体验的重要指标。 |
2. 通过Grafana大盘来观测基于vLLM部署的LLM推理服务:将vllm的Grafana JSON model导入到Grafana,创建LLM推理服务的可观测大盘。导入的JSON model请参见vllm官方网站[9]。具体导入操作,请参见如何导出和导入Grafana仪表盘[10]。
3. 通过可观测信息对比普通网关和应用推理扩展的网关的负载均衡性能:参考步骤五,使用以下指令分别向网关的8080端口(采用网关默认服务路由)和8081端口(采用推理扩展的服务路由)发起两次压测。
• 网关默认服务路由
压测命令:
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-prefix-len 1000 \ --random-input-len 4000 \ --random-output-len 3000 \ --random-range-ratio 0.2 \ --num-prompts 3000 \ --max-concurrency 60 \ --host 172.16.12.92 \ # ACK Gateway 网关内网ip --port 8080 \ # 请求8080端口,网关通过默认方式对推理服务进行路由 --endpoint /v1/completions \ --save-result \ 2>&1 | tee benchmark_serving.txt
压测结果:
============ Serving Benchmark Result ============ Successful requests: 2990 Benchmark duration (s): 5822.60 Total input tokens: 10071917 Total generated tokens: 5334789 Request throughput (req/s): 0.51 Output token throughput (tok/s): 916.22 Total Token throughput (tok/s): 2646.02 ---------------Time to First Token---------------- Mean TTFT (ms): 2456.44 Median TTFT (ms): 1366.07 P99 TTFT (ms): 23509.43 -----Time per Output Token (excl. 1st token)------ Mean TPOT (ms): 63.50 Median TPOT (ms): 63.33 P99 TPOT (ms): 75.22 ---------------Inter-token Latency---------------- Mean ITL (ms): 63.47 Median ITL (ms): 55.49 P99 ITL (ms): 59.16 ==================================================
• 推理扩展的服务路由
压测命令:
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-prefix-len 1000 \ --random-input-len 4000 \ --random-output-len 3000 \ --random-range-ratio 0.2 \ --num-prompts 3000 \ --max-concurrency 60 \ --host 172.16.12.92 \ --port 8081 \ # 请求8081端口,网关基于推理扩展对推理服务进行路由 --endpoint /v1/completions \ --save-result \ 2>&1 | tee benchmark_serving_ext.txt
压测结果:
============ Serving Benchmark Result ============ Successful requests: 2990 Benchmark duration (s): 5755.77 Total input tokens: 10071917 Total generated tokens: 5332890 Request throughput (req/s): 0.52 Output token throughput (tok/s): 926.53 Total Token throughput (tok/s): 2676.41 ---------------Time to First Token---------------- Mean TTFT (ms): 1796.93 Median TTFT (ms): 1470.97 P99 TTFT (ms): 8857.07 -----Time per Output Token (excl. 1st token)------ Mean TPOT (ms): 63.10 Median TPOT (ms): 63.03 P99 TPOT (ms): 70.68 ---------------Inter-token Latency---------------- Mean ITL (ms): 63.06 Median ITL (ms): 55.37 P99 ITL (ms): 59.17 ==================================================
在Grafana大盘上,可以观察到对应两次压测的时间段内推理服务的性能指标。
通过压测数据和大盘可以直观地发现基于ACK Gateway的推理扩展对推理服务进行路由和负载均衡时,QwQ-32B推理服务拥有更好的延迟、吞吐量和缓存利用率表现,生产性能更佳。其中请求和token吞吐略有提升,平均TTFT缩短26.8%,P99 TTFT降低62.32%,KV Cache利用率在不同工作负载之间更加均匀。
总结
本文演示了如何在阿里云容器服务ACK中快速部署QwQ-32B模型,并结合OpenWebUI搭建专属企业助手。QwQ-32B模型性能与DeepSeek-R1 671B相当,部署所需资源大大降低,部署bf16精度的模型仅需64GB显存,最低4xA10机器即可满足需求。压测结果表明,在4xA10机器上部署QwQ-32B模型,在8并发时TTFT为4.9s, Output token throughput 为101.89 tok/s。
由于LLM推理流量和工作负载的特殊性,传统的路由调度算法不适用于LLM推理场景,因此阿里云容器服务团队自研了ACK Gateway with AI Extension网关。与Least Request调度策略相比,平均TTFT缩短26.8%,P99 TTFT降低62.32%,KV Cache利用率在不同工作负载之间更加均匀。
注:测试结果与多种因素有关,上述结果仅供参考。
相关链接:
[1] QwQ-32B
https://modelscope.cn/models/Qwen/QwQ-32B
[2] vLLM
https://github.com/vllm-project/vllm
[3] vLLM Github代码库
https://github.com/vllm-project/vllm
[4] 创建包含GPU的Kubernetes集群
[5] 使用OSS静态存储卷
[6] Ingress概述
https://help.aliyun.com/zh/ack/ack-managed-and-ack-dedicated/user-guide/ingress-management-2/
[7] 管理ACK托管集群的相关组件
[8] 默认服务发现
https://help.aliyun.com/zh/arms/prometheus-monitoring/default-pod-service-discovery
[9] vllm官方网站
https://docs.vllm.ai/en/latest/getting_started/examples/prometheus_grafana.html
[10] 如何导出和导入Grafana仪表盘
https://help.aliyun.com/zh/grafana/support/how-to-export-and-import-the-grafana-dashboard
我们是阿里巴巴云计算和大数据技术幕后的核心技术输出者。
获取关于我们的更多信息~