前言

随着大模型在企业场景的深入应用,越来越多的团队开始考虑私有化部署方案。对于100-499人规模的企业团队,如何在保障数据安全的前提下,高效、稳定地部署AI大模型服务于代码生成和知识问答场景,是一个典型的技术挑战。

一、整体架构蓝图

我们采用“Kubernetes集群 + vLLM推理引擎 + Qwen模型 + Dify应用平台”的黄金组合

二、环境准备

2.1 硬件要求

根据团队规模(100-499人),建议配置:

模型规模

推荐GPU

数量

适用场景

Qwen2.5-14B

NVIDIA A10 (24GB)

2-4张

中等规模生产

Qwen2.5-32B

NVIDIA A100 (80GB)

2-4张

大规模生产

Qwen2.5-72B

NVIDIA A100 (80GB)

4-8张

高性能生产

重要:多GPU部署时,必须确保GPU之间通过NVLink互联,否则PCIe会成为性能瓶颈

2.2 软件环境

操作系统:Ubuntu 22.04 LTS

Kubernetes版本:1.28+

容器运行时:Containerd

NVIDIA驱动版本:525+

Helm版本:3.x

2.3 节点标签配置

#k8s加入节点请查看>k8s搭建<

为GPU节点打上标签,便于调度器识别:
# 查看已有节点

kubectl get nodes

# 为GPU节点打标签(以阿里云ACK为例)

kubectl label nodes \

-l aliyun.accelerator/xpu_type=nvidia \

gpu=on \

--overwrite

# 非云环境

kubectl label node <gpu-node-name> gpu=on --overwrite

# 标记GPU型号(用于精确调度)

kubectl label nodes <node-name> accelerator=a100-80g

三、GPU调度层部署

3.1 方案一:NVIDIA Device Plugin(标准GPU独占)

适用于需要独占GPU卡的生产环境:

# 添加NVIDIA Helm仓库

helm repo add nvidia https://nvidia.github.io/k8s-device-plugin

helm repo update

# 安装Device Plugin

helm install nvidia-device-plugin \

nvidia/k8s-device-plugin \

--namespace kube-system \

--set devicePlugin.enabled=true

验证安装:

kubectl get pods -n kube-system | grep nvidia-device-plugin

kubectl describe node <gpu-node> | grep nvidia.com/gpu

3.2 方案二:HAMi(GPU虚拟化/分片)

适用于需要GPU共享、提高利用率的场景,可将一张物理GPU切分为多个虚拟GPU份额:

# 添加HAMi Helm仓库

helm repo add hami https://Project-HAMi.github.io/HAMi

helm repo update hami

# 安装HAMi(需先打gpu=on标签)

helm install hami hami/hami \

--namespace kube-system \

--set device.nvidia.driver.enabled=false \

--set global.managedNodeSelectorEnable=true \

--set global.managedNodeSelector.gpu=on \

--set devicePlugin.deviceSplitCount=10

验证安装:

kubectl get pods -n kube-system -l app.kubernetes.io/instance=hami

kubectl get nodes -o custom-columns=NAME:.metadata.name,GPU:.status.allocatable.nvidia\\.com/gpu

四、模型数据准备

4.1 下载Qwen模型

以Qwen1.5-4B-Chat为例(生产环境建议使用Qwen2.5-14B/32B):

# 安装Git和Git LFS

yum install git git-lfs -y # CentOS/RHEL

# 或 apt install git git-lfs -y # Ubuntu

# 从ModelScope克隆模型(国内速度快)

GIT_LFS_SKIP_SMUDGE=1 git clone https://www.modelscope.cn/qwen/Qwen1.5-4B-Chat.git

# 进入目录,拉取大文件

cd Qwen1.5-4B-Chat

git lfs pull

4.2 上传到对象存储(推荐)

对于生产环境,建议将模型存储在OSS或NAS中,通过PV/PVC挂载:

# 安装ossutil(阿里云示例)

wget https://gosspublic.alicdn.com/ossutil/1.7.13/ossutil64

chmod +x ossutil64

./ossutil64 config

# 创建Bucket目录并上传

./ossutil64 mkdir oss://<your-bucket>/models/Qwen1.5-4B-Chat

./ossutil64 cp -r ./Qwen1.5-4B-Chat oss://<your-bucket>/models/Qwen1.5-4B-Chat

4.3 创建K8s存储资源(PV/PVC)

创建PV配置文件 pvc-oss.yaml

apiVersion: v1

kind: PersistentVolume

metadata:

name: llm-model-pv

spec:

capacity:

storage: 100Gi

accessModes:

- ReadWriteMany

persistentVolumeReclaimPolicy: Retain

csi:

driver: ossplugin.csi.alibabacloud.com

