Hugging face Transformers(5)—— Datasets
- Hugging Face 是一家在 AI 领域具有重要影响力的科技公司,他们的开源工具和社区建设为NLP研究和开发提供了强大的支持。它们拥有当前最活跃、最受关注、影响力最大的 NLP 社区,最新最强的 NLP 模型大多在这里发布和开源。该社区也提供了丰富的教程、文档和示例代码,帮助用户快速上手并深入理解各类 Transformer 模型和 NLP 技术
- Transformers 库是 Hugging Face 最著名的贡献之一,它最初是 Transformer 模型的 pytorch 复现库,随着不断建设,至今已经成为 NLP 领域最重要,影响最大的基础设施之一。该库提供了大量预训练的模型,涵盖了多种语言和任务,成为当今大模型工程实现的主流标准,换句话说,如果你正在开发一个大模型,那么按 Transformer 库的代码格式进行工程实现、将 check point 打包成 hugging face 格式开源到社区,对于推广你的工作有很大的助力作用。本系列文章将介绍 Transformers 库的基本使用方法
- 参考:
- 官方教程
- 手把手带你实战HuggingFace Transformers
- datasets 是一个简单易用的数据集加载库,可方便地从本地或 hugging face hub 加载数据集
- 开源数据集列表:https://huggingface.co/datasets
- 文档地址:https://huggingface.co/docs/datasets/index
- 无论自定义还是从 Hugging Face Hud 下载,Transformers 库中的数据集 (Dataset) 是一个包含以下内容的目录:
- 一些通用格式数据文件(如 JSON、CSV、Parquet、文本文件等)
- 一个数据加载脚本,它定义一个
datasets.GeneratorBasedBuilder
,用于从数据文件构造最终程序使用的datasets.arrow_dataset.Dataset
对象。Transformers 库默认调研各类型文件的通用数据加载脚本,遇到以下复杂情况时则需自定义情况 说明 复杂的数据结构 如嵌套的 JSON、特殊格式 多文件组合 需要从多个文件中组合数据 特殊预处理 需要在加载时进行数据清洗或转换 自定义字段映射 原始数据字段与期望格式不匹配
文章目录
- 1. Datasets 的基本使用
-
- 1.1 加载在线数据集
- 1.2 查看数据集
- 1.3 划分数据集
- 1.4 数据选取、过滤和打乱
- 1.5 数据映射
- 1.6 数据集的本地保存和加载
- 2. 加载本地数据集
-
- 2.1 加载 csv 文件
- 2.2 加载 pandas 对象
- 2.3 加载 python list 对象
- 2.4 使用自定义数据加载脚本
- 3. DataCollector
- 4. 最佳实践
1. Datasets 的基本使用
1.1 加载在线数据集
-
使用
datasets.load.load_dataset
方法,可直接从 HF Hub 下载path
形参指定的在线开源数据集from datasets import * datasets = load_dataset(path="madao33/new-title-chinese") datasets
DatasetDict({train: Dataset({features: ['title', 'content'],num_rows: 5850})validation: Dataset({features: ['title', 'content'],num_rows: 1679}) })
注意到在线数据集通常已进行划分并以字典形式呈现。可以传入
split
参数直接加载指定划分,且能通过切片方式加载指定数据# 只加载训练集 dataset = load_dataset("madao33/new-title-chinese", split="train")# 用切片方式,只加载训练集的前100条数据 dataset = load_dataset("madao33/new-title-chinese", split="train[:100]") # 以列表形式加载多个数据集 dataset = load_dataset("madao33/new-title-chinese", split=["train[50%:]", "train[:50%]", "validation[10:20]"])
-
有些数据集是多任务数据集,它们包含多个子任务,需要通过
name
形参指定加载哪个任务的数据。例如# 错误的用法 super_glue_datasets = load_dataset(path="super_glue") # ❌ 会报错 ''' ValueError: Config name is missing. Please pick one among the available configs: ['axb', 'axg', 'boolq', 'cb', 'copa', 'multirc', 'record', 'rte', 'wic', 'wsc', 'wsc.fixed'] '''# 正确的用法 - 指定具体任务 boolq_dataset = load_dataset("super_glue", name="boolq", trust_remote_code=True) # 布尔问答 copa_dataset = load_dataset("super_glue", name="copa", trust_remote_code=True) # 因果推理
其中
trust_remote_code=True
代表使用 HF Hub 开源数据集自定义的数据集脚本 -
数据集、模型等默认下载到
HF_HOME
和HUGGINGFACE_HUB_CACHE
等全局变量指定位置,可以调整# 全局设置存储目录 import os os.environ['HF_HOME'] = r'D:\Programmer\HuggingFace' os.environ['HUGGINGFACE_HUB_CACHE'] = r'D:\Programmer\HuggingFace\Hub'# 在下载时指定存储目录 datasets = load_dataset("madao33/new-title-chinese", cache_dir="D:/MyDatasets/cache")# 详细配置下载行为 from datasets import DownloadConfig download_config = DownloadConfig( # 创建下载配置cache_dir="D:/MyDatasets/cache",force_download=False, # 是否强制重新下载resume_download=True, # 是否支持断点续传 ) datasets = load_dataset("madao33/new-title-chinese", download_config=download_config)
1.2 查看数据集
- 数据通常以
Dict[str, list]
的字典形式保存,支持通过切片形式访问# 加载数据 from datasets import * datasets = load_dataset("madao33/new-title-chinese")# 支持切片形式访问,字典形式(元素为列表)返回 datasets['train'][:2] ''' {'title': ['望海楼美国打“台湾牌”是危险的赌博', '大力推进高校治理能力建设'],'content': ['近期,美国国会众院通过法案...', '在推进“双一流”高校建设进程中...'] } '''# 按字段访问,便于做 batch tokenize datasets['train']['title'][:2] ''' ['望海楼美国打“台湾牌”是危险的赌博', '大力推进高校治理能力建设'] '''# 获取字段名和datasets.features.features.Features 对象 print(datasets['train'].column_names) # ['title', 'content'] print(datasets['train'].features) # {'title': Value(dtype='string', id=None), 'content': Value(dtype='string', id=None)}
1.3 划分数据集
- 有些数据集未进行原始划分或划分不满足要求,这时可以使用
dataset.train_test_split
方法进行划分。对任意Dataset
对象调用此方法,会返回一个由 train 和 test 构成的DatasetDict
datasets = load_dataset("madao33/new-title-chinese") dataset = datasets['train']# 将原本的 'train' 数据集再次按比例划分,10%做测试集,90%做训练集 final_datasets = dataset.train_test_split(test_size=0.1) final_datasets
DatasetDict({train: Dataset({features: ['title', 'content'],num_rows: 5265})test: Dataset({features: ['title', 'content'],num_rows: 585}) })
- 下例演示如何将 “madao33/new-title-chinese” 的 train 数据集重新划分为 train、test、valid 三部分
datasets = load_dataset("madao33/new-title-chinese") dataset = datasets['train']# 先划分出训练集,train 占 80% train_test = dataset.train_test_split(test_size=0.2) # 把占 20% 的 test 对半分,作为 test 和 valid test_val = train_test['test'].train_test_split(test_size=0.5)# 重新组织数据集 final_datasets = DatasetDict({'train': train_test['train'], # 80%'test': test_val['train'], # 10%'validation': test_val['test'] # 10% }) final_datasets
DatasetDict({train: Dataset({features: ['title', 'content'],num_rows: 4680})test: Dataset({features: ['title', 'content'],num_rows: 585})validation: Dataset({features: ['title', 'content'],num_rows: 585}) })
- 如果只是为了划分数据,用 1.1 节介绍的切分加载形式也能做到,
dataset.train_test_split
方法的意义在于其可以进行更精细的控制。例如对二分类任务数据集 BoolQ 来说,我们希望划分后的 train 和 test 都具有相同的正负样本比例,这就需要设置stratify_by_column
对指定列(标签)进行分层采样# super_glue 是一个多任务数据集合,只加载其中 boolq 任务的数据 boolq_dataset = load_dataset("super_glue", "boolq", trust_remote_code=True) dataset = boolq_dataset['train']# 按比例划分,同时确保给定字段 'label' 的取值在数据集中是均衡的 final_datasets = dataset.train_test_split(test_size=0.1, stratify_by_column='label') final_datasets
DatasetDict({train: Dataset({features: ['title', 'content'],num_rows: 4680})test: Dataset({features: ['title', 'content'],num_rows: 585})validation: Dataset({features: ['title', 'content'],num_rows: 585}) })
1.4 数据选取、过滤和打乱
- 前文 1.2 节说明了可以通过切片方式查看数据,注意其会返回普通 python 字典或列表
以上方式适合快速查看数据,但有时我们想获取一个子数据集对象,类似 1.1 节切片加载的效果。这时可以使用from datasets import * datasets = load_dataset("madao33/new-title-chinese")# 支持切片形式访问,字典形式(元素为列表)返回 datasets['train'][:2] ''' {'title': ['望海楼美国打“台湾牌”是危险的赌博', '大力推进高校治理能力建设'],'content': ['近期,美国国会众院通过法案...', '在推进“双一流”高校建设进程中...'] } '''
dataset.select()
方法,这会通过索引引用方式创建新的 Dataset 对象,从而保持所有 Dataset 的方法和属性dataset = load_dataset("madao33/new-title-chinese", split="train")# 取给定索引位置的样本,创建新 datset 对象(注意和 datasets['train'][:2] 这种查看方式不同,后者不创建 dataset 对象) dataset.select([0,1])
Dataset({features: ['title'