Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 

README.md

PaddleNLP 预训练数据流程

本示例致力于打造基于 PaddleNLP 预训练模型的最佳实践。

我们将预训练数据过程划分为以下部分

  • 原始数据转换,原始文本转换为 jsonl 的 json 字符串格式。
  • 数据 ID 化,断句、分词、tokenize 转化为 token id 格式。
  • 训练 index 文件生成,生成 train、valid、test 的每个样本索引。
  • token 动态 mask(可选),python 层实时 mask 文本。

本目录下主要包含一下文件:

├── create_pretraining_data.py
├── merge.py
├── trans_to_json.py
├── words_segmentation.py
└── README.md

环境依赖

  • tqdm
  • numpy
  • pybind11
  • fast_dataindex
  • lac (可选)
  • zstandard (可选)

安装命令pip install tqdm numpy pybind11 fast_dataindex lac zstandard。另,部分功能需要g++>=4.8编译支持

训练全流程数据 Pipeline

飞桨是自主研发、功能完备、开源开放的产业级深度学习平台,集深度学习核心训练和推理框架、基础模型库、端到端开发套件和丰富的工具组件于一体

步骤 阶段                      数据格式 样例
0️⃣初始状态 - 原始数据:
每个 doc 之间用空行间隔开
- 中文,默认每句换行符,作为句子结束。
- 英文,默认使用 nltk 判断句子结束
飞桨是功能完备、开源开放的产业级深度学习平台。
飞桨拥有核心训练和推理框架、基础模型库。

PaddleNLP是自然语言处理领域的优秀工具。
1️⃣原始数据转换
trans_to_json.py
预处理
输入:0️⃣初始状态
输出:jsonl
jsonl 格式:每个 doc 对应一行 json 字符串 {"text": "飞桨是功能完备、开源开放的产业级深度学习平台。飞桨拥有..."}
{"text": "PaddleNLP是自然语言..."}
❇️(可选)数据中文分词
words_segmentation.py
语料分词:中文 WWM
输入:jsonl
输出:0️⃣初始状态
将 jsonl 格式的数据,恢复成分词后的原始格式数据
飞桨 是 功能 完备、开源 开放的 产业级 深度学习 平台。
飞桨 拥有 核心 训练和推理 框架、基础 模型库。

PaddleNLP 是 自然语言处理领域 的 优秀工具。
2️⃣数据 ID 化
create_pretrain_data.py
预处理 bin 格式:数据 id 化后的 token id
idx 格式:数据句子、文章位置索引
-
3️⃣训练 index 文件生成 训练启动 npy 格式:
根据训练步数 max_steps 生成
train、valid、test 的每个样本索引文件
-
4️⃣token 动态 mask(可选) Dataset 取数据 -

注意:

  • ❇️(可选)数据中文分词 是中文预训练做 WWM 的可选步骤
    • 当你的数据比较少时,分词耗时较少,不需要分词步骤。直接在create_pretrain_data.py步骤中分词即可。
    • 目的是为了提前分词,加快后续数据 ID 转化步骤。
    • 如果这里输入的是 jsonl 格式文件,最好为多文件,trans_to_json.py 时候开启no-merge选项。
    • 当你的数据集比较大,或者需要尝试多次转换数据的时候,提前分词可以避免create_pretrain_data.py时每次都运行一次分词程序。
  • 转换后,需要重新进行步骤 1️⃣原始数据转换 trans_to_json.py,最后2️⃣数据 ID 化步骤设置--cn_splited=True参数。
  • 2️⃣数据 ID 化也可以在转化 ID 的同时,一起实现分词。不需要❇️数据中文分词步骤。

数据教程汇总

针对目前开源的数据集,PaddleNLP 提供了详细的数据教程,点击对应数据集的链接,即可开始进行数据制作:

名称 文本类型 纯文本大小 适配模型
CLUECorpusSmall 中文 14GB Llama
OpenWebText2 英文 70GB Llama
WuDaoCorpus2.0 Base 中文 200GB Llama
CLUECorpus2020 中文 200GB Llama

预训练详细准备

下面以 ziya-llama-13b-v1预训练为例,简要介绍一下预训练的全流程。

原始数据

首先下载样例数据:

mkdir data && cd data
wget https://bj.bcebos.com/paddlenlp/models/transformers/data_tools/baike.txt
cd ..