volumeHandle: llm-model-pv

volumeAttributes:

bucket: <your-bucket>

path: /models/Qwen1.5-4B-Chat

otherOpts: "-o umask=022 -o max_stat_cache_size=0 -o allow_other"

---

apiVersion: v1

kind: PersistentVolumeClaim

metadata:

name: llm-model-pvc

spec:

accessModes:

- ReadWriteMany

resources:

requests:

storage: 100Gi

volumeName: llm-model-pv

创建存储资源:

kubectl apply -f pvc-oss.yaml

kubectl get pvc | grep llm-model

五、部署vLLM推理服务

5.1 使用Arena部署(推荐)

Arena是阿里云开源的K8s AI任务管理工具,可简化推理服务部署:

安装Arena客户端

# 下载安装Arena

curl -LO https://aliacs-k8s-cn-hangzhou.oss-cn-hangzhou.aliyuncs.com/arena/arena-installer-0.9.15-linux-amd64.tar.gz

tar -xzf arena-installer-0.9.15-linux-amd64.tar.gz

cd arena-installer

./install.sh --only-binary

部署推理服务(单卡A10,生产推荐)

arena serve custom \

--name=vllm-qwen \

--version=v1 \

--gpus=1 \

--replicas=1 \

--restful-port=8000 \

--readiness-probe-action="tcpSocket" \

--readiness-probe-action-option="port: 8000" \

--readiness-probe-option="initialDelaySeconds: 60" \

--readiness-probe-option="periodSeconds: 30" \

--image=vllm/vllm-openai:v0.8.5 \

--data=llm-model-pvc:/model/Qwen1.5-4B-Chat \

"python3 -m vllm.entrypoints.openai.api_server \

--trust-remote-code \

--model /model/Qwen1.5-4B-Chat/ \

--gpu-memory-utilization 0.95 \

--max-model-len 16384"

部署推理服务(单卡T4,测试环境)

arena serve custom \

--name=vllm-qwen \

--version=v1 \

--gpus=1 \

--replicas=1 \

--restful-port=8000 \

--image=vllm/vllm-openai:v0.8.5 \

--data=llm-model-pvc:/model/Qwen1.5-4B-Chat \

"python3 -m vllm.entrypoints.openai.api_server \

--trust-remote-code \

--model /model/Qwen1.5-4B-Chat/ \

--gpu-memory-utilization 0.95 \

--max-model-len 8192 \

--dtype half"

关键参数说明

参数

说明

--gpus

每个副本使用的GPU数量

--replicas

服务副本数(生产环境建议≥2)

--max-model-len

最大Token长度,越大越消耗显存

--gpu-memory-utilization

GPU显存利用率,建议0.9-0.95

--dtype half

使用FP16精度(T4等不支持BF16的卡需要)

5.2 使用原生K8s YAML部署

若不想使用Arena,可直接使用K8s原生资源:

创建 vllm-deployment.yaml

apiVersion: apps/v1

kind: Deployment

metadata:

name: vllm-qwen

spec:

replicas: 1

strategy:

type: Recreate # 多GPU时必须用Recreate,否则滚动更新会死锁

selector:

matchLabels:

app: vllm-qwen

template:

metadata:

labels:

app: vllm-qwen

spec:

runtimeClassName: nvidia

containers:

- name: vllm

image: vllm/vllm-openai:v0.8.5

args:

- "python3 -m vllm.entrypoints.openai.api_server"

- "--model=/model/Qwen1.5-4B-Chat"

- "--trust-remote-code"

- "--gpu-memory-utilization=0.95"

- "--max-model-len=16384"

- "--tensor-parallel-size=2" # 多卡并行时启用

resources:

limits:

nvidia.com/gpu: "2" # 申请2张GPU

volumeMounts:

- name: model-storage

mountPath: /model

ports:

- containerPort: 8000

volumes:

- name: model-storage

persistentVolumeClaim:

claimName: llm-model-pvc

---

apiVersion: v1

kind: Service

metadata:

name: vllm-qwen-service

spec:

selector:

app: vllm-qwen

ports:

- port: 8000

targetPort: 8000

type: ClusterIP

部署:

kubectl apply -f vllm-deployment.yaml

kubectl get pods -l app=vllm-qwen

kubectl get svc vllm-qwen-service

5.3 多GPU张量并行配置

对于需要多卡并行的场景(如Qwen2.5-14B需要4张V100 16GB),关键配置如下:

spec:

strategy:

type: Recreate # 必须

containers:

- args:

- "--tensor-parallel-size=4" # 张量并行度等于GPU数量

resources:

limits:

nvidia.com/gpu: "4"

nodeSelector:

kubernetes.io/hostname: gpu-node-02 # 固定到有4张NVLink互联GPU的节点

