拓冰建站拓冰建站
首页 / 资讯中心 / 正文

Meta新研究:用判别式语言模型DLM简化检索系统,无需生成向量ID

这次我们来看一个来自 Meta 的新研究用判别式语言模型Discriminative Language Model, DLM直接做检索器绕过了传统双塔架构中生成 item ID 的复杂步骤。对于做搜索、推荐、广告系统的开发者来说这意味着什么简单说就是模型训练和部署的门槛可能被拉低了效果可能还更好。这个研究的核心是“判别式”和“生成式”的路线之争。传统双塔模型比如 DPR、ANCE需要为每个候选 item如商品、文章、视频预先计算一个向量embedding检索时再计算 query 向量和这些向量的相似度。而 Meta 这篇论文提出直接用判别式语言模型例如 BERT 的变体来学习一个函数这个函数直接输出 query 和候选 item 文本之间的相关性分数完全不需要为 item 生成一个独立的 ID 或向量。这听起来有点反直觉但论文给出的实验数据表明在多个公开检索基准上这种 DLM 检索器在效果上可以媲美甚至超越复杂的生成式模型和精心优化的双塔模型。那么对我们这些关心落地的人来说最值得关注的几个点是什么第一模型结构更简单理论上训练和推理的 pipeline 可以简化。第二避免了 item ID 的生成和索引维护这对于 item 集合动态变化如新闻、短视频的场景可能是个优势。第三论文提到了通过知识蒸馏Knowledge Distillation将大型生成式模型如 T5的能力迁移到更小的判别式模型上这为在资源受限环境下获得高性能检索器提供了新思路。本文将带你快速理解这项技术的核心思想并探讨其潜在的部署方式、硬件考量以及如何在自己的环境中进行验证的思路。1. 核心能力速览能力项说明项目类型学术研究 / 检索模型新架构开源团队Meta AI Research核心创新使用判别式语言模型DLM直接进行检索无需为候选 item 生成独立向量或 ID。主要功能给定一个查询query和一组候选文本items直接输出相关性分数完成排序和检索。推荐硬件取决于模型规模。基础版 BERT 类模型GPU 显存 8GB 以上可进行训练和推理纯 CPU 推理在批处理较小时可行但延迟较高。显存占用不确定需按实际选择的预训练模型如 BERT-base, BERT-large及批处理大小batch size测试。支持平台理论上支持任何可运行 PyTorch 或 TensorFlow 的平台。启动/部署方式非传统“一键启动”应用。需按照研究代码进行模型训练或加载预训练权重然后封装为推理服务。是否支持 API原研究未提供但可自行将模型封装为 RESTful API 或 gRPC 服务。是否支持批量任务是模型本身支持批处理输入适合离线批量候选集重排序reranking任务。适合场景搜索系统召回/粗排后的精排阶段、推荐系统候选重排序、开放域问答的文档检索、需要避免维护庞大向量索引的动态内容库。2. 适用场景与使用边界这个工具适合谁搜索/推荐算法工程师希望探索超越双塔模型的新检索架构提升精排阶段效果。全栈开发者或初创团队资源有限希望用相对简单的模型 pipeline 实现高质量的检索功能避免维护复杂的向量索引系统。学术研究人员关注信息检索、表示学习前沿希望复现或基于此工作展开新研究。能解决什么问题简化检索流水线传统双塔需要“编码-索引-检索”三步走。DLM 检索器可以简化为“编码-打分”两步甚至端到端训练降低了系统复杂度。应对动态候选集对于新闻、社交媒体帖子等 item 集合频繁更新的场景不需要为每个新 item 实时计算并更新向量索引只需在推理时将其文本与 query 一起输入模型即可。利用更丰富的交互信息双塔模型在编码时 query 和 item 是独立的交互发生在向量点积。DLM 在输入端就让 query 和 item 文本进行深度交互通过 Transformer 的自注意力机制可能捕捉到更细微的相关性信号。不适合什么场景超大规模候选集的首轮召回如果候选池有百万、千万甚至亿级 item对每个 query 都用 DLM 与所有 item 计算分数计算成本是不可接受的。它更适合在召回例如通过倒排索引或轻量双塔缩小候选范围后如 Top 1000进行精排。对延迟极其敏感的线上服务尽管批处理能提高吞吐但单次推理由于需要编码较长的拼接文本query item可能比双塔的点积运算更慢。需要针对业务延迟要求进行压测和优化。缺乏高质量文本描述的项目DLM 严重依赖 item 的文本信息标题、描述、正文。如果 item 主要是图像、视频或结构化数据仅有 ID 和类别且缺乏丰富的文本特征其优势可能无法发挥。版权、隐私与安全边界模型权重如果使用 Meta 官方开源代码和预训练权重需遵守其对应的开源协议如 MIT, Apache 2.0。训练数据若使用该技术在自己的业务数据上训练模型必须确保训练数据获取合法合规并注意去除用户隐私信息。应用合规应用于搜索、推荐、广告系统时需关注结果的可解释性、公平性避免产生歧视性或有害内容。3. 环境准备与前置条件要复现或尝试 DLM 检索器你需要准备以下环境。请注意由于是前沿研究以下清单基于通用深度学习项目经验具体版本请以项目官方代码库为准。操作系统Linux (Ubuntu 20.04/22.04 推荐) 或 macOS。Windows 可通过 WSL2 进行。Python版本 3.8 或 3.9。建议使用 conda 或 venv 创建独立的虚拟环境。深度学习框架PyTorch 1.9.0 版本。需与 CUDA 版本匹配如果使用 GPU。或TensorFlow 2.4.0如果官方实现基于 TF。Transformers 库(Hugging Face) 4.15.0用于加载预训练语言模型。GPU/CPUGPU训练强烈推荐 NVIDIA GPU显存建议 8GB 以上。需要安装对应版本的 CUDA ( 11.0) 和 cuDNN。CPU仅推理或小规模测试 现代多核 CPU如 Intel i7/i9 或 AMD Ryzen 7/9。内存建议 16GB 以上。依赖管理工具 pip 或 conda。磁盘空间至少 10GB 可用空间用于存放预训练模型、数据集和代码。网络需要能稳定访问 Hugging Face 模型仓库以下载预训练模型。通用检查清单[ ] 确认 GPU 驱动已安装 (nvidia-smi可运行)。[ ] 确认 CUDA 版本与 PyTorch 版本匹配。[ ] 创建并激活 Python 虚拟环境。[ ] 准备至少一个标准检索数据集如 MS MARCO, Natural Questions用于测试。4. 安装部署与启动方式由于这是一篇学术论文并非一个开箱即用的软件包因此“部署”指的是搭建实验环境、运行官方代码如果开源或根据论文思想自行实现。假设 Meta 开源了代码库例如在 GitHub 上名为dlm-retriever通用部署流程如下# 1. 克隆代码仓库 git clone https://github.com/facebookresearch/dlm-retriever.git cd dlm-retriever # 2. 创建并激活虚拟环境以 conda 为例 conda create -n dlm-retrieval python3.9 conda activate dlm-retrieval # 3. 安装依赖 pip install -r requirements.txt # 如果 requirements.txt 不存在可能需要手动安装核心包 pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118 # 请根据CUDA版本调整 pip install transformers datasets accelerate sentencepiece # 4. 下载预训练模型权重如果提供 # 通常代码会通过 Hugging Face Transformers 自动下载例如 # from transformers import AutoModelForSequenceClassification # model AutoModelForSequenceClassification.from_pretrained(facebook/dlm-base-msmarco) # 如果没有官方权重可能需要按照论文描述从头训练或使用基础BERT权重微调。 # 5. 准备数据 # 将数据集如 MS MARCO 的 .tsv 文件放入指定目录或修改配置文件中的路径。模型启动与推理示例论文中的 DLM 通常被构造成一个文本对分类或回归模型。一个极简的推理脚本示例如下import torch from transformers import AutoTokenizer, AutoModelForSequenceClassification # 加载模型和分词器假设模型已微调好并上传至HF Hub model_name your_username/dlm-retriever-msmarco # 替换为实际模型名 tokenizer AutoTokenizer.from_pretrained(model_name) model AutoModelForSequenceClassification.from_pretrained(model_name) model.eval() # 切换到评估模式 device torch.device(cuda if torch.cuda.is_available() else cpu) model.to(device) # 准备一个 query 和一个候选 item query 什么是机器学习 item_text 机器学习是人工智能的一个分支它允许计算机系统通过经验自动改进。 # 构建模型输入通常为 [CLS] query [SEP] item [SEP] inputs tokenizer(query, item_text, truncationTrue, paddingmax_length, max_length512, return_tensorspt) inputs {k: v.to(device) for k, v in inputs.items()} # 推理 with torch.no_grad(): outputs model(**inputs) # 假设是二分类相关/不相关取相关类别的分数 relevance_score torch.softmax(outputs.logits, dim-1)[:, 1].item() print(fQuery: {query}) print(fItem: {item_text[:50]}...) print(f相关性分数: {relevance_score:.4f})封装为 API 服务要用于生产你需要将其封装成服务。以下是一个使用 FastAPI 的简单示例# app.py from fastapi import FastAPI, HTTPException from pydantic import BaseModel import torch from transformers import AutoTokenizer, AutoModelForSequenceClassification import logging app FastAPI() logging.basicConfig(levellogging.INFO) # 全局加载模型实际生产需考虑懒加载、模型池等 MODEL_NAME your_username/dlm-retriever-msmarco try: tokenizer AutoTokenizer.from_pretrained(MODEL_NAME) model AutoModelForSequenceClassification.from_pretrained(MODEL_NAME) model.eval() device torch.device(cuda:0 if torch.cuda.is_available() else cpu) model.to(device) logging.info(fModel loaded on {device}) except Exception as e: logging.error(fFailed to load model: {e}) raise class QueryItemPair(BaseModel): query: str item_text: str app.post(/score/) async def compute_score(pair: QueryItemPair): try: inputs tokenizer(pair.query, pair.item_text, truncationTrue, paddingmax_length, max_length512, return_tensorspt) inputs {k: v.to(device) for k, v in inputs.items()} with torch.no_grad(): outputs model(**inputs) score torch.softmax(outputs.logits, dim-1)[0, 1].item() return {query: pair.query, item_text: pair.item_text[:100], relevance_score: score} except Exception as e: logging.error(fScoring error: {e}) raise HTTPException(status_code500, detailstr(e)) if __name__ __main__: import uvicorn uvicorn.run(app, host0.0.0.0, port8000)启动服务python app.py服务启动后可通过http://localhost:8000/docs访问交互式文档或直接向/score/端点发送 POST 请求。5. 功能测试与效果验证由于没有现成的“软件”界面测试围绕模型的核心能力展开为 (query, item) 对打分并进行排序。5.1 基础打分能力测试测试目的验证模型能否为单个 query-item 对输出合理的相关性分数。输入素材Query: “如何学习Python编程”Item 1 (相关): “Python从入门到实践一本适合初学者的编程书籍涵盖基础语法到项目实战。”Item 2 (弱相关): “Java虚拟机性能调优指南深入讲解JVM内存管理与垃圾回收。”Item 3 (不相关): “周末自驾游三条绝美沿海公路推荐。”操作步骤使用上一节的推理脚本或 API依次计算 Query 与三个 Item 的分数。记录并比较分数。预期结果Item 1 的分数应显著高于 Item 2 和 Item 3。Item 2 的分数可能略高于 Item 3因为同属“技术”范畴但语言不同。Item 3 的分数应最低。判断是否成功模型输出的分数排序与人工判断的相关性排序基本一致。常见失败原因模型未在相关领域数据上微调导致领域不匹配。文本过长被截断丢失关键信息。Tokenizer 词汇表不包含某些专业词汇。5.2 批量排序Reranking测试测试目的验证模型对一批候选 item 进行重新排序的能力这是其核心应用场景。输入素材Query: “Meta发布的判别式检索模型有什么特点”候选 Item 列表(10条)包含相关论文摘要、无关技术博客、新闻快讯等混合文本。操作步骤将 Query 分别与每个候选 Item 文本拼接组成一个批处理batch。使用模型进行批量推理得到每个 pair 的分数。根据分数对候选 Item 进行降序排序。# 批量推理示例 def batch_rerank(query, candidate_texts, model, tokenizer, device, batch_size8): scores [] for i in range(0, len(candidate_texts), batch_size): batch_texts candidate_texts[i:ibatch_size] # 构建批输入 inputs tokenizer([query]*len(batch_texts), batch_texts, truncationTrue, paddingTrue, max_length512, return_tensorspt) inputs {k: v.to(device) for k, v in inputs.items()} with torch.no_grad(): outputs model(**inputs) batch_scores torch.softmax(outputs.logits, dim-1)[:, 1].cpu().numpy() scores.extend(batch_scores.tolist()) # 将分数和原文对应并排序 ranked_items sorted(zip(candidate_texts, scores), keylambda x: x[1], reverseTrue) return ranked_items预期结果与 Query 最相关的论文摘要应排在最前面无关内容排在后面。判断是否成功使用标准检索指标进行评估如MRR10(平均倒数排名)、NDCG10或MAP。如果在公开数据集如 MS MARCO dev set上测试分数应接近论文报告值。常见失败原因批处理大小设置不当导致显存溢出OOM。文本长度差异大padding 过多影响效率或效果。候选集质量极低模型难以区分。5.3 长文本处理能力测试测试目的验证模型处理长文档如学术论文、长文章作为 item 的能力。输入素材一个长文档超过 1000 字作为 item一个具体的 query。操作步骤直接使用完整长文档与 query 拼接注意模型最大长度限制如 512 tokens。使用滑动窗口或选取关键段落如首段、尾段、包含关键词的段落与 query 拼接。比较两种方式的打分差异。预期结果使用关键段落的方法可能比直接截断长文档获得更准确的分数因为更聚焦。判断是否成功模型对关键段落给出的分数能正确反映其与 query 的相关性。常见失败原因模型最大序列长度限制导致长文档信息丢失。6. 接口 API 与批量任务DLM 检索器非常适合通过 API 提供服务并处理批量重排序任务。6.1 接口 API 设计除了前面 FastAPI 的简单示例一个生产级的 API 可能还需要健康检查端点(/health): 检查模型和服务状态。批量打分端点(/batch_score): 接受一个 query 和多个 items返回分数列表。异步任务端点对于超大批量任务提交后返回任务 ID通过另一个端点查询结果。认证与限流保护服务不被滥用。批量打分请求示例 (curl):curl -X POST http://localhost:8000/batch_score/ \ -H Content-Type: application/json \ -d { query: 深度学习在医疗影像中的应用, item_texts: [ 一篇关于CNN用于X光片检测的综述文章。, 天气预报明日全国大部地区晴转多云。, 使用Transformer模型进行病理切片分析的最新研究。, 如何烹饪美味的意大利面。 ] }预期响应:{ query: 深度学习在医疗影像中的应用, scores: [0.95, 0.02, 0.88, 0.01], ranked_indices: [0, 2, 1, 3] }6.2 批量任务处理对于离线大规模重排序例如每天对数百万 query-item 对进行打分建议任务队列使用 Redis、RabbitMQ 或 Apache Kafka 管理任务队列。Worker 进程启动多个模型推理 worker从队列中消费任务。批处理优化在 worker 内部积累一定数量的请求组成一个大的 tensor 进行批处理推理极大提升 GPU 利用率。结果存储将分数和排序结果写入数据库如 PostgreSQL, Elasticsearch或分布式文件系统如 HDFS。简易批量处理脚本框架:# batch_processor.py import pandas as pd from concurrent.futures import ProcessPoolExecutor from your_inference_module import score_single_pair # 导入你的打分函数 def process_chunk(chunk_df): 处理一个数据块 results [] for _, row in chunk_df.iterrows(): score score_single_pair(row[query], row[item_text]) results.append({qid: row[qid], docid: row[docid], score: score}) return results if __name__ __main__: # 读取大数据文件 df pd.read_parquet(large_dataset.parquet) # 分块 chunk_size 10000 chunks [df[i:i chunk_size] for i in range(0, df.shape[0], chunk_size)] results [] with ProcessPoolExecutor(max_workers4) as executor: # 根据CPU核心数调整 future_to_chunk {executor.submit(process_chunk, chunk): chunk for chunk in chunks} for future in concurrent.futures.as_completed(future_to_chunk): chunk_result future.result() results.extend(chunk_result) # 保存结果 pd.DataFrame(results).to_csv(rerank_scores.csv, indexFalse)7. 资源占用与性能观察性能是决定 DLM 检索器能否落地的关键。显存占用观察模型加载加载一个 BERT-base 模型约110M参数在 FP32 精度下仅模型参数就占用约 400MB 显存。加上优化器状态、激活值等训练时显存占用会翻倍。推理阶段主要占用来自输入 token 的激活值。(batch_size * sequence_length * hidden_size)是主要开销。例如batch_size32, seq_len128, hidden_size768仅这一项在 FP32 下就占用约32*128*768*4 bytes ≈ 12.5MB实际会更高。如何监控在代码中使用torch.cuda.memory_allocated()和torch.cuda.max_memory_allocated()。import torch torch.cuda.empty_cache() print(f初始显存: {torch.cuda.memory_allocated(device)/1024**2:.2f} MB) # ... 运行模型 ... print(f峰值显存: {torch.cuda.max_memory_allocated(device)/1024**2:.2f} MB)CPU vs GPU 推理GPU延迟低吞吐高适合线上服务和离线大批量任务。核心是充分利用批处理batch来摊薄数据加载和 kernel 启动开销。CPU无需显卡部署简单但延迟高尤其是单次请求。可通过模型量化如使用 Intel 的 OpenVINO、Facebook 的 PyTorch Quantization、使用 ONNX Runtime 或更轻量模型如 DistilBERT, TinyBERT来加速。性能优化建议动态批处理在 API 服务中收集短时间内到达的请求组成一个批处理进行推理。模型量化将 FP32 模型转换为 INT8可显著减少模型大小和推理延迟对精度影响通常很小。使用更快的运行时尝试将模型导出为 ONNX 格式并使用 ONNX Runtime 进行推理可能获得比原生 PyTorch 更好的性能。序列长度优化分析业务中 query 和 item 文本的长度分布将max_length设置为一个合理的值如 256 或 384而不是固定的 512可以大幅减少计算量。硬件选择对于大规模部署考虑使用带有 Tensor Cores 的 NVIDIA GPU如 T4, A10, A100以获得最佳性价比。8. 常见问题与排查方法问题现象可能原因排查方式解决方案模型加载失败模型文件损坏、路径错误、HF Hub 网络问题、Transformers 版本不兼容。检查模型路径或名称尝试直接from_pretrained一个简单模型如bert-base-uncased看是否成功查看完整错误日志。确保网络通畅使用正确的模型标识符升级/降级 Transformers 库到与代码兼容的版本。CUDA out of memory批处理大小batch size太大输入序列长度max_length太长模型过大GPU 显存被其他进程占用。使用nvidia-smi查看显存占用在代码中打印输入 tensor 的 shape逐步减小 batch size。减小 batch size缩短 max_length使用梯度累积训练时使用模型并行或更小的模型清理不必要的 GPU 进程。推理速度慢使用 CPU 推理批处理大小太小模型未处于eval()模式未使用半精度FP16。检查设备是 CPU 还是 GPU检查 batch size确认代码中调用了model.eval()。使用 GPU增大 batch size在显存允许范围内确保model.eval()尝试使用model.half()进行 FP16 推理。打分结果不合理全0或全1模型未正确训练或微调输入文本的预处理方式如分词、截断与训练时不一致输出层理解错误。用一组已知相关/不相关的简单样本测试检查 tokenizer 的输出input_ids, attention_mask是否正常查看模型最后一层的输出 logits。使用在目标领域上正确微调的模型确保推理时的文本预处理 pipeline 与训练时完全一致正确解读模型输出是分类概率还是回归分数。API 服务请求超时单次推理时间过长服务端未设置超时或超时时间太短网络问题。在服务端本地测试单个请求的耗时检查 API 服务的超时设置如 gunicorn/uwsgi 的 timeout 参数。优化模型推理速度见第7节调整服务端超时时间对于长任务改为异步接口。批量任务内存泄漏在循环中未及时释放 tensor未使用torch.cuda.empty_cache()数据未从 GPU 移回 CPU。使用内存监控工具在循环结束后检查显存是否持续增长。确保将 tensor 移到 CPU.cpu()并转换为 Python 原生类型在循环中适时调用torch.cuda.empty_cache()考虑使用del显式删除不再需要的变量。9. 最佳实践与使用建议从小规模验证开始不要一开始就在全量数据上训练。选择一个小的子集如 1 万条数据快速验证 DLM 相比你现有基线模型如 BM25双塔模型的有效性。重视负样本构建判别式模型的性能很大程度上依赖于负样本的质量。论文中可能使用了困难负样本挖掘、批次内负采样等技术。在你的业务中需要仔细设计负采样策略。利用知识蒸馏如果拥有一个强大但笨重的生成式检索模型或交叉编码器可以将其作为“教师模型”来训练一个轻量级的 DLM“学生模型”。这是平衡效果与效率的实用手段。建立可复现的实验流水线使用 Hydra、MLflow 或 Weights Biases 等工具管理实验配置、参数和结果。确保每个实验都可复现。分阶段部署阶段一离线评估在标注好的测试集上评估确保核心指标如 NDCG10有提升。阶段二A/B 测试影子模式将 DLM 的排序结果记录下来但不影响线上结果用于分析其与线上模型的差异。阶段三小流量 A/B 测试将小部分线上流量切到新模型对比核心业务指标如点击率、转化率。阶段四全量上线。监控与告警上线后监控服务的延迟、成功率、显存使用率。对打分分布进行监控如果出现极端分布如所有分数接近 0 或 1需要触发告警。合规与审计对于影响内容分发的系统保留重要的推理日志如 query, top-K items, scores以便进行效果分析和合规审计。10. 总结与下一步Meta 这篇关于判别式语言模型作为检索器的论文为我们提供了一条绕过 item ID 生成、简化检索系统架构的新思路。它的核心价值在于用更直接的“交互式”建模替代了传统的“表示式”建模在动态候选集和复杂语义匹配场景下可能更具优势。对于想要尝试的工程师最先应该验证的是在你自己业务的小规模数据上DLM 相比现有方案的效果提升是否显著。可以按照本文第5节的方法快速搭建一个测试环境进行验证。最容易踩的坑主要集中在负样本构建、长文本处理以及线上推理性能上。务必关注训练数据的质量并提前对推理延迟和吞吐量进行压测。后续可以探索的方向包括模型轻量化将知识蒸馏与模型量化、剪枝结合打造超高效的端侧检索模型。多模态扩展如何将图像、视频等非文本信息融入 DLM 的框架中是否可以设计一个统一的“判别式多模态模型”来处理图文、视频搜索与生成式检索结合DLM 擅长精排生成式模型如 DSI, NCI擅长通过生成 ID 进行召回。能否将两者结合构建一个“生成式召回 判别式精排”的混合检索系统这项技术目前仍处于研究前沿但其揭示的“判别式”路径为检索系统的发展提供了新的可能性。建议收藏本文提供的实践框架在相关论文代码开源后可以立即动手实验探索其在你业务场景中的潜力。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门