searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

DeepSeek-R1 671B vLLM多机分布式部署推理服务

2025-07-03 09:49:50
1
0

本文演示如何使用云容器引擎控制台,使用vLLM提交部署DeepSeek-R1 并提供UI交互界面。

背景

本文使用4台机器,每台机器8张L40S(48G显存),共32x48GB GPUs

vLLM 是用于运行大语言模型(LLM)推理和服务的工具,针对推理做了很多优化,提高了模型的运行效率和性能,使得在资源有限的情况下也能高效运行大语言模型,提供了兼容 OpenAI 的 API,支持多机多卡分布式部署。

Open WebUI是一个专为本地大语言模型(LLMs)设计的Web界面,它支持多种大语言模型运行工具,例如Ollama、vLLM等。

准备工作

  • 已开通包含GPU/NPU节点的Kubernetes集群。

  • 已安装智算套件。

添加GPU节点(若集群已有GPU资源,请忽略)

  • 点击云容器引擎控制台左侧【节点】->【节点池】,点击【创建节点池】

在规格中可选择【x86计算】或【弹性裸金属服务器】中的【GPU计算加速型】或【GPU型】,节点池创建成功后,进入节点池列表,扩容节点至期望的节点数量。

网络准备

由于需要联网拉取容器镜像和获取模型文件,故需要集群所在节点能够访问外网,具体配置可参考VPC虚拟私有网络的“管理SNAT规则“

存储准备

由于模型文件通常较大,建议将模型文件提保存在共享存储中,供集群中的节点mount使用,本文以使用ZOS为例演示

首先需要创建能够访问ZOS的凭证,具体可参考“使用ZOS动态存储卷”

kubectl create secret generic oss-secret-test --from-literal=AK='<ZOS accesskey>' --from-literal=SK='<ZOS secreykey>'

接下来创建用于保存模型文件的StrongClass和PVC

通过kube APIServer

创建StorageClass,其中需要在参数中指定

allowVolumeExpansion: true
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: models-vllm
parameters:
  azpolicy: single-az
  csi.storage.k8s.io/node-publish-secret-name: oss-secret-test
  csi.storage.k8s.io/node-publish-secret-namespace: default
  type: STANDARD
provisioner: zos.csi.cstor.com
reclaimPolicy: Delete
volumeBindingMode: Immediate

创建PVC,关联StorageClass,其中访问模式修改成多机读写ReadWriteMany,storage根据模型大小适当修改

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: models-vllm
spec:
  accessModes:
  - ReadWriteMany
  resources:
    requests:
      storage: 1500Gi
  storageClassName: models-vllm

获取模型

本文通过使用git lfs拉取魔乐社区模型(同hugging face),使用vllm运行

启动Job用于拉取模型文件,并保存在ZOS

在控制台中启动如下任务,注意选择期望的命名空间

注意:修改对应的镜像仓库前缀为对应资源池,可在容器镜像控制台查看,如杭州7,则修改{image_repo}为registry-vpc-crs-hangzhou7.cnsp-internal.ctyun.cn   

apiVersion: batch/v1
kind: Job
metadata:
  name: download-model
  labels:
    app: download-model
spec:
  template:
    metadata:
      name: download-model
      labels:
        app: download-model
    spec:
      containers:
      - name: download
        image: {image_repo}/icce/git:2.48.1
        command:
        - bash
        - -c
        - |
         cd /data; git clone ${模型仓库}
        volumeMounts:
        - name: data
          mountPath: /data
      volumes:
      - name: data
        persistentVolumeClaim:
          claimName: models-vllm
      restartPolicy: OnFailure

等待任务执行完毕(可通过日志查看文件是否成功)

任务执行完毕后,模型文件就保存在ZOS的PV中的,我们会在后面的流程中使用到

运行模型服务

通过vllm运行分布式任务,以1master,3worker为例,每个Pod有8张卡

通过Kube APIServer提交以下yaml文件

注意:修改对应的镜像仓库前缀为对应资源池,可在容器镜像控制台查看,如杭州7,则修改{image_repo}为registry-vpc-crs-hangzhou7.cnsp-internal.ctyun.cn   

apiVersion: apps/v1
kind: Deployment
metadata:
  name: vllm-master
