笔记
0工具
0此页用于记录用户反馈问题后的每一次改进
关于
“写笔记”支持四种格式——Word 文档、Excel 表格、Markdown、纯文本,起稿或二次编辑时都能随时切换,同一篇笔记想用哪种形态来记,都由你说了算。
md、txt、csv、json 这类纯文本则原样载入,不做多余加工。拿一张现成的表倒进来、改几笔、再导出去,等于白用一台免费的格式转换器。
要带走就在右上角点“下载”,可导出 PDF、Word、Markdown、Excel、TXT 等格式;列表卡片“⋯”菜单里,也有同样的下载入口。
在“工具”页点“+ 上传工具”即可发布:填好名称与链接,再用 Markdown 把使用方法写清楚——能解决什么问题、怎么装、怎么用,比堆介绍实在。
要分发安装包就一并上传压缩包(ZIP、RAR、7Z、TAR.GZ,最大 35MB),别人在详情页一键下载;只放链接不带附件也可以。
工具按大家的收藏热度排序,好用的自然会被顶上来。发布后可在详情页或卡片菜单里编辑、下架。
写笔记时勾上“隐藏”,这篇就只存在于你自己的账号里:不进列表、不进搜索、不上首页精选,也不会出现在任何公开的页面,链接发给别人同样打不开。
适合放密码、草稿、日记这类只给自己看的内容;想公开,去“发布”打开它,把“隐藏”的勾去掉再保存,之后编辑会默认保持原状态,不会悄悄变回公开。
不想公开、只想临时给人看:点“分享”生成一条带密码和有效期的链接,到期自动失效,你也能随时撤销。
你的内容会同时保存在多个副本上,系统定期做备份与完整性校验,再配合异地容灾机制:就算某台机器出问题,数据也不会丢,可以长期放心存放;特别重要的资料,仍建议你另外再留一份备份。
全站跑在容器化、模块化的现代架构上,更新、部署、回滚都很快,扩展性和稳定性都按长期运营的标准来设计(Built for reliability, designed to scale)。
这个网站最早只是一个人的笔记仓库,后来慢慢长成现在的知识中枢。设计上很克制——没有广告、没有追踪、没有推荐算法,只是干干净净地存放一些东西;既然做好了,就公开出来,万一有人用得上呢。
不做大而全,不做平台梦,保持简单、保持克制、保持好奇。所有内容都由用户贡献、由用户维护:不会突然冒出付费墙,不会在角落塞广告位,也不会把你的数据卖给第三方。
产品会持续迭代,站内日志页记录着每一次改动,改了什么都有迹可循;想了解这个站是怎么一步步走到今天的,翻翻日志就能看到来龙去脉。
如果在这里看到涉嫌违规的内容,点对应卡片右侧的“举报”按钮就能提交,我们会尽快核实处理;也谢谢你花一点时间,一起把这里维护干净。
趋势
美团搜索3.0:LLM 语义表征在排序模型的探索与应用
为什么要做这件事
先交代一下背景。美团搜索的业务里,服务零售和商品零售是两条大的线。服务零售的特点是:品类极其分散(丽人、休闲娱乐、家政、进场零售……),搜索意图五花八门(交易型、信息型、留资型都有),而且供给高度非标准化——一个服务往往由券、时间、场次、空间、技师等多个维度组合而成,履约又依赖“人”和“场所”。
这种业务形态给排序模型出了一个难题:传统精排模型的语义建模基本靠文本匹配特征,但这些特征构建成本高、泛化能力弱。遇到长尾品类或者复杂Query,词面匹配经常直接失效。举个例子:用户搜“宠物SPA+洗澡”,商品名称可能是“萌宠清洁护理套餐”;搜“春节大扫除”,商品名称是“深度保洁服务套餐”——词面上几乎没有重叠,但语义上高度相关。这种语义Gap在服务零售场景里特别普遍。
大模型的出现给了我们一个新思路。从2025年Q4到2026年Q2,我们系统性做了三期迭代,核心方向是用LLM给Query、POI(商家)、Deal(商品)生成语义向量表征,把cosine相似度作为特征注入排序模型。三期全部完成了Launch Review并全量上线,都有显著的线上收益。
这篇文章把三期实践完整拆开讲,包括每期的技术方案、踩过的坑、反直觉的发现,以及现在回头看的一些思考。
一期:验证可行性——64维向量带来的信心
核心思路
一期目标很纯粹:验证LLM表征对精排模型有没有实质帮助。服务零售精排在语义层面的建模几乎为零,主要靠少量文本匹配和Query统计特征。所以整个一期设计都围绕“先把路走通”来展开。
整体思路:选一个轻量级LLM做基座,对Query和POI信息统一建模,通过微调让模型判断“这个搜索词和这个商家是否匹配”,然后全量推理出Query和POI各自的语义向量,计算cosine相似度作为特征注入精排。
技术方案
模型设计与特殊Token
一期选的是小参数量的开源基座模型,全参数微调。
要提取语义表征,需要一个明确的“聚合点”——模型在哪个位置把输入文本的语义信息汇聚成一个向量。直接用序列末尾Token或者Mean Pooling也可以,但缺少可学习性。我们的设计是在词表中新增三个特殊Token:<|query|>、<|item|>、<|qi|>,作为专门的聚合锚点,在训练中与模型参数一起优化。嵌入采用平均初始化法,参考了vocab-expansion的做法。
输入Prompt的结构长这样:
用户查询:{}<|query|>
候选商铺信息如下:
商铺名称:{}
热销商品:{}
所属品牌:{}
商铺分类:{} - {} - {}
用户评分:{}分
平均价格:{}元
所在商圈:{}<|item|>
请判断该商铺是否匹配用户查询<|qi|>
为什么要三个Token而不是一个?因为需要三种不同类型的表征:<|query|>聚合Query侧语义,<|item|>聚合item侧语义,<|qi|>聚合双侧融合信息。前两者用于推理时独立提取Embedding并计算cosine相似度,后者仅用于微调时的辅助Loss。
Attention Mask与三次Forward Pass
这里有个关键细节。三个特殊Token内嵌在同一条Prompt序列里,意味着训练时Query和item的文本信息混在一起。如果不加干预,<|query|>会“看到”后面的item文本,<|item|>也会“看到”前面的Query文本。对<|qi|>来说这没问题——它本来就要看两侧信息。但对<|query|>和<|item|>来说就是问题:推理时Query和item的Embedding是分别独立生成的,如果训练时它们“看到”了对方的信息,学到的表征就会依赖对方上下文,推理时只输入单侧文本,产出的表征就失去了意义。
解决办法:通过Attention Mask对同一条输入序列做三次独立forward pass。提取query表征时,mask把注意力限制在Query文本段;提取item表征时,mask限制在item文本段;提取融合表征时用完整mask。这样确保Query和item的表征是自包含的,可以独立提取和存储。
表征提取方式:取transformer最后一层在特殊Token位置的hidden state,经两层MLP(hidden_size → 512 → ReLU → LayerNorm → 64)降至64维。
训练数据与双Loss设计
从服务零售垂直搜索链路的精排日志中抽取近2个月、共3000余万条训练样本,下单:点击未下单:未点击 = 1:3:6。
训练目标包含两个Loss协同优化:
- Loss₁:基于
<|query|>和<|item|>单侧表征的cosine相似度,经可学习温度参数缩放后做二分类交叉熵,让模型从语义层面学习匹配程度。 - Loss₂:基于
<|qi|>融合双侧信息,经MLP后预测点击率,让学到的语义表征对齐下游排序目标。
最终Loss:L = Loss₁ + Loss₂。
双Loss设计的逻辑:让模型同时学习“单侧表征的质量”和“双侧匹配的判断”——前者直接服务于推理时的cosine相似度计算,后者辅助表征对齐下游点击率预估目标。
推理、分桶与特征注入
推理时分别独立生成Query和item的语义Embedding,离线存储至Hive表,按天例行增量更新。
拿到Embedding后,计算Query与item的cosine相似度,按预设分桶边界划分成10个桶。分桶边界为[-0.40, -0.30, -0.18, -0.12, 0.00, 0.10, 0.16, 0.22, 0.30],设计时考虑了每个桶内的样本量分布,并尽可能区分下单与未下单、点击与未点击等行为标签。
我们抽取了2万条搜索曝光样本做验证,结果很直观:Query和item语义越相似,点击/下单的样本占比越高。
每个分桶分配一个可学习的Embedding向量(12维),拼接到精排模型现有特征中。用分桶而非连续相似度值的原因是:离散化后的特征能更好地被精排模型的特征交叉网络利用,同时降低噪声敏感度。用可学习Embedding是为了增强模型对不同相似度区间的表达能力。
离线验证:引入表征特征后点击NDCG +9bp,下单NDCG +13bp。
线上效果
实验周期2025年9月18日至10月1日,20%流量14天,AA校验通过。
- 大盘搜索支付订单显著+0.20%
- 服务零售订单显著+0.27%
- 长尾NDCG@5显著+2.21pp
- 长尾BadCase@1显著-2.96pp
长尾指标的大幅提升完全符合预期——长尾Query恰恰是传统词面匹配最薄弱的地方。一个只有64维的语义表征,仅通过分桶拼接的方式注入精排,就带来了显著的订单增量。这个结果直接证明了LLM语义表征在精排场景的价值。
一期的局限性
一期验证了可行性,但也暴露了四个明显短板:
- 只覆盖Query-商家两端,商品侧语义完全缺失——服务零售场景中用户很多时候是在搜商品而非搜商家。
- 全参数微调训练成本高、维护困难,不利于快速迭代。
- 微调目标以点击率预估为主,对排序优化不够全面——下游精排同时也关注成单目标。
- 三次Forward Pass的推理效率有优化空间。
这些问题成为二期系统性升级的起点。
二期:系统性重构——从二分类到对比学习
核心动机
二期不是单点优化,而是系统性重构表征生产的全流程——从训练数据、基座模型、微调方式、表征提取、降维方式到损失函数,逐一对应一期的短板进行升级,同时将下挂商品(Deal)纳入建模,构建Query-POI-Deal三元语义表征体系。
贯穿二期的核心矛盾:一期的训练目标是“判断Query和商家是否匹配”的二分类问题,但排序模型真正需要的是“在多个候选中哪个更匹配”的相对序关系。这个矛盾直接驱动了从点击率分类到对比学习的损失函数重设计,也间接影响了训练数据构建(需要难负样本)、表征提取方式(需要更高效的聚合)等其他模块的决策。
技术方案
训练数据:从单条样本到五元组
一期每条样本只有Query和POI两部分。二期将每条样本扩展为五元组:Query、Deal正样本、POI正样本、Deal难负样本、POI难负样本。
难负样本的选取是关键。Deal难负样本来自同一请求、同一商家下曝光但未点击的商品;POI难负样本来自同一请求下曝光但未点击的商家。这种“同请求”的难负采样策略确保了负样本与正样本在Query意图和上下文上高度相似,只在“是否被用户选择”上有差异,能迫使模型学到更精细的判别能力。
最终构建了2766万条训练样本。
Prompt设计:一个反直觉的发现
确定了“喂什么数据”后,下一步是“怎么组织成文本”。我们尝试了多种Prompt方案:
- 精简信息陈述+总结引导
- 简单任务指令
- 丰富版任务指令
- 仅信息陈述
实验发现一个反直觉的结论:精简信息陈述+总结引导效果最好,过于复杂的任务指令反而降低表征质量。
这与常见LLM问答任务的直觉相反。我们的推测是:在Embedding训练场景中,Prompt的作用是引导模型理解“要聚合哪些语义信息”,而非传统的“指令遵循”。过于复杂的指令会干扰模型对核心语义信息的聚合——就像给一个本该专注于理解文本的人过多任务要求,反而分散了注意力。
具体的Prompt如下:
- 商家:“商铺信息如下:商铺名称为{},热销商品为{},品牌名为{},主营类目的三级标签分别是{}、{}、{},次营类目为{},所属商圈为{}。请根据以上信息,详细描述该商铺:”
- 下挂商品:“商品信息如下:商品名称为{},商品类目的三级标签分别是{}、{}、{},所属商家名称为{}。请根据以上信息,详细描述该商品:”
- 搜索词:“查询信息如下:用户查询词为{}。请根据该查询词,总结用户的查询意图:”
二期在商家Prompt中新增了“次级经营品类”、“热销商品”等信息,期望学到更完整的商家语义表征。
还有一个值得注意的实验发现:我们尝试在商品特征中引入CPV(商品属性)信息后,排序评估效果反而下降。推测原因是当前CPV信息过于繁杂,未经筛选地引入反而带来噪声。这个反直觉的结果说明:在表征训练中,信息质量比信息量更重要。
基座模型与微调方式:从全参到LoRA
基座模型选择上,我们横向对比了参数量在0.5B~8B的多个模型,涵盖通用、Embedding、Instruct等多个系列。
实验发现中等参数档位是效果与推理成本的最优平衡点——更大的模型在NDCG指标上提升有限且推理成本显著上升;最小参数档位则在各项指标上全面落后。最终选定专门为文本表征任务优化的Embedding模型变体,它在Click-AUC和NDCG上均优于同参数量的通用模型。
微调方式从全参数微调切换到LoRA(r=8、α=32,目标模块q_proj和v_proj)。对比实验发现一个有趣的现象:LoRA在NDCG指标上优于全参数微调,但全参在AUC上略有优势。这一现象仅在本场景中观察到,是否具有普适性有待验证。综合考虑训练效率和维护成本,最终选择LoRA。
表征提取:从三Token单序列到独立序列+可学习向量
一期在同一条序列中内嵌三个词表Token,通过三次Forward Pass和不同Attention Mask实现信息隔离,推理效率低。
二期彻底重构了表征提取方式:不再将Query和item放在同一条序列中,而是各自在独立序列中处理;特殊Token不再是vocabulary token,而是nn.Parameter——一个维度为hidden_size的可学习向量。
具体做法:对输入文本做tokenize后取input embeddings,找到序列中最后一个有效位置,将该位置的Embedding覆写为对应的可学习向量,经过Transformer后取该位置的hidden state作为表征。Query、POI、Deal各有独立的可学习向量。
这种设计相比一期的优势:
- 不再需要Attention Mask隔离(各实体本就在独立序列中处理)
- 一次Forward可以同时处理五路输入(五元组的各部分拼接在batch维度上),推理效率大幅提升
- 可学习向量直接作为“聚合锚点”放在序列末尾,模型在训练中学会在该位置汇聚全序列的语义信息
对比实验显示,Last Special Token Embedding优于Mean Pooling和直接取最后一个有效Token。推测原因是可学习的特殊Token比固定位置或平均池化更能有效聚合序列信息并区分不同实体类型。
降维方式:从Linear到MRL-E
一期用两层MLP将hidden state降至64维。二期改用MRL-E(Matryoshka Representation Learning)策略:设置嵌套维度列表[1024, 512, 256, 128],训练时对每个维度分别计算损失并取平均,推理时直接截取前128维。
MRL-E相比Linear降维的核心优势不在于精度提升(离线指标差异不大),而在于灵活性:同一套训练出的表征可以根据不同场景的效率需求选择不同维度,无需重新训练。这在后续三期将表征迁移到下挂精排时体现了价值——不同模块对Embedding维度的要求可能不同,MRL-E提供了开箱即用的多尺度选择。
损失函数:从分类到对比学习
这是二期最核心的升级,也是“从分类到排序”这一核心矛盾的直接解法。
一期用BCE Loss做点击率二分类,模型只学到“是否匹配”的绝对判断。但排序模型需要的是相对序——在多个候选中哪个更匹配。
InfoNCE Loss天然面向这个目标:它利用Batch内负样本构建对比任务,最大化正样本对相似度的同时最小化与batch内其他样本的相似度,本质上是在做“从N个候选中选出正确匹配”的排序训练。
我们具体设计了三组InfoNCE Loss:
- Query↔POI
- Query↔Deal
- POI↔Deal
三组对比覆盖了三元实体间所有两两关系,使表征空间同时编码Query-商家匹配度、Query-商品匹配度和商家-商品一致性。采用归一化嵌入后的内积作为相似度度量,温度参数可学习。
但如果InfoNCE的负样本仅来自Batch内随机采样,难度不够——大部分Batch内负样本与Query的语义差距很明显,模型不费力就能区分。为此引入Triplet Loss专门处理构建出的难负样本:采用欧氏距离,margin=0.5,分别计算Query-POI和Query-Deal的Triplet Loss。
消融实验验证了这一设计:
- 引入Triplet Loss后,Q2I-Click-AUC +4.85pp
- Q2I-Order-AUC +11.02pp
Order-AUC的提升幅度远高于Click-AUC,说明难负样本建模对排序下单信号的捕获比点击信号更难、但更有价值——这也印证了“从分类到排序”的转型方向是正确的。
最终的训练目标为五个损失的加权和:
L_total = L_InfoNCE(Q→P) + L_InfoNCE(Q→D) + L_InfoNCE(P→D) + λ1·L_Triplet(Q,P) + λ2·L_Triplet(Q,D)
二期的线上效果
(二期实验周期和数据在原文中未完整展示,但三期累计完成3个LR并全量上线,均带来显著线上收益。)
三期:跨场景迁移复用
核心动机
二期构建了Query-POI-Deal三元语义表征体系,在商家精排上取得了显著收益。三期要解决的是另一个问题:这套表征能力能不能迁移到其他排序模块?
服务零售搜索链路中,除了商家精排,还有下挂精排(对商家下的具体商品排序)。下挂精排同样面临语义理解问题,但它对特征维度、推理延迟的要求与商家精排不同。如果为下挂精排单独训练一套表征,成本高、周期长;如果能复用二期的表征,只需要做适配和微调,就能快速见效。
技术方案
这里MRL-E的灵活性就体现出来了。二期训练时设置了嵌套维度[1024, 512, 256, 128],推理时截取前128维用于商家精排。三期在下挂精排中,可以根据下挂模块对特征维度的要求,直接截取其他维度使用,无需重新训练。
具体做法上,三期将二期的语义表征能力迁移到下挂精排场景,针对下挂精排的特点做了适配:
- 特征注入方式上,下挂精排更关注Deal粒度的语义匹配,所以重点使用Query-Deal的相似度信号
- 结合下挂精排的排序目标,对表征做了适当的任务适配
- 利用二期的MRL-E特性,按需选择表征维度,平衡效果与计算成本
关键收获
三期的核心价值在于验证了:一套系统性设计的语义表征体系,可以在不同排序模块间迁移复用。这避免了重复训练成本,也说明二期的投入有更广泛的杠杆效应。
一些沉淀下来的思考
回头看这三期迭代,有几个点我觉得值得单独拎出来说:
关于“从分类到排序”的转型。一期用BCE做二分类,模型学到的是“是否匹配”的绝对判断;二期切到InfoNCE+Triplet的组合,模型学到的是“哪个更匹配”的相对序关系。这个转型直接对齐了排序模型的目标。消融实验里Order-AUC +11.02pp的提升说明,难负样本建模对下单信号的捕获价值远超点击信号——用户下单比点击包含更明确的偏好信息。
关于难负样本。这是二期效果提升的关键因素之一。“同请求同商家曝光未点击”的样本设计,确保负样本与正样本在Query意图和上下文上高度相似,只在用户选择上有差异。这才是模型真正需要学会区分的边界。如果负样本太容易区分,模型学到的判别能力就粗糙。
关于Prompt的“少即是多”。二期实验发现精简信息陈述+总结引导效果最好,复杂任务指令反而降低表征质量。这和我们做LLM应用时的直觉相反。在Embedding训练场景中,Prompt是引导模型理解“要聚合哪些语义信息”,而不是“指令遵循”。这个结论对我们后续做其他表征场景有直接参考价值。
关于信息质量vs信息量。CPV特征引入后效果反而下降,这个反直觉的结果提醒我们:表征训练中,未经筛选的信息引入可能带来噪声,干扰模型对核心语义的聚合。在特征工程中“多多益善”的思路,在表征训练中不一定成立。
关于MRL-E的长期价值。当时选择MRL-E主要是看中灵活性,没想到三期迁移时直接受益。同一套表征,商家精排用128维,下挂精排按需截取其他维度,免去了重新训练的成本。如果当时用Linear降维,三期就需要单独训练一套表征,成本和周期都会显著增加。
写在最后
从一期64维向量的“试水”,到二期系统性重构表征生产全流程,再到三期跨场景迁移复用,这套体系一步步走向成熟。当前的工作还只是LLM语义表征在排序模型应用的一部分,后续还有很多方向值得探索:更大参数规模的基座模型是否有边际收益、如何更高效地更新表征以捕捉实时语义变化、多模态信息如何融入表征体系……
这些就留给后续的迭代了。