为什么必须用Recreate? 滚动更新时,新Pod无法获得旧Pod占用的GPU,导致调度死锁。Recreate策略会先删除旧Pod再创建新Pod

5.4 验证服务

# 查看服务状态

arena serve get vllm-qwen

# 端口转发(仅用于测试,生产环境用Ingress)

kubectl port-forward svc/vllm-qwen-v1 8000:8000

# 发送测试请求(集群内部)

curl http://localhost:8000/v1/chat/completions \

-H "Content-Type: application/json" \

-d '{

"model": "/model/Qwen1.5-4B-Chat/",

"messages": [{"role": "user", "content": "写一个Python快速排序"}],

"max_tokens": 500,

"temperature": 0.7

}'

预期输出包含模型生成的代码,表明服务部署成功。

六、部署Dify应用平台

6.1 安装Dify

# 克隆Dify仓库

git clone https://github.com/langgenius/dify.git

cd dify/docker

# 复制环境变量

cp .env.example .env

# 启动Dify

docker compose up -d

6.2 在K8s中部署Dify(生产推荐可选)

创建 dify-deployment.yaml

apiVersion: apps/v1

kind: Deployment

metadata:

name: dify

spec:

replicas: 2

selector:

matchLabels:

app: dify

template:

metadata:

labels:

app: dify

spec:

containers:

- name: dify-api

image: langgenius/dify-api:latest

ports:

- containerPort: 5001

env:

- name: MODE

value: api

- name: SECRET_KEY

valueFrom:

secretKeyRef:

name: dify-secret

key: secret-key

# 添加其他环境变量...

---

apiVersion: v1

kind: Service

metadata:

name: dify-service

spec:

selector:

app: dify

ports:

- port: 80

targetPort: 5001

type: ClusterIP

---

apiVersion: networking.k8s.io/v1

kind: Ingress

metadata:

name: dify-ingress

spec:

rules:

- host: ai.yourcompany.com

http:

paths:

- path: /

pathType: Prefix

backend:

service:

name: dify-service

port:

number: 80

部署:

kubectl apply -f dify-deployment.yaml

kubectl get ingress

6.3 配置Dify连接vLLM

  1. 访问 http://ai.yourcompany.com 登录Dify

  2. 进入「设置」→「模型供应商」

  3. 选择「OpenAI-API-compatible」

  4. 填写配置:

  • 模型名称/model/Qwen1.5-4B-Chat/

  • API Endpoint URLhttp://vllm-qwen-service.default.svc.cluster.local:8000/v1

  • API Key:随意填写(内网无鉴权时用占位符)

七、用户访问与对外暴露

7.1 通过Ingress对外暴露

创建 vllm-ingress.yaml

apiVersion: networking.k8s.io/v1

kind: Ingress

metadata:

name: vllm-ingress

spec:

ingressClassName: nginx

rules:

- host: model-api.yourcompany.com

http:

paths:

- path: /v1

pathType: Prefix

backend:

service:

name: vllm-qwen-service

port:

number: 8000

7.2 使用LoadBalancer(云环境)

apiVersion: v1

kind: Service

metadata:

name: vllm-qwen-public

spec:

type: LoadBalancer

selector:

app: vllm-qwen

ports:

- port: 80

targetPort: 8000

八、GPU算力分配策略

8.1 三种分配模式对比(根据实际选择)

策略

实现方式

适用场景

独占

nvidia.com/gpu: 1

生产环境,性能可预测

MIG分片

HAMi / NVIDIA MIG

高端GPU(A100/H100)硬隔离

时间切片

vGPU调度器

开发测试,提高利用率

8.2 HAMi GPU分片示例

使用HAMi时,可以为Pod申请部分GPU显存和算力:

spec:

containers:

- resources:

limits:

nvidia.com/gpu: 1 # 1个虚拟GPU

nvidia.com/gpumem: 22000 # 22GB显存

nvidia.com/gpucores: 100 # 100%算力

查看GPU可分配资源:

kubectl get nodes -o custom-columns=NAME:.metadata.name,GPU:.status.allocatable.nvidia\\.com/gpu

8.3 时间切片(Time-Slicing)示例

时间切片是一种GPU共享调度策略,它允许多个Pod分时共享同一张物理GPU。与MIG的硬隔离不同,时间切片是“软隔离”,多个任务轮流使用GPU计算单元,但显存是共享的(需要注意隔离性),时间切片功能由NVIDIA GPU Operator提供,它包含了Device Plugin和配置时间切片所需的组件:

部署NVIDIA GPU Operator

# 添加NVIDIA Helm仓库

helm repo add nvidia https://nvidia.github.io/gpu-operator

helm repo update

# 安装GPU Operator(默认会启用Device Plugin)

