NLP(九十四)transformers模块中的DataCollator
本文将会详细介绍HuggingFace开源的
transformers
模块中的DataCollator.
引言
Data
Collator是HuggingFace开源的transformers
模块进行数据处理的重要部分。它的输入是由数据集元素组成的列表,将其组装成批次,其中数据集元素为相同数据类型的train_dataset或者eval_dataset。
为了组装成数据批次,Data collators会应用某些处理(比如padding),有些(比如DataCollatorForLanguageModeling)还会在数据批次上应用随机数据增强(比如随机masking)。
Data collators是为了特定任务而设计的,如下:
- Causal language modeling (CLM)
- Masking language modeling (MLM)
- Sequence classification
- Seq2Seq
- Token classification
以sequence classification任务为例,data collator只需将所有序列填充到一个小批次中,以确保它们具有相同的长度。
使用例子进行解读
在transformers
模块源码中,data
collators源码位于data/data_collator.py脚本中,所有data
collator的父类为DataCollatorMixin
,代码如下:
1 |
|
这个类根据输入return_tensors
决定处理哪种矩阵torch、tensorflow、numpy,一般不直接使用。
以下是其派生的子类,我们将一一进行了解。
DefaultDataCollator
DefaultDataCollator类为默认DataCollator类,它不进行任何padding或者truncation,并且假设所有的输入样本拥有相同的长度。如果输入样本长度不一样,则会报错。
该类一般不直接使用。
DataCollatorWithPadding
DataCollatorWithPadding类将输入的input_ids
、attention_mask
等向量做padding处理,截断或补充padding,使得它们的长度保持统一。
1 |
|
输出结果如下:
1 |
|
这里使用的transformers
模块版本为4.39.3,
tokenizers
模块版本为0.15.2。
我们为Qwen1.5-7B
模型的tokenier为例。从上面的输出中可以看到,原始的数据经tokenize后input_ids和attention_mask长度并不一样,使用DataCollatorWithPadding后它们的长度一样,使用151643数字(对应token为<|endoftext|>)进行填充。
DataCollatorWithPadding类还有其他参数,比如padding, max_length, pad_to_multiple_of, return_tensors等,我们可以指定序列最大长度,比如:
1 |
|
DataCollatorForTokenClassification
DataCollatorForTokenClassification类适用于序列标注任务(token classification),比如命名实体识别(NER),每个token都会对应一个预测label,当一个序列的token比label多时,对额外的label位置添加-100处理,使得在计算交叉熵损失时,-100位置的label损失为0不用考虑。
1 |
|
输出结果为:
1 |
|
可以看到,此时仍对序列进行了填充,使得所有序列保持同一长度,同时对token多于label的场景使用-100进行填充。
DataCollatorForSeq2Seq
DataCollatorForSeq2Seq类适用于Seq2Seq任务,包括机器翻译,文本生成任务等。该类根据前面的序列来预测后面序列,后面序列为labels,一个batch内多条后面序列长度不同时,用-100来填充。同样地,在计算损失时,-100位置的损失不予考虑。
1 |
|
输出结果为:
1 |
|
可以看到,后面序列labels长度不一致,使用-100填充至batch内最大长度。
DataCollatorForLanguageModeling
DataCollatorForLanguageModeling类适用于语言模型,比如BERT系列等。
该类有个mlm参数,其默认值为True, 取值如下:
- 如果设置为False,则labels与inputs一致,使用-100进行填充
- 如果设置为True,则labels对于non-masked tokens设置为-100,对于masked token,其处理方式同BERT模型:80% MASK(MASK值), 10% random(随机替换成其它token值), 10% original(原始值)。
mlm_probability参数默认值为0.15,即对input_ids中的token会有15%的概率进行mask。
1 |
|
输出结果为:
1 |
|
注意: 我们这里使用模型为bert-base-chinese,基座为BERT模型。
输出的labels列表中第三个序列中第三个元素进行了mask。
DataCollatorForWholeWordMask
DataCollatorForWholeWordMask类继承了DataCollatorForLanguageModeling类,区别在于其全词掩盖功能(WholeWordMask),该遮词方法需要在tokenizer分词的时候就对期望连续遮住的词汇的非第一个字前加上##标记。
DataCollatorForSOP
DataCollatorForSOP适用于句子顺序预测任务,将会在后续版本中进行移除,这里不再介绍。
DataCollatorForPermutationLanguageModeling
DataCollatorForPermutationLanguageModeling适用于置换语言模型(permutation language modeling),比如XLNet模型等,可以参考XLNet模型的相关解读,这里不予介绍。
NER实战
在文章NLP(六十六)使用HuggingFace中的Trainer进行BERT模型微调中,我们完成文本分类任务时使用的Data Collator为DataCollatorWithPadding。
我们使用DataCollatorForTokenClassification类来完成命名实体识别任务,数据集用peoples_daily_ner
,模型采用bert-base-chinese
。
训练脚本如下:
1 |
|
这里我们的数据预处理方式比较粗糙,样本的token与label并没有严格对应,不过对于bert-base-chinese
模型,大多数样本已经满足要求了。
我们对测试集进行评估:
1 |
|
评估指标如下:
1 |
|
在新样本的表现如下:
输入: 王安石的另一位好友叫吴充。 输出: ['B-PER', 'I-PER', 'I-PER', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'B-PER', 'I-PER', 'O']
上述的NER模型训练仅仅只是一个例子,实际上,上述NER任务的模型效果还有很多改进的空间。
总结
本文主要介绍了transformers
模块中的Data Collotor。
事实上,transformers
模块中的Trainer和trl
模块中的SFTrainer都高度集成了,Data
Collotor只是其中一个部分,后续有机会将会继续深入研究~
参考文献
- Transformers仓库解读之一DataCollator: https://lowin.li/2021/09/25/transformers-yi-datacollator/
- Data Collator: https://huggingface.co/docs/transformers/main_classes/data_collator
- Data Collators in HuggingFace: https://towardsdatascience.com/data-collators-in-huggingface-a0c76db798d2
- NLP(六十六)使用HuggingFace中的Trainer进行BERT模型微调
- NLP(三十四)使用keras-bert实现序列标注任务
欢迎关注我的知识星球“自然语言处理奇幻之旅”,笔者正在努力构建自己的技术社区。