微调神经机器翻译模型全流程

MBART: Multilingual Denoising Pre-training for Neural Machine Translation

模型下载

mBART 是一个基于序列到序列的去噪自编码器,使用 BART 目标在多种语言的大规模单语语料库上进行预训练。mBART 是首批通过去噪完整文本在多种语言上预训练序列到序列模型的方法之一,而以往的方法则仅集中在编码器、解码器或重构文本的部分内容。

首先需要在github上下载mbart的预训练模型,我们要完成的任务是微调:README
在这里插入图片描述
下载mbart.CC25模型,下载解压后的目录如下:

├── mbart.cc25.v2
    └── dict.txt
    └── model.pt
    └── sentence.bpe.model

dict是模型的词典文件,model是mbart的预训练模型,sentence.bpe.model是sentencepiece训练分词的模型。
我们在en->vi双语对上对预训练模型进行微调:
在这里插入图片描述
数据为IWSLT15的双语对,下载好数据之后对训练集、验证集和测试集重新命名,整理后的目录如下

├── en_vi 
    └── test.en_XX
    └── test.vi_VN
    └── train.en_XX
    └── train.vi_VN
    └── valid.en_XX
    └── valid.vi_VN

环境准备

这里需要特定的fairseq版本来完成以下的这些命令,因此推荐新创建一个conda环境来隔离版本,这里我们命名为mbart_ft.

fairseq=0.10.2
python=3.8
numpy=1.19.5

数据分词

首先使用sentencepiece模型对数据进行分词,由于原文中描述没有额外的 true-casing、normalizing punctuation / characters.因此我们直接分词即可。

#!/bin/bash

SPM=/path/to/sentencepiece/build/src/spm_encode
MODEL=/mbart/mbart.cc25.v2/sentence.bpe.model
DATA=/mbart/en_vi 
DEST=/mbart/en_vi/spm
TRAIN=train         
VALID=valid        
TEST=test           
SRC=en_XX              
TGT=vi_VN              

${SPM} --model=${MODEL} < ${DATA}/${TRAIN}.${SRC} > ${DEST}/${TRAIN}.spm.${SRC} &
${SPM} --model=${MODEL} < ${DATA}/${TRAIN}.${TGT} > ${DEST}/${TRAIN}.spm.${TGT} &
${SPM} --model=${MODEL} < ${DATA}/${VALID}.${SRC} > ${DEST}/${VALID}.spm.${SRC} &
${SPM} --model=${MODEL} < ${DATA}/${VALID}.${TGT} > ${DEST}/${VALID}.spm.${TGT} &
${SPM} --model=${MODEL} < ${DATA}/${TEST}.${SRC} > ${DEST}/${TEST}.spm.${SRC} &
${SPM} --model=${MODEL} < ${DATA}/${TEST}.${TGT} > ${DEST}/${TEST}.spm.${TGT} &

wait
echo "SentencePiece encoding completed!"

我们创建spm目录,分词后的目录文件为:

├── en_vi
	├── spm 
    	└── test.spm.en_XX
    	└── test.spm.vi_VN
    	└── train.spm.en_XX
    	└── train.spm.vi_VN
    	└── valid.spm.en_XX
    	└── valid.spm.vi_VN

数据预处理

使用fairseq将数据处理为满足训练的、输入模型的格式。包含两种语言的词典文件、二进制格式和分词转换为id的文件。

#!/bin/bash

BASEDIR=/mbart/en_vi
DATA=${BASEDIR}/spm
DEST=${BASEDIR}/ids
DICT=/mbart/mbart.cc25.v2/dict.txt
SRC=en_XX
TGT=en_vi

TRAIN=train
VALID=valid
TEST=test

fairseq-preprocess \
--source-lang ${SRC} \
--target-lang ${TGT} \
--trainpref ${DATA}/${TRAIN}.spm \
--validpref ${DATA}/${VALID}.spm \
--testpref ${DATA}/${TEST}.spm  \
--destdir ${DEST}/  \
--thresholdtgt 0 \
--thresholdsrc 0 \
--srcdict ${DICT} \
--tgtdict ${DICT} \
--workers 70

预处理后的模型数据准备的目录为:

