项目实训10-RM和PPO训练过程

RM和PPO训练过程

RM 训练

编写 rm 训练的脚本 ds_rm.sh,和上述的模板以及sft相应的模板内容,编写类似的sft过程的调用脚本,利用奖励机制对文本的生成内容进行一定的优化。

accelerate launch src/train_rm.py \
    --model_name_or_path /home/mnt/workspace/model/chatglm2-6b-32k \
    --dataset judgement  \
    --do_train \
    --finetuning_type lora \
    --output_dir /home/mnt/workspace/trained \
    --overwrite_cache \
    --per_device_train_batch_size 1 \
    --gradient_accumulation_steps 1 \
    --lr_scheduler_type cosine \
    --logging_steps 10 \
    --save_steps 1000 \
    --learning_rate 1e-3 \
    --num_train_epochs 15.0 \
    --plot_loss \
    --fp16 

执行该sh脚本,并对原模型进行训练调参,更具之前所写的代码:

使用的PairwisePeftTrainer和整体结构来看,我们可以推测奖励策略的一些关键特点。这种类型的训练通常用于比较任务,其中模型需要评估一对样本,并决定哪个更好。这种训练通常应用于奖励模型(reward models),这类模型用来指导或调整其他模型的行为。PairwisePeftTrainer类,继承自PeftTrainer,专门用于计算成对损失(pairwise loss),这是在奖励模型训练中经常使用的一种方法。

  1. 初始化和属性:

    • 类初始化时调用了基类PeftTrainer的初始化方法,并设置了can_return_loss属性为True。这表明这个训练器可以在评估过程中返回损失值,这对于监控和优化模型非常重要。
  2. 计算损失:

    • compute_loss
      

      方法是这个类的核心。在这里,它计算成对损失,即比较一对样本的奖励分数,并根据它们的差异计算损失。具体实现如下:

      • 输入处理:输入字典inputs包含了批量数据,该方法首先通过input_ids的大小确定批次大小(batch_size),这假定输入的批次是成对的(即每两个样本为一组)。
      • 模型计算:调用模型得到输出,其中values是从模型最后一个输出(EOS token,即句子结束符)得到的分数,代表整个句子的奖励。
      • 分割奖励:将values分成两部分,r_acceptr_reject,分别代表接受和拒绝这个样本的奖励分数。假设成对的输入中,前半是"好"的样本,后半是"差"的样本。
      • 损失计算:损失是基于r_acceptr_reject的差异计算的,使用的是对数sigmoid损失函数,这种方法通常用于处理成对或二元选择任务,公式为-log(sigmoid(r_accept - r_reject))。这种损失函数鼓励模型增加"好"样本的分数,减少"差"样本的分数,使模型能够区分高质量和低质量的输出。
  3. 输出:

    • 如果return_outputsTrue,则返回一个元组,包括计算的损失值和每个样本的具体奖励分数(接受和拒绝)。这可以用于进一步的分析和优化。

总结来说,PairwisePeftTrainer通过对成对样本的比较,强化模型对"好"与"差"样本的区分能力。这种训练方式非常适合于那些需要精细评估和选择最佳响应的任务,如文本摘要、对话系统中的回复生成等。这类奖励模型训练策略强调了通过直接比较来学习和优化,是一种有效的训练手段。

成对损失(Pairwise Loss)是一种在机器学习中常用于比较任务的损失函数,尤其适用于那些需要模型学习区分两个样本优劣的场景。这种损失函数设计是为了直接比较成对的样本,并优化模型以正确区分它们。

成对损失的基本概念

成对损失主要用于排序问题、推荐系统和一些特定的分类任务中,它基于以下几个关键点:

  1. 成对样本:训练数据由成对的样本组成,通常一个样本是正面(更好)的,另一个是负面(较差)的。
  2. 目标:目标是使模型能够正确区分这两个样本的优劣,即让模型更倾向于将高质量的样本评分高于低质量的样本。

具体实现

在你提供的代码中,成对损失是通过以下方式实现的:

  • 使用模型的输出,这里是每个样本句子结束符(EOS)的输出值,作为该样本的“奖励”。
  • 计算两组样本(接受和拒绝)的奖励差异。
  • 使用sigmoid函数和对数损失来计算最终损失。公式是-log(sigmoid(r_accept - r_reject)),这个函数形状鼓励模型增大接受样本的分数,减少拒绝样本的分数。

损失函数的选择

