MLM+NSP微调场景下TextDatasetForNextSentencePrediction内存与缺__len__报错咨询
首先修正数据集基类继承关系
你当前自定义的类继承的是PyTorch普通Dataset(映射式数据集),这类数据集要求必须实现__getitem__和__len__方法,天生不适合流式场景。你需要把继承的基类改为IterableDataset(迭代式数据集),这类数据集专门面向流式数据生成场景,仅需要实现__iter__方法即可,Hugging Face Trainer对该类数据集做了适配,只要正确设置max_steps就不会强制校验__len__属性,也不会主动调用len()方法触发报错。修正
__iter__方法的定义错误
你当前代码里的__iter__方法多了一个多余的输入参数i,需要修改为:
def __iter__(self): yield from self.create_documents_with_batching()
合理设置
max_steps参数
无需将max_steps设为极大值,你可以提前抽1-2GB的样本数据跑一遍统计单位数据量生成的样本数,再乘以你的总数据集大小得到预估的总训练样本数,除以梯度累积步长和批次大小就能得到合理的max_steps值,训练到指定步数会自动终止。
如果需要完全匹配总数据量,也可以提前离线遍历一次数据集统计总样本数,将结果存在一个小的元数据文件中,在数据集类的__init__方法中读取该值,额外实现一个__len__方法直接返回该值即可,全程不需要加载全量数据到内存。可选优化:负采样适配
你当前的实现里NSP负样本只会从当前加载的文档批次内选取,如果批次大小设置的足够大(如你代码里默认的10240),对训练效果影响极小。如果需要全局负采样,可以提前离线统计所有文档的文件偏移量建立索引,采样时通过偏移量读取对应文档即可,不需要全量加载数据。
注意:如果使用多进程加载数据,需要给IterableDataset添加worker_init_fn处理数据分片,避免不同进程读取到重复的样本。
内容的提问来源于stack exchange,提问作者Prasanna

