LLaMA-Factory icon indicating copy to clipboard operation
LLaMA-Factory copied to clipboard

DPO训练完成后,推理阶段模型重复输出

Open WXLJZ opened this issue 8 months ago • 4 comments

Reminder

  • [x] I have read the above rules and searched the existing issues.

System Info

您好!我使用的是llamafactory的核心包src文件,具体版本不太记得了(但是肯定是2025年2-3月发布的版本),以下是我的环境。

python 3.8
transformers 4.45.2
peft 0.13.2
trl 0.11.4

Reproduction

我使用的是Qwen2.5-7B-Instruct模型,进行DPO训练,训练过程并未出现任何异常情况,但是在训练完成后进行推理时,出现了重复回答的情况。我查阅了相关的issue,但都未得到一个解决方法。以下是我的训练脚本(因为使用的核心包,无法使用llamafactory-cli env 导出环境,抱歉!)

do_train: True
seed: 2025
model_name_or_path: /home/xxxx/models/Qwen/Qwen2.5-7B-Instruct
template: qwen
stage: dpo
lora_target: all
dataset: dpo_train
cutoff_len: 1024
dataset_dir: ./data
finetuning_type: lora
lora_rank: 8
output_dir: ./checkpoints/qwen_dpo
overwrite_output_dir: True
overwrite_cache: False
per_device_train_batch_size: 1
per_device_eval_batch_size: 1
gradient_accumulation_steps: 4
lr_scheduler_type: cosine
evaluation_strategy: steps
logging_steps: 100
save_steps: 2000
save_total_limit: 3
val_size: 0.01
save_safetensors: False
learning_rate: 0.0001
num_train_epochs: 3.0
load_best_model_at_end: False
bf16: False
fp16: True
resume_from_checkpoint: None
pref_beta: 0.1
pref_loss: sigmoid
plot_loss: False
pref_ftx: 0.1
report_to: wandb
run_name: [AI-Text-CLS] DPO-AI-Text-Classifier
warmup_ratio: 0.1
ddp_find_unused_parameters: False
packing: False

推理时使用的是自己编写的脚本,如下:

# predict model
from llamafactory import ChatModel
class Model:
    def __init__(self, model_name_or_path, checkpoint_dir, template, temperature=0.1, top_p=0.9, finetuning_type="lora"):
        args = {
            "model_name_or_path": model_name_or_path,
            "adapter_name_or_path": checkpoint_dir,
            "template": template,
            "max_new_tokens": 5,
            "finetuning_type": finetuning_type,
            "temperature": temperature,
            "top_p": top_p,
        }  
        self.chat_model = ChatModel(args=args)

    def generate(self, query):
        res = self.chat_model.chat(query)
        return res

# 推理时,自定义的评估函数如下(节选):
def evaluate_test_data(test_data, model_name_or_path, checkpoint_dir, template, temperature=0.1, top_p=1.0, finetuning_type="lora"):
    """
    Compute scores given the predictions and gold labels
    """
    model = Model(model_name_or_path, checkpoint_dir, template, temperature, top_p, finetuning_type)

    trues, preds = [], []
    all_results = []  # 用于保存全部记录
    error_records = []  # 用于保存错误的记录
    error_id = 0  # 记录错误记录的条数
    for data in tqdm(test_data, desc="Predicting the Test_Data"):
        instruction = data['instruction']

        message = [
            {"role": "user", "content": instruction}
        ]
        pred = model.generate(message)[0].response_text

下面是推理时,打印出来的结果的截图:

Image

Others

不知具体是因为推理部分的参数配置错误,还是训练时的参数配置有问题呢?

WXLJZ avatar Apr 15 '25 15:04 WXLJZ

我看论文中推荐的epoch为1,你把num_train_epochs:设置为1试试。

Gaominsong avatar Apr 16 '25 01:04 Gaominsong

我看论文中推荐的epoch为1,你把num_train_epochs:设置为1试试。

感谢您的回复,但是我的数据量为27000,只训练一轮会不会太少了?

WXLJZ avatar Apr 16 '25 01:04 WXLJZ

我看论文中推荐的epoch为1,你把num_train_epochs:设置为1试试。

感谢您的回复,但是我的数据量为27000,只训练一轮会不会太少了?

因为我最近也在学DPO,从我看到的资料来看dpo通常只能训练一个epoch,多了显著过拟合,另外lr可以调小一点。你可以先进行一轮训练看看chosen rewards - rejected rewards曲线。 另外,如果你的训练数据不是基于DPO初始化模型生成的,你可以先使用偏好训练数据中的prompt+y_w进行SFT,SFT后的模型再进行DPO训练效果要好很多。

Gaominsong avatar Apr 16 '25 02:04 Gaominsong

因为我最近也在学DPO,从我看到的资料来看dpo通常只能训练一个epoch,多了显著过拟合,另外lr可以调小一点。你可以先进行一轮训练看看chosen rewards - rejected rewards曲线。 请教一下:

  1. 为什么lr调小会比较好?
  2. 为什么基于DPO初始化模型生成的数据对中的y_w不能进行sft?

waterdrink avatar May 19 '25 05:05 waterdrink