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

使用DataCollatorForCompletionOnlyLM的SFT训练无效果问题求助

问题:SFTTrainer结合DataCollatorForCompletionOnlyLM微调无训练效果

项目背景

我正在开展一个参数提取项目,需要在数据集GalaktischeGurke/parameter_extraction_1500_mail_contract_invoice上微调Llama-2-7b模型。由于数据集上下文过长,全量训练会导致性能大幅下降,因此计划使用SFTTrainer搭配DataCollatorForCompletionOnlyLM,仅针对回复部分进行微调。

测试过程与问题

在调整自己的训练循环前,我先测试了官方示例代码:

from transformers import AutoModelForCausalLM, AutoTokenizer
from datasets import load_dataset
from trl import SFTTrainer, DataCollatorForCompletionOnlyLM

dataset = load_dataset("timdettmers/openassistant-guanaco", split="train")
output_dir = "./results"

model = AutoModelForCausalLM.from_pretrained("facebook/opt-350m")
tokenizer = AutoTokenizer.from_pretrained("facebook/opt-350m")

instruction_template = "### Human:"
response_template = "### Assistant:"
collator = DataCollatorForCompletionOnlyLM(instruction_template=instruction_template, response_template=response_template, tokenizer=tokenizer, mlm=False)

trainer = SFTTrainer(
    model,
    train_dataset=dataset,
    dataset_text_field="text",
    data_collator=collator,
)

trainer.train() 

import os
output_dir = os.path.join(output_dir, "final_checkpoint")
trainer.model.save_pretrained(output_dir)

训练循环未报错,但完全没有训练效果:wandb上无train/loss曲线,保存的模型也未发生变化。

已尝试的方案

  • 使用带预格式化函数的代码
  • 在trainer中设置packing=False
  • 自定义训练循环
    以上尝试均无效果;同时发现DataCollatorForCompletionOnlyLM在Transformers官方文档中无相关说明。

可能的原因与解决方案

1. 模板匹配失败,损失掩码未生成

DataCollatorForCompletionOnlyLM的核心是通过模板定位回复区域,仅对该区域计算损失。如果数据集文本格式和设置的instruction_template/response_template不匹配,会导致collator无法识别回复部分,所有位置损失被掩码,模型无梯度更新。

  • 解决方法:
    • 手动打印数据集的text字段,确认### Human:和### Assistant:与数据中的实际分隔符完全一致(包括空格、大小写)。
    • 若数据集格式不同,修改模板参数为数据中实际使用的分隔符。

2. Tokenizer缺失pad token或设置错误

OPT、Llama-2等模型默认无pad token,DataCollatorForCompletionOnlyLM需要正确的pad token处理批量数据,否则掩码逻辑可能失效。

  • 解决方法:
    • 为tokenizer设置pad token:
      tokenizer.pad_token = tokenizer.eos_token
      
    • 确认tokenizer的padding_side设置为"right"(符合因果语言模型的训练逻辑)。

3. SFTTrainer训练配置缺失或参数冻结

若模型参数被意外冻结,或SFTTrainer未配置基础训练参数,会导致模型权重不更新。

  • 解决方法:
    • 检查模型参数的requires_grad状态,确保至少部分参数可训练:
      for param in model.parameters():
          print(param.requires_grad)  # 应存在True值
      
    • 为SFTTrainer添加TrainingArguments,明确训练批次、日志步长等参数,确保训练流程正常触发:
      from transformers import TrainingArguments
      
      training_args = TrainingArguments(
          per_device_train_batch_size=4,
          logging_steps=10,
          output_dir="./results",
          num_train_epochs=1
      )
      
      trainer = SFTTrainer(
          model,
          args=training_args,
          train_dataset=dataset,
          dataset_text_field="text",
          data_collator=collator,
      )
      

4. TRL版本兼容性问题

DataCollatorForCompletionOnlyLM属于trl库而非transformers,旧版本可能存在掩码逻辑bug。

  • 解决方法:
    • 升级trl到最新版本:
      pip install --upgrade trl
      

5. 手动验证掩码效果

在训练前检查collator的输出,确认labels字段是否正确掩码(非回复区域为-100,回复区域为正常token id):

sample = dataset[0]
tokenized_sample = tokenizer(sample["text"], return_tensors="pt")
collated = collator([tokenized_sample])
print(collated["labels"])

若所有值均为-100,说明模板匹配失败,需调整模板参数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 17:22:40