使用阿里云ACS GPU算力构建QwQ-32B模型推理服务
配置 oss
- 第1步,登录阿里云OSS控制台,创建与acs同地域的存储桶(示例 华北6(乌兰察布),桶名称 ai-hzt-20250407)
模式选择: 自定义创建
Bucket 名称: ai-hzt-20250407
地域: 华北6(乌兰察布)
存储类型: 标准存储
存储冗余类型: 同城冗余存储(推荐)
阻止公共访问: 已开通
读写权限: 私有
- 第2步,调整存储桶的访问权限
#.1.权限控制 - 阻止公共访问 - 未开启
#.2.权限控制 - 读写权限 - 设置 公共读写
#.3.权限控制 - Bucket 授权策略 - Bucket 授权策略,先新增1个授权
授权资源:整个 Bucket
资源路径:ai-hzt-20250407/*
授权用户:所有账号(*)
授权操作:简单设置 \ 只读(包含ListObject操作)
#.4.权限控制 - Bucket 授权策略 - Bucket 授权策略,再新增1个授权
授权资源:整个 Bucket
资源路径:ai-hzt-20250407/*
授权用户:所有账号(*)
授权操作:简单设置 \ 读/写
- 第3步,配置 ossutil 以便操作 oss(注意:将 123456 替换为真实的ak/sk)
#.安装 ossutil
curl -L http://iso.sqlfans.cn/cloud/aliyun/oss/ossutil.v1.7.19 -o /usr/bin/ossutil
chmod +x /usr/bin/ossutil
ossutil --version
#.配置 ossutil
touch ~/.ossutilconfig
echo [Credentials] > ~/.ossutilconfig
echo language=CH >> ~/.ossutilconfig
echo accessKeyID=123456 >> ~/.ossutilconfig
echo accessKeySecret=123456 >> ~/.ossutilconfig
echo endpoint=oss-cn-wulanchabu.aliyuncs.com >> ~/.ossutilconfig
cat ~/.ossutilconfig
#.验证一下
ossutil ls oss://ai-hzt-20250407
- 第4步,下载 QwQ-32B 模型(约 64.66 GB)及 压测数据(约 641.68 MB),并上传到指定oss目录,示例目录 QwQ-32B 及 ShareGPT_V3_unfiltered_cleaned_split
注:提交工单可以快速将 QwQ-32B及压测数据复制到指定的 Bucket,可省去此步
#.安装 git-lfs 插件
apt install -y git-lfs
#.从 modelscope 下载模型
cd /data/
git lfs install
GIT_LFS_SKIP_SMUDGE=1 git clone https://www.modelscope.cn/Qwen/QwQ-32B.git
cd QwQ-32B
git lfs pull
#.将模型上传至oss目录(ossutil cp支持断点续传)
cd /data/
ossutil mkdir oss://ai-hzt-20250407/QwQ-32B
ossutil cp -r ./QwQ-32B oss://ai-hzt-20250407/QwQ-32B
#.利用 modelscope 下载压测数据
# rm -f /usr/lib/python3.12/EXTERNALLY-MANAGED
pip3 install modelscope
modelscope download --dataset gliang1001/ShareGPT_V3_unfiltered_cleaned_split ShareGPT_V3_unfiltered_cleaned_split.json --local_dir /data/
#.将压测数据上传至oss目录(ossutil cp支持断点续传)
cd /data/
ossutil mkdir oss://ai-hzt-20250407/ShareGPT_V3_unfiltered_cleaned_split
ossutil cp -r ./ShareGPT_V3_unfiltered_cleaned_split.json oss://ai-hzt-20250407/ShareGPT_V3_unfiltered_cleaned_split/
部署 acs
- 第1步,登录阿里云ACS控制台,创建容器集群(根据GPU型号选择地域和可用区,示例 华北6(乌兰察布))
注:需要开通 Prometheus 监控功能,否则创建之前的检查操作就会失败。创建过程耗时 4 分钟
#.集群配置
集群名称: hzt-qwq32b-2025
地域: 华北6(乌兰察布)
Kubernetes 版本: 1.31.1-aliyun.1(建议最新版)
维护窗口: 周三 00:00,时长 3小时
#.网络配置
选择专有网络: 自动创建
配置SNAT: 为专有网络配置SNAT(是否勾选取决于可用区,比如可用区D则不支持)
可用区: 可用区C(根据 GPU型 / PPU810E 匹配)
安全组: 自动创建企业级安全组(自动创建的企业级安全组将默认允许 VPC 内全部网段互通)
API server 访问配置: 使用 EIP 暴露 API server(建议开启)
Service CIDR: 10.0.0.0/16
#.组件配置
服务发现: CoreDNS
Ingress: 不安装
日志服务: 使用日志服务(此次仅测试,建议不开启)
- 第2步,在目标集群详情页,依次选择 配置管理 - 保密字典 - 使用YAML创建资源(示例 acs-image-secret),然后将模板内容替换为如下内容
apiVersion: v1
kind: Secret
metadata:
name: acs-image-secret # 可自定义名称
namespace: default # 根据集群中实际的 namespace 名称修改
type: kubernetes.io/dockerconfigjson
data:
.dockerconfigjson: ewoJImF1dGhzIjogewoJCSJlZ3NsaW5nanVuLXJlZ2lzdHJ5LmNuLXd1bGFuY2hhYnUuY3IuYWxpeXVuY3MuY29tIjogewoJCQkiYXV0aCI6ICJiVzk1WVc5QU1Ua3dNekF4TlRBM05USXlPVEl3T1RwRGJuQkZVakEyTWxGdklRPT0iCgkJfQoJfQp9Cg==
- 第3步,在目标集群详情页,依次选择 配置管理 - 保密字典 - 创建(示例 llm-test)(注意:将 123456 替换为真实的ak/sk)
名称: llm-test
类型: Opaque,勾选 对数据值进行 base64 编码
名称 值
akId 123456
akSecret 123456
- 第4步,在目标集群详情页,依次选择 配置管理 - 配置项,确认已存在 kube-root-ca.crt 这个配置项
- 第5步,在目标集群详情页,依次选择 存储 - 存储卷 - 创建,为目标集群配置名为 oss-pv 的存储卷(注意:存储桶 ai-hzt-20250407、将 123456 替换为真实的ak/sk)
存储卷类型: OSS
名称: oss-pv
总量: 150 Gi(OSS静态卷总量仅起声明效果,实际容量不受限制,使用量以OSS控制台为准)
访问模式: ReadWriteMany
访问证书: 新建保密字典
命名空间:default 名称:llm-test
AccessKey ID:123456 AccessKey Secret:123456
可选参数: 不用填写
Bucket ID: 选择Bucket ai-hzt-20250407
OSS Path: 不用填写,默认为/
访问域名: 私网域名
- 第6步,在目标集群详情页,依次选择 存储 - 存储声明 - 创建,为目标集群配置名为 oss-pvc 的存储声明(注意:存储卷 oss-pv)
存储声明类型: OSS
名称: oss-pvc
分配模式: 已有存储卷
已有存储卷: 选择已有存储卷 oss-pv
总量: 150 Gi
- 第7步,在目标集群详情页,依次选择 工作负载 - 无状态 - 使用YAML创建资源,然后将模板内容替换为如下内容,为目标集群配置名为 llm-test 的Deployment(注意:存储声明 oss-pvc、挂载点 /mnt/QWQ-32B)
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: llm-test
name: llm-test
namespace: default
spec:
progressDeadlineSeconds: 6000
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
app: llm-test
template:
metadata:
labels:
alibabacloud.com/compute-class: gpu
alibabacloud.com/gpu-model-series: PPU810E
alibabacloud.com/compute-qos: default
app: llm-test
spec:
imagePullSecrets:
- name: acs-image-secret
containers:
- name: llm-test
image: egslingjun-registry.cn-wulanchabu.cr.aliyuncs.com/egslingjun/inference-xpu-pytorch:preview-25.02-v1.4.2preview-vllm0.6.6.post1-torch2.5.1-cuda12.3-20250207
imagePullPolicy: IfNotPresent
command:
- sh
- -c
- python3 -m vllm.entrypoints.openai.api_server --model /mnt/QWQ-32B/ -tp 2 --gpu-memory-utilization 0.98 --max-model-len 1000 --trust-remote-code
resources:
limits:
cpu: 16
memory: 80G
alibabacloud.com/ppu: 2
ephemeral-storage: 200G
requests:
cpu: 16
memory: 80G
alibabacloud.com/ppu: 2
ephemeral-storage: 200G
volumeMounts:
- mountPath: /mnt
name: data
- mountPath: /dev/shm
name: cache-volume
- mountPath: /ppu-data
name: ephemeral
volumes:
- name: data
persistentVolumeClaim:
claimName: oss-pvc
- name: cache-volume
emptyDir:
medium: Memory
sizeLimit: 500G
- name: ephemeral
emptyDir:
sizeLimit: 200G
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
terminationGracePeriodSeconds: 30
---
apiVersion: v1
kind: Service
metadata:
annotations:
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-address-type: "internet"
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-ip-version: "ipv4"
labels:
app: llm-test
name: svc-llm
namespace: default
spec:
type: LoadBalancer
externalTrafficPolicy: Local
ports:
- name: http
port: 80
targetPort: 8000
protocol: TCP
selector:
app: llm-test
- 第8步,在目标集群详情页,依次选择 工作负载 - 无状态 - 选择 llm-test - 容器组 - 终端,选择 llm-test,进入容器终端页面
- 第9步,在容器终端页面,通过 curl 发起问答测试
curl http://127.0.0.1:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "/mnt/QWQ-32B/",
"messages": [
{
"role": "user",
"content": "给闺女写一份来自未来2035的信,同时告诉她要好好学习科技,做科技的主人,推动科技,经济发展;她现在是3年级"
}
],
"max_tokens": 900,
"temperature": 0.7,
"top_p": 0.9,
"seed": 10
}'
- 第10步,在容器终端页面,拷贝oss挂载点中的压测文件到指定目录,执行一次推理服务压测
#.拷贝压测文件
cd /opt/vllm/benchmarks
cp -r /mnt/ShareGPT_V3_unfiltered_cleaned_split/ .
#.执行压测(参数 --num-prompts 200 每秒请求200次)
python3 benchmark_serving.py --backend vllm --model /mnt/QWQ-32B/ --dataset-name sharegpt \
--dataset-path ShareGPT_V3_unfiltered_cleaned_split/ShareGPT_V3_unfiltered_cleaned_split.json \
--request-rate 1 --num-prompts 200 --port 8000
附录
遇到的问题
- 问题1:执行
pip3 install modelscope报错 error: externally-managed-environment - 解决1:删除 EXTERNALLY-MANAGED 后重试即可
rm -f /usr/lib/python3.12/EXTERNALLY-MANAGED
配置 kubectl
- 登录阿里云ACS控制台,在目标集群的详情页,选择 集群信息,复制连接信息中的凭证,粘贴到
~/.kube/config,使用kubectl连接Kubernetes集群
#.安装 kubectl
curl -L http://iso.sqlfans.cn/k8s/kubectl.v1.32.3 -o /usr/bin/kubectl
chmod +x /usr/bin/kubectl
kubectl version
#.配置 kubectl,将123456替换为acs控制台复制的凭证
mkdir ~/.kube
touch ~/.kube/config
cert=123456
echo ${cert} > ~/.kube/config
#.验证一下
kubectl get nodes
kubectl get namespace
- 附:以下是部署 open-webui 服务,由于未开通公网,无法直接访问,所以没有用到
#.创建Open WebUI应用及服务
curl -L http://iso.sqlfans.cn/cloud/aliyun/acs/acs-create-open-webui.yaml -o /opt/openwebui.yaml
kubectl apply -f /opt/openwebui.yaml
#.使用kubectl port-forward在推理服务与本地环境间建立端口转发
kubectl port-forward svc/openwebui 8080:8080
#.清理open-webui
kubectl delete deployment openwebui
kubectl delete service openwebui
如何彻底清理
- 如果不再需要使用本文档中部署的模型推理服务,可参考如下清理环境:
#.清理模型推理工作负载和服务
kubectl delete deployment llm-test
kubectl delete service svc-llm
#.清理pv和pvc
kubectl delete pvc oss-pvc
kubectl delete pv oss-pv