一、背景
1.1 PAI-DSW 全面拥抱 Cloud Native AI,打造一站式云端 AI 开发体验
云原生技术通过灵活的资源管理和标准化的运维能力显著提升了 AI 开发与应用的构建效率。这一最佳实践,称为 CNAI(Cloud Native AI),已成为构建AI基础设施的首选方案。CNAI 有效地解决了在 AI 工程化过程中软件环境维护复杂、异构硬件管理分散以及计算资源分配不均等问题,让数据科学家/AI 开发者能够更加专注于核心业务逻辑的研发与创新。
PAI-DSW(Data Science Workshop) 围绕阿里云的云原生 Kubernetes 与 AI 体系所构建,是为数据科学家/AI 开发者量身打造的一站式云原生 AI 开发平台。
DSW 开发机实例集成了JupyterLab、WebIDE、Terminal 多种云端开发环境,用户可以直接在云端环境中编写、调试和运行代码,无需在本地进行安装和配置,大大提高了开发效率。同时 DSW 实例完全基于容器化设计,运行在阿里云容器服务 ACK 之上,在提供丰富异构计算资源的同时,支持挂载 OSS、NAS、CPFS 类型的数据集,预置了多种开源框架的镜像,支持实例的生命周期管理,支持和用户 VPC 网络打通,实现开箱即用的高效开发模式,是全功能的数据科学开发站。
Notebook Lab 专注于 Notebook 的开发和管理,提供轻量化的开发界面,只需在运行调试时远程连接 DSW 实例作为运行时环境,同时将 Notebook 文件的管理/分享与 DSW 开发机实例解耦,适合 Notebook 单文件开发场景。
Notebook Gallery 提供了丰富的大数据及AI教程案例,来自各个行业与技术方向,包括 LLM、AIGC 等前沿技术,用户可一键启动,便于学习和二次开发。
1.2 云原生体系下数据科学家/AI 开发者开发体验的鸿沟
在云原生架构下,新的 AI 用户场景带来了诸多挑战和需求。其中一个核心痛点是在 Kubernetes 上进行开发时,数据操作缺乏灵活性。Kubernetes 仅提供异构存储服务接入和管理的标准接口(CSI,Container Storage Interface),但未定义应用如何在容器集群中使用和管理数据,包括异构数据源的定义、多数据源的管理以及挂载点的动态更新。而在模型开发过程中,数据科学家和 AI 开发者需要管理数据集版本,能够动态加载和切换数据集,以便进行模型开发、调试和训练。但在当前的 Kubernetes 框架下尚缺乏一套成熟的标准方案来支持这些操作,这也成为了云原生领域亟待解决的能力缺口之一。
来到 PAI-DSW 的用户场景,DSW 开发机实例由 Kubernetes 集群中的 Pod 承载,同样面临上述痛点。开发者在使用 DSW 进行模型开发时,通常需要接入来自不同数据源的数据集,此时加载新数据集需要重启 DSW 实例,我们称为“启动时挂载”。重启操作会导致底层 Kubernetes 环境中对应 Pod 被删除并重新创建。在这个过程中,一方面用户原有实例中正在运行的程序会被中断,另一方面重启的过程往往需要分钟级的时间,如果底层资源是弹性资源,很有可能在重启的过程中遇到资源被抢占、无库存的情况,严重影响用户体验,因此DSW 期望运行中的开发机可以动态增加新的数据挂载而无需重启实例。
二、Fluid 助力 DSW 升级数据体验
2.1 What is Fluid
Fluid是一个 Kubernetes 原生的分布式数据集编排和加速引擎。Fluid 诞生的初衷即是为数据的灵活使用和其访问延时问题提供云原生的解决方案,主要服务于云原生场景下的数据密集型应用,例如大数据应用、AI 应用等。通过 Kubernetes 服务提供的数据层抽象,可以让数据像流体一样在诸如 HDFS、OSS、Ceph 等存储源和 Kubernetes 上层云原生应用计算之间灵活高效地移动、复制、驱逐、转换和管理。而具体数据操作对用户透明,用户不必再担心访问远端数据的效率、管理数据源的便捷性,以及如何帮助 Kuberntes 作出运维调度决策等问题。用户只需以最自然的 Kubernetes 原生数据卷方式直接访问抽象出来的数据,剩余任务和底层细节全部交给 Fluid 处理。因此许多用户将 Fluid 应用到更广泛的场景中,比如针对AIGC、大模型、大数据、混合云、自动驾驶数据仿真、开发机数据集管理等场景。
想要达到这个目的,做好对“计算任务使用数据的过程”的抽象是重中之重,因此 Fluid 提出了弹性数据集 Dataset的概念,并将其定位为 Kubernetes 中的“一等公民”。弹性数据集 Dataset 通过分布式缓存技术提高了计算任务访问数据使用效率,用云原生的方式把集群中的缓存作为可以管理、调度、弹性的 Kubernetes 资源,并且根据应用访问数据的特点为应用获得更好的性能服务。
另一方面,Fluid 还致力于提升人使用数据的效率。围绕此目标,Fluid 团队做了一系列的工作,包括 ThinRuntime 的低代码数据接入机制,屏蔽了 Kubernetes 繁杂的接口体系,让用户以低代码的形式完成数据接入;支持跨 namespace 共享 Dataset 缓存机制,让公开数据能够在不同团队共享,有效提升了平台开发团队和数据科学家/AI 开发者之间的协作效率等。进一步,为了针对性解决上文所描述模型开发过程中的数据访问体验鸿沟,Fluid 提供了为运行中实例所引用的数据集挂载点的动态挂载/卸载的能力。
2.2 Fluid 支持数据集动态挂载/卸载
提到数据的挂载/卸载操作,就离不开 CSI 体系,但现有的 CSI 体系设计实现,延续了 Kubernetes 在传统在线应用或离线 Job 场景下的设计理念,无法满足 CNAI 场景下数据科学家/AI 开发者的数据使用需求:
- CSI 围绕 Kubernetes 原生资源 PVC、PV 所实现,One PVC - One PV - One Source 的关联关系,虽然保证了数据管理上的原子性,但也大大提升了资源管理、运维和使用的复杂度。为了解决此类场景下的数据使用问题,Fluid 围绕弹性数据集 Dataset的概念,基于One PVC-One Dataset - Multiple Data Source的资源模型进行 API 设计,在优化了数据使用体验的同时,也为数据源管理的动态性提供了基础。
- CSI 作为 Kubernetes 社区提供的标准存储接口,基于该接口的实现都默认延续了 Kubernetes Storage 相关资源Immutable的设计,这就导致了一旦 Pod 创建,那么 Pod 所引用的数据源不可新增或者删除,这大大地限制了资源使用的灵活度。Fluid 中弹性数据集 Dataset提供了Mutable API,围绕 Mutable API,Fluid 提供两项能力:
- 当弹性数据集 Dataset作为 Mutable API 被设计,这就意味着当用户修改了 Dataset Fluid 需要能够及时感知到变化的发生,并做出相应的动作,Fluid 围绕此提供了一套异步调谐更新机制。
- 出于安全考虑,云上开发平台通常不会提供给他们的客户所能触及到的容器的特权权限和 FUSE 设备,这就意味着挂载动作无法在用户容器中直接进行,要由 DaemonSet MountPod(Sidecar in Serverless Pod)来完成,并需要将挂载点传播至用户容器,因此 Fluid 提供了挂载点的传播机制,并且将这套复杂机制的实现配置托管封装起来(包括 MountPod 的创建,Sidecar 的注入,Volume、PV、PVC 的配置等),让用户在模型开发时只需要关注 Dataset 的配置,减少在运维配置上的精力投入。
方案架构
为了提升使用数据的效率,Fluid 提供了 ThinRuntime 能力,允许用户描述任何自定义的存储系统,并对接到 Fluid 中,无需感知复杂的 Kubernetes CSI 接口体系。动态挂载能力基于 ThinRuntime 的灵活存储系统接入能力,并更进一步地拓展其动态性。相比于 Kubernetes 中 PVC 与 PV一一对应的关系,Fluid Dataset 描述的是一个或多个相关联的数据源集合,同时允许用户可以在 Pod 运行时增加/减少 Fluid Dataset 中指向的存储系统。利用Fluid提供的异步更新机制和挂载点传播机制,当用户动态修改 Dataset中描述的数据源时,Fluid 自动完成新挂载点的挂载、挂载点传播等行为,使得新挂载点对于用户业务容器立即可见。
上图描述了本设计的完整流程,在此流程中:
Control Plane:
- Fluid Dataset:Fluid 的目标是为 AI 与大数据云原生应用提供一层高效便捷的数据抽象,将数据从存储抽象出来从而提供多数据源、异构数据源支持,因此 Fluid 定义了 Dataset 数据集是逻辑上相关的一组数据源的集合,被运算引擎、应用所使用,并且 Mutable API 的设计使得 Dataset 可以提供 More Than PV 的数据源使用上的动态性。具体来说,Dataset 中描述了一个或多个数据源信息,包括挂载数据源时需要使用的参数、敏感信息(AK/SK),如下方 Dataset 的示例中,定义了两个数据源的相关信息,该数据源可以在 Pod 运行中被动态地增加或减少,相对应实现挂载新的数据源或卸载已有数据源。
apiVersion: data.fluid.io/v1alpha1
kind: Dataset
metadata:
name: demo-for-dynamic-mount
spec:
...
mounts:
- mountPoint: oss://bucket-name-1
name: mount-point-1
path: /subpaht-for-mount-point-1
options:
fs.oss.endpoint: oss-cn-shanghai-internal.aliyuncs.com
- mountPoint: oss://bucket-name-2
name: mount-point-2
path: /subpaht-for-mount-point-2
options:
fs.oss.endpoint: oss-cn-shanghai-internal.aliyuncs.com
- Fluid ThinRuntime/ThinRuntimeProfile:提供可扩展的通用存储系统实现,允许用户以低代码方式接入各类存储系统,复用 Fluid 提供的数据编排管理、运行时平台访问接入核心能力。其描述了一个 FUSE 文件系统类型以及用户快速将自己的 FUSE 文件系统与 Fluid 对接的相关配置。
apiVersion: data.fluid.io/v1alpha1
kind: ThinRuntime
metadata:
name: demo-for-dynamic-mount
spec:
profileName: profile-demo-for-dynamic-mount
---
apiVersion: data.fluid.io/v1alpha1
kind: ThinRuntimeProfile
metadata:
name: profile-demo-for-dynamic-mount
spec:
fileSystemType: thin
fuse:
image: xxx
imageTag: xxx
command:
- tini
- -g
- --
- /usr/local/bin/entrypoint.sh
- Fluid Controller:作为 Fluid CR 的控制器,其同时 watch 与 ThinRuntime 绑定的 Dataset 变化,进行 Reconcile,以 Configmap 作为介质,将 dataset 的挂载点更新,异步更新至数据面。
- Fluid Webhook:在 Serverless 场景下,为了解决 DaemonSet 的支持问题,Fluid Webhook 会根据 Pod 定义中所使用 Fluid Dataset PVC,注入 Sidecar,实现与标准节点上 Fuse Pod 相同的功能。
Data Plane
- FUSE Pod(Fuse SideCar in Serverless Pod)中Fluid DynamicMountEngine作为数据面负责响应 Dataset 中挂载点信息更新的组件,会实时感知 Fluid Controller 通过异步更新链路下发的 dataset 中挂载点配置,与 Fuse Pod 中已存在的挂载点进行对比,判断此次更新中需要挂载和卸载的数据源。随后利用 Supervisord 机制,为每个需要挂载的数据源创建一个 supervisord program,拉起并运行 FUSE 文件系统挂载进程。对于需要卸载的数据源,对相应的 supervisord program 执行优雅下线,下线完成后,将挂载点卸载。此外,DynamicMountEngine基于 supervisord 的 event 机制,暴露 MountStatusMetrics 供业务侧查询,以判断挂载点的异步更新是否完成。
- Fluid CSI-Plugin 组件实现了标准的 CSI 接口,允许用户通过标准 K8S PVC 的方式,将 Dataset 接入应用 Pod(APP Pod/Container)
2.3 DSW 支持动态挂载技术实现
基于 Fluid 提供的以上能力,PAI-DSW 能够实现 OSS 等存储介质上数据集的动态挂载能力。
PAI-DSW 是标准的 Kubernetes Operator 架构,定义了多 个Kubernetes CRD 和 Controller,用于管理 DSW 实例。启动开启了动态挂载能力的 DSW 实例流程如下:
PAI DataSource CRD:用于管理 PAI-DSW/DLC 等云产品中使用的数据集,目前支持 OSS、NAS、CPFS 等数据源。为了支持动态挂载数据集能力,对 DataSource CRD 进行了扩展:
- 增加了 dynamic 类型,支持动态挂载。
- mountPath 是动态挂载的的根目录,所有动态挂载的数据集都需要挂载到该目录下。
- multiMounts:其值是 json 数组,保存动态挂载的数据集配置,通过更新该字段实现数据集动态挂载或卸载。
- options:指定 FUSE Pod 或 FUSE sidecar container 使用的资源大小。
apiVersion: dlc.alibaba.com/v1
kind: DataSource
metadata:
name: dsw-123456-dynamic-0
namespace: tenantns1
spec:
attributes:
mountPath: /mnt/dynamic/
multiMounts: '[{"endpoint":"oss-cn-hangzhou-internal.aliyuncs.com","mountPath":"/osspath1/","options":"","path":"oss://oss-bucket-1/path1/","type":"oss"},{"endpoint":"oss-cn-hangzhou-internal.aliyuncs.com","mountPath":"/osspath2","options":"","path":"oss://oss-bucket-2/path2/","type":"oss"}]'
options: '{"fs.fuse.pod.mem.limit":"8Gi"}'
name: dsw-123456-dynamic-0
type: dynamic
status:
lastUpdateTime: "2024-11-21T07:02:01Z"
status: Ready
PAI DataSource Controller:作为 PAI DataSource CR 的控制器,其 Watch DataSource CR 的变化,进行 Reconcile,在动态挂载场景,其负责:
- 创建 Fluid ThinRuntime CR,并指定 Fuse Pod 和 Fuse sidecar container 使用的资源大小。
apiVersion: data.fluid.io/v1alpha1
kind: ThinRuntime
metadata:
name: dsw-123456-dynamic-0
namespace: tenantns1
spec:
fuse:
resources:
limits:
cpu: "4"
memory: 8Gi
requests:
cpu: "0"
memory: "0"
profileName: thinruntime-profile
- 创建保存 OSS 临时访问 Token 的 Secret,并定时生成新的 Token 更新到 Secret 中。
apiVersion: v1
data:
AccessKeyId: U1RTLk....
AccessKeySecret: QTNX...
LastUpdate: sOdFZw...
SecurityToken: Q0FJUzJ3S...
kind: Secret
metadata:
name: dsw-123456-dynamic-0
namespace: tenantns1
type: Opaque
- 创建 Fluid Dataset CR,并根据 DataSource CR 配置更新 Fluid Dataset CR,Dataset CR 中会引用上面 Secret 中的 key,每个 key 会被分别挂载为 fuse container 的一个文件,Secret 刷新时自动更新。
apiVersion: data.fluid.io/v1alpha1
kind: Dataset
metadata:
name: dsw-123456-dynamic-0
namespace: tenantns1
spec:
mounts:
- mountPoint: oss://oss-bucket-1/path1/
name: dsw-123456-dynamic-0-lBrlM-1732172519
options:
fs.oss.endpoint: oss-cn-hangzhou-internal.aliyuncs.com
path: /osspath1/
- mountPoint: oss://oss-bucket-2/path2/
name: dsw-123456-dynamic-0-WyPjV-1732172519
options:
fs.oss.endpoint: oss-cn-hangzhou-internal.aliyuncs.com
path: /osspath2/
sharedEncryptOptions:
- name: fs.oss.accessKeyId
valueFrom:
secretKeyRef:
key: AccessKeyId
name: dsw-123456-dynamic-0
- name: fs.oss.accessKeySecret
valueFrom:
secretKeyRef:
key: AccessKeySecret
name: dsw-123456-dynamic-0
- name: fs.oss.stsToken
valueFrom:
secretKeyRef:
key: SecurityToken
name: dsw-123456-dynamic-0
- name: fs.oss.lastUpdate
valueFrom:
secretKeyRef:
key: LastUpdate
name: dsw-123456-dynamic-0
- Watch PVC 的状态,待 ThinRuntime Controller 创建出 PVC,且 Phase 为 Bound 后,将 DataSource CR 状态置为 Ready。
PAI DswInstance Controller:负责管理 DSW 实例对应的 CR:
- 实例启动时根据 DSW 实例中用户的数据集配置,创建出 DataSource CR。
- Watch DataSource CR,待其状态变为 Ready 后,创建 Deployment,将上述 PVC 挂载为动态挂载的根目录,启动 DSW Pod。
- 用户动态挂载/卸载数据集时,DswInstance Controller 负责更新 DataSource CR。
apiVersion: apps/v1
kind: Deployment
metadata:
name: dsw-123456
namespace: tenantns1
spec:
replicas: 1
template:
spec:
containers:
- image: registry-vpc.cn-hangzhou.cr.aliyuncs.com/pai/tensorflow:latest
name: main
volumeMounts:
- mountPath: /mnt/dynamic/
mountPropagation: HostToContainer
name: dsw-123456-dynamic-0
volumes:
- name: dsw-123456-dynamic-0
persistentVolumeClaim:
claimName: dsw-123456-dynamic-0
三、AC2 为动态挂载能力提供安全可靠的容器化接入方案
阿里云 AI 容器镜像(Alibaba Cloud AI Containers 简称 AC2)是阿里云提供的面向 AI 场景的系列容器镜像,通过提供开箱即用的 AI 应用环境,包括内置 CUDA AI 库、AI 框架 PyTorch,并结合阿里云基础设施进行性能优化、兼容性保障、稳定性保障,让用户可以在阿里云上全容器场景下有更好的使用体验。
目前行业中在构建 AI container 镜像过程中大量使用 pip 构建,由于 pip 的软件来源存在较大的安全隐患,经常可以看到由于 pip 源被投毒而导致发生各种安全生产的问题,Alibaba cloud AI containers 产品镜像为了尽可能规避此类的安全问题,专门提供了AI软件源(epao 源),对外提供的所有的AC2镜像都基于 epao 源构建,并结合 CVE 更新策略和镜像的安全扫描机制,在最大程度上保障了 AI 容器镜像的安全生产。
四、DSW 动态挂载数据集快速实践
4.1 功能介绍
数据科学家/AI 开发者启动 DSW 实例进入开发环境后,在代码开发调试过程中临时发现需要一份新的训练数据集,可以通过简单的两行代码实现挂载操作,指定的数据集会默认挂载至/mnt/dynamic/路径下。目前支持 OSS 存储类型的数据集。
from pai.dsw import mount
mount("oss://bucketname/xxxxx")
通过以下命令可以列出当前 DSW 实例挂载的数据集及挂载状态,包括启动时挂载和动态挂载的所有数据集。
from pai.dsw import list_dataset_configs
list_dataset_configs()
[{'Dynamic': True,
'MountPath': '/mnt/dynamic/your_mount_path/',
'Uri': 'oss://xxxxxx.oss-cn-hangzhou-internal.aliyuncs.com/'}]
在训练数据使用完成后,也可以及时地解除挂载。
from pai.dsw import unmount
mount_path = '/mnt/dynamic/your_mount_path/'
unmount(mount_path)
更多功能介绍可查看动态挂载功能说明文档。
4.2 功能演示
本案例演示了一个常规的大模型 SFT 场景,用户在选择好基模型之后,通常需要获取一个业务数据集对模型进行快速的微调。我们以 Qwen2.5-7B-Instruct 模型为例,从 PAI 的公共数据集选择一个开源的中文医疗数据集,并通过简单的挂载命令将数据集动态挂载至实例中,训练完成后再动态将数据集卸载,整个流程在10分钟内即可完成。欢迎大家前往 PAI-DSW 控制台,在 Notebook Lab 或 DSW 开发机中体验开发过程。
点击链接观看视频:https://cloud.video.taobao.com/vod/Eenyicc-U0BOmGavXxXbTO5U8VTSjFJs9xZdDfCi8Yo.mp4
五、未来展望
在当前发布的版本中, 我们已经支持了在 DSW 实例中动态挂载/卸载阿里云 OSS 数据集,但动态挂载作为数据科学家/AI开发者在 CNAI 体系下进行模型开发的高频场景需求,仍有许多可以持续优化完善的地方,包括:
- 支持更多存储类型的接入,适配阿里云全存储产品家族
- 探索更安全、性能无损的挂载传播方案
- 接入缓存系统,对于公开数据集实现一人访问,全员共享加速体验,进一步提升数据访问效率
- 探索数据可写场景动态挂载,提供更灵活的开发体验