资讯详情

PaddleNLP 语义匹配模型库 semantic_search 模块详解:ERNIE 双塔与交叉编码器实战

📅 2026/9/24 18:02:45 | 华诺云谱 👁 阅读
PaddleNLP 语义匹配模型库 semantic_search 模块详解:ERNIE 双塔与交叉编码器实战
PaddleNLP 语义匹配模型库 semantic_search 模块详解ERNIE 双塔与交叉编码器实战【免费下载链接】PaddleNLPEasy-to-use and powerful LLM and SLM library with awesome model zoo.项目地址: https://gitcode.com/gh_mirrors/pa/PaddleNLPsemantic_search 是 PaddleNLP transformers 目录下的语义匹配语义检索模型模块围绕 ERNIE 预训练模型封装了 ErnieEncoder、ErnieDualEncoder 与 ErnieCrossEncoder 三类组件分别对应向量编码、双塔召回与交叉排序三种经典语义匹配范式。读完本文你将掌握这三类编码器的构造参数、推理与训练调用方式、RocketQA 预训练模型的选择方法并能将其接入端到端语义检索系统。模块定位与文档入口在 PaddleNLP 中paddlenlp.transformers.semantic_search是专门承载语义匹配模型实现的子模块其 API 文档入口为 paddlenlp.transformers.semantic_search对应实现文件为 semantic_search/modeling.py。模块对外导出的类通过__all__明确声明见init.py__all__ [ErnieDualEncoder, ErnieCrossEncoder, ErnieEncoder]ErnieEncoder单塔语义编码器基于 ERNIE 输出句向量是另外两个类的基础组件ErnieDualEncoder双塔Dual-Encoder模型同时封装 Query 编码器与 Title/Passage 编码器用于向量召回RetrievalErnieCrossEncoder交叉Cross-Encoder模型将 Query 与 Passage 拼接后输入单个 ERNIE用于精排Ranking。三者共用同一套 ERNIE 骨干网络体现了召回用双塔、精排用交叉的工业级语义检索标准流程。ErnieEncoder语义编码基座ErnieEncoder 继承自 ErniePretrainedModel以 ErnieConfig 为配置入口内部封装一个完整的 ErnieModel见 modeling.pyclass ErnieEncoder(ErniePretrainedModel): def __init__(self, config: ErnieConfig, output_emb_size: int | None None): super(ErnieEncoder, self).__init__(config) self.ernie ErnieModel(config) dropout config.classifier_dropout if config.classifier_dropout is not None else 0.1 self.dropout nn.Dropout(dropout) self.classifier nn.Linear(config.hidden_size, config.num_labels) # Compatible to ERNIE-Search for adding extra linear layer if output_emb_size is not None and output_emb_size 0: weight_attr paddle.ParamAttr(initializerpaddle.nn.initializer.TruncatedNormal(std0.02)) self.emb_reduce_linear paddle.nn.Linear(config.hidden_size, output_emb_size, weight_attrweight_attr)其结构要点如下骨干网络self.ernie ErnieModel(config)提供完整的 ERNIE Transformer 编码能力Dropout 与分类头默认 Dropout 为config.classifier_dropout未配置时回退到0.1classifier是一个hidden_size - num_labels的线性层供交叉编码分类使用输出降维层emb_reduce_linear当传入output_emb_size 0时额外增加一个使用TruncatedNormal(std0.02)初始化的线性层将 hidden_size 维向量压缩到指定维度。这是为了兼容 ERNIE-Search 等场景——向量维度越小ANN 索引的内存占用与检索开销越低初始化钩子_init_weights将 LayerNorm 的 epsilon 统一设置为1e-12保证数值稳定性。forward返回(sequence_output, pool_output)其中sequence_output是全序列的 token 级向量pool_output是句级池化输出。get_pooled_embedding正是从sequence_output[:, 0]即 [CLS] token 向量提取句向量这也是 BERT 系模型最常见的句向量取法。ErnieDualEncoder双塔向量召回模型构造参数详解ErnieDualEncoder 将两个 ErnieEncoder 封装进同一个 nn.Layer见 modeling.py使得 Query 向量与 Passage 向量可以通过一个模型同时计算、联合训练。其完整构造签名如下def __init__( self, query_model_name_or_pathNone, title_model_name_or_pathNone, share_parametersFalse, output_emb_sizeNone, dropoutNone, reinitializeFalse, use_cross_batchFalse, ):参数类型默认值说明query_model_name_or_pathstrNoneQuery 端 ERNIE 的预训练模型名或本地路径title_model_name_or_pathstrNoneTitle/Passage 端 ERNIE 的预训练模型名或本地路径share_parametersboolFalse为 True 时两端共享同一套参数self.title_ernie self.query_ernie大幅减少参数量output_emb_sizeintNone输出句向量维度0 时启用 emb_reduce_linear 降维dropoutfloatNoneDropout 比率目前透传给 ErnieEncoder 由其 config 决定reinitializeboolFalse为 True 时执行init_epsilon_weights将 LayerNorm epsilon 重置为1e-5用于兼容 RocketQA v2 权重初始化use_cross_batchboolFalse训练时是否跨 batch 聚合负样本见下文构造逻辑若query_model_name_or_path非空加载 Query 编码器若share_parameters为 TrueTitle 编码器直接复用 Query 编码器否则若提供了title_model_name_or_path独立加载 Title 编码器断言至少一个编码器存在At least one of query_ernie and title_ernie should not be None防止空模型。官方文档示例向量提取模型 Docstring 中给出了最小可用示例完整继承如下见 modeling.pyimport paddle from paddlenlp.transformers import ErnieDualEncoder, ErnieTokenizer model ErnieDualEncoder(rocketqa-zh-dureader-query-encoder, rocketqa-zh-dureader-para-encoder) tokenizer ErnieTokenizer.from_pretrained(rocketqa-zh-dureader-query-encoder) inputs tokenizer(Welcome to use PaddlePaddle and PaddleNLP!) inputs {k: paddle.to_tensor([v]) for (k, v) in inputs.items()} # Get query embedding query_embedding model.get_pooled_embedding(**inputs) # Get title embedding title_embedding model.get_pooled_embedding(**inputs, is_queryFalse)这里分别加载了 RocketQA 的 Query 编码器与 Passage 编码器同一个 tokenizer 编码出的文本通过is_query开关即可从对应塔中拿到向量。get_pooled_embedding内部见 modeling.py会断言is_query与初始化方式一致避免误用未加载的塔。批量向量化get_semantic_embedding针对文档库批量建索引的场景模型提供了生成器方法get_semantic_embedding(data_loader)见 modeling.pydef get_semantic_embedding(self, data_loader): self.eval() with paddle.no_grad(): for batch_data in data_loader: input_ids, token_type_ids batch_data input_ids paddle.to_tensor(input_ids) token_type_ids paddle.to_tensor(token_type_ids) text_embeddings self.get_pooled_embedding(input_ids, token_type_idstoken_type_ids) yield text_embeddings它以yield方式逐 batch 产出句向量自动切到eval()并关闭梯度适合配合 DataLoader 将海量段落写入 ANN 索引库。相似度计算cosine_simcosine_sim同时计算 Query 与 Title 的句向量并输出两者的内积此处输入向量均已归一化内积等价于余弦相似度见 modeling.pyquery_cls_embedding self.get_pooled_embedding( query_input_ids, query_token_type_ids, query_position_ids, query_attention_mask ) title_cls_embedding self.get_pooled_embedding( title_input_ids, title_token_type_ids, title_position_ids, title_attention_mask, is_queryFalse ) cosine_sim paddle.sum(query_cls_embedding * title_cls_embedding, axis-1)该方法可直接用于离线评测或在线打分返回 batch 维度的相似度张量。训练前向三元组与交叉批负样本forward接收一组(query, pos_title, neg_title)三元组见 modeling.py分别提取 Query、正例、负例向量后执行合并候选paddle.concat([pos_title_cls_embedding, neg_title_cls_embedding], axis0)将正负 Passage 拼接交叉批负样本若use_cross_batchTrue先通过paddle.distributed.all_gather聚合所有卡上的候选向量再paddle.concat使每张卡的 Query 都能看到全局 batch 的负样本从而显著扩大负样本池、提升训练信号打分与标签logits paddle.matmul(query_cls_embedding, all_title_cls_embedding, transpose_yTrue)计算 Query 与全部候选的内积得分矩阵标签为paddle.arange(...)构造的对角索引即Query 只与同 batch 的正例匹配指标与损失通过paddle.metric.accuracy计算命中率F.cross_entropy计算多分类交叉熵损失返回{loss: loss, accuracy: accuracy}预测模式当is_predictionTrue时只对(query, pos_title)对做paddle.dot并返回{probs: ..., q_rep: ..., p_rep: ...}便于上线阶段提取向量或直接打分。需要说明的是labels计算中引用了self.rank从代码结构看这是为分布式场景设计的字段实际使用时需结合paddle.distributed的 rank 信息配合use_cross_batch使用。ErnieCrossEncoder交叉精排模型双塔模型以向量相似度召回候选但 Query 与 Passage 之间缺乏细粒度交互交叉编码器将两者拼接后一起送入 ERNIE通过自注意力充分建模交互语义精度更高但计算开销更大因此常用于精排阶段见 modeling.py。构造方式只需指定一个预训练模型def __init__(self, pretrain_model_name_or_path, num_classes2, reinitializeFalse, dropoutNone):num_classes默认 2二分类相关/不相关透传给内部 ErnieEncoder 的 classifierreinitializeTrue时同样将 LayerNorm epsilon 重置为1e-5兼容 RocketQA v2。官方 Docstring 示例完整继承import paddle from paddlenlp.transformers import ErnieCrossEncoder, ErnieTokenizer model ErnieCrossEncoder(rocketqa-zh-dureader-cross-encoder) tokenizer ErnieTokenizer.from_pretrained(rocketqa-zh-dureader-cross-encoder) inputs tokenizer(你们好, text_pair你好) inputs {k: paddle.to_tensor([v]) for (k, v) in inputs.items()} # Get embedding of text pair. embedding model.matching(**inputs)注意这里tokenizer通过text_pair参数把 Query 与 Passage 拼接成单条输入这正是交叉编码的典型用法。交叉编码器提供了三个匹配方法对应不同的特征来源与模型代际方法特征来源适用场景说明matchingpool_output句级池化RocketQA v1 点式预测返回 softmax 后取probs[:, 1]即相关类的概率matching_v2sequence_output[:, 0]CLS tokenRocketQA v2 列式预测用 CLS token 特征替代句级池化matching_v3pool_output句级池化ERNIE-Search 列式预测直接返回未过 softmax 的 logits三个方法都先取特征 → Dropout →classifier线性层。matching默认返回probs[:, 1]二分类相关概率传入return_prob_distributationTrue时返回完整概率分布。forward默认调用matching并返回完整概率分布若提供labels则同时计算accuracy与F.cross_entropy损失并返回{loss: ..., accuracy: ...}从而支持有监督精排训练。RocketQA 系列预训练模型与配置semantic_search 模块的所有示例均基于 RocketQA 系列预训练模型其完整配置注册在 ernie/configuration.py 的PRETRAINED_INIT_CONFIGURATION中。以中英文档检索常用的rocketqa-zh-dureader-query-encoder为例见 configuration.py{ attention_probs_dropout_prob: 0.1, hidden_act: relu, hidden_dropout_prob: 0.1, hidden_size: 768, initializer_range: 0.02, max_position_embeddings: 513, num_attention_heads: 12, num_hidden_layers: 12, type_vocab_size: 2, vocab_size: 18000, pad_token_id: 0 }可见该系列采用 12 层、12 头、768 维的 ERNIE 结构中文词表大小 18000激活函数为 relu。仓库中注册的 RocketQA 模型按用途可分为双塔召回模型rocketqa-zh-dureader-query-encoder/rocketqa-zh-dureader-para-encoder中文 DuReader 场景、rocketqa-v1-marco-query-encoder/rocketqa-v1-marco-para-encoder英文 MS MARCO 场景以及rocketqa-zh-base/medium-*-encoder等不同规格交叉精排模型rocketqa-zh-dureader-cross-encoder、rocketqa-v1-marco-cross-encoder以及rocketqa-base/medium/mini/micro/nano-cross-encoder多档位版本见 configuration.py。模型名作为from_pretrained的入参即可自动下载对应权重与配置无需手工组织文件。选型时可按小模型nano/mini用于原型验证、大模型base用于追求精度的原则取舍。端到端实战双塔召回 交叉精排的语义检索系统semantic_search 模块的模型可直接服务于 PaddleNLP 生态中的完整检索系统。仓库在 slm/pipelines/examples/semantic-search/README.md 中给出了召回DensePassageRetriever 精排ErnieRanker ANN 索引 WebUI的端到端方案其核心思路正是语义检索不依赖字面关键词而是捕捉 Query 的真实意图在高维向量空间中度量相似度。一键运行示例源自 semantic_search_example.py# GPU 环境 export CUDA_VISIBLE_DEVICES0 python examples/semantic-search/semantic_search_example.py --device gpu --search_engine faiss # 仅 CPU 环境耗时较长 unset CUDA_VISIBLE_DEVICES python examples/semantic-search/semantic_search_example.py --device cpu --search_engine faiss示例脚本暴露的常用参数与默认值如下参数默认值说明--devicegpu运行设备可选 cpu/gpu--index_namedureader_indexANN 索引名--search_enginefaiss检索引擎可选 faiss/milvus--max_seq_len_query64Query 最大长度--max_seq_len_passage256Passage 最大长度--retriever_batch_size16建索引时的向量化 batch 大小--query_embedding_modelrocketqa-zh-nano-query-encoderQuery 编码模型--passage_embedding_modelrocketqa-zh-nano-query-encoderPassage 编码模型nano 版默认共享--embedding_dim312ANN 索引向量维度--pooling_modecls_token句向量池化方式max/mean/mean_sqrt_len/cls--model_typeernie模型类型ernie_search/ernie/bert/neural_search其中embedding_dim与output_emb_size的对应关系值得注意当model_type为ernie_search或neural_search时示例会将output_emb_size设为embedding_dim即启用本模块emb_reduce_linear降维层把向量压缩到索引所需维度以降低存储与检索开销见 semantic_search_example.py 中DensePassageRetriever的构造逻辑。完整的 Web 检索系统由三部分组成基于 ElasticSearch 的 ANN 服务默认端口 9200、基于 RestAPI 的模型服务、基于 Streamlit 的 WebUI详细搭建步骤可参考 README.md 第 3.4 节多路召回关键词 语义方案见 Multi_Recall.md自定义模型训练与接入流程见 Neural_Search.md。小结paddlenlp.transformers.semantic_search以 ERNIE 为骨干提供了语义匹配领域最核心的三种建模范式ErnieEncoder提供统一的句向量提取与分类能力output_emb_size降维机制让向量可以灵活适配 ANN 索引维度ErnieDualEncoder将 Query/Passage 双塔封装为一模型支持参数共享、三元组训练、跨 batch 负样本与 cosine 打分是向量召回的现成组件ErnieCrossEncoder通过 Query-Passage 拼接交互实现精排matching/matching_v2/matching_v3覆盖 RocketQA v1、v2 与 ERNIE-Search 三代特征方案。配合仓库预置的 RocketQA 系列权重与 semantic-search 示例开发者可以快速搭建双塔召回 交叉精排的完整语义检索链路将上述模型直接用于文本相似度计算、FAQ 匹配、文档检索等生产场景。【免费下载链接】PaddleNLPEasy-to-use and powerful LLM and SLM library with awesome model zoo.项目地址: https://gitcode.com/gh_mirrors/pa/PaddleNLP创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。