文件名 GRPO(todo).md

GRPO(todo)

本文目录

正文

GRPO 是一种用于强化学习(RLHF)的高效算法,它与 PPO 的最大区别在于 不需要独立的 Critic (评论家) 模型,而是通过从同一个 Prompt 采样多组回复(Group),计算它们之间的相对优势(Relative Advantage)来优化策略。

GRPO 算法原理

GRPO和PPO算法流程对比

这是一个非常棒的需求。通过具体的场景和数字流转,最能看清这两个算法本质的差异。

我们设定的场景是:让模型生成一个微型故事

  • 输入 Prompt“请写一个关于一只想要飞翔的兔子的故事。”
  • 评判标准 (Reward):只要故事里包含“勇气”和“尝试”给高分,逻辑不通或消极给低分。

一、 PPO (Proximal Policy Optimization) 的全流程

在 PPO 中,我们有 4 个角色在场:

  1. Actor (演员):正在训练的模型。
  2. Ref Model (老师):冻结的参考模型。
  3. Critic (评论家)正在训练的价值预测模型。
  4. Reward Model (打分器):冻结的打分模型。

流程演示

阶段 1:采样 (Rollout)

  • Actor 输出:针对 Prompt 生成了 1 个 回答。
    • 回答 A:“小白兔爬上了山顶,跳了下来,虽然摔疼了,但它觉得自己离天空更近了。”
  • Ref Model 输出:计算回答 A 的概率,发现和自己生成的概率差不多(没有讲乱码)。$\rightarrow$KL 惩罚很小

阶段 2:打分 (Evaluation)

  • Reward Model (RM):读了回答 A,觉得很励志。
    • 输出实际得分 (Reward) = 0.8 分

阶段 3:评论家预测 (Critic Prediction)

  • Critic:它只看了 Prompt(或者 Prompt+回答的前半部分),根据它过去的经验进行预测。
    • 心理活动:“以前这种题,Actor 一般只能考 0.5 分。”
    • 输出预测分 (Value) = 0.5 分

阶段 4:计算优势 (Advantage Calculation)

  • 系统计算:$优势 = 实际得分 - 预测分 = 0.8 - 0.5 = \mathbf{+0.3}$。
  • 含义:这次表现比预期好了 0.3 分,值得表扬!

阶段 5:反向传播 (Backpropagation)

这里有 两个独立 的训练任务同时进行:

  1. Actor 训练
    • 收到信号:“回答 A 是个好回答 (+0.3)”。
    • 动作:修改参数,增加生成“小白兔爬上山顶…”这句话的概率。
  2. Critic 训练
    • 收到信号:“我预测了 0.5,实际是 0.8,我预测低了,误差 (MSE) 是 0.09。”
    • 动作:修改参数,下次遇到这个题,要把预测值往 0.8 调整,争取下次猜得准一点。

二、 GRPO (Group Relative Policy Optimization) 的全流程

在 GRPO 中,我们把 Critic 开除了。只剩下 3 个角色。

流程演示

阶段 1:组采样 (Group Rollout)

  • Actor 输出:针对 Prompt,强制生成 一组 (例如 4 个) 不同的回答。
    • 回答 A:“小白兔做了一个滑翔伞,飞了起来。”
    • 回答 B:“小白兔只是坐在洞口发呆。” (消极)
    • 回答 C:“小白兔爬树跳下来,摔伤了腿,但它很开心。” (励志)
    • 回答 D:“asdfg ghjkl…” (乱码/逻辑错误)

阶段 2:打分 (Scoring)

  • Reward Model (RM) 给这 4 个回答分别打分:
    • A: 0.9 分
    • B: 0.2 分
    • C: 0.8 分
    • D: 0.0 分

阶段 3:计算基准 (Baseline Calculation)

  • 不靠预测,靠统计
  • 计算这组的平均分:$(0.9 + 0.2 + 0.8 + 0.0) / 4 = \mathbf{0.475}$ (这是基准线)。

阶段 4:计算优势 (Advantage Calculation)

  • 用每个人的分减去平均分(归一化):
    • A 的优势:$0.9 - 0.475 = \mathbf{+0.425}$ (表现优异)
    • B 的优势:$0.2 - 0.475 = \mathbf{-0.275}$ (表现拉垮)
    • C 的优势:$0.8 - 0.475 = \mathbf{+0.325}$ (表现良好)
    • D 的优势:$0.0 - 0.475 = \mathbf{-0.475}$ (表现极差)