├── en_vi
	├── ids 
    	└── dict.en_XX.txt
    	└── dict.vi_VN.txt
    	└── preprocess.log
    	└── test.en_XX-vi_VN.en_XX.bin
    	└── test.en_XX-vi_VN.en_XX.idx
    	└── test.en_XX-vi_VN.vi_VN.bin
    	└── test.en_XX-vi_VN.vi_VN.idx
    	└── train.en_XX-vi_VN.en_XX.bin
    	└── train.en_XX-vi_VN.en_XX.idx
    	└── train.en_XX-vi_VN.vi_VN.bin
    	└── train.en_XX-vi_VN.vi_VN.idx
    	└── valid.en_XX-vi_VN.en_XX.bin
    	└── valid.en_XX-vi_VN.en_XX.idx
    	└── valid.en_XX-vi_VN.vi_VN.bin
    	└── valid.en_XX-vi_VN.vi_VN.idx

训练集和验证集在训练过程中被用到,而测试集只在评价生成中被用到。

模型的训练

需要注意的是,与官方文档设置的参数相比,有一处需要修改。
--max-update 40000:模型参数更新次数。
----total-num-update 40000 这是设置学习率调度器的更新次数,即学习率更新40k次训练停止。
在mbart的原文中:

We use a maximum of 40K training updates for all low and medium resource pairs and 100K for high resource pairs.

我们的en-vi双语数据属于低资源语言对,因此参数更新次数40K次,即应该设置--max-update 40000

#!/bin/bash
source /path/to/conda/etc/profile.d/conda.sh
conda activate mbart_ft

BASEDIR=/mbart/en_vi
PRETRAIN=/mbart/mbart.cc25.v2/model.pt # 已下载的预训练模型路径
DATA=${BASEDIR}/ids    # 预处理后的二进制数据路径

SRC=en_XX
TGT=vi_VN

langs=ar_AR,cs_CZ,de_DE,en_XX,es_XX,et_EE,fi_FI,fr_XX,gu_IN,hi_IN,it_IT,ja_XX,kk_KZ,ko_KR,lt_LT,lv_LV,my_MM,ne_NP,nl_XX,ro_RO,ru_RU,si_LK,tr_TR,vi_VN,zh_CN

fairseq-train ${DATA} \
  --encoder-normalize-before --decoder-normalize-before \
  --arch mbart_large --layernorm-embedding \
  --task translation_from_pretrained_bart \
  --source-lang ${SRC} --target-lang ${TGT} \
  --criterion label_smoothed_cross_entropy --label-smoothing 0.2 \
  --optimizer adam --adam-eps 1e-06 --adam-betas '(0.9, 0.98)' \
  --lr-scheduler polynomial_decay --lr 3e-05 --warmup-updates 2500 --max-update 40000 \
  --dropout 0.3 --attention-dropout 0.1 --weight-decay 0.0 \
  --max-tokens 1024 --update-freq 2 \
  --save-interval 1 --save-interval-updates 5000 --keep-interval-updates 10 --no-epoch-checkpoints \
  --seed 222 --log-format simple --log-interval 2 \
  --restore-file $PRETRAIN \
  --reset-optimizer --reset-meters --reset-dataloader --reset-lr-scheduler \
  --langs $langs \
  --save-dir ${BASEDIR} \
  --ddp-backend no_c10d

在一块RTX 4090显卡上,运行3个小时后,训练结束。我们设置了每5000次更新保存一次检查点,微调模型保存的文件位置为 --save-dir ${BASEDIR}
微调后的目录文件为:

├── en_vi
	├── ids 
	├── spm
    └── dict.en_XX.txt
    └── checkpoint_2_5000.pt
    └── checkpoint_4_10000.pt
    └── checkpoint_6_15000.pt
    └── checkpoint_8_20000.pt
    └── checkpoint_10_25000.pt
    └── checkpoint_12_30000.pt
    └── checkpoint_14_35000.pt
    └── checkpoint_16_40000.pt
    └── checkpoint_best.pt
    └── checkpoint_last.pt
    └── ...train...test...valid

模型的解码

