人工智能大模型NLP深度学习预训练微调RLHF模型量化【免费下载链接】PaddleNLPEasy-to-use and powerful LLM and SLM library with awesome model zoo.项目地址https://gitcode.com/gh_mirrors/pa/PaddleNLP点击查看免费下载本指南围绕 PaddleNLP 的 dataset_self_defined.rst 展开系统讲解如何借助load_dataset、MapDataset、IterDataset三大利器将本地文件、paddle.io.Dataset/IterableDataset以及任意 Python 对象List、Tuple、生成器、HuggingFace Dataset 等转化为可直接参与模型训练的数据集。阅读本文后你将掌握自定义数据集的标准写法规约、lazy惰性加载的取舍、标签自动转 ID 的底层机制以及map/filter/shard等数据处理流水线 API能够从容应对序列标注、文本分类、阅读理解等任务的自有数据接入。一、三种自定义数据集的方式总览PaddleNLP 的数据集体系以两个核心类为骨架见 paddlenlp/datasets/dataset.pyMapDataset继承自paddle.io.Dataset基于__getitem__/__len__的随机访问式map-style数据集支持按下标索引样本IterDataset继承自paddle.io.IterableDataset基于__iter__的流式iterable-style数据集逐条产出样本。围绕它们PaddleNLP 提供了统一入口load_dataset。当传入的参数是一个自定义读取函数时源码会走inspect.isfunction(path_or_read_func)分支dataset.py#L187-L198内部用SimpleBuilder包装读取函数并返回对应的MapDataset或IterDataset。基于这一设计自定义数据集主要有三条路径数据来源推荐方式返回类型本地文件编写 reader 函数传入load_datasetMapDatasetlazyFalse或IterDatasetlazyTruepaddle.io.Dataset/IterableDataset直接包装进MapDataset/IterDataset对应 PaddleNLP 类型任意 Python 对象传入含__getitem__/__len__或__iter__的对象MapDataset/IterDataset无论哪条路径最终产出的都是MapDataset或IterDataset它们为后续的map、filter、shard等数据加工提供了统一 API。二、从本地文件创建数据集最推荐2.1 编写 reader 函数并交给 load_dataset当数据存储在本地文件中时PaddleNLP 推荐的做法是根据本地数据格式编写一个读取函数reader将其传给load_dataset。以典型的序列标注任务词与标签按\002分隔、每行一条样本、首行为表头为例from paddlenlp.datasets import load_dataset def read(data_path): with open(data_path, r, encodingutf-8) as f: # 跳过表头 next(f) for line in f: words, labels line.strip(\n).split(\t) words words.split(\002) labels labels.split(\002) yield {tokens: words, labels: labels} # data_path 是 read() 的参数 map_ds load_dataset(read, data_pathtrain.txt, lazyFalse) iter_ds load_dataset(read, data_pathtrain.txt, lazyTrue)这里有两条重要的书写规范用生成器generator实现读取逻辑。yield逐条产出样本既能在lazyFalse时一次性物化到内存也能在lazyTrue时保持流式语义——这一点从 dataset.py#L777-L788 的SimpleBuilder.read实现可以看得很清楚lazy 模式下直接包装生成器非 lazy 模式下才list(examples)。每个样本格式化为字典如{tokens: ..., labels: ...}。字典结构便于后续map流水线按字段处理也方便训练过程中监控数据流。SimpleBuilder在非 lazy 模式下还会检测对象是否具备__len__/__getitem__否则自动list化后包装dataset.py#L784-L788。事实上内置数据集msra_ner的读取逻辑就是这一写法的“官方模板”见 paddlenlp/datasets/msra_ner.py#L51-L63其_read方法同样以生成器方式逐行解析\t分隔、\002切分 tokens 与 tags 并yield字典。2.2 MapDataset 与 IterDataset 如何取舍多数场景下MapDataset即可满足需求数据量可控、支持按下标随机访问、便于打乱与多进程并行。只有当数据集大到无法一次性载入内存时才考虑使用IterDataset其逐条读取、内存占用恒定的特性适合超大规模语料。对应到load_dataset的参数上lazyFalse返回MapDatasetlazyTrue返回IterDatasetlazyNone使用数据集预设的默认类型内置DatasetBuilder通常默认MapDataset如 msra_ner.py#L65-L67 中MsraNer类默认lazy False。需要特别强调的是在自定义 reader 模式下lazy参数是必填的。源码中对应断言为assert lazy is not None, lazy can not be None in custom mode.dataset.py#L188因为自定义读取函数本身无法决定返回哪种数据集类型必须由调用方显式指定。同时reader 函数的其他参数会以关键字参数形式原样透传——load_dataset通过inspect.signature只筛选 reader 声明过的参数名dataset.py#L192-L195因此data_path之外的任何自定义参数都可以放心传递。2.3 关于标签自动转换的边界需要注意只有 PaddleNLP 内置数据集才支持自动的 label-to-id 转换详细条件可参考 how_to_write_a_DatasetBuilder.rst。对于上例这种自定义数据集必须在自己的特征转换方法里手动实现标签到 ID 的映射。内置数据集的自动转换机制是这样的DatasetBuilder.read会读取get_labels()返回的标签列表检测样本字典中的标签列键名必须是label或labels并自动将其替换为 IDdataset.py#L647-L736。例如MsraNer.get_labels()返回[B-PER, I-PER, B-ORG, I-ORG, B-LOC, I-LOC, O]msra_ner.py#L65-L67读取时每个labels字段就会自动映射为对应的整数。自定义数据集不具备该能力需要自己在map转换函数中完成或参照内置数据集的做法自行实现。三、从 paddle.io.Dataset / IterableDataset 创建paddle.io.Dataset与paddle.io.IterableDataset可以直接配合DataLoader训练但有时我们需要更方便的数据处理手段——例如特征转换、数据清洗、数据增强。PaddleNLP 内置的MapDataset/IterDataset恰好提供了这些 API。如果你习惯用paddle.io.Dataset/IterableDataset构建数据集只需用MapDataset或IterDataset把它们包一层即可完成转换。下面以MapDataset为例IterDataset用法完全类似from paddle.io import Dataset from paddlenlp.datasets import MapDataset class MyDataset(Dataset): def __init__(self, path): def load_data_from_source(path): ... ... return data self.data load_data_from_source(path) def __getitem__(self, idx): return self.data[idx] def __len__(self): return len(self.data) ds MyDataset(data_path) # paddle.io.Dataset new_ds MapDataset(ds) # paddlenlp.datasets.MapDataset包装完成后new_ds便拥有了map、filter、shard等 PaddleNLP 扩展方法见 dataset.py#L278-L397map(fn, lazyTrue, batchedFalse, num_workers0)对每个样本执行转换函数。lazyTrue时转换延迟到访问样本时才执行适合随机性转换如数据增强保证每个 epoch 结果不同batchedTrue时fn接收全部样本并返回一批转换结果num_workers1时启用多进程并行处理。filter(fn, num_workers0)用返回布尔值的函数过滤样本返回False的样本被丢弃。shard(num_shards, index, contiguousFalse)将数据集切分为多份默认按分布式训练的world_size与rank自动分片contiguousTrue时按连续块切分。四、从其他 Python 对象创建4.1 用 List / Tuple / DataFrame 创建 MapDataset理论上任何实现了__getitem__与__len__的 Python 对象都可以作为MapDataset的初始化参数包括List、Tuple、DataFrame等。看一个最小示例from paddlenlp.datasets import MapDataset data_source_1 [1, 2, 3, 4, 5] data_source_2 (a, b, c, d) list_ds MapDataset(data_source_1) tuple_ds MapDataset(data_source_2) print(list_ds[0]) # 1 print(tuple_ds[0]) # a从源码看MapDataset.__init__只是把数据源保存为self.data__getitem__在有转换流水线时先执行_transform再返回dataset.py#L252-L270因此任意支持下标访问与长度计算的对象都能无缝接入。4.2 用 List / Generator 创建 IterDataset同理任何实现了__iter__的 Python 对象都可以创建IterDataset例如List和生成器from paddlenlp.datasets import IterDataset data_source_1 [a, b, c, d] data_source_2 (i for i in range(5)) list_ds IterDataset(data_source_1) gen_ds IterDataset(data_source_2) print([data for data in list_ds]) # [a, b, c, d] print([data for data in gen_ds]) # [0, 1, 2, 3, 4]4.3 生成器对象的两条重要警示源码在IterDataset.__iter__中对生成器数据源有专门处理dataset.py#L450-L457传入生成器对象时第二次迭代会自动重置生成器重新调用生成器函数若要复用已生成的数据需要先把它转换成 List。IterDataset生成的数据只能迭代一次——流式语义决定了它不支持随机回访。源码同时会发出警告Receiving generator as data source, data can only be iterated once。这一特性在训练场景中很关键如果你的训练循环需要对数据集做多轮遍历务必确认数据源是 List 或可重复迭代的对象或者使用函数式 readerload_dataset(read, ...)传入的是函数而非生成器实例每次迭代都会重新调用函数天然支持重复迭代。4.4 包装第三方数据集以 HuggingFace Dataset 为例只要满足上述条件第三方数据集同样可以一键转换。例如 HuggingFacedatasets库加载的数据集from paddlenlp.datasets import MapDataset from datasets import load_dataset hf_train_ds load_dataset(msra_ner, splittrain) print(type(hf_train_ds)) # class datasets.arrow_dataset.Dataset train_ds MapDataset(hf_train_ds) print(type(train_ds)) # class paddlenlp.datasets.dataset.MapDataset print(train_ds[2]) # {id: 2, # ner_tags: [0, 0, 0, 5, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 0, 0, 0, 0, 0, 0, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0], # tokens: [因, 有, 关, 日, 寇, 在, 京, 掠, 夺, 文, 物, # 详, 情, , 藏, 界, 较, 为, 重, 视, , 也, # 是, 我, 们, 收, 藏, 北, 京, 史, 料, 中, 的, # 要, 件, 之, 一, 。]}同样适用于抽取式阅读理解CMRC2018、文本分类GLUE SST-2、语言建模PTB等格式各异的数据集# 阅读理解cmrc2018 hf_train_ds load_dataset(cmrc2018, splittrain) train_ds MapDataset(hf_train_ds) print(train_ds[1818]) # {answers: {answer_start: [9], text: [字仲可]}, # context: 徐珂原名昌字仲可浙江杭县今属杭州市人。光绪举人。 # 后任商务印书馆编辑。参加南社。1901年在上海担任了《外交报》、 # 《东方杂志》的编辑1911年接管《东方杂志》的杂纂部。与潘仕成、 # 王晋卿、王辑塘、冒鹤亭等友好。编有《清稗类钞》、《历代白话诗选》、 # 《古今词选集评》等。光绪十五年1889年举人。后任商务印书馆编辑。 # 参加南社。曾担任袁世凯在天津小站练兵时的幕僚不久离去。, # id: TRAIN_113_QUERY_0, # question: 徐珂字什么} # 文本分类glue/sst2 hf_train_ds load_dataset(glue, sst2, splittrain) train_ds MapDataset(hf_train_ds) print(train_ds[0]) # {idx: 0, label: 0, sentence: hide new secretions from the parental units } # 语言建模ptb_text_only hf_train_ds load_dataset(ptb_text_only, splittrain) train_ds MapDataset(hf_train_ds) print(train_ds[1]) # {sentence: pierre unk N years old will join the board as a nonexecutive director nov. N}可以看到包装后的样本仍然保持字段化字典结构随后即可用map接上 tokenizer 与特征转换逻辑。五、进阶复用内置数据集格式与自定义 DatasetBuilder5.1 内置数据集的另一种本地接入方式除自定义 reader 外如果你的本地数据与某内置数据集格式一致还可以直接复用内置的DatasetBuilder通过load_dataset的data_files参数指定本地文件路径详见 dataset_load.rst。例如用本地 SQuAD 格式文件替换内置训练/验证集from paddlenlp.datasets import load_dataset train_ds, dev_ds load_dataset(squad, data_files(my_train_file.json, my_dev_file.json)) test_ds load_dataset(squad, data_filesmy_test_file.json)注意当不同 split 需要不同读取方式时必须在splits参数中提供对应的 split 信息且splits与data_files的数量要一一对应——此时splits不再表示选择内置子集而是指定本地数据的读取格式。5.2 从 reader 到 DatasetBuilder完整的自定义数据集体系load_dataset(read_func, ...)本质上是SimpleBuilder一个最小化的DatasetBuilder在工作。若要贡献可复用、可自动下载、支持 label-to-id 转换的完整数据集可以继承DatasetBuilder并实现_get_data下载/校验文件与_read生成器方式读取样本两个必需方法外加可选的get_labels/get_vocab详见 how_to_write_a_DatasetBuilder.rst。PaddleNLP 内置的 20 数据集全部遵循该协议完整清单见 dataset_list.md。5.3 分布式训练下的分片与多进程无论自定义还是内置数据集接入训练后都可能面临分布式场景。MapDataset.shard与IterDataset.shard均支持按world_size/rank自动分片默认取paddle.distributed的全局信息dataset.py#L313-L349、dataset.py#L479-L504map/filter的num_workers参数则利用multiprocess进程池并行处理dataset.py#L278-L307。此外IterDataset还提供skip(n)方法用于跳过前 n 条样本函数式数据源不支持dataset.py#L459-L463。六、总结与实践建议回顾 PaddleNLP 自定义数据集的三条路径可以提炼出如下选型建议本地文件首选生成器式 reader load_dataset(read, data_path..., lazy...)记得lazy必填样本务必输出字典格式。已有 paddle.io 数据集直接MapDataset(ds)/IterDataset(ds)包装即刻获得map/filter/shard能力。任意 Python 对象 / 第三方数据集满足__getitem____len__或__iter__协议即可包装HuggingFace Dataset 开箱即用。生产级复用继承DatasetBuilder实现_get_data_readget_labels即可获得自动下载、MD5 校验、label-to-id 转换等全套内置数据集能力。需要记住的两个易错点自定义模式下标签需手动转 ID生成器数据源只能迭代一次。掌握这些规约后无论数据是本地 TSV、HuggingFace 数据集还是内存中的 Python 对象都能在 PaddleNLP 中统一为MapDataset/IterDataset顺畅接入后续的 tokenizer 转换与DataLoader训练流水线。赞分享人工智能大模型NLP深度学习预训练微调RLHF模型量化【免费下载链接】PaddleNLPEasy-to-use and powerful LLM and SLM library with awesome model zoo.项目地址https://gitcode.com/gh_mirrors/pa/PaddleNLP点击查看免费下载相关推荐【特别福利】 PaddleNLP自定义数据集完全指南【特别福利】 PaddleNLP自定义数据集完全指南 还在为NLP任务中的数据预处理而烦恼吗面对各种格式的本地数据不知道如何快速集成到PaddleNLP框架人工智能大模型深度学习NLP预训练微调模型推理服务模型量化分布式训练强化学习Axure 中文语言包安装指南三步复制9/10/11 界面变简体中文Axure 中文语言包安装指南三步复制9/10/11 界面变简体中文 如果你正在用 Axure RP 9、10 或 11这篇就是为你准备的。开源项目 ax如何用 run_all.py --isolated 为每个技能在独立环境中运行测试套件如何用 run_all.py isolated 为每个技能在独立环境中运行测试套件 scientific agent skills 仓库把每个技能的测试放在仓库人工智能大模型NLP深度学习预训练微调RLHF模型量化模型推理服务本地部署模型压缩强化学习模型评测创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