阶段 5:反向传播 (Backpropagation)

  • Actor 训练
    • 收到信号:大力提倡 A 和 C,稍微抑制 B,严厉打击 D。
    • 最终的参数更新 (Gradient Update): 系统会计算这4个结果的梯度,最后相加(或取平均)
    • 动作:更新参数,让模型更倾向于输出 A 和 C 的逻辑。
  • Critic 训练。不需要训练 Critic。

三、 Actor 和 Critic 训练方式的区别

在 PPO 中,这两个模型虽然都在“学习”,但它们学习的目标(Loss Function)完全不同,就像球员球评的区别。

维度 Actor (演员/策略模型) Critic (评论家/价值模型)
身份 生成器 (Generator) 回归器 (Regressor)
输入 Prompt Prompt (有时也包含 Response)
输出 下一个 Token 的概率分布 (词表大小, e.g., 32000维) 一个实数标量 (Value, e.g., 0.5)
学习目标 最大化奖励 (Maximize Reward) 最小化预测误差 (Minimize MSE)
Loss 函数 Policy Loss:

如果优势是正的,让这个动作概率变大;

如果优势是负的,让这个动作概率变小。
Value Loss (MSE):

$(预测分 - 真实奖励)^2$

努力让预测分无限接近真实奖励。
直观理解 怎么踢球才能进球? 怎么预测这场球能不能赢?
训练难度 。因为搜索空间巨大,且容易过拟合。 中等。这是一个标准的监督学习任务(拟合曲线)。
GRPO 的处理 保留 删除 (用统计平均值代替预测)

总结这一场景

  • PPO 就像是你写了一篇作文,老师(Critic)先预估你平时水平是 70 分,结果你考了 80 分。你因为“超常发挥 10 分”而感到开心(更新策略)。同时老师也反思“看来我低估他了,下次预估 75 分”(更新 Critic)。
  • GRPO 就像是你一口气写了 4 篇作文。虽然没有老师给你预估,但你自己一比:第 1 篇比平均水平好,第 2 篇比平均水平差。你保留好的,抛弃差的。你不需要一个老师告诉你“平均水平”是多少,你自己算出来的就是平均水平。

VERL-GRPO脚本、参数解析

# Tested successfully on the hiyouga/verl:ngc-th2.6.0-cu126-vllm0.8.4-flashinfer0.2.2-cxx11abi0 image.
# It outperforms the Qwen2 7B base model by two percentage points on the test set of GSM8K.

set -x

python3 -m verl.trainer.main_ppo \
  algorithm.adv_estimator=grpo \
  data.train_files=$HOME/data/gsm8k/train.parquet \
  data.val_files=$HOME/data/gsm8k/test.parquet \
  data.train_batch_size=1024 \
  data.max_prompt_length=512 \
  data.max_response_length=1024 \
  data.filter_overlong_prompts=True \
  data.truncation='error' \
  actor_rollout_ref.model.path=Qwen/Qwen3-8B \
  actor_rollout_ref.actor.optim.lr=1e-6 \
  actor_rollout_ref.model.use_remove_padding=True \
  actor_rollout_ref.actor.ppo_mini_batch_size=256 \
  actor_rollout_ref.actor.ppo_micro_batch_size_per_gpu=32 \
  actor_rollout_ref.actor.use_kl_loss=True \
  actor_rollout_ref.actor.kl_loss_coef=0.001 \
  actor_rollout_ref.actor.kl_loss_type=low_var_kl \
  actor_rollout_ref.actor.entropy_coeff=0 \
  actor_rollout_ref.model.enable_gradient_checkpointing=True \
  actor_rollout_ref.actor.fsdp_config.param_offload=False \
  actor_rollout_ref.actor.fsdp_config.optimizer_offload=False \
  actor_rollout_ref.rollout.log_prob_micro_batch_size_per_gpu=32 \
  actor_rollout_ref.rollout.tensor_model_parallel_size=2 \
  actor_rollout_ref.rollout.name=vllm \
  actor_rollout_ref.rollout.gpu_memory_utilization=0.6 \
  actor_rollout_ref.rollout.n=5 \
  actor_rollout_ref.ref.log_prob_micro_batch_size_per_gpu=32 \
  actor_rollout_ref.ref.fsdp_config.param_offload=True \
  algorithm.use_kl_in_reward=False \
  trainer.critic_warmup=0 \
  trainer.logger='["console","wandb"]' \
  trainer.project_name='verl_grpo_example_gsm8k' \
  trainer.experiment_name='qwen3_8b_function_rm' \
  trainer.n_gpus_per_node=8 \
  trainer.nnodes=1 \
  trainer.save_freq=20 \
  trainer.test_freq=5 \
  trainer.total_epochs=15 $@

