在Kubernetes的架构体系中,计算与存储是分离的,这给数据密集型的深度学习作业带来较高的网络IO开销。为了解决该问题,我们基于JuiceFS在开源项目Paddle Operator中实现了样本缓存组件,大幅提升了云上飞桨分布式训练作业的执行效率。
*Paddle Operator:
https://github.com/PaddleFlow/paddle-operator
数据集及其管理操作的自定义资源抽象。将样本数据集及其管理操作抽象成Kubernetes的自定义资源,屏蔽数据操作的底层细节,减轻用户心智负担。用户可以很方便地通过操作自定义资源对象来管理数据,包括数据同步、数据预热、清理缓存、淘汰历史数据等,同时也支持定时任务。
基于JuiceFS加速远程数据访问。JuiceFS是一款面向云环境设计的高性能共享文件系统,其在数据组织管理和访问性能上进行了大量针对性的优化。基于JuiceFS实现样本数据缓存引擎,能够提供高效的文件访问性能。
充分利用本地存储,缓存加速模型训练。要能够充分利用计算集群本地存储,比如内存和磁盘,来缓存热点样本数据集,并配合缓存亲和性调度,在用户无感知的情况下,智能地将作业调度到有缓存的节点上。这样就不用反复访问远程存储,从而加速模型训练速度,一定程度上也能提升GPU资源的利用率。
统一数据接口,支持多种存储后端。样本缓存组件要能够支持多种存储后端,并且能提供统一的POSIX协议接口,用户无需在模型开发和训练阶段使用不同的数据访问接口,降低模型开发成本。同时样本缓存组件也要能够支持从多个不同的存储源导入数据,适配用户现有的数据存储状态。
面临的挑战
Kubernetes 调度器是缓存无感知的,也就是说kube-scheduler并没有针对本地缓存数据的调度策略,因此模型训练作业未必能调度到有缓存的节点,从而导致缓存无法重用。如何实现缓存亲和性调度,协同编排训练作业与缓存数据,是我们面临的首要问题。
在数据并行的分布式训练任务中,单机往往存放不下所有的样本数据,因此样本数据是要能够以分区的形式分散缓存在各计算节点上。然而,我们知道负责管理自定义资源的控制器(Controller Manager)不一定运行在缓存节点上,如何通过自定义控制器来管理分布式的缓存数据,也是实现该方案时要考虑的难点问题。
除了前述两点,如何结合飞桨框架合理地对样本数据进行分发和预热,提高本地缓存命中率,减少作业访问远程数据的次数,从而提高作业执行效率,这还需要进一步的探索。
整体设计方案
1.自定义API资源(Custom Resource)
2.自定义控制器(Controller Manager)
控制器在 Kubernetes 的 Operator 框架中是用来监听 API 对象的变化(比如创建、修改、删除等),然后以此来决定实际要执行的具体工作。
PaddleJob Controller负责管理PaddleJob的生命周期,比如创建参数服务器和训练节点的Pod,并维护工作节点的副本数等。
SampleSet Controller负责管理SampleSet的生命周期,其中包括创建 PV/PVC等资源对象、创建缓存运行时服务、给缓存节点打标签等工作。
SampleJob Controller负责管理SampleJob的生命周期,通过请求缓存运行时服务的接口,触发缓存引擎异步执行数据管理操作,并获取执行结果。
3.缓存引擎(Cache Engine)
难点突破与优化
在上述的整体架构中,Cache Runtime Server是非常重要的一个组件,它由Kubernetes原生的API资源StatefulSet实现,在每个缓存节点上都会运行该服务,其承担了缓存数据分区管理等工作,也是解决难点问题的突破口。下图是用户创建SampleSet后,Paddle Operator对PaddleJob完成缓存亲和性调度的大概流程。
使用示例
apiVersion: batch.paddlepaddle.org/v1alpha1
kind: SampleSet
metadata:
name: imagenet
namespace: paddle-system
spec:
# 分区数,一个Kubernetes节点表示一个分区
partitions: 2
source:
uri: bos://paddleflow-public.hkg.bcebos.com/imagenet
secretRef:
name: imagenet
通过kubectl apply -f命令可以创建该样本数据集,您还可以查看样本数据集及其缓存的状态:
apiVersion: batch.paddlepaddle.org/v1
kind: PaddleJob
metadata:
name: resnet
spec:
# 指定要使用的 SampleSet
sampleSetRef:
name: imagenet
mountPath: /data
worker:
replicas: 2
template:
spec:
containers:
- name: resnet
image: registry.baidubce.com/paddle-operator/demo-resnet:v1
command:
- python
args:
- "-m"
- "paddle.distributed.launch"
- "./tools/train.py"
- "-c"
- "./config/ResNet50.yaml"
resources:
limits:
nvidia.com/gpu: 2
性能测试
总结及展望
欢迎大家进群,一起学习交流~
飞桨官方QQ群:441226485
推理部署官方QQ群:959308808
ERNIE QQ群:958422639
PaddleX QQ群:957286141
PaddleParl QQ群:483490828
在Kubernetes的架构体系中,计算与存储是分离的,这给数据密集型的深度学习作业带来较高的网络IO开销。为了解决该问题,我们基于JuiceFS在开源项目Paddle Operator中实现了样本缓存组件,大幅提升了云上飞桨分布式训练作业的执行效率。
*Paddle Operator:
https://github.com/PaddleFlow/paddle-operator
数据集及其管理操作的自定义资源抽象。将样本数据集及其管理操作抽象成Kubernetes的自定义资源,屏蔽数据操作的底层细节,减轻用户心智负担。用户可以很方便地通过操作自定义资源对象来管理数据,包括数据同步、数据预热、清理缓存、淘汰历史数据等,同时也支持定时任务。
基于JuiceFS加速远程数据访问。JuiceFS是一款面向云环境设计的高性能共享文件系统,其在数据组织管理和访问性能上进行了大量针对性的优化。基于JuiceFS实现样本数据缓存引擎,能够提供高效的文件访问性能。
充分利用本地存储,缓存加速模型训练。要能够充分利用计算集群本地存储,比如内存和磁盘,来缓存热点样本数据集,并配合缓存亲和性调度,在用户无感知的情况下,智能地将作业调度到有缓存的节点上。这样就不用反复访问远程存储,从而加速模型训练速度,一定程度上也能提升GPU资源的利用率。
统一数据接口,支持多种存储后端。样本缓存组件要能够支持多种存储后端,并且能提供统一的POSIX协议接口,用户无需在模型开发和训练阶段使用不同的数据访问接口,降低模型开发成本。同时样本缓存组件也要能够支持从多个不同的存储源导入数据,适配用户现有的数据存储状态。
面临的挑战
Kubernetes 调度器是缓存无感知的,也就是说kube-scheduler并没有针对本地缓存数据的调度策略,因此模型训练作业未必能调度到有缓存的节点,从而导致缓存无法重用。如何实现缓存亲和性调度,协同编排训练作业与缓存数据,是我们面临的首要问题。
在数据并行的分布式训练任务中,单机往往存放不下所有的样本数据,因此样本数据是要能够以分区的形式分散缓存在各计算节点上。然而,我们知道负责管理自定义资源的控制器(Controller Manager)不一定运行在缓存节点上,如何通过自定义控制器来管理分布式的缓存数据,也是实现该方案时要考虑的难点问题。
除了前述两点,如何结合飞桨框架合理地对样本数据进行分发和预热,提高本地缓存命中率,减少作业访问远程数据的次数,从而提高作业执行效率,这还需要进一步的探索。
整体设计方案
1.自定义API资源(Custom Resource)
2.自定义控制器(Controller Manager)
控制器在 Kubernetes 的 Operator 框架中是用来监听 API 对象的变化(比如创建、修改、删除等),然后以此来决定实际要执行的具体工作。
PaddleJob Controller负责管理PaddleJob的生命周期,比如创建参数服务器和训练节点的Pod,并维护工作节点的副本数等。
SampleSet Controller负责管理SampleSet的生命周期,其中包括创建 PV/PVC等资源对象、创建缓存运行时服务、给缓存节点打标签等工作。
SampleJob Controller负责管理SampleJob的生命周期,通过请求缓存运行时服务的接口,触发缓存引擎异步执行数据管理操作,并获取执行结果。
3.缓存引擎(Cache Engine)
难点突破与优化
在上述的整体架构中,Cache Runtime Server是非常重要的一个组件,它由Kubernetes原生的API资源StatefulSet实现,在每个缓存节点上都会运行该服务,其承担了缓存数据分区管理等工作,也是解决难点问题的突破口。下图是用户创建SampleSet后,Paddle Operator对PaddleJob完成缓存亲和性调度的大概流程。
使用示例
apiVersion: batch.paddlepaddle.org/v1alpha1
kind: SampleSet
metadata:
name: imagenet
namespace: paddle-system
spec:
# 分区数,一个Kubernetes节点表示一个分区
partitions: 2
source:
uri: bos://paddleflow-public.hkg.bcebos.com/imagenet
secretRef:
name: imagenet
通过kubectl apply -f命令可以创建该样本数据集,您还可以查看样本数据集及其缓存的状态:
apiVersion: batch.paddlepaddle.org/v1
kind: PaddleJob
metadata:
name: resnet
spec:
# 指定要使用的 SampleSet
sampleSetRef:
name: imagenet
mountPath: /data
worker:
replicas: 2
template:
spec:
containers:
- name: resnet
image: registry.baidubce.com/paddle-operator/demo-resnet:v1
command:
- python
args:
- "-m"
- "paddle.distributed.launch"
- "./tools/train.py"
- "-c"
- "./config/ResNet50.yaml"
resources:
limits:
nvidia.com/gpu: 2
性能测试
总结及展望
欢迎大家进群,一起学习交流~
飞桨官方QQ群:441226485
推理部署官方QQ群:959308808
ERNIE QQ群:958422639
PaddleX QQ群:957286141
PaddleParl QQ群:483490828