【Python】科研代码学习:五 Data Collator,Datasets Data Collator Default data collator DefaultDataCollator DataCollatorWithPadding 其他 Data Collator Datasets
Data Collator
HF官网API:Data Collator Transformers源码阅读:transformers data_collator小记 提到输入训练集/验证集数据 ,就基本绕不开 Data Collator 它的作用是将多个数据进行批处理(Batch) ,并转换成 train_dataset 和 eval_dataset 相同的数据类型 为了让它工作顺利,可能会做一些处理(padding / random masking) 但是我发现,在 Datasets 的一些API中,或者单独使用 Data Collator 的情况很少啊 再仔细查看发现,其作用主要是 给 Trainer 的初始化创建提供了一个 Data Collator,让 Trainer 在训练和评估的时候会自己去对数据进行批处理或特殊处理 下面看一下 Data Collator 里面的东西吧。
Default data collator
首先,它是一个方法,首先 输入类型,其实就是一个任意的列表 InputDataClass = NewType("InputDataClass", Any) 然后可以指定用 pytorch / tensorflow / numpy 中的一个版本,大部分都是使用 pt 发现,首先他把 features 也就是输入通过 vars() 转成了字典 然后它处理了标签 ,也就是 label 或 label_ids 看下API描述: label: handles a single value (int or float) per object label_ids: handles a list of values per object 哦,就是单标签和多标签的区别。 最后做了些类型转换 ,输出打包为 Dict[str, Any]
DefaultDataCollator
上面是一个函数,这里是一个类(需要实例化) 调用它相当于调用了上述的函数
DataCollatorWithPadding
如果不知道 Padding的,可以看一下后面的补充知识 这里看一下源码和参数含义 需要提供 tokenizer,以及 padding 策略。其他过程和上述 DefaultDataCollator 差不多。
Padding
知乎:LLM padding 细节 可以翻译成对齐吧 简单来说就是,输入经过词嵌入后,产生的 List[int] 词嵌入数组长度不一致,很难进行并行处理 我们通过把所有数组长度统一到其中最长的那个数组长度 ,也就是其中添加 tokenizer.pad_token 即可。 例如 tokenizer(prompts, return_tensors="pt", padding=True) ,其中 attention_mask 中的 0 表示 padding 但是 padding 会增加无用字符,浪费训练资源,所以还有其他不用 padding 的训练方式。 其他的技术细节请参考上述知乎链接。
其他 Data Collator
针对不同任务,也提供了不同的 Data Collator,看一眼吧: DataCollatorForTokenClassification:给token分类的 DataCollatorForSeq2Seq:给s2s任务的 DataCollatorForLanguageModeling:给LM用的,mlm 参数给 MLM任务使用 DataCollatorForWholeWordMask:给LM用的,(used for language modeling that masks entire words) DataCollatorForPermutationLanguageModeling:给(permutation language modeling)用的
Datasets
HF官网API:Datasets 前面介绍的都在 transformers 库里的,而这个是在 Datasets 库的 主要功能就是从 HF 中加载与上传数据集,给 Audio,CV,NLP任务用途的。 它比较简单,最主要的方法也就是下面这个
load_dataset
来看一下源码 它参数比较多,我就选择重要参数介绍吧。详细请去API查看 path :数据集的名字 (请去HF中查找)或本地路径 (json, csv, text等格式)或数据集脚本 ( dataset script,一个py文件) split:默认 None,不划分训练集和测试集,最终直接返回一个 DatasetDict 。若指定 train / test / validation(这个真难找,图片在下方),则返回 Dataset 类型。 data_dir:设置保存路径。 看一下例子: 通过HF加载数据集 (ds = dataset缩写,是一个规范)
from datasets import load_dataset
ds = load_dataset( 'rotten_tomatoes' , split= 'train' ) data_files = { 'train' : 'train.csv' , 'test' : 'test.csv' }
ds = load_dataset( 'namespace/your_dataset_name' , data_files= data_files)
通过本地加载数据集,通过 csv / json / loading_script 加载
from datasets import load_dataset
ds = load_dataset( 'csv' , data_files= 'path/to/local/my_dataset.csv' ) from datasets import load_dataset
ds = load_dataset( 'json' , data_files= 'path/to/local/my_dataset.json' ) from datasets import load_dataset
ds = load_dataset( 'path/to/local/loading_script/loading_script.py' , split= 'train' )
如果通过自动下载后,可以使用下面方法来设置数据存储到本地目录 通过 save_to_disk 存到本地后,需要使用 load_from_disk 加载
dataset. save_to_disk( dataset_dict_path= './data/ChnSentiCorp' )
dataset = load_from_disk( './data/ChnSentiCorp' )
其他一些基本操作
HuggingFace学习笔记(3) 数据集工具datasets 参考上面的知乎笔记,可以学到一些内容: 1)dataset = dataset['train'] 可以直接获得其中的训练子集 2)Dataset 内核和 pandas.dataframe 差不多 3)索引 :ds[i] 取出第 i 条记录 4)排序 :sorted_ds = ds.sort("colum_name") 5)打乱 :shuffled_ds = ds.shuffle(seed=42) 6)采样 :ds.select([0,10,11,...]) 表示拿出哪些记录 7)训练测试集拆分 :ds.train_test_split(test_size=0.1),即9:1拆成训练集与测试集 8)重命名列 :ds.rename_column('bef', 'aft') 9)删除列 :ds.remove_columns(['colum_name']) 10)过滤 :dataset.filter(func) 比如
def func ( data) : return data[ 'text' ] . startswith( '非常不错' )
11)遍历修改 :new_ds = ds.map(func),这个比较常用 比如
def f ( data) : data[ 'text' ] = 'My sentence: ' + data[ 'text' ] return data
12)批处理加速 :filter()、map()两个函数都支持批处理加速 添加如下关键词即可,注意 num_proc 表示使用的进程数。
maped_datatset = dataset. map ( function= f, batched= True , batch_size= 1000 , num_proc= 4 )