成对损失的一个典型选择是对数损失函数,它可以强化模型对成对样本间差异的识别能力。这种损失函数的优点包括:

  • 直接优化差异:这种损失直接针对样本间的差异进行优化,这对于那些需要精确比较的任务尤为重要。
  • 灵活性高:可以根据不同的应用需求调整差异的计算方式,例如通过不同的激活函数或不同的差异计算策略。
  • 有助于排序和推荐:在推荐系统和信息检索领域尤为有用,因为这些领域经常需要对项目或信息进行排序。

应用场景

成对损失在多种应用场景中都非常有用,如:

  • 推荐系统:优化模型以更好地排序推荐项。
  • 信息检索:改进搜索算法,以便于更准确地排序搜索结果。
  • 文本生成:比如你的代码所示的奖励模型训练,优化生成的文本质量。

总之,成对损失是一种强大的工具,可以帮助模型学习如何根据质量或相关性准确地排序或区分对象,这对于提升模型在特定任务上的表现至关重要。

训练后获得其loss并将其绘制成为图像:
在这里插入图片描述

PPO 训练策略

编写 rm 训练的脚本 ds_rm.sh,和上述的模板以及sft相应的模板内容,编写类似的sft和rm过程的调用脚本,利用近端策略优化机制对文本的生成内容进行一定的优化。

accelerate launch src/train_ppo.py \
    --model_name_or_path /home/mnt/workspace/model/chatglm2-6b-32k \
    --dataset judgement  \
    --do_train \
    --finetuning_type lora \
    --output_dir /home/mnt/workspace/trained \
    --overwrite_cache \
    --per_device_train_batch_size 1 \
    --gradient_accumulation_steps 1 \
    --lr_scheduler_type cosine \
    --logging_steps 10 \
    --save_steps 1000 \
    --learning_rate 1e-3 \
    --num_train_epochs 15.0 \
    --plot_loss \
    --fp16 

在之前所描述的代码中,PPO策略进行微调预训练模型而设计的。它继承自PPOTrainerPeftTrainer,融合了两者的特点,实现了在序列到序列(seq2seq)任务中的应用。实际应用中使用PPO策略来优化序列生成任务。通过精心设计的训练循环和更新策略,它能够有效地利用PPO的优势,提高模型在特定任务上的表现。

PPO的实现和过程主要体现在PPOPeftTrainer类中的ppo_train方法。这个方法详细定义了如何使用PPO进行训练,包括数据的处理、模型响应的生成、奖励的计算,以及基于这些奖励进行的策略更新。下面逐步分析这一实现:

  1. 数据准备和迭代
  • 使用iter(self.dataloader)初始化数据加载器,这保证了每个训练步骤都能从数据集中获取新的数据样本。
  1. 响应生成
  • 在每个训练步骤中,generate函数被调用来生成模型对应的响应。这一部分主要利用当前模型策略(由模型参数决定)根据输入数据产生输出。
  1. 计算奖励
  • 为了计算奖励,模型首先在生成响应之后,调整为奖励模型模式(可能通过改变其内部状态或使用特定的奖励计算模型)。奖励的计算是基于生成的响应和一些内部逻辑,可能涉及到与真实数据的比较或其他评估标准。
  • self.model(**self.prepare_model_inputs(queries, responses))中,模型接收处理好的查询和响应,然后输出奖励值。
  1. PPO 更新步骤
  • 在计算出奖励后,代码执行PPO的关键部分,即策略更新。这通常涉及计算新策略与旧策略之间的比例,然后根据PPO的目标函数来更新策略参数。具体的实现细节可能隐藏在self.step(queries, responses, rewards)调用中,这里的step方法可能封装了梯度计算和参数更新的逻辑。
  • 重要的是,更新过程中使用了梯度累积(config.gradient_accumulation_steps),这是一种常用的技术,可以在不增加显存需求的情况下,有效地处理更大的批次数据。
  1. 训练监控和日志记录
  • 训练过程中使用了loss_meterreward_meter来追踪损失和奖励的平均值,这有助于监控训练的进展和效果。
  • 在特定的训练步骤,通过日志记录当前的损失、奖励、学习率等信息,以及通过self.log_callback.on_log回调函数记录这些信息,这有助于外部监控和分析训练过程。
  1. 模型的保存和持久化
  • 定期保存模型的状态,确保训练过程中的进展不会丢失,同时允许从特定检查点恢复训练。

这个PPO实现过程的核心在于如何根据奖励来调整和优化策略,以及如何在此基础上实现有效的训练和参数更新。通过将PPO策略集成到自定义的训练器中,代码有效地将PPO的理论优势转化为实际的训练性能提升。

并绘制训练过程的损失图像:

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值