Llama2-Chinese项目给出pretrain的data为QA数据格式,可能会有疑问pretrain不应该是Text数据格式吗?而在Chinese-LLaMA-Alpaca-2和open-llama2预训练使用的LoRA技术,给出pretrain的data为Text数据格式。所以推测应该pretrain时QA和Text数据格式都应该支持。然后马上就会有一个疑问,两者有什么区别呢?再回答这个问题之前,先来看看Llama2-Chinese和open-llama2是如何处理QA和Text数据的。
一.Llama2-Chineses是如何处理QA数据格式的?
1.raw_datasets数据
首先使用raw_datasets = load_dataset()
加载原始数据,如下所示:
然后通过tokenize_function
分词函数对raw_datasets
进行处理,如下所示:
deftokenize_function(examples):#分词函数
withCaptureLogger(tok_logger)ascl:#捕获日志记录器
output=tokenizer([''+item+''foriteminexamples[text_column_name]])#分词
returnoutput#输出
对应的控制台输出日志,如下所示:
Runningtokenizerondataset:0%||0/9861[00:00,?examples/s]CachingprocesseddatasetatL:20230825_NLP工程化公众号nlp-engineering20230916_Llama2-Chinesetrainpretrainoutput_modeldataset_cachecsvdefault-0be939ed6ae746cd.0.0eea64c71ca8b46dd3f537ed218fc9bf495d5707789152eb2764f5c78fa66d59dcache-5995c58fe2972c10.arrow
09/20/202321:52:13-INFO-datasets.arrow_dataset-CachingprocesseddatasetatL:20230825_NLP工程化公众号nlp-engineering20230916_Llama2-Chinesetrainpretrainoutput_modeldataset_cachecsvdefault-0be939ed6ae746cd.0.0eea64c71ca8b46dd3f537ed218fc9bf495d5707789152eb2764f5c78fa66d59dcache-5995c58fe2972c10.arrow
Runningtokenizerondataset:100%|██████████|9861/9861[00:11Runningtokenizerondataset:0%||0/400[00:00,?examples/s]CachingprocesseddatasetatL:20230825_NLP工程化公众号nlp-engineering20230916_Llama2-Chinesetrainpretrainoutput_modeldataset_cachecsvdefault-0be939ed6ae746cd.0.0eea64c71ca8b46dd3f537ed218fc9bf495d5707789152eb2764f5c78fa66d59dcache-44181180d09c5991.arrow
09/20/202321:52:21-INFO-datasets.arrow_dataset-CachingprocesseddatasetatL:20230825_NLP工程化公众号nlp-engineering20230916_Llama2-Chinesetrainpretrainoutput_modeldataset_cachecsvdefault-0be939ed6ae746cd.0.0eea64c71ca8b46dd3f537ed218fc9bf495d5707789152eb2764f5c78fa66d59dcache-44181180d09c5991.arrow
Runningtokenizerondataset:100%|██████████|400/400[00:01
2.tokenized_datasets数据
然后tokenized_datasets = raw_datasets.map()
如下所示:
可以看到tokenized_datasets
主要是包含['input_ids', 'attention_mask']
这2列数据,拿出其中1条如下所示:
'input_ids':[1,1,1,12968,29901,29871,31999,30544,30287,30502,31658,31596,30214,30698,31376,31931,30880,30742,234,176,151,31751,31658,31596,30210,30594,31016,31175,31072,30267,30847,30801,30742,234,176,151,31480,30544,30594,31016,31175,31072,30214,31915,31229,31370,31751,31050,30780,30768,31043,30267,30004,13,31658,31596,29901,376,30287,30408,30417,30923,31022,234,170,149,30882,29908,30594,31016,31175,31072,29901,29871,29896,29900,234,170,149,30004,13,2,1,4007,22137,29901,29871,30287,30408,30417,29947,29953,29946,29900,29900,234,170,149,30267,30004,13,2,2]
#'input_ids':'Human:给出一个问题,要求助手回答该问题的时间限制。如果回答超出时间限制,客户应该得到通知。问题:"一天有多少秒?"时间限制:10秒Assistant:一天有86400秒。'
'attention_mask':[1,1,1,1,1,...1,1,1,1,1]
3.lm_datasets数据
接下来得到lm_datasets = tokenized_datasets.map()
,其中group_text()
函数如下所示:
defgroup_texts(examples):
#翻译:连接所有文本。
concatenated_examples={k:list(chain(*examples[k]))forkinexamples.keys()}#连接所有文本
#concatenated_examples={k:sum(examples[k],[])forkinexamples.keys()}
total_length=len(concatenated_examples[list(examples.keys())[0]])#总长度
#Wedropthesmallremainder,wecouldaddpaddingifthemodelsupporteditinsteadofthisdrop,youcancustomizethisparttoyourneeds.
#翻译:我们丢弃了小的余数,如果模型支持,我们可以添加填充,而不是这个丢弃,您可以根据需要自定义这部分。
iftotal_length>=block_size:#如果总长度大于块大小
total_length=(total_length//block_size)*block_size#总长度
#Splitbychunksofmax_len.
#翻译:按max_len分割。
result={#结果
k:[t[i:i+block_size]foriinrange(0,total_length,block_size)]#拼接的示例
fork,tinconcatenated_examples.items()#拼接的示例
}
#print(datetime.datetime.now().strftime('%Y-%m-%d%H:%M:%S'))
logger.info("grouptextsinputexampleslength%dafter_groupsize%d"%(len(examples['input_ids']),len(result["input_ids"])))#组文本输入示例长度%d后组大小%d
result["labels"]=result["input_ids"].copy()#标签
returnresult#返回结果
对应的控制台输出日志,如下所示:
09/20/202321:52:21-WARNING-__main__-Thechosentokenizersupportsa`model_max_length`thatislongerthanthedefault`block_size`valueof1024.Ifyouwouldliketousealonger`block_size`upto`tokenizer.model_max_length`youcanoverridethisdefaultwith`--block_sizexxx`.
Groupingtextsinchunksof1024:0%||0/9861[00:00,?examples/s]09/20/202321:52:29-INFO-__main__-grouptextsinputexampleslength9861after_groupsize3246
CachingprocesseddatasetatL:20230825_NLP工程化公众号nlp-engineering20230916_Llama2-Chinesetrainpretrainoutput_modeldataset_cachecsvdefault-0be939ed6ae746cd.0.0eea64c71ca8b46dd3f537ed218fc9bf495d5707789152eb2764f5c78fa66d59dcache-18dbcb518f2766e1.arrow
09/20/202321:52:29-INFO-datasets.arrow_dataset-CachingprocesseddatasetatL:20230825_NLP工程化公众号nlp-engineering20230916_Llama2-Chinesetrainpretrainoutput_modeldataset_cachecsvdefault-0be939ed6ae746cd.0.0eea64c71ca8b服务器托管网46dd3f537ed218fc9bf495d5707789152eb2764f5c78fa66d59dcache-18dbcb518f2766e1.arrow
Groupingtextsinchunksof1024:100%|██████████|9861/9861[00:11Groupingtextsinchunksof1024:0%||0/400[00:00,?examples/s]CachingprocesseddatasetatL:20230825_NLP工程化公众号nlp-engineering20230916_Llama2-Chinesetrainpretrainoutput_modeldataset_cachecsvdefault-0be939ed6ae746cd.0.0eea64c71ca8b46dd3f537ed218fc9bf495d5707789152eb2764f5c78fa66d59dcache-962b32747bcb1aec.arrow
09/20/202321:52:35-INFO-__main__-grouptextsinputexampleslength400after_groupsize738
09/20/202321:52:35-IN服务器托管网FO-datasets.arrow_dataset-CachingprocesseddatasetatL:20230825_NLP工程化公众号nlp-engineering20230916_Llama2-Chinesetrainpretrainoutput_modeldataset_cachecsvdefault-0be939ed6ae746cd.0.0eea64c71ca8b46dd3f537ed218fc9bf495d5707789152eb2764f5c78fa66d59dcache-962b32747bcb1aec.arrow
Groupingtextsinchunksof1024:100%|██████████|400/400[00:02
lm_datasets的列名包括[‘input_ids’, ‘attention_mask’, ‘labels’],如下所示:
train_dataset就是lm_datasets中train的部分,如下所示:
4.定义训练器Trainer训练模型
通过trainer.train(resume_from_checkpoint=checkpoint)
训练模型,如下所示:
二.open-llama2是如何处理Text数据格式的?
1.raw_dataset数据
raw_dataset = load_dataset("text", data_files=data_file, cache_dir=cache_dir, keep_in_memory=False)
加载预训练数据,如下所示:
2.tokenized_dataset数据
对raw_dataset
进行text转id处理,如下所示:
3.grouped_datasets和processed_dataset数据
这两者包含[‘input_ids’, ‘attention_mask’, ‘labels’]三列数据,并且processed_dataset = grouped_datasets
。如下所示:
4.lm_datasets数据
lm_datasets = processed_dataset['train']
,如下所示:
通过tokenizer.decode(train_dataset[0]['input_ids'])
对数据进行解码,如下所示:
青海省人民政府是中华人民共和国青海省的最高地方行政机构。1950年1月由原青海省人民军政委员会改组成立。1955年1月改称青海省人民委员会。1967年8月改为青海省革命委员会。1979年8月,青海省革命委员会撤销,复设青海省人民政府。湖南省人民政府驻北京办事处,是中华人民共和国湖南省人民政府驻北京市的办事处,该办事处负责领导联络协调、招商引资、信息调研、对外宣传、接待服务以及服务驻北京市天津企业等相关事项。该办事处为副局级单位。
综上所述,加载QA数据时,train_dataset的shape为[3246, 3],而加载Text数据时,train_dataset的shape为[1, 3],可见前者是按照逐行处理的,而后者是合并后处理的。最后思考最开始的那个疑问,两者有什么区别呢?从数据处理上来说,无论是QA还是Text数据格式,都是把它们当做Text数据处理的。看似没有区别,实际上LLM有着强大的模式识别能力,从QA数据集上是可以识别到问答模式的,尽管做的都是无监督学习,没有明确的特征X和标签y。问了下ChatGPT增量训练使用QA数据集和Text数据集间的区别,如下所示:
特征 | QA 数据集增量训练 | Text 数据集增量训练 |
---|---|---|
数据格式 | 问题和答案对的形式 | 连续的文本段落、句子或单词序列 |
目标任务 | 提高问题回答性能 | 提高文本理解和生成性能 |
数据内容 | 问题和答案对,通常领域特定 | 通常为通用文本,如新闻文章、小说等 |
数据预处理 | 问题和答案的提取、分词、标记化等 | 文本清理、标记化、分段等 |
应用示例 | 问答、领域特定任务 | 文本生成、文章摘要、翻译等 |
这个回答参考下就行了,还是要以场景为导向来思考,比如要训练一个心理咨询机器人,现在已经有了一个LLM的base模型,如果要增量预训练肯定也是在医疗非结构化文本(比如教材、文献等)上预训练,然后拿心理咨询问答数据进行SFT。应该很少会有人直接拿医疗QA数据集来预训练base模型吧,因为标注的成本还是太高了。若有不当之处,欢迎拍砖。
参考文献:
[1]https://github.com/FlagAlpha/Llama2-Chinese
[2]https://github.com/huxiaosheng123/open-llama2
[3]https://github.com/ymcui/Chinese-LLaMA-Alpaca-2
[4]https://github.com/tatsu-lab/stanford_alpaca
[5]https://github.com/huggingface/transformers/blob/main/examples/pytorch/language-modeling/run_clm.py
[6]https://github.com/ai408/nlp-engineering/blob/main/20230916_Llama2-Chinese/train/pretrain/pretrain_clm.py
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
机房租用,北京机房租用,IDC机房托管, http://www.fwqtg.net
了解OpenTelemetry的朋友应该知道,为了将率属于同一个请求的多个操作(Span)串起来,上游应用会生成一个唯一的TraceId。在进行跨应用的Web调用时,这个TraceId和代表跟踪操作标识的SpanID一并发给目标应用,W3C还专门指定了一份名为…