我们使用checkpoint_best.pt对其进行解码以及测BLEU分数。
这里我将分词模型复制到了en_vi文件夹中,并且添加--cpu使得解码在cpu上运行。解码生成的文件为/mbart/en_vi/ids/en_vi


2025.1.13修订:
需要注意的是,相比于官方文档,这里删除了--bpe "sentencepiece"--sentencepiece-model $model_dir/sentence.bpe.model以及--sacrebleu
若保留--sacrebleu,由于版本间不匹配会报错
若保留--bpe "sentencepiece",则除了模型推理行“H”,其他源句子、目标句子和行“D”均没有空格出现。说明解码过程中并不需要此参数。
--remove-bpe 'sentencepiece':用于去除分词过程中产生的spm标记。

#!/bin/bash
source /path/to/conda/etc/profile.d/conda.sh
conda activate mbart_ft
model_dir=/mbart/en_vi/ids 

langs=ar_AR,cs_CZ,de_DE,en_XX,es_XX,et_EE,fi_FI,fr_XX,gu_IN,hi_IN,it_IT,ja_XX,kk_KZ,ko_KR,lt_LT,lv_LV,my_MM,ne_NP,nl_XX,ro_RO,ru_RU,si_LK,tr_TR,vi_VN,zh_CN
TOKENIZER=${model_dir}/sentence.bpe.model

fairseq-generate ${model_dir} \
  --path $model_dir/../checkpoint_best.pt \
  --task translation_from_pretrained_bart \
  --gen-subset test \
  --cpu \
  -t vi_VN -s en_XX \
  --remove-bpe 'sentencepiece' \
  --batch-size 32 \
  --langs $langs > ${model_dir}/en_vi

查看生成文件en_vi的片段:

S-74	I lost all hope .[en_XX]
T-74	Tôi hoàn toàn tuyệt vọng .
H-74	-0.4808153808116913	Tôi đã mất hết hy vọng .
D-74	-0.4808153808116913	Tôi đã mất hết hy vọng .
P-74	-0.3194 -0.9490 -0.5736 -0.8777 -0.7397 -0.0389 -0.4746 -0.2814 -0.2920 -0.2618
S-372	Today I am 22 .[en_XX]
T-372	Hôm nay tôi 22 tuổi .
H-372	-0.3478223383426666	Hôm nay tôi 22 tuổi .
D-372	-0.3478223383426666	Hôm nay tôi 22 tuổi .
P-372	-0.5605 -0.0631 -0.4549 -0.2989 -0.4617 -0.4079 -0.3166 -0.3061 -0.2606
S-336	Thank you very much .[en_XX]
T-336	Cám ơn rất nhiều .
H-336	-0.46486935019493103	Cám ơn các bạn rất nhiều .
D-336	-0.46486935019493103	Cám ơn các bạn rất nhiều .
P-336	-1.8484 -0.0979 -0.1278 -0.9053 -0.2160 -0.4894 -0.1446 -0.4404 -0.2856 -0.3061 -0.2521
S-1267	Thank you very much .[en_XX]
T-1267	Cảm ơn rất nhiều .
H-1267	-0.46486935019493103	Cám ơn các bạn rất nhiều .
D-1267	-0.46486935019493103	Cám ơn các bạn rất nhiều .
P-1267	-1.8484 -0.0979 -0.1278 -0.9053 -0.2160 -0.4894 -0.1446 -0.4404 -0.2856 -0.3061 -0.2521
S-21	But many die .[en_XX]
T-21	Nhưng rất nhiều người đã chết .
H-21	-0.5680863261222839	Nhưng nhiều người chết .
D-21	-0.5680863261222839	Nhưng nhiều người chết .
P-21	-0.3266 -1.4395 -0.1804 -1.2362 -0.5122 -0.2999 -0.2973 -0.2526

S:是源句子,在en->vi双语对上,源语言是英语。
T:是人工翻译句子,即测试集中的句子;
H:是模型输出的解码句子,第一个数字为其得分;
D:第一个数字为得分和H一致,但相比于H去掉了所有的空格,和S、T格式相同;
P:翻译过程中每个单词的预测概率。
运行解码脚本后,在ids目录中会生成 en_vi 文件。