这是一份使用 Verl (Volcano RL) 框架进行 GRPO (Group Relative Policy Optimization) 算法训练的启动脚本。

GRPO 是一种用于强化学习(RLHF)的高效算法,它与 PPO 的最大区别在于 不需要独立的 Critic (评论家) 模型,而是通过从同一个 Prompt 采样多组回复(Group),计算它们之间的相对优势(Relative Advantage)来优化策略。

下面为您详细拆解每一个参数的含义,并根据功能模块进行分类解释。


1. 核心算法配置 (algorithm)

  • algorithm.adv_estimator=grpo
    • 含义:指定优势(Advantage)估计器为 GRPO。
    • 解释:这是脚本的核心。传统 PPO 需要一个 Critic 模型来预测分值,而 GRPO 通过对同一个问题生成多个回答(见下文 rollout.n),计算组内平均分作为基线(Baseline),从而节省了 Critic 模型的显存开销。
  • algorithm.use_kl_in_reward=False
    • 含义:是否将 KL 散度(模型输出与参考模型的差异)直接加到 Reward(奖励)中。
    • 解释False 表示 KL 散度作为 Loss(损失函数)的一部分在优化时计算,而不是在生成数据阶段直接修改 Reward 分数。这是 PPO/GRPO 的标准做法。

2. 数据配置 (data)

  • data.train_files=$HOME/data/gsm8k/train.parquet
  • data.val_files=$HOME/data/gsm8k/test.parquet
    • 含义:训练集和验证集的文件路径(Parquet 格式)。GSM8K 是一个经典的数学推理数据集。
  • data.train_batch_size=1024
    • 含义全局采样批次大小(Global Batch Size)。
    • 解释:指在一次参数更新循环(Epoch)开始前,所有 GPU 共同采集的数据样本总量。即:每次训练迭代,环境会提供 1024 个 Prompt。
  • data.max_prompt_length=512
    • 含义:输入 Prompt 的最大 Token 长度。
  • data.max_response_length=1024
    • 含义:模型生成回复的最大 Token 长度。
    • 解释:数学题通常需要较长的思维链(CoT),所以回复长度设得比输入长。
  • data.filter_overlong_prompts=True
    • 含义:自动过滤掉超过 max_prompt_length 的数据。
  • data.truncation='error'
    • 含义:截断策略。设置为 'error' 表示如果数据超长不进行截断,而是直接报错或跳过(结合上一条使用),保证数据完整性。

3. Actor (策略模型) & Rollout (采样) & Ref (参考模型)

Verl 使用 actor_rollout_ref 统一命名空间,因为在 RL 过程中这三个角色紧密相关。

A. 模型基础 (model)

  • actor_rollout_ref.model.path=Qwen/Qwen3-8B
    • 含义:预训练模型路径(HuggingFace 格式)。
  • actor_rollout_ref.model.use_remove_padding=True
    • 含义:是否移除 Padding。
    • 解释:配合 FlashAttention 使用,移除无效的填充 Token 以加速计算。
  • actor_rollout_ref.model.enable_gradient_checkpointing=True
    • 含义:开启梯度检查点(Gradient Checkpointing)。
    • 解释以时间换空间。不保存中间激活值,而在反向传播时重新计算,能显著降低显存占用(约节省 50%-70% 显存),允许更大的 Batch Size。

