PAI-Rec 多路召回截断实践:用 PriorityAdjustCountFilter 和 SnakeFilter 控制精排入口数量

简介: PAI-Rec推荐开发平台提供PriorityAdjustCountFilter(按优先级截取)与SnakeFilter(按权重蛇形交错)两种多路召回截断策略,无需粗排即可将数百候选精准压缩至200个以内进入精排,兼顾保量性、多样性与业务可控性。

背景

在推荐系统中,多路召回会产生大量候选 item。如果不使用粗排(General Rank),这些候选会直接进入精排模型打分,带来较大的计算开销和延迟。

PAI-Rec 提供了两个过滤器来解决这个问题:

  • PriorityAdjustCountFilter:按优先级截取各路召回,保证高优先级召回路的 item 优先入选
  • SnakeFilter:按权重蛇形交错分配各路召回,保证各路 item 均匀混合

两者都能在不使用粗排的情况下,将多路召回的数百甚至上千个候选压缩到指定数量(如 200 个),再进入精排。


一、PriorityAdjustCountFilter —— 按优先级截取

核心逻辑

  1. 将所有候选 item 按 RetrieveId(召回路名称)分组
  2. 按配置顺序(即优先级)从高到低,依次从每路中取 N 个 item
  3. 每路内部按 Score 降序排列,优先取高分 item
  4. 支持两种计数模式:
    • fix:每路固定取 N 个
    • accumulator:累计取满 N 个后停止

配置示例

{
   
  "FilterConfs": [
    {
   
      "Name": "priority_truncate",
      "FilterType": "PriorityAdjustCountFilter",
      "AdjustCountConfs": [
        {
   
          "RecallName": "u2i_recall",
          "Type": "fix",
          "Count": 80
        },
        {
   
          "RecallName": "vector_recall",
          "Type": "fix",
          "Count": 60
        },
        {
   
          "RecallName": "hot_recall",
          "Type": "fix",
          "Count": 40
        },
        {
   
          "RecallName": "new_recall",
          "Type": "fix",
          "Count": 20
        }
      ]
    }
  ]
}

效果:从 u2i 取 80 个 → 向量召回取 60 个 → 热门取 40 个 → 新品取 20 个,总共 200 个进入精排。

累计模式配置

如果希望"总共不超过 200 个,按优先级依次填充":

{
   
  "FilterConfs": [
    {
   
      "Name": "priority_truncate_acc",
      "FilterType": "PriorityAdjustCountFilter",
      "AdjustCountConfs": [
        {
   
          "RecallName": "u2i_recall",
          "Type": "accumulator",
          "Count": 100
        },
        {
   
          "RecallName": "vector_recall",
          "Type": "accumulator",
          "Count": 160
        },
        {
   
          "RecallName": "hot_recall",
          "Type": "accumulator",
          "Count": 200
        }
      ]
    }
  ]
}

效果:先从 u2i 取最多 100 个;再从 vector_recall 取,累计到 160 个;最后从 hot_recall 补满到 200 个。如果前面的路数量不够,后面的路会多取。

适用场景

  • 各路召回有明确优先级(如个性化召回 > 热门召回)
  • 希望保证核心召回路的候选数量不被稀释
  • 对各路占比有确定性要求

二、SnakeFilter —— 按权重蛇形交错分配

核心逻辑

  1. 根据各路的 Weight 按比例计算每路应分配的 item 数量
  2. 按"蛇形"方式轮流从各路取 item:每轮按权重值取对应个数
  3. 各路内部按 Score 降序排列
  4. 遇到重复 item(被多路召回的同一物品),支持两种策略:
    • REFILL_ON_DUPLICATE(默认):跳过重复 item 但不消耗配额,继续取下一个
    • SKIP_ON_DUPLICATE:跳过重复 item 且消耗配额

配置示例

