作者:黄驰琳、露营、车漾
背景
KServe 是 Kubernetes 上的标准模型推理平台,专为高度可扩展的场景而构建,支持现代 Serverless 推理工作负载,用于在任意框架上提供机器学习(ML)模型服务。它提供高性能、高度抽象的接口,以支持常见的 ML 框架(如Tensorflow、XGBoost、Scikit-Learn、PyTorch 和 ONNX)来解决生产模型服务场景。此外,KServe 封装了自动缩放、网络、健康检查和服务配置的复杂性,支持GPU 自动缩放、归零缩放和金丝雀发布等。为生产级别机器学习服务提供了一个简单、可插拔且完整的支持,包括预测、预处理、后处理和可解释性的能力。
人工智能生成内容(AIGC)和大型语言模型(LLM)在近一年内方兴未艾,进一步提升了了大众对 AI 的期望值。为了能够产生新的业务价值,越来越多的公司开始使用 KServe 来部署它们,主要原因是:
但是在生产实践中,KServe 对于大型语言模型(LLMs)的支持依然有不小的挑战。主要问题在于:
KServe 在 Kubecon 2023 就提到了 Fluid 有可能帮助解决其在弹性上遇到的问题。Fluid 是一个开源的 Kubernetes 原生的分布式数据集编排和加速引擎,主要服务于云原生场景下的数据密集型应用,例如大数据应用、AI 应用等。参见数据加速 Fluid 概述 [ 1] 。
阿里云容器服务团队和 KServe,Fluid 社区的小伙伴一起探索在阿里云 Serverless Kubernetes 平台上简单,方便,高性能,生产级别的支持大型语言模型(LLMs):
一切就绪,我们一起开启阿里云 Kubernetes(ACK) 中 KServe 推理大模型之旅:
实践步骤
前提条件
- 已创建 ACK 集群,集群的 Kubernetes 版本 ≥1.18,具体操作,请参见创建 Kubernetes 托管版集群 [ 2] 。
📌 本演示使用的 ACK 集群包含 3 个 ecs.g7.xlarge 规格的 ecs 和 1 个 ecs.g7.2xlarge 规格的 ecs。您可以在创建时选择添加 3 个 ecs.g7.xlarge 规格的 ecs,待集群创建完成后新建一个节点池以增加一个 1 个 ecs.g7.2xlarge 规格的 ecs,关于创建节点池的具体操作请参考创建节点池 [ 3] 。
- 已创建 v1.17 及以上版本的 ASM 实例,并已将上述 ACK 集群添加到该实例中。具体操作,请参见创建 ASM 实例 [ 4] 和添加集群到 ASM 实例 [ 5] 。
您可以使用上述配置来创建阿里云服务网格 ASM 实例,其中:
- 实例规格需要选择企业版(以启用数据面集群 KubeAPI 访问 Istio 资源能力)
- Istio 版本需要选择 v1.17 及以上
- 网格的地域、专有网络需要与创建的 Kubernetes 集群保持一致,以保证网络畅通
- 可以视需求选择是否勾选 “使用 EIP 暴露 API Server”,开启后将为内网 SLB 实例创建并绑定一个 EIP,您将可以从公网访问 ASM 实例的 API Server,并操作 Istio CR
- 可观测性及网格审计部分依赖日志服务和阿里云 Prometheus 监控服务,若依赖服务尚未开通,在创建时您可以不勾选
- 【重要】必须勾选启用数据面集群 KubeAPI 访问 Istio 资源。
- 集群本地域名需要与您的 Kubernetes 集群的本地域名保持一致。
- ASM 实例已经开启通过数据面集群 KubeAPI 访问 Istio 资源能力。具体操作,参考:通过数据面集群 KubeAPI 访问 Istio 资源 [ 6] 。
- 已为集群添加入口网关。本实例使用 ASM 入口网关作为集群网关,ASM 入口网关名称为默认的 ingressgateway,开放端口 80 和 443。具体操作,请参见创建入口网关服务 [ 7] 。
- 已在 ACK 或 ASK 集群中部署 Knative Serving 组件,并开启 Knative on ASM 功能。具体操作,参考:使用 Knative on ASM 部署 Serveless 应用 [ 8] 中的前提及步骤一。
步骤一:开启 KServe on ASM 功能
📌 说明:KServe on ASM 功能依赖 cert-manager 组件的部署与使用。cert-manager 是一个证书生命周期管理系统,支持证书的申请、部署等功能。如果您没有在集群中安装 cert-manager,您需要在 KServe on ASM 页面开启 在集群中自动安装 CertManager 组件,以自动为您安装 cert-manager;否则您需要关闭此项,再单击启用 KServe on ASM。
步骤二:安装 ACK-Fluid 并开启 AI 模型缓存加速
📌 说明:如果您的数据面集群为 ACK 集群,您需要在 ACK 集群中安装云原生AI套件并部署 ack-fluid 组件。参考:加速在线应用数据访问 [ 10] 。
如果您的数据面集群为 ASK 集群,您需要在 ASK 集群中部署 ack-fluid 组件。参考:加速 Job 应用数据访问 [1****1] 。
a. 准备训练好的 AI 模型保存数据。本文以基于 pytorch 的开源 transformer 大语言模型 bloom 为例,可以在 hugging face 社区中获取模型数据:huggingface.co/bigscience/…
b. 将下载的模型数据文件上传至 OSS Bucket,并记录模型数据文件的保存位置。模型数据文件的保存位置格式为 oss://{bucket}/{path}。例如,如果您创建了名为 fluid-demo 的 bucket,并在 bucket 中的 models/bloom 目录中上传了所有的模型数据文件,则模型数据文件的保存位置为 oss://fluid-demo/models/bloom
📌 说明:您可以通过 OSS 提供的客户端工具 ossutil 上传数据。具体操作,请参见安装 ossutil [ 12] 。
a. 使用 kubectl 连接到数据面 ACK/ASK 集群。具体操作,参考:通过 kubectl 连接 Kubernetes 集群 [ 13] 。
b. 使用 kubectl 创建命名空间,以部署 Fluid 及 KServe AI 服务。本文以 kserve-fluid-demo 命名空间为例。
kubectl create ns kserve-fluid-demo
c. 使用 kubectl 为命名空间添加 eci 标签,以将命名空间中的 Pod 调度到虚拟节点上。
kubectl label namespace kserve-fluid-demo alibabacloud.com/eci=true
d. 使用以下内容,创建 oss-secret.yaml 文件。其中 fs.oss.accessKeyId 和 fs.oss.accessKeySecret 分别代表可以访问 OSS 的 accessKeyId 和 accessKeySecret。
apiVersion: v1
kind: Secret
metadata:
name: access-key
stringData:
fs.oss.accessKeyId: xxx #替换为可以访问OSS的阿里云accessKeyId
fs.oss.accessKeySecret: xxx #替换为可以访问OSSd的阿里云accessKeySecret
e. 执行以下命令,部署 Secret,配置 OSS 访问秘钥。
kubectl apply -f oss-secret.yaml -n kserve-fluid-demo
a. 使用以下内容,保存为 oss-jindo.yaml 文件。
apiVersion: data.fluid.io/v1alpha1
kind: Dataset
metadata:
name: oss-data
spec:
mounts:
- mountPoint: "oss://{bucket}/{path}" # 需要替换为模型数据文件的保存位置
name: bloom-560m
path: /bloom-560m
options:
fs.oss.endpoint: "{endpoint}" # 需要替换为实际的OSS endpoint地址
encryptOptions:
- name: fs.oss.accessKeyId
valueFrom:
secretKeyRef:
name: access-key
key: fs.oss.accessKeyId
- name: fs.oss.accessKeySecret
valueFrom:
secretKeyRef:
name: access-key
key: fs.oss.accessKeySecret
accessModes:
- ReadOnlyMany
---
apiVersion: data.fluid.io/v1alpha1
kind: JindoRuntime
metadata:
name: oss-data
spec:
replicas: 2
tieredstore:
levels:
- mediumtype: SSD
volumeType: emptyDir
path: /mnt/ssd0/cache
quota: 50Gi
high: "0.95"
low: "0.7"
fuse:
args:
- -ometrics_port=-1
master:
nodeSelector:
node.kubernetes.io/instance-type: ecs.g7.xlarge
worker:
nodeSelector:
node.kubernetes.io/instance-type: ecs.g7.xlarge
📌 说明:您需要将 Dataset CR 中的 oss://{bucket}/{path} 替换为上文中记录的模型数据文件的保存位置。将 Dataset CR 中的 {endpoint}替换为 OSS 的访问域名。如何获取不同地域 OSS 的访问域名,参考:访问域名和数据中心 [ 14] 。
a. 执行以下命令,部署 Dataset 和 JindoRuntime CR。
kubectl create -f oss-jindo.yaml -n kserve-fluid-demo
b. 执行以下命令,查看 Dataset 和 JindoRuntime 的部署情况。
kubectl get jindoruntime,dataset -n kserve-fluid-demo
预期输出:
NAME MASTER PHASE WORKER PHASE FUSE PHASE AGE
jindoruntime.data.fluid.io/oss-data Ready Ready Ready 3m
NAME UFS TOTAL SIZE CACHED CACHE CAPACITY CACHED PERCENTAGE PHASE AGE
dataset.data.fluid.io/oss-data 3.14GiB 0.00B 100.00GiB 0.0% Bound 3m
由预期输出中得到,Dataset 的 PHASE为Bound,JindoRuntime 的 FUSE PHASE 为 Ready,代表 Dataset 和 JindoRuntime 都部署成功。
a. 使用以下内容,保存为 oss-dataload.yaml。
apiVersion: data.fluid.io/v1alpha1
kind: DataLoad
metadata:
name: oss-dataload
spec:
dataset:
name: oss-data
namespace: kserve-fluid-demo
target:
- path: /bloom-560m
replicas: 2
b. 执行以下命令,部署 Dataload 以预热数据。
kubectl create -f oss-dataload.yaml -n kserve-fluid-demo
c. 执行以下命令,查看数据预热的进度。
kubectl get dataload -n kserve-fluid-demo
预期输出:
NAME DATASET PHASE AGE DURATIONoss-dataload
oss-data Complete 1m 45s
由预期输出得到,数据预热耗时约 45s。需要等待一段时间才能使得数据预热完成。
步骤三:部署 AI 模型推理服务
apiVersion: "serving.kserve.io/v1beta1"
kind: "InferenceService"
metadata:
name: "fluid-bloom"
spec:
predictor:
timeout: 600
minReplicas: 0
nodeSelector:
node.kubernetes.io/instance-type: ecs.g7.2xlarge
containers:
- name: kserve-container
image: cheyang/kserve-fluid:bloom-gpu
resources:
limits:
cpu: "3"
memory: 8Gi
requests:
cpu: "3"
memory: 8Gi
env:
- name: STORAGE_URI
value: "pvc://oss-data/bloom-560m"
- name: MODEL_NAME
value: "bloom"
# 如果使用GPU则设置成True,否则设置为False
- name: GPU_ENABLED
value: "False"
📌 说明:本例中的 InferenceService 配置中在 image 字段使用了 cheyang/kserve-fluid:bloom-gpu 示例镜像,该镜像提供加载模型及推理服务的接口,您可以在 KServe 开源社区中找到此示例镜像的代码,并进行镜像自定义:github.com/kserve/kser…
kubectl create -f oss-fluid-isvc.yaml -n kserve-fluid-demo
kubectl get inferenceservice -n kserve-fluid-demo
预期输出:
NAME URL
READY PREV LATEST PREVROLLEDOUTREVISION LATESTREADYREVISION AGEfluid-bloom http://fluid-bloom.kserve-fluid-demo.example.com True 100 fluid-bloom-predictor-00001 2d
由预期输出可以看到 READY 字段为 True,证明 AI 模型推理服务已经部署成功。
步骤四:访问 AI 模型推理服务
a. 登录 ASM 控制台,在左侧导航栏,选择服务网格 > 网格管理。
b. 在网格管理页面,单击目标实例名称,然后在左侧导航栏,选择 ASM 网关 > 入口网关。
c. 在入口网关页面找到名为 ingressgateway 的 ASM 入口网关,在服务地址区域,查看并获取 ASM 网关服务地址。
执行以下命令,访问示例 AI 模型推理服务 bloom,将其中的 ASM 网关服务地址替换为上文中获取的 ASM 入口网关地址。
curl -v -H "Content-Type: application/json" -H "Host: fluid-bloom.kserve-fluid-demo.example.com" "http://{ASM网关服务地址}:80/v1/models/bloom:predict" -d '{"prompt": "It was a dark and stormy night", "result_length": 50}'
预期输出:
* Trying xxx.xx.xx.xx :80...
* Connected to xxx.xx.xx.xx (xxx.xx.xx.xx ) port 80 (#0)
> POST /v1/models/bloom:predict HTTP/1.1
> Host: fluid-bloom-predictor.kserve-fluid-demo.example.com
> User-Agent: curl/7.84.0
> Accept: */*
> Content-Type: application/json
> Content-Length: 65
>
* Mark bundle as not supporting multiuse