You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Transformers中微调mBART-50学习新单词失败,求原因及解决办法

问题描述

尝试在Python的Transformers库中微调mBART-50(对应论文为mBART: Multilingual Denoising Pre-training for Neural Machine Translation,Hugging Face预训练模型为facebook/mbart-large-50),让模型学习将自定义法语单词billozarion翻译为英语单词plorization。代码大部分参考Hugging Face官方文档编写,但模型未学会该映射,测试输出仍为billozarion而非预期的plorization。运行环境为Ubuntu 20.04.5 LTS,搭配NVIDIA A100/T4 GPU及CUDA 12.0,conda环境配置为Python 3.9,安装transformers==4.28.1、chardet==5.1.0、sentencepiece==0.1.99、protobuf==3.20。

失败原因分析
  • 仅执行前向传播,无参数更新:原代码仅调用model(**model_inputs, labels=labels)完成前向传播,但未计算损失、执行反向传播或更新模型参数,模型权重完全没有变化,自然无法学习新映射。
  • 分词器不统一:训练阶段使用facebook/mbart-large-50的分词器,测试阶段却切换为facebook/mbart-large-50-many-to-many-mmt的分词器,两者的token映射规则可能存在差异,导致输入输出的token不匹配。
  • 输入文本冗余空格:src_text和tgt_text前后带有空格,会被分词器识别为额外的token干扰学习,导致模型无法聚焦目标单词的映射关系。
  • 缺少训练核心组件:未配置优化器、学习率等训练必备组件,也没有梯度清零操作,无法完成参数更新的闭环。
解决办法

以下是修正后的完整代码,包含梯度更新流程、统一分词器、清理输入等关键调整:

from transformers import MBartForConditionalGeneration, MBart50TokenizerFast, AdamW

# 加载模型和统一分词器
print('Model loading started')
model = MBartForConditionalGeneration.from_pretrained("facebook/mbart-large-50")
tokenizer = MBart50TokenizerFast.from_pretrained("facebook/mbart-large-50", src_lang="fr_XX", tgt_lang="en_XX")
print('Model loading done')

# 清理输入文本,去除冗余空格
src_text = "billozarion"
tgt_text = "plorization"

# 处理输入和标签
model_inputs = tokenizer(src_text, return_tensors="pt")
with tokenizer.as_target_tokenizer():
    labels = tokenizer(tgt_text, return_tensors="pt").input_ids

# 配置优化器
optimizer = AdamW(model.parameters(), lr=5e-5)

print('Fine-tuning started')
# 调整训练轮次,单样本无需1000轮
for i in range(50):
    # 梯度清零
    optimizer.zero_grad()
    # 前向传播并获取损失
    outputs = model(**model_inputs, labels=labels)
    loss = outputs.loss
    # 反向传播
    loss.backward()
    # 更新参数
    optimizer.step()
    # 打印训练进度
    if (i+1) % 10 == 0:
        print(f"Step {i+1}, Loss: {loss.item():.4f}")
print('Fine-tuning ended')
    
# 测试模型,使用同一个分词器
tokenizer.src_lang = "fr_XX"
article_fr = src_text
encoded_fr = tokenizer(article_fr, return_tensors="pt")
generated_tokens = model.generate(**encoded_fr, forced_bos_token_id=tokenizer.lang_code_to_id["en_XX"])
translation = tokenizer.batch_decode(generated_tokens, skip_special_tokens=True)
print("Translation result:", translation)

关键调整说明:

  1. 添加训练闭环:引入AdamW优化器,每次训练步骤先清零梯度,再计算损失、执行反向传播,最后更新模型参数,完成完整的参数更新流程。
  2. 统一分词器:训练和测试阶段使用同一个facebook/mbart-large-50分词器,避免token映射不一致问题。
  3. 清理输入文本:去除输入单词前后的空格,确保分词器仅处理目标单词本身。
  4. 调整训练轮次:单样本训练无需1000轮,50轮左右即可让模型学会简单映射,避免不必要的计算开销。

内容的提问来源于stack exchange,提问作者Franck Dernoncourt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 01:02:51