深度学习大内存数据集:单样本存储VS分块存储方案抉择
大规模多受试者分类器训练的数据集IO方案推荐
问题背景
我正在训练一个分类器,数据来自多个数据集,每个数据集包含多名受试者,每名受试者完成了多组trial。当前磁盘数据结构为:
dataset1_subject1.ptdataset1_subject2.pt- ...
datasetN_subjectX.pt
每个.pt文件通过torch.load()加载后是形状为n_trials, n_channel, n_time的张量,但整体数据集过大无法全部载入内存,且要求每个batch必须包含来自多名受试者的样本。
现有备选方案与疑问
已了解的两种方案
- 分块加载:加载部分数据打乱后分成大块,每次载入一块到内存,采样耗尽后再加载下一块。优点是加载速度快;缺点是交叉验证难度高,每次拆分都要重新生成块。
- 单样本拆分存储:将每个受试者的张量拆成单个trial文件(如
ds1_subject1_sample001.pt),预计生成77k个文件,再通过HDF5或内存映射实现懒加载,但不清楚二者差异。
核心疑问
- 使用HDF5是否必须拆分为单个trial?能否在不载入整个受试者数据的前提下抽取单个trial?
- 目前倾向于拆成77k个单文件并打包成.tar格式,同时了解到PyTorch高效IO库支持多GPU训练,想请教最优方案及经验分享。
推荐方案及实操经验
优先推荐:PyTorch高效IO库
针对你的多GPU训练需求,这个库是最优选择:
- 天然支持懒加载和多进程数据加载,无需手动处理分块或单文件拆分的繁琐逻辑
- 可直接基于现有
.pt文件构建数据集,通过自定义采样器实现跨受试者的batch采样(比如每次从不同受试者的文件中抽取trial) - 交叉验证时只需调整采样器的拆分规则,无需重新生成数据块,完美解决分块加载的痛点
HDF5方案优化(无需拆单trial)
不用拆成单个trial文件,直接把每个受试者的数据存入HDF5的一个数据集(如/dataset1/subject1),利用HDF5的随机访问特性:
- 加载时通过索引直接读取单个trial(如
h5_file['/dataset1/subject1'][trial_idx]),无需载入整个受试者的张量 - 相比77k个小文件,HDF5单文件(或按数据集分几个大HDF5文件)能大幅减少磁盘IO开销,避免小文件爆炸的问题
- 内存映射(mmap)是HDF5的默认加载方式之一,数据会按需载入内存,不会一次性占满内存
不推荐:拆成77k个单文件打包成.tar
虽然.tar能整合文件,但单个小文件的IO效率依然很低,多进程加载时会出现大量磁盘寻址开销,反而拖慢训练速度;而且后续维护、修改数据的成本极高,远不如HDF5或PyTorch IO库灵活。
实操建议
- 优先选PyTorch IO库的实现方式:
- 先遍历所有
.pt文件,记录每个文件对应的受试者、数据集信息,以及该文件包含的trial数量 - 自定义采样器,每次采样时随机选择不同的文件,再随机抽取该文件中的一个trial
- 用
DataLoader开启多进程加载,每个进程负责加载单个文件并抽取trial,避免内存溢出
- 先遍历所有
- 追求极致IO效率选HDF5:
- 按数据集创建HDF5文件(如
dataset1.h5),每个受试者对应一个数据集,存储其n_trials, n_channel, n_time的张量 - 训练时通过HDF5的随机访问读取单个trial,配合PyTorch的
Dataset和DataLoader实现批量采样
- 按数据集创建HDF5文件(如
内容的提问来源于stack exchange,提问作者Samuel
相关产品推荐
相关产品推荐