原始数据转换 jsonl 格式

使用trans_to_json.py转化为 json 串格式,下面是脚本的使用说明

optional arguments:
  -h, --help            show this help message and exit
  --input_path INPUT_PATH
                        Path to you raw files. Folder or file path.
                        必须设置,可以是文件夹或者单个文件。文件夹中的目录默认最多搜索两层子目录。
  --output_path OUTPUT_PATH
                        Path to save the output json files.
                        必须设置,输出文件的名字。
  --json_key JSON_KEY   The content key of json file.
                        建议不修改,默认的key是text
  --doc_spliter DOC_SPLITER
                        Spliter between documents. We will strip the line, if you use blank line to split doc, leave it blank.
                        根据实际情况修改,默认空行作为文章换行符。
  --min_doc_length MIN_DOC_LENGTH
                        Minimal char of a document.
                        可选。过滤掉长度多短的文章,默认值10
  --workers WORKERS     Number of worker processes to launch
                        可选。多进程转化文件,适用于 input_path 中包含的文件数据较多的情况。每个文件,分配给不同worker处理
  --log_interval LOG_INTERVAL
                        Interval between progress updates.
                        可选。此处的interval是值处理完文件个数的间隔。
  --no-merge            Don't merge the file.
                        可选。默认不开启这个选项,默认每个文件转换的jsonl文本,会拼接成到同一个文件。
  --no-shuffle          Don't shuffle the file.
                        可选。默认不开启这个选项,默认对处理完进行shuffle。

根据说明,我们使用下面简单命令,可以得到baike_sample.jsonl文件。此处,我们对文章所有 doc 进行了 shuffle。