├── en_vi
	├── ids 
    	└── sentence.bpe.model
    	└── en_vi
    	└── train...test...valid...dict...
	├── spm
	├── train...valid...test...

模型的评价

cat en_vi | grep -P "^H" |sort -V |cut -f 3- | sed 's/\[vi_VN\]//g' > en_vi.hyp
cat en_vi | grep -P "^T" |sort -V |cut -f 2- | sed 's/\[vi_VN\]//g' > en_vi.ref
sacrebleu  en_vi.ref -i en_vi.hyp -m bleu -tok "spm"

这里将 H 开头的行提取,并去掉前两个字段,仅保留模型输出的解码句子,将他们合成 en_vi.hyp文件;
将 T 开头的行提取,并去掉第一个字段,保留test文件中的目标句子,将他们合成 en_vi.ref 文件。
这两行代码运行后,目录ids中应该多出两个文件。

├── en_vi
	├── ids 
    	└── en_vi
    	└── en_vi.hyp
    	└── en_vi.ref
    	└── train...test...valid...dict...
	├── spm
	├── train...valid...test...

这两个文件的行数应该一致,使用sacrebleu来测bleu的分数,指定 -tok 分词方式是 “spm” 即sentencepiece。
我们测试的模型评价结果为:

{
 "name": "BLEU",
 "score": 35.4,
 "signature": "nrefs:1|case:mixed|eff:no|tok:flores101|smooth:exp|version:2.4.3",
 "verbose_score": "66.3/42.8/28.8/19.5 (BP = 0.997 ratio = 0.997 hyp_len = 34971 ref_len = 35063)",
 "nrefs": "1",
 "case": "mixed",
 "eff": "no",
 "tok": "flores101",
 "smooth": "exp",
 "version": "2.4.3"
}

可以看到,我们复现了原文中在en->vi方向的 BLEU 评分。


附录

原版本未删除--bpe "sentencepiece"--sentencepiece-model $model_dir/sentence.bpe.model参数,fairseq推理后生成的en_vi文件为:

S-74    Ilostallhope.[en_XX]
T-74    Tôihoàntoàntuyệtvọng.
H-74    -0.4808153808116913     Tôi đã mất hết hy vọng .
D-74    -0.4808153808116913     Tôiđãmấthếthyvọng.
P-74    -0.3194 -0.9490 -0.5736 -0.8777 -0.7397 -0.0389 -0.4746 -0.2814 -0.2920 -0.2618
S-372   TodayIam22.[en_XX]
T-372   Hômnaytôi22tuổi.
H-372   -0.3478223383426666     Hôm nay tôi 22 tuổi .
D-372   -0.3478223383426666     Hômnaytôi22tuổi.
P-372   -0.5605 -0.0631 -0.4549 -0.2989 -0.4617 -0.4079 -0.3166 -0.3061 -0.2606
S-336   Thankyouverymuch.[en_XX]
T-336   Cámơnrấtnhiều.
H-336   -0.46486935019493103    Cám ơn các bạn rất nhiều .
D-336   -0.46486935019493103    Cámơncácbạnrấtnhiều.
P-336   -1.8484 -0.0979 -0.1278 -0.9053 -0.2160 -0.4894 -0.1446 -0.4404 -0.2856 -0.3061 -0.2521
S-1267  Thankyouverymuch.[en_XX]
T-1267  Cảmơnrấtnhiều.
H-1267  -0.46486935019493103    Cám ơn các bạn rất nhiều .
D-1267  -0.46486935019493103    Cámơncácbạnrấtnhiều.
P-1267  -1.8484 -0.0979 -0.1278 -0.9053 -0.2160 -0.4894 -0.1446 -0.4404 -0.2856 -0.3061 -0.2521
S-21    Butmanydie.[en_XX]
T-21    Nhưngrấtnhiềungườiđãchết.
H-21    -0.5680863261222839     Nhưng nhiều người chết .
D-21    -0.5680863261222839     Nhưngnhiềungườichết.
P-21    -0.3266 -1.4395 -0.1804 -1.2362 -0.5122 -0.2999 -0.2973 -0.2526

