作者简介
吕冬冬
云知声超算平台架构师, 负责大规模分布式机器学习平台架构设计与功能研发,负责深度学习算法应用的优化与 AI 模型加速。研究领域包括高性能计算、分布式文件存储、分布式缓存等。有多年的云原生开源社区经验。
刘青松
云知声算法研究员,负责机器学习平台和应用算法研发,研究领域包括云原生架构研究、高性能计算、语音和视觉应用、机器学习算法等。
Atlas平台介绍
云知声,是一家专注物联网人工智能服务公司。云知声的 AI 技术栈涵盖了信号、语音、图像、文本的感知和表达能力,知识、理解、分析、决策等认知技术,并朝着多模态人工智能系统方向发展。云知声 Atlas 超算平台作为底层基础架构,支持着公司在 AI 各个领域的模型训练与推理服务的开展。云知声很早就开始布局建设业界领先的 GPU/CPU 异构 Atlas 计算平台和分布式文件存储系统,该计算集群可为 AI 计算提供高性能计算和海量数据的存储访问能力。云知声团队基于 Kubernetes 开源架构之上,进行了相应的核心功能研发,成功构建了浮点处理能力超过10 PFLOPS(一亿亿次/秒)的 AI 超级计算服务平台。该平台支持主流机器学习架构,开发者能够实现语音、语言、大数据、多模态等核心技术的高效研发。平台也开放了相应的算力与存储,为中小微企业和院校机构提供定制化计算服务。
问题与挑战
Atlas 计算平台采用是计算与存储分离的架构,目前整个平台的存储服务器、计算服务器之间以及计算与存储服务器之间的底层网络架构是由 100GB 的 InfiniBand 进行互联。
计算平台的模型训练数据存储系统由多套 PB 量级的高性能分布式文件系统 Lustre 组成。Lustre 分布式文件系统兼容 POSIX 接口,多种深度学习框架能够直接进行数据读取。计算与存储分离的架构使计算跟存储能够独立进行扩容,整体架构较为灵活。但是之前平台也遇到了数据访问效率低与底层存储带宽瓶颈等问题:
存储带宽瓶颈
在存储资源相对固定的情况下,随着平台用户的增加,其带宽、元数据负载以及服务器的负载都呈现出来较大的上升。集群存在多个单机任务运行在同一个 GPU 节点,造成 IO 资源的竞争,由于 IO 的竞争导致了整个训练周期拉长了,大大降低了研发影响效率。
海量小文件
第二个问题是模型训练数据集本身的特点问题。在降噪场景中有用户的任务存在接近 TB 量级的小文件,导致底层分布式文件系统的的元数据服务压力很大。大量的小文件使得程序本身读数据的效率较低,数据读取缓慢造成 GPU 大部分时间在等数据,整体 GPU 的整体利用率较低,延长了模型的训练周期。
数据种类多
由于平台支持的业务类型较广,用户的数据类型较多,文件大小类型也不同,很难通过调优一套存储的参数来适配多种业务类型。结合用户的业务类型分析,我们发现平台数据主要还是用来做模型训练占的比重比较大,其余部分主要进行模型的推理与 CPU 密集型数据生成任务。
数据冗余
在平台中存在数据集重叠的问题,同一个组内或者不同组有使用到相同的数据集,但是却存储了多份,造成了存储空间的浪费。
早期解决方案
如何通过最小的预算与架构改动来应对存储总带宽的瓶颈以及减少元数据服务器的压力,云知声 Atlas 也进行一系列的探索与研发。
带宽限制
考虑到大量的并发读取会造成存储带宽达到极限,造成存储卡顿或者存储系统瘫痪。平台通过限制每个计算节点的客户端带宽以及每个用户的 UID/GID 限制带宽,但是该方法存在不够灵活、没办法充分利用 GPU 的计算能力的问题,当有 2 个大 IO 的训练任务分配到了同一个节点,由于节点的带宽限制,2个训练任务的 IO 都有上限,数据读取的速度限制导致 GPU 没办法充分发挥并行读取的优势,通过监控发现该类型的 GPU 利用率在 40% 左右,严重浪费了硬件资源。
聚合大文件
考虑到平台的小文件太多,会对元数据造成较大的压力,我们进行了相应的措施,首先通过检测每个用户的 inode 数量与存储总量判断用户的小文件数量,限制用户小文件的数量。第二是推行一系列数据聚合的工具,让用户将小文件聚合成 lmdb、tfrecord 之类的大文件格式。
任务调度器重构
为了避免任务都聚集在同一个节点上,我们通过定制任务调度器插件,增加调度策略,判断节点的计算资源的使用情况,优先将任务调度到空闲节点,避免多个任务跑在同一个节点造成的 IO 竞争,但是该方案在平台的计算资源出现满载的情况下还是不可避免。
多级缓存
为了充分利用空闲的硬件以及减轻底层存储系统的压力,在最早期平台研发了第一版本的缓存方案作做为过渡。该方法能够一定程度缓解存储的压力,但是其对于数据的管理还是不够自动化,这只能作为我们过渡到新架构的一个临时替代解决的方案。
全新的架构
云知声在 2020 年开始调研 Alluxio并进行了一系列的测试,包括功能的适配与性能测试等,发现 Alluxio 能够满足目前云知声需求,能够较为快速并且以较低的成本解决我们存在的几个痛点:
· Alluxio Fuse 提供了 POSIX 文件系统接口,用户能够无缝的使用分布式缓存,程序无需做更改;
· Alluxio 支持对多种文件系统的支持,包括分布式文件系统、对象存储等,当我们平台后续引入新的存储,Alluxio 缓存都能很好的进行支持,保证我们整个缓存架构的稳定性;
· Alluxio 提供较好的缓存管理,Alluxio 的层次化存储机制能够充分利用内存、固态硬盘或者磁盘,降低具有弹性扩张特性的数据驱动型应用的成本开销;
· 支持以 Kubernetes 或者容器的方式部署到平台中,与现有的技术栈较为一致;
· Alluxio 提供了 HA 支持,保证了分布式缓存系统的高可用性
相比早前的计算与存储分离的架构,Alluxio 在计算与存储之间引入一层 Cache 层,将底层存储的压力转移到各个计算节点的内存或者本地硬盘中,用户的任务能享受本地存储带来的速度提升优势,整个平台能够兼容分布式文件系统与本地硬盘两者的优势。
在使用 Alluxio 进行业务端整合时,我们遇到了权限控制、以及数据挂载等问题。Fluid 提供了一种更加云原生的方式来使用 Alluxio, 其提供了一种全新的数据集管理方式,缓存数据集跟云原生的资源一样,能够被 kubernetes 进行相应的分配与调度,有效的解决早期缓存与 kubernetes 使用方式独立的问题。
最终我们的架构是使用 Alluxio 作为 Fluid 的缓存加速引擎,其负责做底层分布式文件系统到计算节点本地缓存介质的数据迁移以及缓存的管理,为平台的应用程序提供了数据加速的功能。而 Fluid 负责缓存与应用的编排,基于 Fluid,平台能够感知缓存,将之前需要很多人工的缓存操作,转移到平台层智能化处理。
引入新架构后,我们在自研的模型训练任务提交工具 atlasctl 将 fluid 功能进行集成,尽可能的为用户屏蔽一些复杂的概念,用户通过 atlasctl cache create 并指定添加一些参数信息例如缓存的大小,缓存介质等即可创建缓存数据集。该工具的集成为用户屏蔽了负载的缓存机制信息,让他们更加关注与数据与业务本身。