阿里云CPFS全栈自研高性能存储:AI训练成本降低69%的工程实践
1. 从存储吃掉一半预算说起CPFS到底在解决什么问题做过大模型训练的人都有一个共同体会算力账单虽然贵但真正让人肉疼的往往是存储。一个千亿参数级别的模型训练数据集动辄几十TB到上百TBcheckpoint每几百步就要落一次盘每个checkpoint又是几百GB起步。GPU集群跑起来之后计算卡在等数据、数据加载器卡在IO、checkpoint写入把带宽打满——这些场景叠加在一起存储层的压力比很多人想象的要大得多。阿里云这次发布的新一代全栈自研高性能存储CPFS官方给出的核心数字是降低AI存储成本69%。这个数字背后其实对应着一个非常具体的工程问题AI训练场景下的存储既要求极高的吞吐和极低的延迟又要求成本能压到大规模长期训练可以承受的水平。这两件事在传统存储架构里是矛盾的——要性能就上全闪成本立刻起飞要成本就上机械盘或对象存储吞吐和延迟又扛不住。CPFS的全称是Cloud Parallel File System也就是云上并行文件系统。它不是一个新名字但新一代全栈自研这几个字是关键。所谓全栈自研指的是从底层存储引擎、网络协议栈、客户端到上层数据加速层都是自己做的而不是拼装开源组件或者依赖第三方。这一点对AI场景特别重要因为AI负载的IO模式和传统企业应用完全不同通用存储方案很难在成本和性能之间找到那个甜点。这篇文章我想从一线使用者的角度把CPFS这类高性能存储到底怎么帮AI训练省钱、省在哪些环节、实际落地时要注意什么尽量讲透。不管你是正在搭训练集群的算法工程师还是负责存储选型的运维或者是想搞清楚为什么存储能省69%这个数字怎么来的技术管理者下面这些内容应该都能对上你的需求。2. AI训练的IO画像为什么通用存储在这里会水土不服2.1 训练负载的三种典型IO模式要把存储成本讲清楚得先搞清楚AI训练到底在读写什么。我把它归纳成三类这三类的特征差异极大混在一起用一套存储策略必然出问题。第一类是顺序大块读。训练数据在预处理之后通常会被打包成类似TFRecord、WebDataset或者Parquet这样的分片文件每个分片几百MB到几GB。训练时DataLoader按顺序把这些分片读进来这是典型的顺序大块读吞吐要求高但对单次延迟不敏感。这类负载其实用高吞吐的并行文件系统或者对象存储都能扛。第二类是随机小文件读。这个在NLP和多模态场景里特别常见——原始语料是几百万甚至上千万个小文件tokenize之后如果没做好合并训练时就是海量随机小IO。这种负载对元数据服务metadata service的压力极大传统POSIX文件系统在这里往往直接跪掉因为每次open/stat都要走一次元数据查询。第三类是周期性大块写。这就是checkpoint。训练每隔N步就要把整个模型状态写下来几百GB到几TB不等写入时带宽瞬间打满写完又要立刻能读回来做恢复验证。这类负载的特点是突发性极强对写入带宽和持久化延迟要求都很高。2.2 通用存储在AI场景下的三个贵理解了IO画像就能明白为什么通用存储在AI训练里会显得又贵又慢。贵在过度配置。为了扛住checkpoint的突发带宽很多团队直接上全闪阵列但全闪在大部分训练时间里其实是闲置的——数据加载阶段用不到那么高的IOPScheckpoint又不是每时每刻都在写。为了那10%时间的峰值付了100%的全闪成本这是最常见的浪费。贵在元数据瓶颈导致的算力空转。小文件随机读把元数据服务打满之后GPU利用率会掉到30%甚至更低。这时候你付的是GPU的钱但GPU在等IO。算力空转的成本往往比存储本身还高只是它不出现在存储账单上容易被忽略。贵在数据搬运。很多团队的训练数据放在对象存储训练前要先下载到本地盘或者并行文件系统训练完checkpoint又要传回对象存储归档。这一来一回的搬运既消耗网络带宽又要额外准备中转存储整体TCO被拉高。CPFS这类方案的核心思路就是针对这三类IO分别做优化而不是用一套通用策略硬扛所有场景。3. 全栈自研的含金量从存储引擎到客户端的每一层都在为AI让路3.1 并行文件系统的并行到底并行在哪很多人对并行文件系统的理解停留在多个客户端能同时读写这其实只说对了一半。真正的并行体现在两个层面数据面的并行和元数据面的并行。数据面上一个文件会被切分成多个chunk分散到多个存储节点上客户端读写时同时和多个节点通信聚合带宽。这是Lustre、GPFS这些传统并行文件系统的老思路。CPFS在这一层的关键改进是chunk的分布策略和客户端缓存策略——针对AI的顺序大块读它会把连续数据尽量放在同一批节点上减少跨节点跳转针对checkpoint的大块写它会做写入聚合避免小包频繁落盘。元数据面上传统方案是一个中心化的MDSMetadata Server所有open/stat/lookup都打到它身上小文件一多就成瓶颈。CPFS的做法是元数据分片加分布式锁把命名空间切成多个分区每个分区独立处理元数据请求。这样小文件随机读的吞吐能线性扩展而不是卡在单点。3.2 客户端为什么是自研的关键一环存储系统再强客户端拖后腿也白搭。AI训练里客户端就是每台GPU服务器上的挂载进程它的效率直接决定了GPU能不能吃满数据。自研客户端能做的事情通用客户端做不了。比如预读策略——训练是顺序读客户端可以提前把后面的数据拉进本地缓存GPU要的时候直接命中。再比如写回聚合——checkpoint写入时客户端先在本地把小块聚合成大块再发出去减少网络往返。还有多路径并发——同时走多张网卡、多条链路把单机带宽打满。这些优化听起来简单但要和上层训练框架PyTorch的DataLoader、TensorFlow的tf.data配合好需要客户端能感知到应用的IO模式。这就是全栈自研的价值从应用到存储中间没有黑盒每一层都能针对性调优。3.3 成本69%是怎么算出来的官方说的降低69%我理解主要来自三个方面的叠加。一是分层存储。热数据正在训练用的放高性能层温数据近期可能用到的checkpoint放容量层冷数据归档的历史版本放低成本层。自动分层之后不需要所有数据都占着最贵的介质。这一块通常能省30%到40%。二是元数据优化带来的算力利用率提升。小文件场景下GPU利用率从30%提到70%等于同样的算力能干两倍多的活摊到单位训练任务上的综合成本大幅下降。这部分省的不是存储钱是算力钱但算在总账里非常可观。三是减少数据搬运。训练数据直接放在CPFS上checkpoint也直接落CPFS省掉了对象存储和文件系统之间的来回搬运以及为此准备的中转存储。这部分省的是网络和额外存储的开销。三个因素叠加69%这个数字在特定场景下是能对上的。当然具体到每个团队能省多少取决于原来的架构有多浪费——原来全闪硬扛的省得最多原来已经做了分层的边际收益就小一些。4. 落地实操把CPFS接进现有训练流水线的几个关键动作4.1 数据预处理阶段的格式选择CPFS再快也救不了格式没做好的数据。我的经验是在数据进入CPFS之前一定要做一次格式合并。具体做法是把海量小文件合并成中等大小的分片每个分片控制在256MB到1GB之间。太小了元数据压力大太大了单次读取的启动延迟高而且不利于shuffle。合并的时候用WebDataset的tar格式或者TFRecord都行关键是每个分片里包含足够多的样本让顺序读能连续跑起来。如果原始数据实在没法合并比如需要按样本随机访问那就得靠CPFS的元数据分片能力硬扛但这时候要监控元数据服务的QPS别等到打满了才发现。4.2 挂载参数与客户端调优CPFS挂载到GPU服务器上之后有几个参数值得调。# 典型的CPFS挂载命令示意具体参数以官方文档为准 mount -t cpfs -o rsize1048576,wsize1048576,readahead16, \ max_readahead32,prototcp,timeo600,retrans2 \ cpfs_endpoint:/share /mnt/cpfsrsize和wsize设大一点减少单次IO的次数。readahead控制预读窗口顺序读场景可以调大。这些参数不是越大越好要结合你的数据块大小和网络带宽来定——预读窗口太大会把客户端内存吃光反而影响训练进程。还有一个容易忽略的点是客户端缓存目录的位置。如果本地有NVMe盘把缓存目录指到NVMe上顺序读的命中率会明显提升。但要注意缓存一致性多机训练时不同节点看到的缓存可能不同步涉及写操作时要小心。4.3 checkpoint写入的节奏控制checkpoint是存储压力最大的时刻也是最容易出问题的地方。我的建议是错峰写入。如果有多机多卡训练不要让所有rank同时写checkpoint。可以让rank 0先写写完通知其他rank或者用异步写入的方式训练继续跑checkpoint在后台落盘。CPFS支持并发写但并发写同一个文件需要应用层做协调不然会互相覆盖。另外checkpoint的保留策略要提前定好。很多团队是每N步存一个存了几百个版本占了几百TB空间其实大部分永远不会被读回来。建议只保留最近几个版本加热备老的自动转冷或者删掉。这一条执行下去存储成本立刻降一截。4.4 监控指标要看哪些接进生产之后有几个指标必须盯着。指标含义健康范围参考客户端读带宽单节点从CPFS读数据的速度接近网卡线速的70%以上元数据QPS每秒元数据操作数低于元数据服务标称上限的60%GPU利用率训练时GPU实际计算占比稳定在70%以上checkpoint写入耗时单次checkpoint落盘时间不超过训练步间隔的1/3缓存命中率客户端预读命中比例顺序读场景应高于80%GPU利用率是最直观的指标。如果它长期低于50%而算力本身没问题那基本可以断定是IO拖了后腿这时候就要回头查存储侧的带宽和延迟。5. 踩过的坑与真实体感CPFS不是银弹但这些场景它确实能打5.1 小文件没合并直接上元数据照样崩我见过一个团队兴冲冲把上千万个小文件的语料直接扔到CPFS上开训结果元数据QPS直接打满训练速度比原来还慢。问题不在CPFS在于他们跳过了数据预处理这一步。并行文件系统的元数据分片能扛住比传统方案高得多的并发但不是无限的。小文件该合并还是要合并这是铁律。5.2 缓存目录放在系统盘把根分区写满了客户端缓存默认可能落在系统盘训练跑一段时间之后缓存膨胀把根分区写满机器直接hang住。这个坑很隐蔽因为训练进程本身没报错是系统层面的问题。解决办法很简单挂载时显式指定缓存目录到大容量数据盘并且设置缓存上限。5.3 多机训练时checkpoint互相覆盖这个坑出在应用层。多个rank同时写同一个checkpoint文件如果没有协调机制后写的会覆盖先写的恢复的时候模型状态是错的。正确做法是每个rank写自己的分片最后合并或者只让rank 0写其他rank等待。CPFS本身不解决这个问题得靠训练框架的checkpoint逻辑来保证。5.4 分层策略没配好热数据被误判成冷数据自动分层依赖访问频率的统计如果统计窗口设得太短刚写入还没被读过的checkpoint可能被判定为冷数据转到低成本层结果下次恢复时读回来特别慢。分层策略的窗口期要根据实际训练节奏来定一般建议至少覆盖一个完整的checkpoint周期。5.5 网络带宽是隐藏瓶颈CPFS的性能再高如果GPU服务器到存储的网络带宽不够照样跑不满。特别是checkpoint写入时如果多台机器同时写汇聚到存储端的网络可能成为瓶颈。规划的时候要算清楚单机需要多少读带宽、多少写带宽乘以机器数再留30%余量这才是网络该有的规格。6. 这套方案适合谁以及选型时的几个判断点CPFS这类高性能存储不是所有团队都需要。如果你的训练数据只有几个GB或者模型小到单卡就能跑那用普通云盘甚至本地盘就够了上CPFS是杀鸡用牛刀。但如果符合下面几条中的两条以上就值得认真考虑训练数据超过10TB有多机多卡集群checkpoint频繁且体积大GPU利用率长期上不去怀疑是IO问题存储成本在总预算里占比超过20%。选型的时候我建议重点看三个东西。一是元数据能力问清楚元数据服务的QPS上限和扩展方式这决定了小文件场景能不能扛。二是分层策略的灵活性能不能按目录、按文件类型、按访问频率自定义分层规则而不是只有一套默认策略。三是客户端兼容性能不能无缝挂载到现有的训练环境需不需要改训练代码这直接影响落地成本。最后说一句体感存储这个东西平时不出问题的时候没人注意一出问题就是全局性的。CPFS把AI场景的IO特征吃透之后做针对性优化方向是对的。但再好的存储也需要使用者在数据格式、挂载参数、checkpoint策略上配合好才能把性能真正释放出来。工具是一半用法是另一半。
上一篇/下一篇内容由系统自动关联
返回资讯列表 →