B. Actor 训练参数 (actor)

  • actor_rollout_ref.actor.optim.lr=1e-6
    • 含义:学习率。RLHF 阶段学习率通常很低(如 1e-6),防止破坏预训练模型的知识。
  • actor_rollout_ref.actor.ppo_mini_batch_size=256
    • 含义PPO 更新时的 Mini-Batch 大小
    • 解释:虽然采集了 1024 个数据(train_batch_size),但在计算梯度更新时,会切分成 256 大小的块进行更新,以减少显存压力。
  • actor_rollout_ref.actor.ppo_micro_batch_size_per_gpu=32
    • 含义:单张 GPU 上的微批次大小。
    • 解释:用于梯度累积(Gradient Accumulation)。即单卡每次前向传播处理 32 条数据。
  • actor_rollout_ref.actor.use_kl_loss=True
  • actor_rollout_ref.actor.kl_loss_coef=0.001
  • actor_rollout_ref.actor.kl_loss_type=low_var_kl
    • 含义:KL 散度惩罚配置。
    • 解释:防止模型为了获得高分而通过“作弊”或输出乱码偏离原模型太远。0.001 是惩罚系数。
  • actor_rollout_ref.actor.fsdp_config.param_offload=False
  • actor_rollout_ref.actor.fsdp_config.optimizer_offload=False
    • 含义:FSDP(Fully Sharded Data Parallel)的卸载配置。
    • 解释False 表示参数和优化器状态都保留在 GPU 上,不卸载到 CPU。这能保证训练速度最快,但对显存要求高。

C. Rollout 采样/推理配置 (rollout)

  • actor_rollout_ref.rollout.name=vllm
    • 含义:使用 vLLM 作为推理引擎。
    • 解释:vLLM 生成速度极快,适合 RL 训练中大规模的数据采样环节。
  • actor_rollout_ref.rollout.gpu_memory_utilization=0.6
    • 含义:vLLM 占用 GPU 显存的比例(60%)。
    • 解释:必须预留一部分显存给 Actor 进行训练(反向传播)。如果设得太高,训练时会 OOM(显存溢出)。
  • actor_rollout_ref.rollout.n=5
    • 含义组采样数量(Group Size)这是 GRPO 的关键参数
    • 解释:对于每一个 Prompt,模型会生成 5 个不同的回复。GRPO 会计算这 5 个回复的平均奖励,优秀的回复获得正优势,差的获得负优势。
  • actor_rollout_ref.rollout.tensor_model_parallel_size=2
    • 含义:推理时的张量并行(TP)大小。
    • 解释:将模型切分到 2 张卡上进行推理。

D. Reference 参考模型 (ref)

  • actor_rollout_ref.ref.fsdp_config.param_offload=True
    • 含义:参考模型的参数卸载到 CPU。
    • 解释非常明智的设置。Ref 模型只在计算 KL 散度时做一次前向传播,且参数是冻结的(不更新)。将其卸载到 CPU 可以为 Actor 的训练腾出宝贵的 GPU 显存。

4. 训练器通用配置 (trainer)

  • trainer.n_gpus_per_node=8
  • trainer.nnodes=1
    • 含义:单机 8 卡训练。
  • trainer.project_name='verl_grpo_example_gsm8k'
  • trainer.experiment_name='qwen3_8b_function_rm'
    • 含义:WandB(Weights & Biases)的项目名和实验名,用于在网页端查看 Loss 曲线。
  • trainer.total_epochs=15
    • 含义:总共训练 15 个 Epoch。
    • 注意:在 RL 中,Epoch 通常指对同一批采集的数据(Replay Buffer)重复利用几次进行更新。这里如果指的是外层循环,则表示采集-更新这个过程重复 15 次。
  • trainer.save_freq=20
    • 含义:每 20 个 step 保存一次检查点。
  • trainer.logger='["console","wandb"]'
    • 含义:日志同时输出到控制台和 WandB。

总结:数据流向举例

假设你有一个数学题 Prompt:“1+1等于几?”

  1. Rollout (vLLM):
    • 根据 rollout.n=5,模型生成 5 个答案:
      • A: “2”
      • B: “等于2”
      • C: “3” (错误)
      • D: “是二”
      • E: “2”
  2. Reward:
    • 环境/Reward Model 给分:A(1.0), B(1.0), C(0.0), D(1.0), E(1.0)。
    • 组平均分:0.8。
  3. Advantage (GRPO):
    • A 的优势:1.0 - 0.8 = +0.2 (鼓励)
    • C 的优势:0.0 - 0.8 = -0.8 (强烈抑制)
  4. Actor Update:
    • 使用 ppo_mini_batch_size=256 的块大小,利用这些优势值更新 Qwen3-8B 的参数。
    • 同时,ref 模型计算 KL 散度,确保 Qwen3-8B 不要因为过度优化“1+1”而忘记怎么说正常的人话。
    • 由于 ref 开启了 offload=True,计算完 KL 后它的显存占用会被清理或移至 CPU,保证训练流畅。

