news 2026/9/7 10:00:42

Transformers 机器翻译实战:基于 T5 的英法翻译模型微调、SacreBLEU 评估与推理全流程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Transformers 机器翻译实战:基于 T5 的英法翻译模型微调、SacreBLEU 评估与推理全流程

Transformers 机器翻译实战:基于 T5 的英法翻译模型微调、SacreBLEU 评估与推理全流程

【免费下载链接】transformers🤗 Transformers: the model-definition framework for state-of-the-art machine learning models in text, vision, audio, and multimodal models, for both inference and training.项目地址: https://gitcode.com/GitHub_Trending/tra/transformers

本文基于 Transformers 仓库的阿拉伯语任务教程 docs/source/ar/tasks/translation.md 整理并深化,完整讲解如何用Seq2SeqTrainer在 OPUS Books 英法子集上微调 T5 实现英文到法文翻译,覆盖数据集加载、动态填充预处理、SacreBLEU 评估、训练参数配置与推理生成等全链路,并结合仓库中 Seq2SeqTrainer、DataCollatorForSeq2Seq 的源码实现,帮助读者理解每个训练与评估环节背后的调用机制。

1. 翻译任务与总体路线

翻译(Translation)是将文本从一种语言转换到另一种语言的过程,在 Transformers 中通常被建模为序列到序列(Seq2Seq)任务:编码器读取源语言句子,解码器自回归地生成目标语言句子。除了最典型的双语文本翻译,这类模型同样可以扩展到语音翻译、语音转文本等跨模态场景。

本指南对应仓库教程中的实战目标是:

  1. 在 OPUS Books 数据集的英法(en-fr)子集上微调google-t5/t5-small,实现英文到法文的翻译;
  2. 使用微调后的模型进行推理,并通过pipelinemodel.generate两种方式使用它。

在动手之前,先确认安装了必要的依赖库:

pip install transformers datasets evaluate sacrebleu

如果希望把训练产物上传到 Hub 并与社区共享,建议先登录 Hugging Face 账号(在交互式环境中执行notebook_login()即可):

>>> from huggingface_hub import notebook_login >>> notebook_login()

后续训练阶段会通过push_to_hub=True自动推送模型,这一步是前提。

2. 加载 OPUS Books 英法数据集

使用datasets库加载 OPUS Books 数据集的英法子集:

>>> from datasets import load_dataset >>> books = load_dataset("opus_books", "en-fr")

教程采用train_test_split将训练部分再拆分为训练集与验证集(留出 20% 作为测试数据),而不是使用数据集自带的划分字段:

>>> books = books["train"].train_test_split(test_size=0.2)

查看一条样本可以确认数据结构:

>>> books["train"][0] {'id': '90560', 'translation': {'en': 'But this lofty plateau measured only a few fathoms, and soon we reentered Our Element.', 'fr': 'Mais ce plateau élevé ne mesurait que quelques toises, et bientôt nous fûmes rentrés dans notre élément.'}}

其中translation字段是一个字典,分别存放同一段文字的英文与法文译文,这正是 Seq2Seq 训练所需的“输入-目标”配对;id为样本编号,训练时不需要。

3. 数据预处理:任务前缀、目标语言与动态填充

3.1 加载 T5 分词器

>>> from transformers import AutoTokenizer >>> checkpoint = "google-t5/t5-small" >>> tokenizer = AutoTokenizer.from_pretrained(checkpoint)

3.2 预处理函数的三个关键职责

