-
Notifications
You must be signed in to change notification settings - Fork 142
快速上手
这里我们通过常用的例子来简要说明如何使用TencentPretrain,更多的细节请参考使用说明章节。我们首先使用文本预训练模型BERT和书评情感分类数据集。我们在书评语料上对模型进行预训练,然后在书评情感分类数据集上对其进行微调。这个过程有三个输入文件:书评语料,书评情感分类数据集和中文词典。这些文件均为UTF-8编码,并被包括在这个项目中。
BERT模型要求的预训练语料格式是一行一个句子,不同文档使用空行分隔,如下所示:
doc1-sent1
doc1-sent2
doc1-sent3
doc2-sent1
doc3-sent1
doc3-sent2
书评语料是由书评情感分类数据集去掉标签得到的。我们将一条评论从中间分开,从而形成一个两句话的文档,具体可见corpora文件夹中的book_review_bert.txt。
分类数据集的格式如下:
label text_a
1 instance1
0 instance2
1 instance3
标签和文本之间用\t分隔,第一行是列名。对于n分类,标签应该是0到n-1之间(包括0和n-1)的整数。
词典文件的格式是一行一个单词,我们使用谷歌提供的包含21128个中文字符的词典文件models/google_zh_vocab.txt。
我们首先对书评语料进行预处理。预处理阶段需要将语料处理成为指定预训练模型要求的数据格式(--data_processor):
python3 preprocess.py --corpus_path corpora/book_review_bert.txt --vocab_path models/google_zh_vocab.txt \
--dataset_path dataset.pt --processes_num 8 --data_processor bert
注意我们需要安装 six>=1.12.0。
预处理非常耗时,使用多个进程可以大大加快预处理速度(--processes_num)。默认的分词器为 --tokenizer bert 。原始文本在预处理之后被转换为pretrain.py可以接收的输入,dataset.pt。然后下载Google中文预训练模型google_zh_model.bin(此文件为TencentPretrain支持的格式,原始模型来自于这里),并将其放在 models 文件夹中。接着加载Google中文预训练模型,在书评语料上对其进行增量预训练。预训练模型通常由词向量层,编码层和目标任务层组成。因此要构建预训练模型,我们应该给出这些信息,比如编码层使用什么类型的Encoder模块。这里我们通过配置文件(--config_path)指定模型使用的模块类型和超参数等信息。具体可见models/bert/base_config.json。假设我们有一台带有8个GPU的机器:
python3 pretrain.py --dataset_path dataset.pt --vocab_path models/google_zh_vocab.txt \
--pretrained_model_path models/google_zh_model.bin \
--config_path models/bert/base_config.json \
--output_model_path models/book_review_model.bin \
--world_size 8 --gpu_ranks 0 1 2 3 4 5 6 7 \
--total_steps 5000 --save_checkpoint_steps 1000 --batch_size 32
mv models/book_review_model.bin-5000 models/book_review_model.bin
请注意,pretrain.py输出的模型会带有记录训练步数的后缀(--total_steps),这里我们可以删除后缀以方便使用。
然后,我们在下游分类数据集上微调预训练模型,我们使用 pretrain.py 的输出book_review_model.bin(加载词向量层和编码层参数):
python3 finetune/run_classifier.py --pretrained_model_path models/book_review_model.bin \
--vocab_path models/google_zh_vocab.txt \
--config_path models/bert/base_config.json \
--train_path datasets/book_review/train.tsv \
--dev_path datasets/book_review/dev.tsv \
--test_path datasets/book_review/test.tsv \
--epochs_num 3 --batch_size 32
微调后的模型的默认路径是models/finetuned_model.bin。注意到预训练的实际batch size大小是 --batch_size 乘以 --world_size;分类等下游任务微调的实际的batch size大小是 --batch_size 。然后我们利用微调后的分类器模型进行预测:
python3 inference/run_classifier_infer.py --load_model_path models/finetuned_model.bin \
--vocab_path models/google_zh_vocab.txt \
--config_path models/bert/base_config.json \
--test_path datasets/book_review/test_nolabel.tsv \
--prediction_path datasets/book_review/prediction.tsv \
--labels_num 2
--test_path 指定需要预测的文件,文件需要包括text_a列; --prediction_path 指定预测结果的文件; 注意到我们需要指定分类任务标签的个数 --labels_num ,这里是二分类任务。
我们还可以使用 google_zh_model.bin 在下游分类数据集上微调:
python3 finetune/run_classifier.py --pretrained_model_path models/google_zh_model.bin \
--vocab_path models/google_zh_vocab.txt \
--config_path models/bert/base_config.json \
--train_path datasets/book_review/train.tsv \
--dev_path datasets/book_review/dev.tsv \
--test_path datasets/book_review/test.tsv \
--epochs_num 3 --batch_size 32
前面提到过,模型相关的关键信息一般放在配置文件中。这里我们进一步介绍前面使用的BERT-base模型的配置文件 models/bert/base_config.json :
{
"emb_size": 768,
"feedforward_size": 3072,
"hidden_size": 768,
"hidden_act": "gelu",
"heads_num": 12,
"layers_num": 12,
"max_seq_length": 512,
"dropout": 0.1,
"data_processor": "bert"
"embedding": ["word", "pos", "seg"],
"encoder": "transformer",
"mask": "fully_visible",
"target": ["mlm", "sp"],
"tie_weights": true
}
BERT模型的词向量层是word(token)、position、segment向量的求和,因此使用 "embedding": ["word", "pos", "seg"] ;BERT使用Transformer编码器("encoder": "transformer"),并且句子中的任意一个词可以看到所有词的信息,因此我们使用 fully_visible 遮罩类型("mask": "fully_visible");在预训练目标任务方面,BERT同时使用遮罩语言模型和句子预测,因此使用 "target": ["mlm", "sp"] 。"tie_weights": true 指定embedding层和softmax前一层共享参数。预训练阶段还需要指定 dataset.pt 的格式("data_processor": "bert")。这里和预处理阶段 --data_processor bert 保持一致。
推荐使用CUDA_VISIBLE_DEVICES指定程序可见的GPU(如果不指定,则使用所有的GPU)。假设我们需要使用0号GPU和2号GPU:
python3 preprocess.py --corpus_path corpora/book_review_bert.txt --vocab_path models/google_zh_vocab.txt \
--dataset_path dataset.pt --processes_num 8 --data_processor bert
CUDA_VISIBLE_DEVICES=0,2 python3 pretrain.py --dataset_path dataset.pt --vocab_path models/google_zh_vocab.txt \
--pretrained_model_path models/google_zh_model.bin \
--config_path models/bert/base_config.json \
--output_model_path models/book_review_model.bin \
--world_size 2 --gpu_ranks 0 1 \
--total_steps 5000 --save_checkpoint_steps 1000 --batch_size 32
mv models/book_review_model.bin-5000 models/book_review_model.bin
CUDA_VISIBLE_DEVICES=0,2 python3 finetune/run_classifier.py --pretrained_model_path models/book_review_model.bin \
--vocab_path models/google_zh_vocab.txt \
--config_path models/bert/base_config.json \
--train_path datasets/book_review/train.tsv \
--dev_path datasets/book_review/dev.tsv \
--test_path datasets/book_review/test.tsv \
--output_model_path models/classifier_model.bin \
--epochs_num 3 --batch_size 32
CUDA_VISIBLE_DEVICES=0,2 python3 inference/run_classifier_infer.py --load_model_path models/classifier_model.bin \
--vocab_path models/google_zh_vocab.txt \
--config_path models/bert/base_config.json \
--test_path datasets/book_review/test_nolabel.tsv \
--prediction_path datasets/book_review/prediction.tsv \
--labels_num 2
注意到我们在微调阶段使用 --output_model_path 指定微调后的模型的输出路径。
预测是否是下一个句子(NSP)是BERT的目标任务之一,但是,NSP任务不适合句子级别的评论,因为我们需要将句子切分为多个部分去构造文档。 TencentPretrain可以让用户自由选择不同的目标任务。这里我们选择使用遮罩语言模型(MLM)作为目标任务。去掉NSP目标任务,只使用MLM目标任务对评论语料可能是更合适的选择:
python3 preprocess.py --corpus_path corpora/book_review.txt --vocab_path models/google_zh_vocab.txt \
--dataset_path dataset.pt --processes_num 8 --dynamic_masking --data_processor mlm
python3 pretrain.py --dataset_path dataset.pt --vocab_path models/google_zh_vocab.txt \
--pretrained_model_path models/google_zh_model.bin \
--config_path models/bert/base_config.json \
--output_model_path models/book_review_mlm_model.bin \
--world_size 8 --gpu_ranks 0 1 2 3 4 5 6 7 \
--total_steps 5000 --save_checkpoint_steps 1000 --batch_size 32 \
--data_processor mlm --target mlm
mv models/book_review_mlm_model.bin-5000 models/book_review_mlm_model.bin
CUDA_VISIBLE_DEVICES=0,1 python3 finetune/run_classifier.py --pretrained_model_path models/book_review_mlm_model.bin \
--vocab_path models/google_zh_vocab.txt \
--config_path models/bert/base_config.json \
--train_path datasets/book_review/train.tsv \
--dev_path datasets/book_review/dev.tsv \
--test_path datasets/book_review/test.tsv \
--epochs_num 3 --batch_size 32
在预训练阶段,我们仍然使用BERT-base配置文件 models/bert/base_config.json ,但是由于只保留MLM目标任务,因此在命令行中进行指定 --data_processor mlm --target mlm 。我们可以通过多种方式去控制模型的类型,超参数等信息,它们的优先级如下:命令行、配置文件、默认设置。也就是说,我们在命令行中指定的信息会覆盖配置文件中的信息以及默认的信息。 这里使用了动态遮罩策略(--dynamic_masking)。动态遮罩策略能减小 dataset.pt 的大小,并且相对于静态遮罩通常会有更好的效果。因此推荐使用动态遮罩。 不同的预训练目标需要不同格式的语料。MLM目标对应的语料格式为一行一个文档:
doc1
doc2
doc3
注意到当预训练目标被改为MLM后,我们使用的预训练语料为 corpora/book_review.txt 而不是 corpora/book_review_bert.txt。
除了分类外,TencentPretrain还可以用于其他多种下游任务的微调。在下游任务数据集章节中,我们可以下载各种数据集。这里我们下载LCQMC、MSRA-NER、CMRC2018数据集,并将它们放到 datasets 文件夹中
我们可以使用 run_classifier.py 进行文本对分类:
python3 finetune/run_classifier.py --pretrained_model_path models/google_zh_model.bin \
--vocab_path models/google_zh_vocab.txt \
--config_path models/bert/base_config.json \
--train_path datasets/lcqmc/train.tsv \
--dev_path datasets/lcqmc/dev.tsv \
--test_path datasets/lcqmc/test.tsv \
--output_model_path models/classifier_model.bin \
--batch_size 32 --epochs_num 3 --seq_length 128
对于文本对分类,数据集需要包括text_a、text_b、label列。 然后我们使用微调后的文本对分类模型进行推理:
python3 inference/run_classifier_infer.py --load_model_path models/classifier_model.bin \
--vocab_path models/google_zh_vocab.txt \
--config_path models/bert/base_config.json \
--test_path datasets/lcqmc/test.tsv \
--prediction_path datasets/lcqmc/prediction.tsv \
--seq_length 128 --labels_num 2
被预测的文件(--test_path)需要包括text_a和text_b列。
我们可以使用 run_ner.py 进行命名实体识别:
python3 finetune/run_ner.py --pretrained_model_path models/google_zh_model.bin \
--vocab_path models/google_zh_vocab.txt \
--config_path models/bert/base_config.json \
--train_path datasets/msra_ner/train.tsv \
--dev_path datasets/msra_ner/dev.tsv \
--test_path datasets/msra_ner/test.tsv \
--output_model_path models/ner_model.bin \
--label2id_path datasets/msra_ner/label2id.json \
--epochs_num 5 --batch_size 16
--label2id_path 指定用于命名实体识别的label2id文件的路径。 然后我们使用微调后的命名实体模型模型进行推理:
python3 inference/run_ner_infer.py --load_model_path models/ner_model.bin \
--vocab_path models/google_zh_vocab.txt \
--config_path models/bert/base_config.json \
--test_path datasets/msra_ner/test_nolabel.tsv \
--prediction_path datasets/msra_ner/prediction.tsv \
--label2id_path datasets/msra_ner/label2id.json
我们可以使用 run_cmrc.py 进行机器阅读理解:
python3 finetune/run_cmrc.py --pretrained_model_path models/google_zh_model.bin \
--vocab_path models/google_zh_vocab.txt \
--config_path models/bert/base_config.json \
--train_path datasets/cmrc2018/train.json --dev_path datasets/cmrc2018/dev.json \
--output_model_path models/cmrc_model.bin \
--epochs_num 2 --batch_size 8 --seq_length 512
我们不指定 --test_path ,因为CMRC2018数据集不提供测试集的标签。 然后,我们使用微调后的机器阅读理解模型进行推理:
python3 inference/run_cmrc_infer.py --load_model_path models/cmrc_model.bin \
--vocab_path models/google_zh_vocab.txt \
--config_path models/bert/base_config.json \
--test_path datasets/cmrc2018/test.json \
--prediction_path datasets/cmrc2018/prediction.json \
--seq_length 512
TencentPretrain支持分类任务的交叉验证,在竞赛数据集SMP2020-EWECT上使用交叉验证的示例:
CUDA_VISIBLE_DEVICES=0 python3 finetune/run_classifier_cv.py --pretrained_model_path models/google_zh_model.bin \
--vocab_path models/google_zh_vocab.txt \
--config_path models/bert/base_config.json \
--train_path datasets/smp2020-ewect/virus/train.tsv \
--train_features_path datasets/smp2020-ewect/virus/train_features.npy \
--output_model_path models/classifier_model.bin \
--epochs_num 3 --batch_size 32 --folds_num 5
google_zh_model.bin 的结果为79.1/63.8(准确率/F1值); --folds_num 指定交叉验证的轮数; --output_path 指定微调模型的路径,共保存 --folds_num 个微调后的模型,并将 fold ID 后缀添加到模型名称中; --train_features_path 指定out-of-fold预测文件的路径;训练集被分成了 --folds_num 折。一折样本的预测概率是由其他折上的数据训练的模型预测得到的。train_features.npy 可用于stacking集成。竞赛解决方案章节给出了更多详细信息。
我们可以进一步尝试不同的预训练模型。例如,可以下载RoBERTa-wwm-ext-large from HIT并将其转换为TencentPretrain格式:
python3 scripts/convert_bert_from_huggingface_to_tencentpretrain.py --input_model_path models/chinese_roberta_wwm_large_ext_pytorch/pytorch_model.bin \
--output_model_path models/chinese_roberta_wwm_large_ext_pytorch/pytorch_tencentpretrain_model.bin \
--layers_num 24
CUDA_VISIBLE_DEVICES=0,1 python3 finetune/run_classifier_cv.py --pretrained_model_path models/chinese_roberta_wwm_large_ext_pytorch/pytorch_tencentpretrain_model.bin \
--vocab_path models/google_zh_vocab.txt \
--config_path models/bert/large_config.json \
--train_path datasets/smp2020-ewect/virus/train.tsv \
--train_features_path datasets/smp2020-ewect/virus/train_features.npy \
--output_model_path models/classifier_model.bin \
--folds_num 5 --epochs_num 3 --batch_size 32
RoBERTa-wwm-ext-large 的结果为80.3/66.8(准确率/F1值)。注意到这里使用BERT-large的配置文件(--config_path models/bert/large_config.json)。为了方便用户使用,我们已经将其他机构的预训练模型权重转换为TencentPretrain格式。预训练模型仓库章节给出了更多详细信息。
使用我们的预训练模型评论语料RoBERTa-large的示例如下:
CUDA_VISIBLE_DEVICES=0,1 python3 finetune/run_classifier_cv.py --pretrained_model_path models/review_roberta_large_model.bin \
--vocab_path models/google_zh_vocab.txt \
--config_path models/bert/large_config.json \
--train_path datasets/smp2020-ewect/virus/train.tsv \
--train_features_path datasets/smp2020-ewect/virus/train_features.npy \
--output_model_path models/classifier_model.bin \
--folds_num 5 --learning_rate 1e-5 --epochs_num 3 --batch_size 32 --seed 11
结果为81.3/68.4(准确率/F1值),与其他开源预训练模型相比,这一结果很具有竞争力。这个预训练模型使用的语料和SMP2020-EWECT(微博评论数据集)高度相似。 有时大模型无法收敛,我们需要通过指定 --seed 尝试不同的随机种子。
TencentPretrain支持Transformer之外的编码器。这里我们选择2层LSTM编码器来替代12层Transformer编码器。我们首先下载2层LSTM编码器的预训练模型cluecorpussmall_lstm_lm_model.bin。这个预训练模型在CLUECorpusSmall语料上训练了50万步:
python3 preprocess.py --corpus_path corpora/cluecorpussmall.txt --vocab_path models/google_zh_vocab.txt \
--dataset_path dataset.pt --processes_num 8 --seq_length 256 --data_processor lm
python3 pretrain.py --dataset_path dataset.pt --vocab_path models/google_zh_vocab.txt \
--config_path models/rnn/lstm_config.json \
--output_model_path models/cluecorpussmall_lstm_lm_model.bin \
--world_size 8 --gpu_ranks 0 1 2 3 4 5 6 7 \
--total_steps 500000 --save_checkpoint_steps 100000 \
--learning_rate 1e-3 --batch_size 64
把预训练模型记录训练步数的后缀去掉,然后在下游分类数据集上对其进行微调:
python3 finetune/run_classifier.py --pretrained_model_path models/cluecorpussmall_lstm_lm_model.bin \
--vocab_path models/google_zh_vocab.txt \
--config_path models/rnn/lstm_config.json \
--train_path datasets/book_review/train.tsv \
--dev_path datasets/book_review/dev.tsv \
--test_path datasets/book_review/test.tsv \
--learning_rate 1e-3 --epochs_num 5 --batch_size 64 \
--pooling mean
python3 inference/run_classifier_infer.py --load_model_path models/finetuned_model.bin \
--vocab_path models/google_zh_vocab.txt \
--config_path models/rnn/lstm_config.json \
--test_path datasets/book_review/test_nolabel.tsv \
--prediction_path datasets/book_review/prediction.tsv \
--pooling mean --labels_num 2
我们可以在测试集上得到约85的准确率。相比之下,我们使用相同的LSTM编码器,但是不加载预训练模型,只能得到约81的准确率。
TencentPretrain还支持更多的预训练模型。 我们下载ELMo预训练模型cluecorpussmall_elmo_model.bin。这个预训练模型在CLUECorpusSmall语料上训练了50万步:
python3 preprocess.py --corpus_path corpora/cluecorpussmall.txt --vocab_path models/google_zh_vocab.txt \
--dataset_path dataset.pt --processes_num 8 --seq_length 256 --data_processor bilm
python3 pretrain.py --dataset_path dataset.pt --vocab_path models/google_zh_vocab.txt \
--config_path models/rnn/bilstm_config.json \
--output_model_path models/cluecorpussmall_elmo_model.bin \
--world_size 8 --gpu_ranks 0 1 2 3 4 5 6 7 \
--total_steps 500000 --save_checkpoint_steps 100000 \
--learning_rate 5e-4 --batch_size 64
把预训练模型记录训练步数的后缀去掉,然后在书评情感分类数据集上对其进行增量预训练和微调:
python3 preprocess.py --corpus_path corpora/book_review.txt --vocab_path models/google_zh_vocab.txt \
--dataset_path dataset.pt --processes_num 8 --seq_length 192 --data_processor bilm
python3 pretrain.py --dataset_path dataset.pt --vocab_path models/google_zh_vocab.txt \
--pretrained_model_path models/cluecorpussmall_elmo_model.bin \
--config_path models/rnn/bilstm_config.json \
--output_model_path models/book_review_elmo_model.bin \
--world_size 8 --gpu_ranks 0 1 2 3 4 5 6 7 \
--total_steps 5000 --save_checkpoint_steps 2500 \
--learning_rate 5e-4 --batch_size 64
mv models/book_review_elmo_model.bin-5000 models/book_review_elmo_model.bin
python3 finetune/run_classifier.py --pretrained_model_path models/book_review_elmo_model.bin \
--vocab_path models/google_zh_vocab.txt \
--config_path models/rnn/bilstm_config.json \
--train_path datasets/book_review/train.tsv \
--dev_path datasets/book_review/dev.tsv \
--test_path datasets/book_review/test.tsv \
--learning_rate 5e-4 --epochs_num 5 --batch_size 64 --seq_length 192 \
--pooling max
python3 inference/run_classifier_infer.py --load_model_path models/finetuned_model.bin \
--vocab_path models/google_zh_vocab.txt \
--config_path models/rnn/bilstm_config.json \
--test_path datasets/book_review/test_nolabel.tsv \
--prediction_path datasets/book_review/prediction.tsv \
--seq_length 192 --pooling max --labels_num 2
corpora/book_review.txt 是由书评情感分类数据集去掉标签得到的。
在分类数据集上微调GatedCNN模型的示例:
python3 finetune/run_classifier.py --pretrained_model_path models/cluecorpussmall_gatedcnn_lm_model.bin \
--vocab_path models/google_zh_vocab.txt \
--config_path models/cnn/gatedcnn_9_config.json \
--train_path datasets/book_review/train.tsv \
--dev_path datasets/book_review/dev.tsv \
--test_path datasets/book_review/test.tsv \
--learning_rate 5e-5 --epochs_num 5 --batch_size 64 \
--pooling mean
python3 inference/run_classifier_infer.py --load_model_path models/finetuned_model.bin \
--vocab_path models/google_zh_vocab.txt \
--config_path models/cnn/gatedcnn_9_config.json \
--test_path datasets/book_review/test_nolabel.tsv \
--prediction_path datasets/book_review/prediction.tsv \
--pooling mean --labels_num 2
用户可以从这里下载 wikizh_gatedcnn_lm_model.bin。这个预训练模型在CLUECorpusSmall语料上训练了50万步:
python3 preprocess.py --corpus_path corpora/cluecorpussmall.txt --vocab_path models/google_zh_vocab.txt \
--dataset_path dataset.pt --processes_num 8 --seq_length 256 --data_processor lm
python3 pretrain.py --dataset_path dataset.pt --vocab_path models/google_zh_vocab.txt \
--config_path models/cnn/gatedcnn_9_config.json \
--output_model_path models/cluecorpussmall_gatedcnn_lm_model.bin \
--world_size 8 --gpu_ranks 0 1 2 3 4 5 6 7 \
--total_steps 500000 --save_checkpoint_steps 100000 --report_steps 100 \
--learning_rate 1e-4 --batch_size 64
使用GPT-2模型微调下游任务示例:
python3 finetune/run_classifier.py --pretrained_model_path models/cluecorpussmall_gpt2_seq1024_model.bin \
--vocab_path models/google_zh_vocab.txt \
--config_path models/gpt2/config.json \
--train_path datasets/book_review/train.tsv \
--dev_path datasets/book_review/dev.tsv \
--test_path datasets/book_review/test.tsv \
--epochs_num 3 --batch_size 32 \
--pooling mean
使用GPT-2模型生成文本示例:
python3 scripts/generate_lm.py --load_model_path models/cluecorpussmall_gpt2_seq1024_model.bin \
--vocab_path models/google_zh_vocab.txt \
--config_path models/gpt2/config.json \
--test_path beginning.txt --prediction_path generated_text.txt \
--seq_length 128
用户可以从这里下载 cluecorpussmall_gpt2_seq1024_model.bin 。beginning.txt 包含一段文本的开头。
使用LSTM语言模型生成文本示例:
python3 scripts/generate_lm.py --load_model_path models/cluecorpussmall_lstm_lm_model.bin \
--vocab_path models/google_zh_vocab.txt \
--config_path models/rnn/lstm_config.json \
--test_path beginning.txt --prediction_path generated_text.txt \
--seq_length 128
使用GatedCNN语言模型生成文本示例:
python3 scripts/generate_lm.py --load_model_path models/cluecorpussmall_gatedcnn_lm_model.bin \
--vocab_path models/google_zh_vocab.txt \
--config_path models/cnn/gatedcnn_9_config.json \
--test_path beginning.txt --prediction_path generated_text.txt \
--seq_length 128
在大多数情况下,我们使用 --vocab_path models/google_zh_vocab.txt 和 --tokenizer bert 组合进行分词。在项目的大多数脚本中, --tokenizer bert 作为默认的分词器被使用。因此我们通常不会显式的指定 --tokenizer 。这里我们展示更多的分词器和词典的使用方法。
--tokenizer bert 在处理中文的时候是基于字的。如果我们想得到基于词的预训练模型并基于其进行微调和推理,那么首先我们要对语料进行分词,词与词之间用空格分隔。然后,我们基于对 corpora/book_review.txt 分词后的语料(corpora/book_review_seg.txt)构建词典:
python3 scripts/build_vocab.py --corpus_path corpora/book_review_seg.txt \
--output_path models/book_review_word_vocab.txt \
--delimiter space --workers_num 8 --min_count 5
由于词与词之间用空格分隔,因此在预处理和预训练阶段需要使用 --tokenizer space 。基于词的模型预处理和预训练示例:
python3 preprocess.py --corpus_path corpora/book_review_seg.txt \
--vocab_path models/book_review_word_vocab.txt --tokenizer space \
--dataset_path book_review_word_dataset.pt \
--processes_num 8 --seq_length 128 --dynamic_masking --data_processor mlm
python3 pretrain.py --dataset_path book_review_word_dataset.pt \
--vocab_path models/book_review_word_vocab.txt --tokenizer space \
--config_path models/bert/base_config.json \
--output_model_path models/book_review_word_model.bin \
--world_size 8 --gpu_ranks 0 1 2 3 4 5 6 7 \
--total_steps 5000 --save_checkpoint_steps 2500 --report_steps 500 \
--learning_rate 1e-4 --batch_size 64 \
--data_processor mlm --target mlm
在下游任务微调和推理的过程中,我们同样需要显式的指定 --vocab_path models/book_review_word_vocab.txt 和 --tokenizer space ,并且数据集的训练/验证/测试集文本列(text_a和text_b)需要使用相同的分词工具进行分词。我们对 datasets/book_review/ 中的文件进行分词,放在 datasets/book_review_seg/ 文件夹中:
mv models/book_review_word_model.bin-5000 models/book_review_word_model.bin
python3 finetune/run_classifier.py --pretrained_model_path models/book_review_word_model.bin \
--vocab_path models/book_review_word_vocab.txt --tokenizer space \
--config_path models/bert/base_config.json \
--train_path datasets/book_review_seg/train.tsv \
--dev_path datasets/book_review_seg/dev.tsv \
--test_path datasets/book_review_seg/test.tsv \
--epochs_num 3 --batch_size 32
python3 inference/run_classifier_infer.py --load_model_path models/finetuned_model.bin \
--vocab_path models/book_review_word_vocab.txt --tokenizer space \
--config_path models/bert/base_config.json \
--test_path datasets/book_review_seg/test_nolabel.tsv \
--prediction_path datasets/book_review_seg/prediction.tsv \
--labels_num 2
使用SentencePiece分词示例:
python3 preprocess.py --corpus_path corpora/book_review.txt \
--spm_model_path models/cluecorpussmall_spm.model \
--dataset_path book_review_word_sentencepiece_dataset.pt \
--processes_num 8 --seq_length 128 --dynamic_masking \
--data_processor mlm
python3 pretrain.py --dataset_path book_review_word_sentencepiece_dataset.pt \
--spm_model_path models/cluecorpussmall_spm.model \
--output_model_path models/book_review_word_sentencepiece_model.bin \
--world_size 8 --gpu_ranks 0 1 2 3 4 5 6 7 \
--total_steps 5000 --save_checkpoint_steps 2500 --report_steps 500 \
--learning_rate 1e-4 --batch_size 64 \
--data_processor mlm --target mlm
mv models/book_review_word_sentencepiece_model.bin-5000 models/book_review_word_sentencepiece_model.bin
python3 finetune/run_classifier.py --pretrained_model_path models/book_review_word_sentencepiece_model.bin \
--spm_model_path models/cluecorpussmall_spm.model \
--config_path models/bert/base_config.json \
--train_path datasets/book_review/train.tsv \
--dev_path datasets/book_review/dev.tsv \
--test_path datasets/book_review/test.tsv \
--epochs_num 3 --batch_size 32
python3 inference/run_classifier_infer.py --load_model_path models/finetuned_model.bin \
--spm_model_path models/cluecorpussmall_spm.model \
--config_path models/bert/base_config.json \
--test_path datasets/book_review/test_nolabel.tsv \
--prediction_path datasets/book_review/prediction.tsv \
--labels_num 2
通过 --spm_model_path models/cluecorpussmall_spm.model 指定使用在CLUECorpusSmall语料上训练的SentencePiece分词模型。
如果使用基于字的分词方式,可以使用 --vocab_path models/google_zh_vocab.txt 和 --tokenizer char 的组合代替上面的 --spm_model_path models/cluecorpussmall_spm.model,其余的选项不变。 由于谷歌提供的词典 models/google_zh_vocab.txt 是基于字的,因此可以直接使用。
更深入的细节原理请参见分词和词典章节。