python trans_to_json.py  --input_path ./data --output_path baike_sample
#查看数据
head -1 baike_sample.jsonl
{"text": "中国效仿西方发展工业的过程,于中华民国国民政府成立后至中日战争开战前夕已顺畅发展,尽管其间受到内外因素的多重干扰。尔后直至中日战争和国共战争的结束,
中国始有较为长期的和平发展时期。\n1980年代以来,邓小平政府宣布改革开放,开始实行社会主义市场经济并推行经济体制改革。中国大陆近年至2010年,GDP超过72000亿美元,
已经成为美国之后的世界第二经济大国,普遍认为中国是世界上发展速度最快的经济体,但是人均国民生产总值仍位于世界中等水平(第89位),并逐渐受到资源限制和贫富差距加
大的制约。中华人民共和国省份中,广东为GDP最高的第一强省,浙江为人均收入最高的第一富省。中国大陆、香港、澳门、台湾之间的经济联系在全球化的过程中日益紧密。\n"}

数据 ID 化

本部分,我们使用 create_pretraining_data.py 脚本将前面得到的 baike_sample.jsonl 进行 tokenize id 化处理。

optional arguments:
  -h, --help            show this help message and exit
  --model_name_or_path MODEL_NAME_OR_PATH
                        What model to use.
                        必须设置,如:idea-ccnl/ziya-llama-13b-v1, 可以参考已有的模型名称 https://github.com/PaddlePaddle/PaddleNLP/blob/develop/llm
data input/output:
  --input_path INPUT_PATH
                        Path to input JSON files.
                        必须设置,输入文件jsonl的目录
  --output_prefix OUTPUT_PREFIX
                        Output prefix to store output file.
                        必须设置,输出文件的名称。
                        假设名称为XXX,则会输出 XXX.bin, XXX.idx 两个文件。
                        bin文件,数据id化后的token ids; idx文件,数据句子、文章位置索引。
  --data_format {JSON}  Only support json format for now. One document per line.
                        不需要设置。目前默认处理jsonl数据格式
  --json_key JSON_KEY   For JSON format. Space separate listed of keys to extract from json
                        文本串json的key值。同前面trans_to_json.py的json_key,默认text为key
  --split_sentences     Split documents into sentences.
                        是否需要将文章划分成句子。一般而言,GPT不需要,BERT/ERNIE模型需要
  --data_impl {mmap,lazy}
                        Convert the json into mmap/lazy format.
                        处理后的数据格式,可选“mmap”或“lazy”,其中“mmap”格式在读入数据时会建立内存映射,“lazy”格式在读入数据时直接从文件读取。

chinese words:
  --chinese             Is corpus need words segmentation step for chinese words.
                        若设置了split_sentences,并处理中文则需要设置。
  --cn_whole_word_segment
                        Is corpus need words segmentation step for chinese words WWM.
                        可选。是否需要WWM策略。一般而言,BERT/ERNIE模型需要,GPT不需要。
  --cn_seg_func {lac,seg,jieba}
                        Words segment function for chinese words.
                        默认jieba,jieba速度较快,lac模型更准确,计算量高。
  --cn_splited          Is chinese corpus is split into words.
                        分词后的文本,可选。设置此选项则,cn_seg_func不起作用。
                        例如分词后文本串 "中国 效仿 西方 发展 工业 的过 程"
  --cn_split_dimer CN_SPLIT_DIMER
                        Split dimer between chinese words.
                        配合cn_splited使用,默认空格表示分词间隔。

common config:
  --append_eos          Append an <eos> token to the end of a document.
                        gpt类模型专用,gpt设置此选项,表示doc结束。针对tokenizer中不包含eos_token情况,输出提示warning并且不添加<eos>。
  --log_interval LOG_INTERVAL
                        Interval between progress updates
                        打印日志间隔,interval表示处理 文本行数/doc数的 间隔。
  --workers WORKERS     Number of worker processes to launch
                        处理文本id化的进程个数。
  --max_repeated_len    Max length of repeated chars to keep
                        最大保留重复的字符个数。

通过下面脚本转化,我们可以得到处理好的预训练数据,token ids:baike_sample.bin, 文章索引信息baike_sample.idx.

  • 针对 llama 模型
python -u  create_pretraining_data.py \
    --model_name_or_path "idea-ccnl/ziya-llama-13b-v1" \
    --input_path "baike_sample.jsonl" \
    --output_prefix "baike_sample"  \
    --data_format "JSON" \
    --json_key "text" \
    --data_impl "mmap" \
    --append_eos \
    --log_interval 5 \
    --workers 40
  • 针对 ernie 模型
python -u  create_pretraining_data.py \
    --model_name_or_path "ernie-3.0-base-zh" \
    --input_path "baike_sample.jsonl" \
    --output_prefix "baike_sample"  \
    --data_format "JSON" \
    --json_key "text" \
    --split_sentences \
    --data_impl "mmap" \
    --chinese \
    --cn_whole_word_segment \
    --cn_seg_func "jieba" \
    --log_interval 5 \
    --workers 40
  1. 如果您使用已经分好词的语料,可以设置 --cn_splited 为 True,同时指定--cn_split_dimer 如空格。
  2. 使用自定义词表的话,请指定 model_name 为词表所在的文件夹地址。

若需要预处理的文件过大,该脚本所耗费的时间可能会很长。此时可以考虑将 jsonl 文件拆分为多个小文件,并行使用 create_pretraining_data.py 进行处理,得到多个.bin & .idx 文件。 之后使用如下 merge 脚本合并多个小的.bin & .idx 文件。

python merge.py \
    --input /root/data \
    --output-prefix /root/data/merged \
    --data_impl mmap

使用说明:

arguments:
  --input INPUT_PATH
                        Path to the folder where the files to be merged.
                        待合并的文件所在文件夹,文件夹内各个小文件需按merge的顺序排列,如1.bin / 1.idx,2.bin / 2.idx...
  --output_prefix OUTPUT_PREFIX
                        Output prefix to store output file.
                        合并后输出文件的名称,假设名称为XXX,则会输出 XXX.bin, XXX.idx 两个文件。
  --data_impl {mmap,lazy}
                        Convert the json into mmap/lazy format.
                        merge前后的数据格式,可选“mmap”或“lazy,各个待merge的文件需格式一致。”。

预训练开始

得到了处理好的训练数据,就可以开始模型的预训练了。简单将预处理好的数据,拷贝到 data 目录,即可开始预训练。

mkdir data
mv ./preprocess/baike_sample* ./data

代码说明:

  • 动态 mask 相关代码实现在./data_tools/dataset_utils.py 用户可以根据自己的需求,灵活修改 mask 方式。具体可以参考dataset_utils.pycreate_masked_lm_predictions函数。 可以自定义的选项有 do_whole_word_mask, favor_longer_ngram, do_permutation, geometric_dist 等, 可以参考Megatron使用这些 lm_mask 策略。

参考内容

注: 大部分数据流程,参考自Megatron,特此表达感谢。