{
   
  "FilterConfs": [
    {
   
      "Name": "snake_truncate",
      "FilterType": "SnakeFilter",
      "RetainNum": 200,
      "AdjustCountConfs": [
        {
   
          "RecallName": "u2i_recall",
          "Weight": 4
        },
        {
   
          "RecallName": "vector_recall",
          "Weight": 3
        },
        {
   
          "RecallName": "hot_recall",
          "Weight": 2
        },
        {
   
          "RecallName": "new_recall",
          "Weight": 1
        }
      ]
    }
  ]
}

效果:总共保留 200 个候选,按 4:3:2:1 的比例分配。蛇形交错取出,最终结果中:

  • u2i_recall 约 80 个
  • vector_recall 约 60 个
  • hot_recall 约 40 个
  • new_recall 约 20 个

输出结果的排列顺序是交错的(每轮 u2i 取 4 个 → vector 取 3 个 → hot 取 2 个 → new 取 1 个),有利于后续排序的多样性。

SKIP_ON_DUPLICATE 模式

当一个 item 被多路召回同时命中时,默认模式会让它"不占坑位"(即不消耗当前路的配额),如果你希望严格按权重分配坑位数(即使遇到重复也消耗配额),可以设置:

{
   
  "FilterConfs": [
    {
   
      "Name": "snake_truncate_skip",
      "FilterType": "SnakeFilter",
      "RetainNum": 200,
      "SnakeType": "SKIP_ON_DUPLICATE",
      "AdjustCountConfs": [
        {
   
          "RecallName": "u2i_recall",
          "Weight": 4
        },
        {
   
          "RecallName": "vector_recall",
          "Weight": 3
        }
      ]
    }
  ]
}

适用场景

  • 各路召回没有明确优先级,希望"雨露均沾"
  • 希望最终候选的多样性更好(交错排列)
  • 各路召回重叠较多,需要合理去重分配

三、完整配置示例:两者组合使用

在实际业务中,可以组合使用:先用 PriorityAdjustCountFilter 做初步截断(如从 1000 降到 400),再用 SnakeFilter 做精确的权重分配(从 400 降到 200)。

{
   
  "FilterConfs": [
    {
   
      "Name": "exposure_filter",
      "FilterType": "User2ItemExposureFilter",
      "TimeInterval": 300,
      "WriteLog": true,
      "DaoConf": {
   
        "AdapterType": "featurestore",
        "FeatureStoreName": "fs_pairec",
        "FeatureStoreViewName": "user_expose"
      }
    },
    {
   
      "Name": "priority_truncate",
      "FilterType": "PriorityAdjustCountFilter",
      "AdjustCountConfs": [
        {
   
          "RecallName": "u2i_recall",
          "Type": "accumulator",
          "Count": 150
        },
        {
   
          "RecallName": "vector_recall",
          "Type": "accumulator",
          "Count": 280
        },
        {
   
          "RecallName": "hot_recall",
          "Type": "accumulator",
          "Count": 350
        },
        {
   
          "RecallName": "new_recall",
          "Type": "accumulator",
          "Count": 400
        }
      ]
    },
    {
   
      "Name": "snake_truncate",
      "FilterType": "SnakeFilter",
      "RetainNum": 200,
      "AdjustCountConfs": [
        {
   
          "RecallName": "u2i_recall",
          "Weight": 4
        },
        {
   
          "RecallName": "vector_recall",
          "Weight": 3
        },
        {
   
          "RecallName": "hot_recall",
          "Weight": 2
        },
        {
   
          "RecallName": "new_recall",
          "Weight": 1
        }
      ]
    }
  ],

  "FilterNames": {
   
    "home_feed": ["exposure_filter", "priority_truncate", "snake_truncate"]
  }
}

执行流程

多路召回 (1000+ items)
    ↓
曝光过滤 (去除已曝光)
    ↓
PriorityAdjustCountFilter (按优先级截取到 400)
    ↓
SnakeFilter (按权重蛇形分配到 200)
    ↓
精排模型打分 (200 items)
    ↓
