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

使用from_pretrained加载自定义微调EncoderDecoderModel异常问题

BERT EncoderDecoder模型加载警告及输出异常问题排查

问题说明

在Google Colab中使用Hugging Face Transformers库构建BERT-based EncoderDecoder模型,经Seq2SeqTrainer微调后保存至Google Drive。在另一Colab加载模型时,反复出现以下警告:

The following encoder weights were not tied to the decoder ['bert/pooler'] 

同时模型存在异常行为:首次输入输出看似可用(但与微调时结果有差异),再次输入前一次的输出时,模型会返回完全相同的内容(如输入“apple”得“banana”,再输入“banana”仍输出“banana”)。

问题分析与解决

1. bert/pooler未绑定警告的本质

该警告属于正常现象,无需过度担心:

  • BERT的pooler层用于提取句子的整体表征,但在EncoderDecoder架构中,解码器仅依赖encoder的最后一层隐藏状态,并不需要pooler层的输出。
  • 当设置tie_encoder_decoder=True时,框架会尝试绑定编码器和解码器的可共享权重,但pooler层不属于共享范畴,因此触发警告。
  • 若要消除警告,可在加载模型时显式设置tie_encoder_decoder=False,或者直接忽略该提示(不影响模型功能)。

2. 输出重复异常的原因及解决

该异常与pooler警告无关,主要由以下几点导致:

(1)生成配置不合理

  • 代码中设置no_repeat_ngram_size=0,这会允许模型生成完全重复的内容,极易陷入循环输出。建议将其设置为2或3,限制重复n元组的生成:
    model.config.no_repeat_ngram_size = 2
    
  • min_length=10的设置可能强制模型为短输入(如“banana”)凑够长度,导致重复生成。可根据任务需求调整该值,或设置为1取消强制长度限制。

(2)模型保存与加载的一致性问题

  • 当前代码中直接调用model.save_pretrained,但Seq2SeqTrainer训练后会将最优模型保存至output_dir下的checkpoint-xxx子文件夹中。如果未加载训练后的checkpoint就保存,实际保存的是初始未训练模型,这会导致加载后的输出与微调结果不符。
  • 正确的保存方式应为训练后调用trainer.save_model("/folder/path"),或者加载指定checkpoint后再保存:
    # 训练完成后保存最优模型
    trainer.save_model("/folder/path")
    
    # 或者加载某一checkpoint后保存
    model = EncoderDecoderModel.from_pretrained("./checkpoint-100")
    model.save_pretrained("/folder/path")
    
  • 加载模型时,应直接读取保存的配置,避免手动重复设置参数,确保训练与推理时的配置一致:
    model = EncoderDecoderModel.from_pretrained("/folder/path")
    # 如需调整参数,基于加载后的配置修改
    model.config.num_beams = 4
    

(3)生成时的参数对齐

调用model.generate()时,需确保生成参数(如max_length、num_beams、length_penalty)与训练时predict_with_generate=True所用参数一致,否则会导致输出差异。

修正后示例代码

训练与保存阶段

from transformers import EncoderDecoderModel, Seq2SeqTrainingArguments, Seq2SeqTrainer

# 初始化模型
model = EncoderDecoderModel.from_encoder_decoder_pretrained(
    "bert-base-uncased", 
    "bert-base-uncased", 
    tie_encoder_decoder=True
)

# 合理设置生成配置
model.config.max_length = 512
model.config.min_length = 1
model.config.no_repeat_ngram_size = 2
model.config.early_stopping = True
model.config.length_penalty = 2.0
model.config.num_beams = 4

# 训练参数
training_args = Seq2SeqTrainingArguments(
    predict_with_generate=True,
    fp16=True,
    output_dir="./",
    logging_steps=2,
    save_steps=10,
    per_device_train_batch_size=8
)

# 初始化训练器并训练
trainer = Seq2SeqTrainer(
    model=model,
    tokenizer=tokenizer,
    args=training_args,
    train_dataset=train
)
trainer.train()

# 保存训练后的模型
trainer.save_model("/content/drive/MyDrive/finetuned_bert_seq2seq")

加载与推理阶段

from transformers import EncoderDecoderModel, AutoTokenizer

# 加载模型与tokenizer
model = EncoderDecoderModel.from_pretrained("/content/drive/MyDrive/finetuned_bert_seq2seq")
tokenizer = AutoTokenizer.from_pretrained("/content/drive/MyDrive/finetuned_bert_seq2seq")

# 推理示例
input_text = "apple"
inputs = tokenizer(input_text, return_tensors="pt", padding=True, truncation=True)
outputs = model.generate(**inputs)
print(tokenizer.decode(outputs[0], skip_special_tokens=True))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 13:23:21