跳到内容

Kthena

Kthena 是一个原生于 Kubernetes 的 LLM 推理平台,它改变了组织在生产环境中部署和管理大型语言模型的方式。它构建于声明式模型生命周期管理和智能请求路由之上,为 LLM 推理工作负载提供了高性能和企业级的可伸缩性。

本指南将演示如何在 Kubernetes 上部署生产级的多节点 vLLM 服务。

我们将

  • 安装所需的组件(Kthena + Volcano)。
  • 通过 Kthena 的 ModelServing CR 部署多节点 vLLM 模型。
  • 验证部署。

1. 先决条件

您需要

  • 一个具有GPU 节点的 Kubernetes 集群。
  • 具有 cluster-admin 或同等权限的 kubectl 访问权限。
  • 已安装的Volcano,用于作业调度。
  • 已安装的Kthena,且 ModelServing CRD 可用。
  • 如果从 Hugging Face Hub 加载模型,则需要有效的Hugging Face 令牌

1.1 安装 Volcano

helm repo add volcano-sh https://volcano-sh.github.io/helm-charts
helm repo update
helm install volcano volcano-sh/volcano -n volcano-system --create-namespace

这提供了 Kthena 使用的作业调度和网络拓扑功能。

1.2 安装 Kthena

helm install kthena oci://ghcr.io/volcano-sh/charts/kthena --version v0.1.0 --namespace kthena-system --create-namespace
  • 将创建 kthena-system 命名空间。
  • Kthena 控制器和 CRD(包括 ModelServing)已安装并运行正常。

验证

kubectl get crd | grep modelserving

您应该会看到

modelservings.workload.serving.volcano.sh   ...

2. 多节点 vLLM ModelServing 示例

Kthena 提供了一个示例清单,用于部署一个运行 Llama 的多节点 vLLM 集群。概念上,这等同于 vLLM 生产栈的 Helm 部署,但用 ModelServing 来表达。

示例(llama-multinode)的简化版本如下所示:

  • spec.replicas: 1 – 一个 ServingGroup(一个逻辑模型部署)。
  • roles:
    • entryTemplate – 定义运行的leader Pod,包括
      • vLLM 的多节点集群引导脚本(Ray 集群)。
      • vLLM 兼容 OpenAI 的 API 服务器
    • workerTemplate – 定义加入 leader 的 Ray 集群的worker Pod。

示例 YAML 的关键点

  • 镜像vllm/vllm-openai:latest(与上游 vLLM 镜像匹配)。
  • 命令(leader)
command:
  - sh
  - -c
  - >
    bash /vllm-workspace/examples/online_serving/multi-node-serving.sh leader --ray_cluster_size=2;
    python3 -m vllm.entrypoints.openai.api_server
      --port 8080
      --model meta-llama/Llama-3.1-405B-Instruct
      --tensor-parallel-size 8
      --pipeline-parallel-size 2
  • 命令(worker)
command:
  - sh
  - -c
  - >
    bash /vllm-workspace/examples/online_serving/multi-node-serving.sh worker --ray_address=$(ENTRY_ADDRESS)

3. 通过 Kthena 部署多节点 llama vLLM

3.1 准备清单

推荐:使用 Secret 而不是原始环境变量

kubectl create secret generic hf-token \
  -n default \
  --from-literal=HUGGING_FACE_HUB_TOKEN='<your-token>'

3.2 应用 ModelServing

cat  <<EOF | kubectl apply -f -
apiVersion: workload.serving.volcano.sh/v1alpha1
kind: ModelServing
metadata:
  name: llama-multinode
  namespace: default
