- 赛题简述:
广告检索引擎是在线广告系统的核心模块,涉及到广告的匹配、过滤、排序、计价等核心能力。在单机无法容纳的广告数据规模下,如何实现高性能的广告检索是持续探索的技术问题。本题将提供一份广告数据集,要求设计实现一个包含核心功能的高性能的分布式广告检索引擎;
-
**提交方式:**复赛阶段采用源代码打包上传的提交方式,压缩包目录和文件规范请在复赛开放后参考题目相关说明;
-
复赛评测说明:「引擎赛道」系统每天为每个团队提供10次正式评测的机会,复赛提交截止时间:2023年7月23日20:00;
-
**排行榜更新:**在复赛期间,我们会根据比赛前2周参赛者提交运行的情况,可能会进行一些判分限制的调整,这段期间内不会公开展示排行榜,正式的排行榜将在2023年7月10日22:00起展示,之前的正式提交的程序会进行重新跑分,按照赛题评测指标从高到低排序。排行榜将基于参赛团队在本阶段历史最优成绩进行排名展示,最终结果以晋级榜单为准;
-
**晋级榜单:**复赛结束,以排行榜成绩作为复赛成绩参考依据,组委会将会对参与队伍的代码进行人工审核。如果存在相互作弊、未按赛题要求实现等行为,组委会有权取消其参赛资格,晋级空缺名额递补,最终复赛晋级榜单将于2023年7月24日公布。
广告业务由广告主、媒体、广告平台等几个角色组成。假设一个典型的电商搜索广告场景:广告主在广告平台中创建了若干推广计划(带有投放时段、投放状态等属性),每个计划下可以创建若干推广单元;每个推广单元可以绑定一个商品(一个商品可以绑定在多个推广单元上),并为该商品选择若干推广关键词、设置该关键词的出价。如下图所示:
当消费者在电商APP中搜索某个关键词的时候,会触发一个广告请求。广告平台中的广告引擎,会根据当前请求中的关键词(可能有多个)、时段等信息,召回关键词匹配、时段匹配、投放状态匹配的广告(注1),并对召回的多个广告进行排序、计算计费价格(注2)。
请设计实现一个包含上述功能的广告引擎,加载【数据文件】中的广告数据(注3),响应并发的广告请求,为每个请求返回排名TopN的推广单元及对应的计费价格。
运行时环境要求,详见(注4)。评分规则,详见该说明最后的描述,其他细节描述见(注5),接口描述见(注6)。
广告召回规则说明。例如有如下4组推广计划-推广单元:
● 计划1(投放时段为0,1,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,1,0,0,0,投放状态为1),单元1(商品1,选择了关键词1,关键词2)
● 计划2(投放时段为0,1,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,1,0,0,0,投放状态为1),单元2(商品2,选择了关键词2,关键词3)
● 计划3(投放时段为0,1,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,投放状态为1),单元3(商品3,选择了关键词1,关键词3)
● 计划4(投放时段为0,1,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,1,0,0,0,投放状态为0),单元4(商品4,选择了关键词1,关键词4)
对于"关键词1、时段10"的一个请求,只有单元1可以被召回(单元2关键词不匹配,单元3投放时段不匹配,单元4投放状态不匹配)。
广告排序和计费规则说明。
- 排序分数 = 预估点击率 x 出价(分数越高,排序越靠前)
- 预估点击率 = 商品向量 和 用户_关键词向量 的余弦距离
- 计费价格 = 第 i+1 名的排序分数 / 第 i 名的预估点击率(i表示排序名次,例如i=1代表排名第1的广告)
广告数据格式说明:文件包含多列,各列之间用 Tab符 分隔。
-
- 【数据文件】评测环境文件路径为: /data/raw_data.csv ,字段说明:
-
-
- keywrod: 关键词
- adgroup_id: 广告单元id
- keyword_prices: 出价列表
- status: 投放状态(取值范围为[0, 1],1代表可投)
- timings:投放时段(逗号分隔的24个值,取值范围为[0, 1],1代表可投)
- vector:商品向量(float类型的2维向量)
- campaign_id:计划id
- item_id:商品id
-
-
- 【数据文件】格式示例如下,提供的数据为csv文件不含 header:
keywrod(uint64) | adgroup_id(uint64) | price(uint64) | status(int8) | timings(int8, 0/1列表,长度24) | vector(float列表) | campaign_id(uint64) | item_id(uint64) |
---|---|---|---|---|---|---|---|
123 | 1 | 123 | 1 | 0,0,0,...,1,1,1,...0 | 0.894423,0.4472136 | 1 | 1 |
以上各种“id”、“关键词” 均uint64范围内的整数。
广告数据大小说明:
总文件大小 69G
关键词的数量: ~100万
广告单元的数量: ~500万
广告计划的数据:~100万
广告单元上的关键词数量: ~100
-
服务可运行在最多3个16G内存16cpu的容器中
-
- 学生需要注册1个入口服务ip到etcd中, 例如
-
-
- key: /services/searchservice
- value: 127.0.0.1:8080
-
-
选手开发自测:在本地环境,使用主办方提供的Dockerfile,自行下载开发版本的【数据文件】,并用testbench测试
-
选手提交验证:在网页中提交代码地址(包含代码构建脚本)。
-
验证的运行时环境:主办方提供运行时容器,根据选手提供的启动脚本,启动对应服务,加载【数据文件】。
-
索引构建+索引Load时间要求在10min内,加载完成再注册etcd
-
提供的数据中(包括请求数据)用于点击率预估的二维向量提前做过了归一化,选手不必再显式做归一化
-
排序过程遇到adgroup_id重复,则优先选择排序分数高者,如若同时排序分数相等则取出价低者;若排序过程中排序分数相同,选择出价低者,
-
出价相同,adgroup_id大的排前面。
-
浮点运算相关:请计算过程中全部使用float32
-
点击率预估分计算原始结果加上0.000001f,确保非0
-
出价结果(uint64),涉及浮点运算,请按照四舍五入取整
-
若召回的广告集合少于等于请求的topn时,最后一名的计费价格使用其自身的出价
接口协议定义,包括判题所需接口、支持赛题运行场景的模拟接口等,最好能提供请求包和回包示例
syntax = "proto3";
package alimama.proto;
message Request {
// 指定返回的广告需要匹配的keyword。
repeated uint64 keywords = 1;
// 根据用户和关键词生成的上下文向量。向量维度为2。
repeated float context_vector = 2;
// 指定返回的广告需要匹配的时段,取值范围为[0,23]
uint64 hour = 3;
// 返回的广告单元的数量,若满足后续条件的广告单元数量不足`topn`个,则返回所有满足条件的广告单元
// 若满足后续条件的广告单元数量超过`topn`个,则返回按分数降序排列的前`topn`个广告单元。
uint64 topn = 4;
}
message Response {
// 广告单元id
repeated uint64 adgroup_ids = 1;
// 广告单元对应的出价(单位为分)
repeated uint64 prices = 2;
}
service SearchService {
rpc Search(Request) returns (Response) {}
}
评分逻辑:Score= 0.5 * ResultScore + 0.2 * ResponseTimeScore + 0.2 * CapacityScore + 0.1 * ServiceScore
- ad集合(top 100%可调)正确加50分
- ad集合(top 100%可调)正确,且相对顺序正确加30分
- ad集合(top 100%可调)正确,且相对顺序正确,扣费正确加20分
- 超时 500ms,请求成功率需达到99.9%(成功返回结果数量/总请求数量),未达标得0分
- 最终平均分达到80分就可以进行下一阶段测试
- 得分=100 * 2 * qps / (3 * M); 目前示例程序压测qps大约3k左右,M 为3000
- 最大超时时间100ms下,请求成功率需达到99.9%(成功返回结果数量/总请求数量),未达标得0分
- 每个qps测试中抽样1% 验证正确性,最后正确性部份平均分未达到80分则停止后续测试该项得0分
- qps为3000,得分=(100-T) ^ 2 / 100;T为p99延迟
- 最大超时时间100ms下,请求成功率需达到99.9%(成功返回结果数量/总请求数量),未达标得0分
- 抽样1% 验证正确性,最后正确性部份平均分未达到80分则停止后续测试该项得0分
- 以最大qps *0.6压力压测5分钟
- 最大超时时间100ms下,请求成功率需达到99.9%(成功返回结果数量/总请求数量),未达标得0分
- 抽样1% 验证正确性,最后正确性部份平均分未达到80分则该项得0分