opennmt-py+sentencepeice+ctranslate2训练及部署机器翻译模型

Posted 陈仙女歪歪技术分享

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了opennmt-py+sentencepeice+ctranslate2训练及部署机器翻译模型相关的知识,希望对你有一定的参考价值。

机器翻译模型训练步骤

运行环境:ubantu或centos,python3.6以上
tip:本人在撰写这个的时候是python小白+深度学习小白所以有些地方写的比较细致,前几年写的了一直没发出来,有什么问题欢迎留言交流。后续会出工作和学习中遇到的各种问题及解决方案(暂时只限NLP方向机器翻译方向)

一、训练分词模型

用sentencepiece进行分词
git地址:https://github.com/google/sentencepiece

1.训练分词模型

下载sentencepiece进入根目录

spm_train --input=/home/cspm_train --input=/home//tmp/fr-zh.fr --model_prefix=/tmp/spm_fr --vocab_size=32000  train_extremely_large_corpus=truehenqiulin/tmp/fr-zh.fr --model_prefix=/tmp/spm_fr --vocab_size=32000  train_extremely_large_corpus=true

如果报错可能是因为内存不够然后尝试把数据量调小一点指定训练语料大小数据
–input_sentence_size:语料大小
–vocab_size:词表大小
–shuffle_input_sentence:大语料集要这个参数
–model_type:训练方式 unigram (default), bpe, char,word

spm_train --input=/home//tmp/fr-zh.fr --model_prefix=/tmp/spam_fr --vocab_size=32000 --input_sentence_size=1752096  and --shuffle_input_sentence=true

2.生成词表

model:模型位置
–output_format:id/piece 被分词文件路径

spm_encode --model=/tmp/zh.model  --output_format=piece /home//tmp/zh_file.text /tmp/1.test

也可以分词到指定文件

spm_encode --model /home//protmp/OpenNMT-py//spam_fr.model</home//protmp/OpenNMT-py//general_domain_fr_zh/datasets/general_domain.fr.test>/home//tmp/fr.spm.txt

二、训练机翻模型

用Opennmt-py训练机翻模型
git地址:https://github.com/OpenNMT/OpenNMT-py
准备工作:把数据分成三份:训练集,开发集,测试集

1.构建配置文件 config.yaml

如果已经进行了分词transforms: [sentencepiece]则不需要加
filtertoolong:过滤句子长度

# wmt14_en_de.yaml
save_data: data/wmt/run/example

# Corpus opts:
data:
    train:
        path_src: /general_domain_fr_zh/datasets/general_domain.fr.test
        path_tgt: /general_domain_fr_zh/datasets/general_domain.zh.train
        transforms: [sentencepiece]
#        权重
        weight: 23
    valid:
        path_src: /general_domain_fr_zh/datasets/general_domain.fr.test
        path_tgt: /general_domain_fr_zh/datasets/general_domain.zh.test
        transforms: [sentencepiece]

### Transform related opts:
#### Subword
src_subword_model: /spm_fr.model
tgt_subword_model: /spm_zh.model
src_subword_type: sentencepiece
tgt_subword_type: sentencepiece
# onmttok_kwargs: "'mode': 'none', 'spacer_annotate': True"

subword_nbest: 1
subword_alpha: 0.0
#### Filter 过滤长句
src_seq_length: 120
tgt_seq_length: 120

# silently ignore empty lines in the data
skip_empty_level: silent


# # Vocab opts
# ### vocab:
src_vocab: /general_domain_fr_zh/vocab/general_domain_fr.vocab
tgt_vocab: /general_domain_fr_zh/vocab/general_domain_zh.vocab
src_vocab_size: 20000
tgt_vocab_size: 32000
vocab_size_multiple: 8
src_words_min_frequency: 3
tgt_words_min_frequency: 3

# # Model training parameters

# General opts
save_model: /general_domain_fr_zh/model/model
keep_checkpoint: 10
save_checkpoint_steps: 5000
average_decay: 0.0005
seed: 1234
report_every: 100
train_steps: 50000
valid_steps: 5000
train_from: /general_domain_fr_zh/model_step_10000.pt #从指定检查点训练
# Batching
queue_size: 2048
bucket_size: 32768
pool_factor: 8192
world_size: 2
gpu_ranks: [0,1]  #占了两个gpu
batch_type: "tokens"
batch_size: 4096
valid_batch_size: 16 #
batch_size_multiple: 1
max_generator_batches: 0
accum_count: [3]
accum_steps: [0]

# Optimization
model_dtype: "fp32"
optim: "adam"
learning_rate: 2
warmup_steps: 6000
decay_method: "noam"
adam_beta2: 0.998
max_grad_norm: 0
label_smoothing: 0.1
param_init: 0
param_init_glorot: true
normalization: "tokens"