可以看到,测试集源句子S以及目标句子T的空格被误删除。由此提取的模型生成文件en_vi.hyp和翻译参考文件en_vi.ref同样误删空格。且模型输出句子H是正常的,这就说明是在解码过程中出现的问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/953680.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

RTX 5090 加持,科研服务器如何颠覆 AI 深度学习构架?

RTX 5090作为英伟达旗舰级GPU&#xff0c;凭借Ada Lovelace架构&#xff0c;融合创新的SM多单元流处理器、第三代RT Core与第四代Tensor Core&#xff0c;打造出极为强劲的计算体系。其24GB GDDR6X显存搭配1TB/s带宽&#xff0c;能以极低延迟和超高吞吐量处理大规模张量数据&am…

【2025最新】机器学习类计算机毕设选题80套,适合大数据,人工智能

【2025最新】机器学习类型计算机毕设选题 1-10套 基于Spring Boot的物流管理系统的设计与实现 基于机器学习的虚假招聘信息的分析与预测 基于机器学习的影响数据科学家职业变动因素的分析与预测 基于Spring Boot的历史文物交流平台的设计与实现 基于机器学习的肥胖影响因素的分…

【PPTist】幻灯片放映

放映功能的代码都在 src/hooks/useScreening.ts&#xff0c;我们看一下 从当前页开始 放映的功能。 // 进入放映状态&#xff08;从当前页开始&#xff09; const enterScreening () > {enterFullscreen()screenStore.setScreening(true) }首先是 enterFullscreen()&#…

MySQL 16 章——变量、流程控制和游标

一、变量 在MySQL数据库的存储过程和存储函数中&#xff0c;可以使用变量来存储查询或计算的中间结果数据&#xff0c;或者输出最终的结果数据 在MySQL数据库中&#xff0c;变量分为系统变量和用户自定义变量 &#xff08;1&#xff09;系统变量 1.1.1系统变量分类 变量由…

T-SQL编程

目录 1、T-SQL的元素 1.1 标识符 1. 常规标识符 2. 分隔标识符 1.2 变量 1. 全局变量 2. 局部变量 1.3 运算符 1. 算数运算符 2. 赋值运算符 3. 位运算符 4. 比较运算符 5. 逻辑运算符 6. 字符串连接运算符 7. 一元运算符 8. 运算符的优先级和结合性 1.4 批处…

2024 China Collegiate Programming Contest (CCPC) Zhengzhou Onsite 基础题题解

L. Z-order Curve 思路&#xff1a;这题目说了&#xff0c;上面那一行&#xff0c;只有在偶数位才有可能存在1&#xff0c;那么一定存在这样的数&#xff0c;0 ,1,100, 10000,那么反之&#xff0c;我们的数列是行的二倍&#xff0c;因此会出现10,1000,100000这样的数&#xff0…

Unity2D初级背包设计后篇 拓展举例与不足分析

Unity2D初级背包设计中篇 MVC分层撰写(万字详解)-CSDN博客、 如果你已经搞懂了中篇&#xff0c;那么对这个背包的拓展将极为简单&#xff0c;我就在这里举个例子吧 目录 1.添加物品描述信息 2.拓展思路与不足分析 1.没有删除只有丢弃功能&#xff0c;所以可以添加垃圾桶 2.格…

vue(七) vue进阶

目录 第一课&#xff1a;Vue方法、计算机属性及侦听器 一、数组变化侦测 方法1&#xff1a;变更方法 方法2&#xff1a;替换一个数组 例子&#xff1a;小Demo:合并两个数组 二、计算属性 1.基础&#xff08;不推荐&#xff09; 2.使用计算属性来完成案例 3.使用函数的方…

Spring Boot 2 学习指南与资料分享

Spring Boot 2 学习资料 Spring Boot 2 学习资料 Spring Boot 2 学习资料 在当今竞争激烈的 Java 后端开发领域&#xff0c;Spring Boot 2 凭借其卓越的特性&#xff0c;为开发者们开辟了一条高效、便捷的开发之路。如果你渴望深入学习 Spring Boot 2&#xff0c;以下这份精心…

YangQG 面试题汇总

