拼多多大模型算法秋招一面:过程奖励模型与 GRPO
- 轮次
- 一面
- 时间
- 2026-09
- 来源
- 牛客网
《面试题目》
- 为什么商品审核场景需要智能体,直接使用多模态模型分类不行吗?
- 智能体中的过程奖励模型应该如何训练,怎样避免它只学习轨迹长度?
- GRPO 不训练独立价值模型,它的优势和代价分别是什么?
- 为什么训练过程中 Rollout 会成为瓶颈,GPU 明明也参与生成,为什么利用率还会偏低?
- On-policy 强化学习中,如果 Rollout 使用的模型参数落后于训练参数,会产生什么问题?
- 为什么 DPO 训练有时会出现 chosen 和 rejected 的概率同时下降?
- 如何判断奖励模型学到的是任务质量,而不是输出格式、长度或者某些关键词?
- 多个智能体协作相比单个智能体加更多工具,真正的优势在哪里?
- 多智能体同时修改共享状态时,如何避免互相覆盖和错误传播?
- 如何设计智能体的终止条件,避免它陷入无限工具调用?
- 知识库规模达到千万级文档后,为什么只调整向量数据库参数通常解决不了召回问题?
- RAG 中召回的文档彼此冲突时,模型应该相信哪一份?
- 请做一下自我介绍
《参考解析》
过程奖励模型:先解决标签,再解决长度偏置
PRM 的难点不在模型结构,而在步级标签怎么来。人工逐步标注成本极高,主流做法是蒙特卡洛估计:把轨迹在第 i 步截断,用当前策略从该状态继续 rollout K 次(K 取 4~8),用最终答案的正确率作为这一步的软标签,形式上就是 soft label = 正确次数 / K,硬标签则取 0/1 阈值。轨迹里每个动作打三类标签:正、负、中性(中性用于尚未产生结论的中间步)。训练目标是 Bradley-Terry 成对排序损失 L = -log σ(r_chosen - r_rejected),而不是直接回归软标签,成对形式对标签噪声更鲁棒。
长度偏置要在数据和聚合两处同时治。数据侧做长度匹配(length-matched pairs):同一道题的正负轨迹按 token 数分桶,让正负样本的长度分布对齐,同时必须显式包含”短而正确”和”长但错误”这两类反例——如果正样本普遍更长,模型一定会把长度当信号。聚合侧不要用 sum 把所有步的分数加起来,sum 天然奖励长轨迹;用最后一步的分数,或者做长度归一化取平均。更狠一点是解耦式训练:一个 head 学正确性、一个 head 学长度,训练时对抗地去掉长度可预测的成分。评估必须看 held-out 集上”奖励与长度”的 Spearman 相关系数(目标接近 0)和分长度桶的成对准确率,只看训练分布上的整体准确率会被表面特征骗过去。最后是上线前的反事实回归:把奖励最高的那批轨迹抽出来交给规则校验器或人工复核,专门查 reward 很高但结论错误的样本。
GRPO:省掉价值模型,但成本转移到了采样
GRPO 对同一道题采样一组回答(DeepSeekMath 里 G 默认 64),用组内奖励的均值和标准差归一化出相对优势 A_i = (r_i - mean(r)) / std(r),从而不再需要与策略同规模的价值模型。省下的是三笔开销:一份参数量的显存、每步的前向计算,以及价值模型拟合不准引入的偏差。它对”答案可自动验证”的任务最有效——数学题比对终值、代码跑单测、工具调用检查返回结构。
代价同样明确。第一,采样量变成 G 倍,rollout 成本直接乘上组大小;第二,如果一组样本奖励全相同,std(r) = 0,优势全为 0,这道题不贡献任何梯度——所以必须按 pass rate 做难度筛选,把全对(≈1)和全错(≈0)的题目过滤掉,只留中间难度的题;第三,奖励稀疏时可能长期采不到正样本,得靠可验证的中间奖励兜底。另外注意 std 归一化本身会引入长度偏置(长回答更容易出现高方差),后来有工作直接把 std 去掉、改成只减均值再按固定尺度缩放。一句话结论:GRPO 不是消灭了成本,是把价值模型的成本换成生成成本,只有生成能被高并发并行、而训练侧显存紧张时才划算。
Rollout 为什么慢:算子的形状不一样
训练的算子是大矩阵乘,批内序列长度接近、可以打满 Tensor Core;推理是逐 token 自回归解码,每步只算一个位置,算子规模小、访存密集。更麻烦的是长度不齐:一批请求里有的已经结束、有的还在生成,静态批处理会给短序列补大量无效 padding,或者让先结束的槽位空转。工具调用型轨迹还有额外的阻塞——等检索、等代码执行,此时 GPU 上没有足够的活跃请求可跑。
优化的抓手是分开看的:Continuous Batching(迭代级调度,序列一结束立刻补新请求)、长度分桶、动态移除已完成序列、训练与推理集群解耦、权重更新和 KV Cache 增量同步。多个训练版本共享 Rollout 服务时,必须给每条轨迹记策略版本号。
关于”GPU 利用率”这个指标本身:平均值会骗人,因为解码阶段和 prefill 阶段的利用率差异很大。更有意义的观测是一组组合指标——每秒生成 token 数、有效 token 占比、调度队列等待时间,以及换算到”每条可用轨迹”的成本。只看平均利用率,很容易把”卡在等外部服务”误判成”算力利用不足”。
DPO 里 chosen 和 rejected 概率同时下降
DPO 的目标函数只约束隐式奖励的差:r̂(x, y) = β·log(π_θ(y|x) / π_ref(y|x)),损失是 -log σ(r̂(x, y_w) - r̂(x, y_l))。只要这个差值在变大,损失就在下降——两个绝对概率同时降低完全合法,这种现象一般称为 likelihood displacement,DPO 论文里就讨论过。
两个常见诱因。一是偏好数据里的 chosen 偏离参考模型分布太远(比如 chosen 是人工重写的、风格与 SFT 模型差别很大),抬高它的绝对概率代价很大,模型发现压低 rejected 更省力。二是 β 太小,参考模型的约束太弱,模型滑向”只做相对排序”的解。数据里的长度偏置也会被利用,因为隐式奖励用的是序列总 logprob,长度越长数值越极端,模型学会”把 chosen 拉长、把 rejected 缩短”就能拉大差距。
要修就从这几处下手:β 从 0.1 附近扫(0.01~0.5),清洗弱偏好对和长度失衡的样本,对 logprob 做长度归一化,或者引入一个 SFT 辅助项——total = dpo_loss + α·sft_loss(α 取 0.1 量级),把 chosen 的绝对概率按住。监控上不能只看 loss:TRL 的 DPOTrainer 会打 rewards/chosen、rewards/rejected、rewards/margins、rewards/accuracies、logps 和 KL,看 margin 是不是在涨、chosen 的 logprob 掉了多少、KL 有没有失控。判据是”margin 涨 + 采样质量不降”,如果 margin 一直涨但自由生成的质量在掉,说明训练指标和真实目标已经脱节。
千万级知识库:瓶颈几乎不在向量库
千万级文档下,HNSW / IVF-PQ 的 ANN 查询仍然是毫秒级,把 nprobe、efSearch 调到底也救不回召回质量——真正丢召回的是切分和元数据。一个 chunk 混进多个主题,即使被召回也当不成证据;切得过细又会丢上下文。实践上按文档结构切(标题层级、条款号),单 chunk 控制在 300~800 token,相邻块留 10%~15% 重叠;对合同、规则类文档用 parent-child(small-to-big)策略:用小子块做向量召回,返回父块作为喂给模型的证据。
检索链路应该是”过滤 → 混合召回 → 精排”三段。pre-filter 必须做:按类目、业务线、规则版本、生效时间先把候选空间砍掉一个量级,否则 top-k 里全是过期或跨业务的条款。召回用稠密(embedding)+ 稀疏(BM25)双路,再用 RRF(k=60)做融合——对于缩写、商品型号、规则编号这类精确串,BM25 往往比纯向量更稳。最后接 cross-encoder 重排,取 top 5~10 交给生成。
知识库更新不要覆盖旧向量,改成 append + valid_from / valid_to 区间,查询时带上 as-of 时间,否则模型会检索到已经失效的规则。评估也要拆开:Recall@K(金标证据是否在召回集合里)、重排命中率、最终证据利用率、答案正确率,四个数分开看才知道是”没召回到”还是”召回到了没用上”,只看最终答案会永远归错因。
回到冲突消解:第一步是归因,冲突通常来自三种情况——属于不同业务线、旧版本没删干净、真的是同一条件下的矛盾条款。前两种靠过滤和版本策略就能解掉;第三种不应该让模型悄悄挑一个,正确做法是把冲突显式暴露出来:按来源权威度、生效时间、业务线优先级给一个排序规则,同时把分歧写进上下文让模型显式说明采用了哪一版、为什么。对高风险场景(审核、风控),再加一层要求——关键结论必须有两个独立来源的证据支撑,否则降级为”需要人工确认”。