spec:
  replicas: 1  # master只需要一个副本
  selector:
    matchLabels:
      app: vllm-master
  template:
    metadata:
      labels:
        app: vllm-master
    spec:
      containers:
      - name: vllm-master
        image: {image_repo}/icce/vllm-openai:v0.7.3
        command: ["/bin/bash", "-c", "ray start --block --head --port=6379 & vllm serve /data/DeepSeek-R1-origin  --host 0.0.0.0 --port 8000  --trust-remote-code   --enable-chunked-prefill  --tensor-parallel-size 8 --pipeline-parallel-size 4 --gpu-memory-utilization 0.90 --enforce-eager "]
        resources:
          requests:
            nvidia.com/gpu: "8"
            rdma/rdma_shared_device_a: "1"
          limits:
            nvidia.com/gpu: "8"
            rdma/rdma_shared_device_a: "1"
        env:
        - name: VLLM_HOST_IP
          valueFrom:
            fieldRef:
              fieldPath: status.podIP  # 从环境变量获取 Pod IP
        - name: NCCL_SHM_DISABLE
          value: "1"
        volumeMounts:
        - mountPath: /data
          name: vllm-models
        - name: shm
          mountPath: /dev/shm
      volumes:
      - name: vllm-models
        persistentVolumeClaim:
          claimName: models-vllm
      - name: shm
        emptyDir:
          medium: Memory
          sizeLimit: 500Gi 
---
apiVersion: v1
kind: Service
metadata:
  name: vllm-master-svc
  labels:
    app: vllm-master
spec:
  clusterIP: None  # Headless service
  selector:
    app: vllm-master

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: vllm-worker
spec:
  replicas: 3  # worker节点数量
  selector:
    matchLabels:
      app: vllm-worker
  template:
    metadata:
      labels:
        app: vllm-worker
    spec:
      containers:
      - name: vllm-worker
        image: {image_repo}/icce/vllm-openai:v0.7.3
        command: ["/bin/bash", "-c", "ray start --block --address=vllm-master-svc:6379"]
        resources:
          requests:
            nvidia.com/gpu: "8"
            rdma/rdma_shared_device_a: "1"
          limits:
            nvidia.com/gpu: "8"
            rdma/rdma_shared_device_a: "1"
        env:
        - name: VLLM_HOST_IP
          valueFrom:
            fieldRef:
              fieldPath: status.podIP  # 从环境变量获取 Pod IP
        - name: NCCL_SHM_DISABLE
          value: "1"
        volumeMounts:
        - mountPath: /data
          name: vllm-models
        - name: shm
          mountPath: /dev/shm
      volumes:
      - name: vllm-models
        persistentVolumeClaim:
          claimName: models-vllm
      - name: shm
        emptyDir:
          medium: Memory
          sizeLimit: 500Gi

其中需要注意以下几点:

  1. 指定使用之前download模型的PVC,并mount到vllm serve后参数指定的启动目录(/data)

  2. master数量只有一个,worker节点数量根据模型实际大小和GPU显存大小、数量适当调整

  3. master启动参数:确保tensor-parallel-size ×  pipeline-parallel-size =(master+worker)× 单pod GPU申请数量,通常 tensor-parallel-size 的值为单pod申请卡数  pipeline-parallel-size 为pod数量(即master+worker),其余参数若遇到错误可自行调整

部署OpenWebUI服务

首先创建用于保存OpenWebUI数据的PVC

创建OpenWebUI

注意:由于从官方拉取镜像可能存在失败的情况,可替换镜像为天翼云的容器镜像:registry-vpc-crs-hangzhou7.cnsp-internal.ctyun.cn:443/icce/open-webui:main,其中hangzhou7请根据实际使用的资源池进行替换

apiVersion: apps/v1
kind: Deployment
metadata:
  name: open-webui
spec:
  replicas: 1
  selector:
    matchLabels:
      app: open-webui
  template:
    metadata:
      labels:
        app: open-webui
    spec:
      containers:
      - name: open-webui
        image: ghcr.io/open-webui/open-webui:main
        env:
        - name: OPENAI_API_BASE_URL
         value: ${svc_address}   #前面启动的vllm master address
        - name: ENABLE_OLLAMA_API
          value: "false"

        ports:
        - containerPort: 8080
        volumeMounts:
        - name: webui-volume
          mountPath: /app/backend/data
      volumes:
      - name: webui-volume
        persistentVolumeClaim:
          claimName: webui-vllm

其中需要注意以下几点:

  1. 指定前面用于保存数据之的PVC,并mount到OpenWebUI保存数据的目录(/app/backend/data)

  2. OpenWebUI服务默认端口为8080

  3. 使用环境变量指定后端模型服务的API接口(即vllm后端服务集群内访问方式的信息)

最后,为OpenWebUI创建服务,暴露open-webui的服务

  • 创建服务:点击左侧【网络】->【服务】,选择对应命名空间,点击【创建服务】

  • 填好后点击右下角【提交】

访问服务

  • 在【网络】->【服务】中,找到上一步创建的service外网,在浏览器中访问,按照提示操作

第一次登录需要设置账户/密码

0条评论
0 / 1000
张****江
2文章数
0粉丝数
张****江
2 文章 | 0 粉丝
张****江
2文章数
0粉丝数
张****江
2 文章 | 0 粉丝
原创