helm install gpu-operator nvidia/gpu-operator \

--namespace gpu-operator \

--create-namespace \

--set devicePlugin.enabled=true

开启时间切片功能

时间切片通过配置nvidia.com/vgpu资源来实现。注意:需要在安装GPU Operator时进行配置,否则默认不开启

helm install gpu-operator nvidia/gpu-operator \

--namespace gpu-operator \

--create-namespace \

--set devicePlugin.enabled=true \

--set migStrategy=none \

--set devicePlugin.config.name=time-slicing-config

若已安装,通过values.yaml方式修改配置:

# values.yaml

devicePlugin:

enabled: true

config:

name: time-slicing-config

extraConfig: |

version: v1

flags:

migStrategy: none

sharing:

timeSlicing:

renameByDefault: false

resources:

- name: nvidia.com/gpu

replicas: 4 # 每张物理GPU虚拟成4份

应用配置:

helm upgrade gpu-operator nvidia/gpu-operator -f values.yaml -n gpu-operator

使用时间切片的Pod示例

开启时间切片后,多个Pod可以通过申请nvidia.com/gpu资源来共享同一张物理GPU:

apiVersion: v1

kind: Pod

metadata:

name: vllm-qwen-time-slicing

labels:

app: vllm-qwen-time-slicing

spec:

runtimeClassName: nvidia

containers:

- name: vllm

image: vllm/vllm-openai:v0.8.5

args:

- "python3 -m vllm.entrypoints.openai.api_server"

- "--model=/model/Qwen1.5-4B-Chat"

- "--trust-remote-code"

- "--gpu-memory-utilization=0.8"

- "--max-model-len=4096"

resources:

limits:

nvidia.com/gpu: 1 # 申请1个时间切片(虚拟GPU),而非独占物理卡

volumeMounts:

- name: model-storage

mountPath: /model

volumes:

- name: model-storage

persistentVolumeClaim:

claimName: llm-model-pvc

验证时间切片是否生效

# 查看节点GPU分配状态,会显示虚拟GPU数量

kubectl describe node <gpu-node> | grep nvidia.com/gpu

# 查看Pod中可见的GPU

kubectl exec -it <pod-name> -- nvidia-smi

九、验证与测试

9.1 完整测试流程

# 1. 检查服务状态

kubectl get pods -l app=vllm-qwen

kubectl logs -f <pod-name>

# 2. 内部调用测试(集群内)

kubectl run test-pod --rm -it --image=curlimages/curl -- sh

curl http://vllm-qwen-service:8000/v1/chat/completions \

-H "Content-Type: application/json" \

-d '{"model": "/model/Qwen1.5-4B-Chat/", "messages": [{"role": "user", "content": "你好"}], "max_tokens": 20}'

# 3. 外部调用测试

curl https://model-api.yourcompany.com/v1/chat/completions \

-H "Content-Type: application/json" \

-d '{"model": "/model/Qwen1.5-4B-Chat/", "messages": [{"role": "user", "content": "解释什么是RAG"}], "max_tokens": 200}'

9.2 通过Dify创建第一个应用

  1. 登录Dify,创建「空白应用」

  2. 选择「聊天助手」

  3. 在模型选择中选择已配置的vLLM-Qwen模型

  4. 添加知识库(上传企业内部文档)

  5. 发布并测试

十、常用运维命令速查

# 查看推理服务状态

arena serve get vllm-qwen

# 查看Pod日志

kubectl logs -f deployment/vllm-qwen-v1-custom-serving

# 扩容

kubectl scale deployment vllm-qwen-v1-custom-serving --replicas=3

# 查看GPU使用情况

kubectl exec -it <pod-name> -- nvidia-smi

# 删除服务

arena serve delete vllm-qwen

# 查看节点GPU资源

kubectl describe node <gpu-node> | grep -A5 "Allocated resources"

十一、常见问题排查

Q1: Pod状态为Pending

kubectl describe pod <pod-name>

常见原因:

  1. GPU资源不足:检查节点是否有可用GPU

  2. PVC未绑定:检查kubectl get pvc

  3. 节点标签不匹配:检查nodeSelector

Q2: GPU OOM(显存溢出)

调整以下参数:

  1. 降低--max-model-len

  2. 降低--gpu-memory-utilization(如0.85)

  3. 使用量化模型或--dtype half

Q3: 多GPU滚动更新死锁

确保Deployment使用strategy.type: Recreate,而非默认的RollingUpdate。

核心要点:

  1. Kubernetes作为底座:提供弹性、高可用

  2. vLLM作为推理引擎:高性能、OpenAI-API兼容

  3. Qwen作为模型基座:中文能力强、开源生态好

  4. Dify作为应用平台:低代码、快速构建业务应用

0%