常见RL、GRPO问题汇总

什么是rollout长尾问题?

背景:在强化学习中,Rollout 生成的序列(例如生成文本等)会被用来计算奖励,并通过这些奖励对模型进行训练。

特点:在实际应用中,生成的序列往往不均匀,有些序列很长、有些很短。或者序列中的有些 tokens 可能出现频率很低,导致学习效果难以快速显现,RL难以在这些区域得到足够的梯度更新。

在LLM领域,长尾问题通常 在模型的 输入和输出 过程中都可能受到影响,但具体的影响方式稍有不同:

  • 输入过程的长尾问题(主要针对序列内容、任务类型):可称为罕见任务、低频事件。输入的长尾问题指的是模型可能会面临一些非常稀有的、冷门的或专业的输入,模型在训练时未能充分覆盖这些输入,导致其无法生成准确或相关的响应。
  • 输出过程的长尾问题(主要针对序列长度):输出的长尾问题则指的是模型生成的响应可能缺乏多样性(可通过调整采样参数优化)。还可能指的是 大多数响应在数千个 token 内即可完成,少数实例需要极长的生成时间。

影响:

  • 泛化能力差:如果模型没有足够的能力处理低频(长尾)事件,它会偏向高频事件,这会导致模型在面对不常见的、罕见的或者边缘输入时表现不佳。
  • 实际应用中的误差:对于实际应用,模型可能会错误地忽视或处理不当一些低频事件,这可能会影响用户体验或导致决策错误。例如,推荐系统可能无法正确推荐冷门内容,生成模型可能无法准确生成罕见或特定领域的内容。
  • 训练效率低:长尾问题会导致模型学习过程中的低效,因为模型会过度专注于频繁出现的事件,难以在稀有事件上学习到有效的信息。
  • 长尾延迟:长尾问题通常是LLM在面对低频事件时出现,由于资源配置、模型性能等方面在低频、高频的分配不均,可能导致长尾问题的推理时间很长。
    • 资源分配:对于系统中的低频任务或事件,处理这些任务的资源可能相对较少或者分配不充分。系统可能更多地关注高频事件,这会导致低频事件(即长尾事件)处理时延较大。
    • 模型训练的偏差:如果模型在训练过程中没有充分学习到低频事件的特点,生成或响应这些事件时,模型可能会需要更多的时间进行搜索和决策,从而导致更高的延迟。
    • 拖慢批次进度:在一个训练批次中,绝大多数响应可能很快就生成完毕,但少数耗时极长的生成任务会拖慢整个批次的进度,导致大量 GPU 资源在同步等待中闲置。

举例:

假设你正在训练一个生成新闻文章的模型,输入是某种特定领域的新闻主题。模型在推理过程中需要根据给定的主题生成一篇文章。

  • 短尾(高频事件):例如,关于某个新闻事件的常见描述(如“发生了重大事故”)。这类描述会频繁出现在训练数据中,模型很容易通过奖励函数对这些部分进行有效学习。
  • 长尾(低频事件):然而,某些特定主题或事件(如较为小众的领域或罕见的新闻事件)可能只在训练数据中出现过极少次。例如,一个涉及冷门科技事件的新闻报道,这类事件非常罕见,模型在训练过程中几乎没有机会生成这类内容,导致对这类事件的学习较弱,难以生成高质量的内容。

因此,长尾问题表现在:训练时模型很难通过稀疏的奖励信号来优化这些低频事件,最终导致在推理时对冷门、少见的输入或事件的响应较差。

如何缓解Rollout长尾问题?或者优化?

算法层面:方案1:APRIL。参考链接:https://zhuanlan.zhihu.com/p/1956376495128807242

动机:在现有的同步 RL 框架中,一个更为棘手的问题是响应长度的 “长尾分布”:批次训练是一个同步任务,需要等待当前批次中全部prompt都Rollout完毕,才能计算梯度。这会导致,在一个训练批次中,绝大多数响应可能很快就生成完毕,但少数耗时极长的生成任务拖慢整个批次的进度导致大量** GPU 资源在同步等待中闲置**。随着模型规模和任务复杂度的提升,这一效率瓶颈愈发限制了 RL 训练的可扩展性。

APRIL关键步骤、机制:

机制 核心操作
1. 超额供给 在每个训练迭代开始时,请求远超于批次所需数量的 rollout 任务(例如,请求 2N 而非 N)。
2. 提前终止 一旦收集到目标数量(N)的完整响应,立即主动终止所有仍在进行的、尚未完成的生成任务。
3. 缓存与回收 将那些被终止的部分生成序列存入缓冲区,在后续迭代中恢复并继续生成,确保没有计算被浪费。

流程拆解:

  • 超额供给 (Over-provisioned Generation):在每个训练步骤开始时,启动 N’ 个实例的 rollout 生成,其中 N’ 大于标准批次大小 N(例如,N’ = 2N)。
  • 提前终止 (Early Termination):系统持续监控已完成的 rollout 数量。一旦达到目标数量 N,便立即向推理引擎发送信号,终止所有仍在运行的生成任务。
  • 缓存后续任务 (Buffering Continuations):已完成的 N 个 rollout 被送往训练引擎进行策略优化。而被终止的那些部分生成序列(partial rollouts)及其状态被完整地存入一个后续缓冲区 (continuation buffer)
  • 优先恢复 (Prioritized Resumption):在下一个训练步骤开始时,系统会优先处理缓冲区中的任务,让它们从中断处继续生成,然后再启动新的 rollout 请求以补足N’的总任务量。

整理思路(个人理解):RL训练是多epoch的,同一个prompt会训练多次。因此,可以在首次(或前几次)进行Rollout时,将原本Rollout.n=5,直接设置生成10条响应,但最终只保留生成速度最快的前5条响应,剩余5条未完整输出的序列保存起来,等到下一个epoch时,遇到相同prompt时 进行续写生成。这样不会有GPU浪费。

问题思考:但是,在利用上一个epoch未完整生成的序列进行训练,本质属于off-policy。

工程层面:

什么是on-policy/off-policy

从第一性原理出发,二者的根本区别在于更新模型策略所用数据的来源。

On-Policy,顾名思义,指的是“用正在学习的策略产生的数据来学习”。即,智能体(在LLM中指语言模型本身)严格使用其当前策略(Policy)与环境交互所产生的数据来更新和优化自身。这意味着,一旦策略发生更新,所有旧的交互数据都将被废弃,因为它们是由一个“过时”的策略产生的。

Off-Policy** ,**则更为灵活,它指的是“用并非当前学习的策略所产生的数据来学习”。智能体可以利用由其他策略(甚至是历史策略或人类示范数据)产生的数据来更新当前策略。这解耦了“数据生成”和“策略学习”两个过程,从而提高了数据利用效率。

特性 on-policy off-policy
第一性原理 学习用的数据必须由当前策略生成 学习用的数据可以来自任何策略
数据来源 实时交互,在线生成 离线数据集或历史数据
数据效率 低,用完即扔 高,可重复利用
核心思想 用当前策略产生的经验迭代优化自身 解耦数据生成、策略学习
代表算法 PPO、GRPO DPO、DQN、Q-learning

如果使用模型A生成数据,保存起来,再用这批数据进行模型A的训练,属于on-policy还是off-policy?毕竟模型没变。

off-policy。因为每一个step、epoch,在反向传播、梯度更新过程中,模型参数都会发生微小变化,从而导致模型A变为模型A’。此时应该使用模型A’重新进行响应生成。

假设:

  • 模型 A (Old):上个月的模型,生成了一批数据 D 存在硬盘里。
  • 模型 B (Current):现在的模型。
  • 前提:模型 A 和 模型 B 的参数完全一模一样(权重文件的 Hash 值都一样)。

当你启动训练的第一瞬间

image

  • 你的策略 image 和生成数据的策略 image 是完全重合的。
  • 数学上:image
  • 此时,梯度计算是准确的,符合 On-Policy 的定义

问题出在“训练”这个动作本身的含义上。训练就是修改参数

  • Step 1 结束时:

你用那批数据 D 进行了一次梯度下降。现在的模型变成了 模型 B’ (New)。

显然,模型 B’ ≠ 模型 A。

  • Step 2 开始时:

如果你继续使用那批“上个月的数据 D”(由模型 A 生成):

- **做题的人**:还是模型 A(因为它已经固化在数据里了)。
- **学题的人**:是模型 B'。
- **偏差出现**:$\pi_{current}$ 已经变了,而数据分布 $\pi_{behavior}$ 还是老的。
- **判定**:**Off-Policy**。

###