DeepSeek-R1 671B vLLM多机分布式部署推理服务

2025-07-03 09:49:50
1
0

本文演示如何使用云容器引擎控制台,使用vLLM提交部署DeepSeek-R1 并提供UI交互界面。

背景

本文使用4台机器,每台机器8张L40S(48G显存),共32x48GB GPUs

vLLM 是用于运行大语言模型(LLM)推理和服务的工具,针对推理做了很多优化,提高了模型的运行效率和性能,使得在资源有限的情况下也能高效运行大语言模型,提供了兼容 OpenAI 的 API,支持多机多卡分布式部署。

Open WebUI是一个专为本地大语言模型(LLMs)设计的Web界面,它支持多种大语言模型运行工具,例如Ollama、vLLM等。

准备工作

  • 已开通包含GPU/NPU节点的Kubernetes集群。

  • 已安装智算套件。

添加GPU节点(若集群已有GPU资源,请忽略)

  • 点击云容器引擎控制台左侧【节点】->【节点池】,点击【创建节点池】

在规格中可选择【x86计算】或【弹性裸金属服务器】中的【GPU计算加速型】或【GPU型】,节点池创建成功后,进入节点池列表,扩容节点至期望的节点数量。

网络准备

由于需要联网拉取容器镜像和获取模型文件,故需要集群所在节点能够访问外网,具体配置可参考VPC虚拟私有网络的“管理SNAT规则“

存储准备

由于模型文件通常较大,建议将模型文件提保存在共享存储中,供集群中的节点mount使用,本文以使用ZOS为例演示

首先需要创建能够访问ZOS的凭证,具体可参考“使用ZOS动态存储卷”

kubectl create secret generic oss-secret-test --from-literal=AK='<ZOS accesskey>' --from-literal=SK='<ZOS secreykey>'

接下来创建用于保存模型文件的StrongClass和PVC

通过kube APIServer

创建StorageClass,其中需要在参数中指定

allowVolumeExpansion: true
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: models-vllm
parameters:
  azpolicy: single-az
  csi.storage.k8s.io/node-publish-secret-name: oss-secret-test
  csi.storage.k8s.io/node-publish-secret-namespace: default
  type: STANDARD
provisioner: zos.csi.cstor.com
reclaimPolicy: Delete
volumeBindingMode: Immediate

创建PVC,关联StorageClass,其中访问模式修改成多机读写ReadWriteMany,storage根据模型大小适当修改

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: models-vllm
spec:
  accessModes:
  - ReadWriteMany
  resources:
    requests:
      storage: 1500Gi
  storageClassName: models-vllm

获取模型

本文通过使用git lfs拉取魔乐社区模型(同hugging face),使用vllm运行

启动Job用于拉取模型文件,并保存在ZOS

在控制台中启动如下任务,注意选择期望的命名空间

注意:修改对应的镜像仓库前缀为对应资源池,可在容器镜像控制台查看,如杭州7,则修改{image_repo}为registry-vpc-crs-hangzhou7.cnsp-internal.ctyun.cn   

apiVersion: batch/v1
kind: Job
metadata:
  name: download-model
  labels:
    app: download-model
spec:
  template:
    metadata:
      name: download-model
      labels:
        app: download-model
    spec:
      containers:
      - name: download
        image: {image_repo}/icce/git:2.48.1
        command:
        - bash
        - -c
        - |
         cd /data; git clone ${模型仓库}
        volumeMounts:
        - name: data
          mountPath: /data
      volumes:
      - name: data
        persistentVolumeClaim:
          claimName: models-vllm
      restartPolicy: OnFailure

等待任务执行完毕(可通过日志查看文件是否成功)

任务执行完毕后,模型文件就保存在ZOS的PV中的,我们会在后面的流程中使用到

运行模型服务

通过vllm运行分布式任务,以1master,3worker为例,每个Pod有8张卡

通过Kube APIServer提交以下yaml文件

注意:修改对应的镜像仓库前缀为对应资源池,可在容器镜像控制台查看,如杭州7,则修改{image_repo}为registry-vpc-crs-hangzhou7.cnsp-internal.ctyun.cn   

apiVersion: apps/v1
kind: Deployment
metadata:
  name: vllm-master