重排/多样性调控
    ↓
返回结果

四、关键配置字段说明

PriorityAdjustCountFilter

字段 类型 说明
FilterType string 固定值 "PriorityAdjustCountFilter"
AdjustCountConfs array 各路召回的截取规则,顺序即优先级
AdjustCountConfs[].RecallName string 召回路名称,对应 RecallConfs 中的 Name
AdjustCountConfs[].Type string "fix" = 每路固定数量;"accumulator" = 累计到指定数量
AdjustCountConfs[].Count int fix 模式下为该路取的数量;accumulator 模式下为累计上限
EnsureDiversity bool 是否在截取时保证多样性(需配合 DiversityDaoConf)

SnakeFilter

字段 类型 说明
FilterType string 固定值 "SnakeFilter"
RetainNum int 最终保留的候选总数
SnakeType string 重复处理策略:空(默认)= REFILL_ON_DUPLICATE;"SKIP_ON_DUPLICATE"
AdjustCountConfs array 各路召回的权重配置
AdjustCountConfs[].RecallName string 召回路名称
AdjustCountConfs[].Weight int 权重值,决定各路分配的比例

五、两者的对比与选择

维度 PriorityAdjustCountFilter SnakeFilter
分配策略 按优先级顺序截取 按权重比例蛇形交错
输出顺序 按路分块(先 A 路全部,再 B 路全部) 交错排列(A B C A B C ...)
重复 item 处理 按 RetrieveId 分组,多路命中的 item 只归属一路 支持多路共享同一 item,配额可配
总数控制 通过最后一条 accumulator 的 Count 间接控制 通过 RetainNum 直接控制
多样性 可选 EnsureDiversity 配合多样性约束 天然交错,多样性较好
适合场景 有明确优先级,核心路必须保量 各路平等,追求均匀混合

推荐选择

  • 只需要简单截断:用 PriorityAdjustCountFilter,配置直观
  • 需要均匀混合+精确总数控制:用 SnakeFilter
  • 两者组合:先用 PriorityAdjustCountFilter 粗截(高优保量),再用 SnakeFilter 精细分配(权重混合)

六、注意事项

  1. 过滤顺序:在 FilterNames 中,截断过滤器应放在曝光过滤、状态过滤之后,确保先去掉无效 item 再截断
  2. RecallName 匹配:AdjustCountConfs 中的 RecallName 必须与 RecallConfs 中召回的 Name 完全一致
  3. 未配置的召回路:如果某路召回未在 AdjustCountConfs 中配置,其 item 会被直接丢弃(不会进入最终结果)
  4. 候选不足时:如果某路的实际 item 数不够配额,会取尽该路所有 item,不会报错
  5. 精排数量规划:RetainNum / 最终 Count 应根据精排模型的 QPS 和延迟要求来设置,通常 100~300 是合理范围
  6. 实验参数:两个过滤器都支持通过 AB 实验动态调整参数,可以在实验中验证不同截断策略的效果