按照教程,预处理函数preprocess_function需要完成三件事:

  1. 添加任务前缀(prefix):T5 这类多任务模型需要通过输入前缀识别当前任务,这里为"translate English to French: "。仓库中翻译示例的 README(examples/pytorch/translation/README.md)同样强调:google-t5/t5-small等 T5 系列模型必须配合--source_prefix "translate English to Romanian: "使用,如果 BLEU 分数异常低,首先要检查是否漏掉了 source prefix。
  2. 设置目标语言(text_target:将法文目标句传入分词器的text_target参数,以保证法文文本被正确切分。若不设置,分词器会默认按英文处理目标文本,破坏目标句的编码。
  3. 截断过长序列:通过max_lengthtruncation=True将序列限制在指定长度以内。
>>> source_lang = "en" >>> target_lang = "fr" >>> prefix = "translate English to French: " >>> def preprocess_function(examples): ... inputs = [prefix + example[source_lang] for example in examples["translation"]] ... targets = [example[target_lang] for example in examples["translation"]] ... model_inputs = tokenizer(inputs, text_target=targets, max_length=128, truncation=True) ... return model_inputs

datasetsmap方法批量应用预处理,batched=True让函数一次处理多条样本,显著加快编码速度:

>>> tokenized_books = books.map(preprocess_function, batched=True)

3.3 DataCollatorForSeq2Seq:为什么用动态填充

教程建议使用 [DataCollatorForSeq2Seq] 组装批次,并明确指出:在组批时把句子动态填充(dynamic padding)到批次内最长句,比把整个数据集统一填充到最大长度更高效。

从源码看,DataCollatorForSeq2Seq 的默认padding=True(即'longest'策略),正是“按批内最长序列填充”。它还有三个值得注意的实现细节:

  • label_pad_token_id默认值为-100,用于填充labels。PyTorch 的交叉熵损失会自动忽略-100位置,因此填充部分不会污染训练损失;
  • 当传入model且模型实现了prepare_decoder_input_ids_from_labels时,collator 会直接从labels生成decoder_input_ids(见 data_collator.py#L608-L615),免去解码器输入的准备开销,并在启用 label smoothing 时避免损失被重复计算;
  • 标签填充方向跟随tokenizer.padding_side(默认右侧),保证input_idslabels的位置对齐。
>>> from transformers import DataCollatorForSeq2Seq >>> data_collator = DataCollatorForSeq2Seq(tokenizer=tokenizer, model=checkpoint)

注意第二个参数名为model,教程中直接传入了 checkpoint 字符串,实际效果是让 Trainer 在运行期绑定到已加载的模型对象;如需完全显式控制,也可以传入模型实例。

4. 评估:SacreBLEU 指标与 compute_metrics

翻译质量通常用 BLEU 分数衡量。教程通过evaluate库加载 SacreBLEU 指标:

>>> import evaluate >>> metric = evaluate.load("sacrebleu")

随后定义compute_metrics函数,接收 Trainer 传入的EvalPrediction(预测 token id 与标签 token id),完成解码、后处理与打分:

>>> import numpy as np >>> def postprocess_text(preds, labels): ... preds = [pred.strip() for pred in preds] ... labels = [[label.strip()] for label in labels] ... return preds, labels >>> def compute_metrics(eval_preds): ... preds, labels = eval_preds ... if isinstance(preds, tuple): ... preds = preds[0] ... decoded_preds = tokenizer.batch_decode(preds, skip_special_tokens=True) ... labels = np.where(labels != -100, labels, tokenizer.pad_token_id) ... decoded_labels = tokenizer.batch_decode(labels, skip_special_tokens=True) ... decoded_preds, decoded_labels = postprocess_text(decoded_preds, decoded_labels) ... result = metric.compute(predictions=decoded_preds, references=decoded_labels) ... result = {"bleu": result["score"]} ... prediction_lens = [np.count_nonzero(pred != tokenizer.pad_token_id) for pred in preds] ... result["gen_len"] = np.mean(prediction_lens) ... result = {k: round(v, 4) for k, v in result.items()} ... return result

几个关键实现点值得注意:

  • labels != -100的判断呼应了 3.3 节:-100是动态填充留下的占位符,解码前先替换回pad_token_id,避免把-100这类非法 id 送入batch_decode
  • prediction_lens统计每条生成序列中非 pad token 的数量并取平均,得到gen_len,用于观察模型生成是否过长或过短;
  • if isinstance(preds, tuple)是对predict_with_generate=True场景的兼容:此时 Trainer 返回的预测是(生成 token, 损失)元组,需要取第一个元素。

该函数在训练配置阶段传入Seq2SeqTrainer,每轮评估时自动被调用。

5. 训练:Seq2SeqTrainingArguments 与 Seq2SeqTrainer

5.1 加载模型

AutoModelForSeq2SeqLM加载 T5 的 Seq2Seq 版本(带语言建模头,可直接用于翻译):

>>> from transformers import AutoModelForSeq2SeqLM, Seq2SeqTrainingArguments, Seq2SeqTrainer >>> model = AutoModelForSeq2SeqLM.from_pretrained(checkpoint)

5.2 训练参数配置

教程给出三步骤:配置训练参数、构造 Trainer、执行训练。完整参数如下,并附逐项说明:

>>> training_args = Seq2SeqTrainingArguments( ... output_dir="my_awesome_opus_books_model", ... eval_strategy="epoch", ... learning_rate=2e-5, ... per_device_train_batch_size=16, ... per_device_eval_batch_size=16, ... weight_decay=0.01, ... save_total_limit=3, ... num_train_epochs=2, ... predict_with_generate=True, ... fp16=True, #change to bf16=True for XPU ... push_to_hub=True, ... )
参数取值说明
output_dirmy_awesome_opus_books_model唯一必填项,本地模型与检查点的保存目录
eval_strategy"epoch"每个 epoch 结束后触发一次评估与检查点保存
learning_rate2e-5全参数微调 T5-small 的常用学习率量级
per_device_train_batch_size/per_device_eval_batch_size16/16单卡训练/评估批大小
weight_decay0.01权重衰减,辅助正则化
save_total_limit3最多保留 3 个检查点,避免磁盘占满
num_train_epochs2训练轮数
predict_with_generateTrue评估时用generate生成文本再计算 BLEU,而非仅看损失
fp16True启用 FP16 混合精度(XPU 设备请改为bf16=True
push_to_hubTrue训练结束后自动推送模型到 Hub(需已登录)

从源码看,Seq2SeqTrainingArguments 在TrainingArguments基础上新增了 Seq2Seq 专用的predict_with_generategeneration_max_lengthgeneration_num_beamsgeneration_configsortish_sampler字段。其中predict_with_generate=True直接决定评估走“生成式指标”路径:Seq2SeqTrainer.prediction_step 在self.args.predict_with_generate为真时调用self.model.generate(...)产出整句译文,并把生成结果右填充到max_length后连同标签返回,供compute_metrics计算 BLEU;generation_max_lengthgeneration_num_beams则作为评估循环中generate的默认长度与束搜索宽度(优先级低于显式传入的gen_kwargs)。此外 Seq2SeqTrainer.init支持通过generation_config加载完整的GenerationConfig并做严格校验,覆盖模型默认生成配置。

5.3 执行训练与上传 Hub

>>> trainer = Seq2SeqTrainer( ... model=model, ... args=training_args, ... train_dataset=tokenized_books["train"], ... eval_dataset=tokenized_books["test"], ... processing_class=tokenizer, ... data_collator=data_collator, ... compute_metrics=compute_metrics, ... ) >>> trainer.train()

参数对应关系:train_dataset/eval_dataset是第 2 节拆分出的tokenized_books["train"]tokenized_books["test"]processing_class传入分词器,用于填充、解码等操作;data_collatorcompute_metrics分别绑定第 3、4 节的实现。

训练结束后,调用trainer.push_to_hub()把模型发布到 Hub,供后续推理直接加载:

>>> trainer.push_to_hub()

不熟悉 Trainer 训练流程的读者,可参考仓库内的 Trainer 教程 docs/source/ar/training.md 补充基础概念。

6. 推理:pipeline 与手动 generate 两种方式

6.1 pipeline 方式

对 T5 而言,输入必须带上任务前缀。翻译英文句子时写成:

>>> text = "translate English to French: Legumes share resources with nitrogen-fixing bacteria."

最省事的用法是pipeline,任务名为translation_xx_to_yyxx换为源语言代码,yy换为目标语言代码,如enfrdeeszh等):

>>> from transformers import pipeline >>> translator = pipeline("translation_xx_to_yy", model="username/my_awesome_opus_books_model") >>> translator(text) [{'translation_text': 'Legumes partagent des ressources avec des bactéries azotantes.'}]

6.2 手动 tokenization + generate

如果需要控制生成参数或复用自定义解码逻辑,可以手动复现 pipeline 的内部流程。

第一步,把带前缀的文本编码为 PyTorch 张量:

>>> from transformers import AutoTokenizer >>> tokenizer = AutoTokenizer.from_pretrained("username/my_awesome_opus_books_model") >>> inputs = tokenizer(text, return_tensors="pt").input_ids

第二步,调用model.generate生成译文,教程示例使用了采样式生成参数:

>>> from transformers import AutoModelForSeq2SeqLM >>> model = AutoModelForSeq2SeqLM.from_pretrained("username/my_awesome_opus_books_model") >>> outputs = model.generate(inputs, max_new_tokens=40, do_sample=True, top_k=30, top_p=0.95)

参数含义:max_new_tokens=40限制最多新生成 40 个 token;do_sample=True开启随机采样;top_k=30top_p=0.95分别通过 k 采样与 nucleus 采样收窄候选范围,提升译文流畅度。更多生成策略(贪心、束搜索、各类采样组合)可查阅仓库的生成模块 src/transformers/generation。

第三步,把 token id 解码回文本:

>>> tokenizer.decode(outputs[0], skip_special_tokens=True) 'Les lignées partagent des ressources avec des bactéries enfixant l'azote.'

7. 进阶:命令行微调脚本 run_translation.py

仓库在 examples/pytorch/translation 提供了与教程同源的脚本化微调方案 run_translation.py,其 README 明确列出了支持的翻译架构:BartForConditionalGenerationMBartForConditionalGenerationMarianMTModelPegasusForConditionalGenerationT5ForConditionalGenerationMT5ForConditionalGenerationFSMTForConditionalGeneration(仅翻译)。该脚本同样从datasets库拉取数据(或读取 jsonlines/csv 文件)完成下载、预处理、微调与评估。

以 MarianMT 为例(无需任务前缀):

python run_translation.py \ --model_name_or_path Helsinki-NLP/opus-mt-en-ro \ --do_train \ --do_eval \ --source_lang en \ --target_lang ro \ --dataset_name wmt16 \ --dataset_config_name ro-en \ --output_dir /tmp/tst-translation \ --per_device_train_batch_size=4 \ --per_device_eval_batch_size=4 \ --predict_with_generate

而 T5 系列模型必须额外指定--source_prefix,与第 3.2 节手工教程中的前缀逻辑一致:

python run_translation.py \ --model_name_or_path google-t5/t5-small \ --do_train \ --do_eval \ --source_lang en \ --target_lang ro \ --source_prefix "translate English to Romanian: " \ --dataset_name wmt16 \ --dataset_config_name ro-en \ --output_dir /tmp/tst-translation \ --per_device_train_batch_size=4 \ --per_device_eval_batch_size=4 \ --predict_with_generate

README 还给出两点实用提醒:

  • 若 BLEU 分数很差,先确认是否遗漏--source_prefix(T5 系列);更换语言对时,--source_lang--target_lang--source_prefix三处必须同步修改;
  • MBart 模型的语言代码需要国家码后缀形式,如en_XXro_RO,而非裸的enro

此外该目录下的 run_translation_no_trainer.py 演示了不依赖 Trainer、自行编写训练循环的写法,适合作为理解 Trainer 内部机制的对照阅读。

8. 小结

本教程完整覆盖了 Transformers 中 Seq2Seq 翻译任务的工程闭环:

  1. 数据load_dataset("opus_books", "en-fr")+train_test_split构建英法平行语料;
  2. 预处理:任务前缀 +text_target目标语言编码 +DataCollatorForSeq2Seq动态填充(-100标签填充、decoder_input_ids自动生成均由 collator 源码保障);
  3. 评估:SacreBLEU 指标配合predict_with_generate=True,在 Seq2SeqTrainer.prediction_step 中触发generate生成式评估;
  4. 训练Seq2SeqTrainingArguments控制学习率、精度、检查点与 Hub 推送,trainer.train()一键完成微调;
  5. 推理pipeline("translation_xx_to_yy")快速出结果,或model.generate精细控制max_new_tokensdo_sampletop_ktop_p等生成行为。

掌握这条链路后,替换 checkpoint、语言对与前缀即可将同一套流程迁移到其他 T5/Bart/M2M 等 Seq2Seq 架构的翻译场景中。

【免费下载链接】transformers🤗 Transformers: the model-definition framework for state-of-the-art machine learning models in text, vision, audio, and multimodal models, for both inference and training.项目地址: https://gitcode.com/GitHub_Trending/tra/transformers

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/7 10:00:31

2026 AI游戏开发:用MCP协议让自然语言驱动Unity与Unreal

2026年做AI游戏开发,聊得最多的已经不是“用哪个大模型写代码”,而是“怎么让大模型真正摸到你的引擎”。Unity MCP、UnrealClaude、Blender MCP、蓝湖MCP这些词到处都是,但大部分人装完MCP之后,只是让AI帮忙改了几个脚本&#xf…

作者头像 李华
网站建设 2026/9/7 9:59:34

Python实战:用AT指令与语音Modem实现自动接听电话机器人

之前刷到一个很火的“给100个野人打电话”整活视频,评论区都在玩梗,我却在想:如果反过来,一天之内真的有一百通陌生来电打进来,一个人手动接听、记录号码、统计时长,不仅累,而且大概率会漏掉关键…

作者头像 李华
网站建设 2026/9/7 9:54:41

壹牛NFT数藏系统全开源:部署实战与二次开发指南

简介:一套面向数字藏品与NFT平台开发者的全开源数藏系统源码,基于H5与APP双端设计,适合快速搭建数字艺术藏品展示、交易及盲盒玩法等场景。该系统为最新迭代版本,新增用户找回密码、短信注册实名认证、后台主图配置等功能&#xf…

作者头像 李华
网站建设 2026/9/7 9:49:40

C#实现国密算法SM2/SM3/SM4实战指南与踩坑总结

简介:面向需要在C#项目中集成国产密码算法的.NET开发者,这份资源实现了SM2非对称加密、SM3密码杂凑、SM4分组密码这三套国密算法,并提供完整的Winform界面示例,可直接用于政务系统、金融接口、企业内部数据加密等合规场景&#xf…

作者头像 李华