spec:
  replicas: 1  # master只需要一个副本
  selector:
    matchLabels:
      app: vllm-master
  template:
    metadata:
      labels:
        app: vllm-master
    spec:
      containers:
      - name: vllm-master
        image: {image_repo}/icce/vllm-openai:v0.7.3
        command: ["/bin/bash", "-c", "ray start --block --head --port=6379 & vllm serve /data/DeepSeek-R1-origin  --host 0.0.0.0 --port 8000  --trust-remote-code   --enable-chunked-prefill  --tensor-parallel-size 8 --pipeline-parallel-size 4 --gpu-memory-utilization 0.90 --enforce-eager "]
        resources:
          requests:
            nvidia.com/gpu: "8"
            rdma/rdma_shared_device_a: "1"
          limits:
            nvidia.com/gpu: "8"
            rdma/rdma_shared_device_a: "1"
        env:
        - name: VLLM_HOST_IP
          valueFrom:
            fieldRef:
              fieldPath: status.podIP  # 从环境变量获取 Pod IP
        - name: NCCL_SHM_DISABLE
          value: "1"
        volumeMounts:
        - mountPath: /data
          name: vllm-models
        - name: shm
          mountPath: /dev/shm
      volumes:
      - name: vllm-models
        persistentVolumeClaim:
          claimName: models-vllm
      - name: shm
        emptyDir:
          medium: Memory
          sizeLimit: 500Gi 
---
apiVersion: v1
kind: Service
metadata:
  name: vllm-master-svc
  labels:
    app: vllm-master
spec:
  clusterIP: None  # Headless service
  selector:
    app: vllm-master

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: vllm-worker
spec:
  replicas: 3  # worker节点数量
  selector:
    matchLabels:
      app: vllm-worker
  template:
    metadata:
      labels:
        app: vllm-worker
    spec:
      containers:
      - name: vllm-worker
        image: {image_repo}/icce/vllm-openai:v0.7.3
        command: ["/bin/bash", "-c", "ray start --block --address=vllm-master-svc:6379"]
        resources:
          requests:
            nvidia.com/gpu: "8"
            rdma/rdma_shared_device_a: "1"
          limits:
            nvidia.com/gpu: "8"
            rdma/rdma_shared_device_a: "1"
        env:
        - name: VLLM_HOST_IP
          valueFrom:
            fieldRef:
              fieldPath: status.podIP  # 从环境变量获取 Pod IP
        - name: NCCL_SHM_DISABLE
          value: "1"
        volumeMounts:
        - mountPath: /data
          name: vllm-models
        - name: shm
          mountPath: /dev/shm
      volumes:
      - name: vllm-models
        persistentVolumeClaim:
          claimName: models-vllm
      - name: shm
        emptyDir:
          medium: Memory
          sizeLimit: 500Gi

其中需要注意以下几点:

  1. 指定使用之前download模型的PVC,并mount到vllm serve后参数指定的启动目录(/data)

  2. master数量只有一个,worker节点数量根据模型实际大小和GPU显存大小、数量适当调整

  3. master启动参数:确保tensor-parallel-size ×  pipeline-parallel-size =(master+worker)× 单pod GPU申请数量,通常 tensor-parallel-size 的值为单pod申请卡数  pipeline-parallel-size 为pod数量(即master+worker),其余参数若遇到错误可自行调整

部署OpenWebUI服务

首先创建用于保存OpenWebUI数据的PVC

创建OpenWebUI

注意:由于从官方拉取镜像可能存在失败的情况,可替换镜像为天翼云的容器镜像:registry-vpc-crs-hangzhou7.cnsp-internal.ctyun.cn:443/icce/open-webui:main,其中hangzhou7请根据实际使用的资源池进行替换

apiVersion: apps/v1
kind: Deployment
metadata:
  name: open-webui
spec:
  replicas: 1
  selector:
    matchLabels:
      app: open-webui
  template:
    metadata:
      labels:
        app: open-webui
    spec:
      containers:
      - name: open-webui
        image: ghcr.io/open-webui/open-webui:main
        env:
        - name: OPENAI_API_BASE_URL
         value: ${svc_address}   #前面启动的vllm master address
        - name: ENABLE_OLLAMA_API
          value: "false"

        ports:
        - containerPort: 8080
        volumeMounts:
        - name: webui-volume
          mountPath: /app/backend/data
      volumes:
      - name: webui-volume
        persistentVolumeClaim:
          claimName: webui-vllm

其中需要注意以下几点:

  1. 指定前面用于保存数据之的PVC,并mount到OpenWebUI保存数据的目录(/app/backend/data)

  2. OpenWebUI服务默认端口为8080

  3. 使用环境变量指定后端模型服务的API接口(即vllm后端服务集群内访问方式的信息)

最后,为OpenWebUI创建服务,暴露open-webui的服务

  • 创建服务:点击左侧【网络】->【服务】,选择对应命名空间,点击【创建服务】

  • 填好后点击右下角【提交】

访问服务

  • 在【网络】->【服务】中,找到上一步创建的service外网,在浏览器中访问,按照提示操作

第一次登录需要设置账户/密码

文章来自个人专栏
文章 | 订阅
0条评论
0 / 1000
请输入你的评论
0
0