重排 top_n 与候选池调优
重排的收益取决于两个数字的搭配:候选池大小决定“正确答案有没有被捞进来”,top_n 决定“有多少内容进入上下文”。前者受召回率限制——答案不在池里,重排再准也救不回来;后者影响生成质量与成本——进上下文的条数越多,噪声与 token 消耗同步上升。合理做法是分别扫参:先在若干候选池规模上测量召回上限,再在固定池子下扫 top_n 看端到端指标,两者不要同时改。
基本信息
| 候选池 | 送进重排的候选条数,由粗排召回率决定上限 |
|---|---|
| top_n | 重排后进入上下文的条数 |
| 扫参顺序 | 先定候选池,再定 top_n |
| 指标 | 池内召回率、端到端答案通过率、上下文 token 消耗 |
| 成本 | 重排耗时与候选条数近似线性 |
典型使用场景
- 检索不达标:先看答案片段是否在候选池内,判断是召回问题还是排序问题
- 成本压缩:在质量不降的前提下减少上下文条数,直接省下生成费用
- 长文档场景:片段本身较长,top_n 要相应调小以免超预算
- 多路召回:池子由多路合并而来,扩池的收益要先看合并后是否已饱和
- 版本回归:改动池子或 top_n 后跑同一评测集,避免凭感觉调整
扫参脚本骨架
扫参脚本骨架
for pool in (20, 50, 100):
hits = retrieve(q, top_k=pool)
pool_recall = recall_of(hits, gold) # 池内召回,决定上限
for n in (4, 8, 12):
top = rerank(q, hits, top_n=n)
print(pool, n, pool_recall, eval_generation(q, top))扫参维度对照
| 变量 | 影响 | 观察指标 |
|---|---|---|
| 候选池 20 | 覆盖不足 | 池内召回低,先扩容 |
| 候选池 50~100 | 覆盖较好 | 池内召回趋缓即可停 |
| top_n 4~8 | 噪声小、成本低 | 答案完整度是否下降 |
| top_n 12+ | 信息多、噪声多 | 忠实度与 token 消耗 |
调参落地顺序
- 先量池内召回:确认答案片段确实在候选池中,这一步不达标就别调 top_n
- 再扫 top_n:从 4 与 8 两档起步,观察答案完整度与 token 消耗
- 固定后回归:确定取值后写进配置并纳入评测,避免发布时被随手改动
- 关注重排耗时:候选条数决定重排成本,池子扩大后延迟要重新实测
上下文条数增加后要同步检查提示词模板:原本为 5 条片段写的引导语,突然喂 15 条会稀释注意力,引用编号也可能超出模型的处理习惯。