相关文章
|
7月前
|
机器学习/深度学习 分布式计算 搜索推荐
PAI-Rec 召回引擎:构建高性能推荐系统的核心引擎
PAI-Rec是阿里云智能推荐平台的核心召回引擎,经阿里大规模场景验证。支持多路召回融合(U2I/I2I/向量/随机)、召回即过滤、毫秒级实时更新与分布式弹性架构,开箱即用,助力企业构建毫秒级、高精度、强实时的推荐系统。
669 9
|
存储 NoSQL 安全
【MongoDB】MongoDB可查询加密简介
MongoDB 6.0引入了一个预览功能,它实现了一个近乎神奇的功能,即允许将加密数据用作搜索目标,而无需将密钥传输到数据库。
|
7月前
|
机器学习/深度学习 搜索推荐 数据处理
PAI-Rec推荐开发平台:企业级智能推荐解决方案,驱动业务全域增长
PAI-Rec是阿里云一站式推荐系统平台,集成多路召回、多目标精排(如DBMTL)、GPU加速推理与灵活迭代能力,已助力电商、直播、音视频等多行业提升点击率、转化率与ROI,实现高效、低成本、可自主演进的智能推荐。
633 16
|
5月前
|
Web App开发 缓存 C++
Cursor 界面"结冰"了?!原因分析及解决方案
Cursor界面出现点状雪花样花屏,多因GPU硬件加速与显卡驱动兼容性问题所致。该现象常见于Electron/Chromium应用(如VS Code、Chrome等)。首选解决方案:在Runtime Arguments中启用`"disable-hardware-acceleration": true`并重启。亦可尝试清理缓存、禁用插件、更新或回退显卡驱动。
650 3
|
7月前
|
弹性计算 人工智能 API
阿里云ECS云服务器快速部署OpenClaw实战|千问大模型Qwen3.6-Plus一站式配置教程
随着AI智能体技术不断成熟,OpenClaw(曾用名Clawdbot)已经成为轻量化、可扩展、高稳定性的开源AI执行框架代表。它能够将自然语言指令转化为真实可执行的系统操作、文件处理、信息检索、流程自动化任务,真正实现从“对话”到“执行”的落地。
1235 29
|
7月前
|
并行计算 算法框架/工具 iOS开发
TorchRec在macos ARM芯片(Apple Silicon)上无法安装
JaggedTensor等在macOS ARM芯片上无法运行,主因是ARM64与x86_64架构不兼容,且TorchRec深度依赖CUDA——而Apple Silicon仅支持Metal。fbgemm-gpu缺失、Rosetta 2不支持CUDA指令,导致关键操作失败。建议改用MLX框架或标准PyTorch张量替代。
529 4
|
9月前
|
数据库 C++
向量维度、距离函数,如何影响召回结果
本文揭示向量检索效果不佳的根源常被误判:问题不在embedding模型本身,而在于被忽视的底层选择——向量维度与距离函数。二者共同定义了“相似性”的本质,而非仅调节精度。维度决定语义表达自由度与错误类型,距离函数(L2/Cosine/Dot)则确立“何为相近”的世界观。二者强耦合,直接塑造召回空间。调参前,先问:你更怕漏召,还是误召?
向量维度、距离函数,如何影响召回结果
|
11月前
|
Java 数据库连接 调度
xxljob执行源码分析
本文深入解析XXL-JOB分布式任务调度框架源码,涵盖架构设计、核心执行流程与关键线程池机制。内容包括任务触发、注册、失败重试、日志报告及时间轮调度原理,结合带中文注释的源码包与分析导图,全面剖析其高性能设计实现。
 xxljob执行源码分析
|
10月前
|
安全 小程序 搜索推荐
双迹美业模式商城软件开发
双迹美业模式商城是一款融合“社交电商+美业服务+团队裂变”的数字化平台,首创“498帮扶创业”模式,以低门槛入门、平级/帮扶双激励、O2O闭环运营,助力创业者轻资产入局、美业门店高效获客与复购。含C端小程序、代理端、智能后台三大模块,兼顾合规性与可扩展性。
469 0
|
11月前
|
人工智能 自然语言处理 搜索推荐
AI客服选型指南:2025年12月主流智能客服系统产品测评
随着企业数字化加速,智能客服正向全渠道、智能化、情感化演进,成为服务与增长双引擎。本文详解瓴羊Quick Service、智齿科技等主流厂商的核心优势与适用场景,并从需求匹配、智能化水平、集成能力等维度提供选型指南,展望情感计算、多模态交互与业务融合的未来趋势,助力企业高效决策。瓴羊 Quick Service 依托阿里巴巴20年服务运营经验与阿里云全球基础设施,为企业提供全渠道、全链路、全场景的智能客服解决方案,覆盖售前咨询、售中支持、售后维护全流程,适配零售、电商、汽车、互联网等多行业需求。