一、交叉链表 问题&#xff1a; 给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点&#xff0c;返回 null 。 解题思想&#xff1a; 双指针 备注&#xff1a;不是快慢指针&#xff0c;如果两个长度相…

fastapi 使用

参考&#xff1a; https://fastapi.tiangolo.com/zh/tutorial/first-steps/https://fastapi.tiangolo.com/zh/tutorial/first-steps/ FastAPI 用于基于标准 Python 类型提示使用 Python 构建 API&#xff0c;使用 ASGI 的标准来构建 Python Web 框架和服务器。所有简单理解&a…

2024年度漏洞态势分析报告,需要访问自取即可!(PDF版本)

2024年度漏洞态势分析报告&#xff0c;需要访问自取即可!(PDF版本),大家有什么好的也可以发一下看看

泛目录和泛站有什么差别

啥是 SEO 泛目录&#xff1f; 咱先来说说 SEO 泛目录是啥。想象一下&#xff0c;你有一个巨大的图书馆&#xff0c;里面的书架上摆满了各种各样的书&#xff0c;每一本书都代表着一个网页。而 SEO 泛目录呢&#xff0c;就像是一个超级图书管理员&#xff0c;它的任务就是把这些…

k8s基础(6)—Kubernetes-存储

Kubernetes-存储概述 k8s的持久券简介 Kubernetes的持久卷&#xff08;PersistentVolume, PV&#xff09;和持久卷声明&#xff08;PersistentVolumeClaim, PVC&#xff09;为用户在Kubernetes中使用卷提供了抽象。PV是集群中的一块存储&#xff0c;PVC是对这部分存储的请求。…

深度学习-卷积神经网络反向传播梯度公式推导

这篇文章非常棒&#xff0c;单样本单通道的反向传播梯度公式推导我都理解了。为了防止找不到原网页&#xff0c;所以特复制于此 参考&#xff1a; https://zhuanlan.zhihu.com/p/640697443

论文笔记(四十七)Diffusion policy: Visuomotor policy learning via action diffusion(下)

Diffusion policy: Visuomotor policy learning via action diffusion&#xff08;下&#xff09; 文章概括5. 评估5.1 模拟环境和数据集5.2 评估方法论5.3 关键发现5.4 消融研究 6 真实世界评估6.1 真实世界Push-T任务6.2 杯子翻转任务6.3 酱汁倒入和涂抹任务 7. 实际双臂任务…

C#学习笔记 --- 简单应用

1.operator 运算符重载&#xff1a;使自定义类可以当做操作数一样进行使用。规则自己定。 2.partial 分部类&#xff1a; 同名方法写在不同位置&#xff0c;可以当成一个类使用。 3.索引器&#xff1a;使自定义类可以像数组一样通过索引值 访问到对应的数据。 4.params 数…

汽车基础软件AutoSAR自学攻略(四)-AutoSAR CP分层架构(3) (万字长文-配21张彩图)

汽车基础软件AutoSAR自学攻略(四)-AutoSAR CP分层架构(3) (万字长文-配21张彩图) 前面的两篇博文简述了AutoSAR CP分层架构的概念&#xff0c;下面我们来具体到每一层的具体内容进行讲解&#xff0c;每一层的每一个功能块力求用一个总览图&#xff0c;外加一个例子的图给大家进…

【2024年华为OD机试】 (CD卷,100分)- 最大N个数与最小N个数的和(Java JS PythonC/C++)

一、问题描述 题目描述 给定一个数组&#xff0c;编写一个函数来计算它的最大N个数与最小N个数的和。你需要对数组进行去重。 说明&#xff1a; 数组中数字范围 [0, 1000]最大N个数与最小N个数不能有重叠&#xff0c;如有重叠&#xff0c;输入非法返回 -1输入非法返回 -1 …

WINFORM - DevExpress -> DevExpress总结[安装、案例]

安装devexpress软件 路径尽量不换&#xff0c;后面破解不容易出问题 vs工具箱添加控件例如: ①使用控制台进入DevExpress安装目录: cd C:\Program Files (x86)\DevExpress 20.1\Components\Tools ②添加DevExpress控件&#xff1a; ToolboxCreator.exe/ini:toolboxcreator…