背景
KServe 是 Kubernetes 上的规范模型推理平台,专为高度可扩大的场景而构建,反对古代 Serverless 推理工作负载,用于在任意框架上提供机器学习(ML)模型服务。它提供高性能、高度形象的接口,以反对常见的 ML 框架(如 Tensorflow、XGBoost、Scikit-Learn、PyTorch 和 ONNX)来解决生产模型服务场景。此外,KServe 封装了主动缩放、网络、健康检查和服务配置的复杂性,反对 GPU 主动缩放、归零缩放和金丝雀公布等。为生产级别机器学习服务提供了一个简略、可插拔且残缺的反对,包含预测、预处理、后处理和可解释性的能力。
人工智能生成内容(AIGC)和大型语言模型(LLM)在近一年内方兴未艾,进一步晋升了了公众对 AI 的期望值。为了可能产生新的业务价值,越来越多的公司开始应用 KServe 来部署它们,次要起因是:
- 分布式解决:大型语言模型(LLMs)的参数量宏大,须要极高的计算资源,而 KServe 平台提供了分布式解决能力,能够将计算工作散布到多个节点上进行并行计算,从而减速计算过程。
- Serverless:KServe 平台是无服务器算法的典型代表,能够在需要变动时主动进行扩缩容。这种个性使得部署大型语言模型变得更加灵便和高效,并可能显著晋升模型的响应速度。
- 统一化部署:KServe 平台为用户提供了一种更加简便和对立的形式来部署和治理大型语言模型。这样一来,用户无需自行设置和配置算法环境,即可开始进行模型的训练和预测工作。
- 监控和治理:KServe 平台具备齐备的监控和治理性能,用户能够清晰地理解到模型的运行状况和性能体现,并可能及时调整参数和解决问题,从而保障模型的高效和牢靠。
然而在生产实践中,KServe 对于大型语言模型(LLMs)的反对仍然有不小的挑战。次要问题在于:
- 模型启动工夫长:大型语言模型(LLMs)的参数规模相当微小,体积通常很大甚至达到几百 GB,导致拉取到 GPU 显存的耗时微小,启动工夫十分慢。此外,KServe 通过存储初始化器(Storage Initializer)从近程存储中拉取模型到本地,这也须要很长时间,对依据流量进行 KServe 无服务器主动扩缩容性能产生不利影响。
- 容器镜像拉取工夫长:大型语言模型(LLMs)的运行时环境依赖 GPU 根底环境,相应的容器镜像通常很大,这会导致拉取工夫长,拖慢利用启动速度。
- 模型更新效率低、复杂度高:大型语言模型(LLMs)由多个文件组成,模型更新时只需局部更新或增加局部文件,但 KServe 须要重启容器和从新拉取模型,无奈反对模型的热降级,这带来效率低和复杂度高的问题。
KServe 在 Kubecon 2023 就提到了 Fluid 有可能帮忙解决其在弹性上遇到的问题。Fluid 是一个开源的 Kubernetes 原生的分布式数据集编排和减速引擎,次要服务于云原生场景下的数据密集型利用,例如大数据利用、AI 利用等。参见数据减速 Fluid 概述[1]。
阿里云容器服务团队和 KServe,Fluid 社区的小伙伴一起摸索在阿里云 Serverless Kubernetes 平台上简略,不便,高性能,生产级别的反对大型语言模型(LLMs):
- 服务托管,产品反对:阿里云服务网格(简称 ASM)对于 KServe 提供了原生反对,要晓得 KServe 依赖于底层 Istio 的稳定性对于 KServe 来说十分重要,应用托管的服务网格后,高可用、免运维、内建平安最佳实际;用户能够更专一于大语言模型相干的工作。除此之外 KServe 和 Fluid 也能够一键装置。
- 协同社区优化应用模式:在 KServe 最新版反对除了存储初始化器(Storage Initializer)外,也反对规范的 PVC 模式,通过防止从近程存储中拉取模型到本地,缩小存储有余的危险和晋升启动速度;也能够反对模型热降级。
- 通过弹性分布式缓存减速模型加载流程:Fluid 与 KServe 相结合,通过数据预热到分布式缓存,缩短 Pod 启动工夫 80% 同时反对模型热降级,无容器重启。
- 以上能力齐全通过运行阿里云无服务器 Kubernetes 容器服务(ASK)上,在业务没有运行按需弹性、按秒计费,同时基于申请量的 GPU 无服务器主动扩大,缩放至零。
所有就绪,咱们一起开启阿里云 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 性能
- 登录 ASM 控制台[9],在左侧导航栏,抉择服务网格 > 网格治理。
- 在网格治理页面,单击指标实例名称,而后在左侧导航栏,抉择生态集成核心 > KServe on ASM。
- 在 KServe on ASM 页面,单击启用 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 或 ASK 集群部署 ack-fluid 组件,并保障 ack-fluid 组件的版本在 0.9.10 及以上。
阐明:如果您的数据面集群为 ACK 集群,您须要在 ACK 集群中装置云原生 AI 套件并部署 ack-fluid 组件。参考:减速在线利用数据拜访[10]。
如果您的数据面集群为 ASK 集群,您须要在 ASK 集群中部署 ack-fluid 组件。参考:减速 Job 利用数据拜访[11]。
- 筹备 AI 模型并上传至 OSS Bucket。
a. 筹备训练好的 AI 模型保留数据。本文以基于 pytorch 的开源 transformer 大语言模型 bloom 为例,能够在 hugging face 社区中获取模型数据:https://huggingface.co/bigscience/bloom-560m/tree/main
b. 将下载的模型数据文件上传至 OSS Bucket,并记录模型数据文件的保留地位。模型数据文件的保留地位格局为 oss://{bucket}/{path}。例如,如果您创立了名为 fluid-demo 的 bucket,并在 bucket 中的 models/bloom 目录中上传了所有的模型数据文件,则模型数据文件的保留地位为 oss://fluid-demo/models/bloom
阐明:您能够通过 OSS 提供的客户端工具 ossutil 上传数据。具体操作,请参见装置 ossutil[12]。
- 创立部署 Fluid 及 AI 服务的命名空间,并配置 OSS 拜访权限。
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
- 在 Fluid 中申明待拜访的 AI 模型数据。您须要提交一个 Dataset CR 和一个 Runtime CR。其中,Dataset CR 形容数据在内部存储系统中的 URL 地位,JindoRuntime CR:形容缓存零碎及其具体配置。
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 都部署胜利。
- 在 Fluid 中进行数据预热,晋升数据拜访性能。
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 模型推理服务
- 将以下内容保留为 oss-fluid-isvc.yaml
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 开源社区中找到此示例镜像的代码,并进行镜像自定义:https://github.com/kserve/kserve/tree/master/docs/samples/fluid/docker
- 执行以下命令,部署 InferenceService AI 模型推理服务。
kubectl create -f oss-fluid-isvc.yaml -n kserve-fluid-demo
- 执行以下命令,查看 AI 模型推理服务的部署状态。
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 模型推理服务
- 获取 ASM 入口网关地址
a. 登录 ASM 控制台,在左侧导航栏,抉择服务网格 > 网格治理。
b. 在网格治理页面,单击指标实例名称,而后在左侧导航栏,抉择 ASM 网关 > 入口网关。
c. 在入口网关页面找到名为 ingressgateway 的 ASM 入口网关,在服务地址区域,查看并获取 ASM 网关服务地址。
- 拜访示例 AI 模型推理服务
执行以下命令,拜访示例 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
< HTTP/1.1 200 OK
< content-length: 227
< content-type: application/json
< date: Thu, 20 Apr 2023 09:49:00 GMT
< server: istio-envoy
< x-envoy-upstream-service-time: 1142
<
{"result": "It was a dark and stormy night, and the wind was blowing in the\ndirection of the west. The wind was blowing in the direction of the\nwest, and the wind was blowing in the direction of the west. The\nwind was"}
* Connection #0 to host xxx.xx.xx.xx left intact
从预期输入中看到,AI 模型推理服务胜利对示例输出进行了续写并返回推理后果。
性能基准测试
咱们的性能基准测试将比拟 KServe 应用本身存储初始化器(OSS Storage Initializer)和 Fluid 的推理服务的扩容工夫,测试不同规格模型状况下的扩容工夫,即掂量服务从 0 扩大到 1 所需的工夫。
咱们所选的测试机型为:
- Fluid 机型:ecs.g7.xlarge
- 推理机型:ecs.g7.2xlarge
应用的 Fluid Runtime 为:
- JindoFS
其余前提:
- OSS 的数据桶和 ACK 集群在同一个区域
- 数据预热提前完成
- ACK 集群节点上曾经缓存了容器镜像
性能测试命令:
# Total time includes: pod initialization and running + download model (storage initializer) + load model + inference + network
curl --connect-timeout 3600 --max-time 3600 -o /dev/null -s -w 'Total: %{time_total}s\n' -H "Content-Type: application/json" -H "Host: ${SERVICE_HOSTNAME}" "http://${INGRESS_HOST}:${INGRESS_PORT}/v1/models/bloom:predict" -d '{"prompt":"It was a dark and stormy night","result_length": 50}'
# Total time:
Total:无服务状况下的推理响应工夫(从 0 开始扩容),包含容器调度,启动,模型下载,模型加载到显存,模型推理和网络延迟时间。
咱们能够察看到 Fluid 在大语言模型 (LLM) 的场景下,
- 大幅晋升 KServe 的冷启动速度,模型越大启动工夫优化越显著
- 岂但大幅度节俭模型下载到云盘(Storage Initializer 初始化)的工夫,另外也能够通过减少缓存 worker 带宽的形式冲破云盘的带宽限度(本例子中从云盘读取模型到内存的耗时也能够节俭一半甚至三分之二)
这样恰好能够大幅晋升 KServe 在容器场景下的弹性扩缩容能力。
总结和瞻望
通过现有的云原生 AI 框架反对大模型这种新物种还须要一直地改善和优化,然而道阻且长,行则将至。阿里云容器服务团队违心和社区的小伙伴一起摸索如何可能用更低的老本反对更好的 LLM 推理场景,提供规范凋谢的计划,产品化的能力。咱们后续会提供通过计算弹性扩缩容的法则触发数据缓存的弹性扩缩容来管制老本,以及大模型的热更新办法。
相干链接:
[1] 数据减速 Fluid 概述
https://help.aliyun.com/document_detail/208335.html
[2] 创立 Kubernetes 托管版集群
https://help.aliyun.com/document_detail/95108.html?spm=a2c4g….
[3] 创立节点池
https://help.aliyun.com/document_detail/160490.html?spm=a2c4g…
[4] 创立 ASM 实例
https://help.aliyun.com/document_detail/147793.htm#task-2370657
[5] 增加集群到 ASM 实例
https://help.aliyun.com/document_detail/148231.htm#task-2372122
[6] 通过数据面集群 KubeAPI 拜访 Istio 资源
https://help.aliyun.com/document_detail/431215.html
[7] 创立入口网关服务
https://help.aliyun.com/document_detail/149546.htm#task-2372970
[8] 应用 Knative on ASM 部署 Serveless 利用
https://help.aliyun.com/document_detail/611862.html
[9] ASM 控制台
https://account.aliyun.com/login/login.htm?oauth_callback=htt…
[10] 减速在线利用数据拜访
https://help.aliyun.com/document_detail/440265.html
[11] 减速 Job 利用数据拜访
https://help.aliyun.com/document_detail/456858.html
[12] 装置 ossutil
https://help.aliyun.com/document_detail/120075.htm#concept-30…
[13] 通过 kubectl 连贯 Kubernetes 集群
https://help.aliyun.com/document_detail/86378.html
[14] 拜访域名和数据中心
https://help.aliyun.com/document_detail/31837.html
[15] bigscience/bloom-560m
https://huggingface.co/bigscience/bloom-560m
[16] bigscience/bloom-7b1
https://huggingface.co/bigscience/bloom-7b1
作者:黄驰琳、露营、车漾
点击立刻收费试用云产品 开启云上实际之旅!
原文链接
本文为阿里云原创内容,未经容许不得转载。