# Model
encoder_type: transformer
decoder_type: transformer
enc_layers: 6
dec_layers: 6
heads: 8
rnn_size: 512
word_vec_size: 512
transformer_ff: 2048
dropout_steps: [0]
dropout: [0.1]
attention_dropout: [0.1]
position_encoding: true

2.生成词表

执行以下命令会自动生成词表到配置文件vocab指定的位置

1.如果已经有词表文件此步骤会报错省略此步骤2.直接用训练分词模型时生成的词表为int会报错,最好用build_vocab脚本重新生成双精度格式的

onmt_build_vocab -config /general_domain_fr_zh/config.yaml -n_sample -1

3.训练

python onmt/bin/train.py -config /general_domain_fr_zh/config.yaml

会遇到许多问题导致训练中途中断:

1.训练速度慢

解决方法:(1)把batch_size参数调大(2)Valid_batch_size调大(3)valid_steps改大,但不要超过train_steps否则不会验证(4)开发集数据不要留过大,一两万就行了

2.显存不够,训练中断

解决方法:(1)把batch_size参数调小(2)训练速度过慢加过滤长句transforms: [sentencepiece,filtertoolong]

3.训练中断后从指定检查点进行训练

Train.py -train_from:xx.model 

测试bleu

测试集的译文要先进行分词

spm_encode --model /home//protmp/OpenNMT-py//spam_fr.model</home//protmp/OpenNMT-py//general_domain_fr_zh/datasets/general_domain.fr.test>/home//tmp/fr.spm.txt

翻译

激活环境,配置anaonda3环境参考百度,如果没有环境则进入Opennmt-py根目录下

 source activate opennmt	

执行下列语句进行翻译

python onmt/bin/translate.py -model /home//protmp/OpenNMT-py//general_domain_fr_zh/model/model_step_50000.pt -src /home//tmp/fr.spm.txt -tgt /home//tmp/zh.spm.txt -output /home//tmp/zh.spm.predict.txt

中途遇到的问题:语料大导致翻译速度缓慢
解决方案:

python onmt/bin/translate.py --replace_unk -batch_type tokens -beam_size 5 -gpu 1 -batch_size 4096 -model /home//protmp/OpenNMT-py//general_domain_fr_zh/model/model_step_50000.pt -src /home//tmp/fr.spm.txt -tgt /home//tmp/zh.spm.txt -output /home//tmp/zh.spm.predict.txt

分词还原

spm_decode --model /home//protmp/OpenNMT-py//spam_zh.model -input_format=piece </home//tmp/zh.spm.predict.txt>/home//tmp/zh.predict.txt

测试belu

sacrebleu -l fr-zh  /home///tmp/general_domain.zh.test  < /home///tmp/zh.predict.txt 

注意问题和常用命令

加python环境:无法导入上层包也是这个问题

export PYTHONPATH=$PYTHONPATH:./

查看显存占用情况

nvidia-smi

三、部署模型

1.使用Ctranslate2进行模型转换

首先到opennmt官网下载Ctranslate2,激活opennmt环境

ct2-opennmt-py-converter --model_path /home//OpenNMT-py//general_domain_zh_fr/model/model_step_200000.pt  --output_dir /home//OpenNMT-py//basic/basic_zh_fr_model/convert1028

转换后会生成一个convert文件夹,这个文件的路径便是配置文件里模型的路径
model.bin
source_vocabulary.txt
target_vocabulary.txt

RuntimeError: Unable to open file ‘model.bin’ in model 'mount/converzh0917’遇到这个错误请重新构建配置文件

下面是Linux常用命令可以自行忽略

pip install -i https://pypi.douban.com/simple -r requirements.txt  #指定镜像下载

后台执行python程序

 nohup python -u  scripts/generate_bt_data.py /home//bt/zhfr/news-commentary.tail.zh /home//bt/zhfr/news-commentary.tail.bt.fr >/home//bt/frzh/my.log 2>&1 &
nohup python -u  onmt/bin/train.py  -config /home//OpenNMT-py//general_domain_fr_zh/config.yaml  >/home//OpenNMT-py//general_domain_fr_zh/frzhtrain.log 2>&1 &
 shuf words.txt > shuffled_words.txt 打乱
paste fr_total.clean.nor.tok.tc.fr  zh_total.clean.nor.zh >frzhall.txt 合并
cut  原文件 -f1>新文件 拆指定列
cat frzhall.csv | grep 'A型房间' 查找指定字符数据
sed -n '1200002p' zh.train.src  打印指定行
cat 一个文件 > 另一个文件 把一个文件追加到另一个文件末尾,覆盖
cat 一个文件 >> 另一个文件 把一个文件追加到另一个文件末尾 不覆盖拼接

以上是关于opennmt-py+sentencepeice+ctranslate2训练及部署机器翻译模型的主要内容,如果未能解决你的问题,请参考以下文章