spec:
  schedulerName: volcano
  replicas: 1  # group replicas
  template:
    restartGracePeriodSeconds: 60
    gangPolicy:
      minRoleReplicas:
        405b: 1
    roles:
      - name: 405b
        replicas: 2
        entryTemplate:
          spec:
            containers:
              - name: leader
                image: vllm/vllm-openai:latest
                env:
                  - name: HUGGING_FACE_HUB_TOKEN
                    valueFrom:
                      secretKeyRef:
                        name: hf-token
                        key: HUGGING_FACE_HUB_TOKEN
                command:
                  - sh
                  - -c
                  - "bash /vllm-workspace/examples/online_serving/multi-node-serving.sh leader --ray_cluster_size=2; 
                    python3 -m vllm.entrypoints.openai.api_server --port 8080 --model meta-llama/Llama-3.1-405B-Instruct --tensor-parallel-size 8 --pipeline-parallel-size 2"
                resources:
                  limits:
                    nvidia.com/gpu: "8"
                    memory: 1124Gi
                    ephemeral-storage: 800Gi
                  requests:
                    ephemeral-storage: 800Gi
                    cpu: 125
                ports:
                  - containerPort: 8080
                readinessProbe:
                  tcpSocket:
                    port: 8080
                  initialDelaySeconds: 15
                  periodSeconds: 10
                volumeMounts:
                  - mountPath: /dev/shm
                    name: dshm
            volumes:
            - name: dshm
              emptyDir:
                medium: Memory
                sizeLimit: 15Gi
        workerReplicas: 1
        workerTemplate:
          spec:
            containers:
              - name: worker
                image: vllm/vllm-openai:latest
                command:
                  - sh
                  - -c
                  - "bash /vllm-workspace/examples/online_serving/multi-node-serving.sh worker --ray_address=$(ENTRY_ADDRESS)"
                resources:
                  limits:
                    nvidia.com/gpu: "8"
                    memory: 1124Gi
                    ephemeral-storage: 800Gi
                  requests:
                    ephemeral-storage: 800Gi
                    cpu: 125
                env:
                  - name: HUGGING_FACE_HUB_TOKEN
                    valueFrom:
                      secretKeyRef:
                        name: hf-token
                        key: HUGGING_FACE_HUB_TOKEN
                volumeMounts:
                  - mountPath: /dev/shm
                    name: dshm   
            volumes:
            - name: dshm
              emptyDir:
                medium: Memory
                sizeLimit: 15Gi
EOF

Kthena 将会

  • 创建一个 ModelServing 对象。
  • 为 Volcano 作业调度派生一个 PodGroup
  • 为每个 ServingGroupRole 创建 leader 和 worker Pod。

4. 验证部署

4.1 检查 ModelServing 状态

使用 Kthena 文档中的代码片段

kubectl get modelserving -oyaml | grep status -A 10

您应该会看到类似以下内容:

status:
  availableReplicas: 1
  conditions:
    - type: Available
      status: "True"
      reason: AllGroupsReady
      message: All Serving groups are ready
    - type: Progressing
      status: "False"
      ...
  replicas: 1
  updatedReplicas: 1

4.2 检查 Pod

列出您的部署的 Pod

kubectl get pod -owide -l modelserving.volcano.sh/name=llama-multinode

示例输出(来自文档)

NAMESPACE   NAME                          READY   STATUS    RESTARTS   AGE   IP            NODE           ...
default     llama-multinode-0-405b-0-0    1/1     Running   0          15m   10.244.0.56   192.168.5.12   ...
default     llama-multinode-0-405b-0-1    1/1     Running   0          15m   10.244.0.58   192.168.5.43   ...
default     llama-multinode-0-405b-1-0    1/1     Running   0          15m   10.244.0.57   192.168.5.58   ...
default     llama-multinode-0-405b-1-1    1/1     Running   0          15m   10.244.0.53   192.168.5.36   ...

Pod 名称模式

  • llama-multinode-<group-idx>-<role-name>-<replica-idx>-<ordinal>.

第一个数字表示 ServingGroup。第二个数字(405b)是 Role。剩余的索引标识了该角色中的 Pod。


6. 访问 vLLM 兼容 OpenAI API

通过 Service 暴露入口

apiVersion: v1
kind: Service
metadata:
  name: llama-multinode-openai
  namespace: default
spec:
  selector:
    modelserving.volcano.sh/name: llama-multinode
    modelserving.volcano.sh/entry: "true"
    # optionally further narrow to leader role if you label it
  ports:
    - name: http
      port: 80
      targetPort: 8080
  type: ClusterIP

从您的本地机器端口转发

kubectl port-forward svc/llama-multinode-openai 30080:80 -n default

然后

  • 列出模型
curl -s https://:30080/v1/models
  • 发送一个完成请求(镜像 vLLM 生产栈文档)
curl -X POST https://:30080/v1/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "meta-llama/Llama-3.1-405B-Instruct",
    "prompt": "Once upon a time,",
    "max_tokens": 10
  }'

您应该会收到来自 vLLM 的 OpenAI 风格的响应。


7. 清理

要删除部署及其资源

kubectl delete modelserving llama-multinode -n default

如果您不再需要整个堆栈

helm uninstall kthena -n kthena-system   # or your Kthena release name
helm uninstall volcano -n volcano-system