随着近几年深度学习的蓬勃发展,越来越多的团队开始遇到了单机存储的瓶颈,分布式存储在 AI 领域的重要性不断凸显。AI 团队通常会面临以下几种问题:
数据集太大
历史数据集需要进行全量归档
小文件和非结构化数据太多
训练框架需要 POSIX 接口
公共数据集需要不同团队共享,也可能需要数据隔离
云上训练的数据 I/O 效率不高
本文将会介绍在模型训练中如何使用 JuiceFS,以及优化训练效率的实践。
1.JuiceFS 在模型训练场景中的架构
第一部分:元数据引擎,根据个人选择,可以使用任何数据库,例如 Redis、MySQL 等等,作为元数据引擎。
第三部分:JuiceFS 客户端,用户在使用时需要在每个 GPU 和计算节点上挂载 JuiceFS,这样就可以像访问本地硬盘一样访问 JuiceFS 的文件系统。
如果进行单机模型训练,在首轮训练时,训练集或数据集通常不会命中缓存。但是从第二轮开始,在缓存资源充足的情况下,几乎不需要访问对象存储,达到加速数据 I/O 的效果。
JuiceFS 读写缓存流程
此处,了解评测结果)
当应用程序发起读请求后,请求会先进入左侧的内核空间,内核会查看内核页缓存中是否有请求的数据。如果内核页缓存中没有数据,请求会回到用户空间的 JuiceFS 进程。在用户空间,JuiceFS 进程会处理所有的读写请求。
举个例子,当访问一个文件的一部分数据时,JuiceFS 只会缓存该部分数据对应的 4MB 块到本地缓存目录中,而不会缓存整个文件。这是 JuiceFS 与其他文件系统或缓存系统的显著差异之一。
当本地盘数据读取完成后,数据还会进入内核页缓存。这是因为如果没有使用 direct I/O,Linux 系统默认会将数据存储在内核页缓存中。这些内核页缓存都用于加速缓存访问,如果第一个请求直接命中并返回,那么效率是最高的,并且请求不会通过 FUSE 层进入用户态进程。如果没有命中,则会通过 index 查找,如果在节点目录中没有找到 block,则会通过网络请求到达对象存储,然后将数据读回来并原路返回给应用程序。
上图有一部分的模块叫 Chunk Cache,chunk 是 JuiceFS 中的一个逻辑概念,每个文件会按照 64MB 大小分为多个 chunk,来提升大文件的读取性能。这部分信息会被缓存到 JuiceFS 进程的内存里,来加速元数据访问的效率。
2.为什么训练太慢以及如何排查?
当使用 JuiceFS 进行训练时,性能是最重要的考虑因素,它直接影响到模型训练的速度。以下是可能影响 JuiceFS 效率的几个方面:
元数据引擎
对象存储
本地磁盘
网络带宽
内存
如何排查
JuiceFS 提供了许多工具和命令来帮助用户更好地进行性能调优和诊断。在去年的 Office Hours 中,已经对如何在 JuiceFS 中进行性能调优和诊断进行了全面介绍。如果感兴趣,可以在 B 站上观看视频回放。以下是其中几个方法的简要介绍:
工具1 :juicefs profile 命令
工具2:juicefs stats 命令
JuiceFS 还提供了更底层的信息分析工具,包括 CPU profile 和 heap profile。CPU profile 可以分析 JuiceFS 进程执行速度的瓶颈所在,适用于熟悉源代码的用户。而 heap profile 则主要用于分析内存占用情况,尤其是当 JuiceFS 进程占用大量内存时,需要使用 heap profile 来确定具体哪些函数或数据结构占用了较多内存。
3.一些常见的优化策略
元数据缓存优化
1)调整内核元数据缓存的超时时间
--attr-cache、--entry-cache
和 --dir-entry-cache
参数,这三个参数分别对应不同类型的元数据:attr 表示文件属性(如大小、修改时间、访问时间等),entry 是 Linux 中的概念,表示文件和相关属性,dir-entry 表示目录和其中包含的文件。
2)优化 JuiceFS 客户端的用户态元数据缓存
--open-cache 参数,并设置一个超时时间,以避免每次打开同一个文件都重复访问元数据引擎。另外可以通过 --open-cache-limit
参数控制缓存的最大文件数,默认值是 10000,即最多缓存最近打开的 10000 个文件的元数据在内存中,可以根据数据集的文件个数进行适当调整。
数据缓存
而本地数据缓存相对来说用户更加可控,可以根据具体场景调优缓存参数。首先,可以调整缓存的大小( --cache-size
),默认值为 100G,对于大部分场景都足够了。但是对于占用空间特别大的数据集,需要适当调整缓存大小,否则 100G 的缓存空间可能很快被写满,导致 JuiceFS 无法缓存更多数据。配合 --cache-size 参数一起使用的另一个参数是 --free-space-ratio
,这个参数用于控制缓存盘的空间空闲比例,默认值是 0.1,即最多使用 90% 的磁盘空间缓存数据。
缓存预热
为了提高训练效率,可以通过预热缓存来加速训练任务。JuiceFS 支持预热客户端中的元数据缓存和本地数据缓存,通过使用 juicefs warmup 命令可以将缓存提前预热到缓存盘,从而在训练任务开始时直接命中缓存,提高效率。
增大缓冲区大小
如有帮助的话欢迎关注我们项目 Juicedata/JuiceFS 哟! (0ᴗ0✿