本文介绍了通过对比学习训练本地Embedding模型并结合Reranker模块,提升客服场景下问答对语义匹配能力的方法。文章详细阐述了项目背景、核心技术、数据构造流程、训练流程设计、评估与验证、部署与应用等内容。

CrashSight 客服场景下问答对的语义召回方法

一、项目背景与目标

目标:通过对比学习训练本地Embedding模型,并结合Reranker模块,提升客服场景下问答对的语义匹配能力。

核心价值

  1. 领域适配:解决垂直领域(客服对话)的语义理解问题。
  2. 数据安全:通过本地化部署保障数据隐私。
  3. 成本优化:降低大模型API调用成本,提升性价比。
  4. 效果提升:通过对比学习训练本地Embedding模型,并结合Reranker精排,能够极大的提升客服场景下问答对的语义匹配能力。

二、核心技术与框架

  1. 模型架构

    • Embedding模型:由腾讯实验室提供的 conna-embedding-text-v1 模型,基于中文优化的 Sentence-BERT 架构,结合了 instruction 指令,效果比 sentence-bert 好很多。
    • Reranker模型:使用BGE-Gemma2-Reranker,对候选答案进行精细化排序,由于 v100 是比较老的 Turing 架构,不支持最新的 LLM-reranker,所以选用这个模型。,综合考虑效果和成本都是最合适的。
    • 框架:使用 FlagEmbedding 框架,支持对比学习的轻量级训练框架,这个框架比较全面,结合了很多训练方法,采用的对比学习进行训练,利用了 InfoNCE 损失函数,结合instruction指令。
    • 任务类型:dense retrieval 语义召回,根据用户的问题,召回相似度最高的qa对,是一个不对称的任务。
  2. 对比学习核心

    • 目标:拉近相似QA对的向量距离,推开不相关QA对的向量距离。
    • 损失函数
      • 使用InfoNCE Loss或Triplet Loss,根据实验效果选择最佳方案。
      • 通过温度参数控制相似度分布,优化模型对困难样本的区分能力,温度参数是 0.07,这个参数是用来控制相似度分布的,越小越难区分,越大越容易区分。
      • 使用 InfoNCE Loss 和 Triplet Loss 损失函数,InfoNCE Loss 是用来计算相似度分布的,Triplet Loss 是用来计算相似度分布的。

三、数据构造流程

1. 原始数据来源

  • 客服对话日志(需脱敏处理)。
  • 文档数据生成。

2. 数据清洗与QA对生成

  • 大模型辅助清洗
    1. 使用大语言模型对原始对话进行结构化提取,生成标准化(问题, 答案)对。
    2. 过滤低质量数据,如重复、模糊表述、非完整问答。
  • 示例
     1# 输入原始对话  
     2用户"鸿蒙系统适配吗"  
     3客服"现在已经能接入了"
     4用户"sdk包在哪"
     5客服"在官网,有对应鸿蒙的 sdk 文档"
     6用户"官网地址是什么"
     7客服"https://crashsight.qq.com/documents/zh/crashsight/sdkDocuments/harmony-sdk"
     8
     9大模型进行清洗后输出QA对
    10{query: "如何接入鸿蒙系统", answer: "有对应鸿蒙的 sdk 文档:https://crashsight.qq.com/documents/zh/crashsight/sdkDocuments/harmony-sdk"}  
    

3. 对比学习数据集构建

  • 正样本:同一对话中的(query, answer)对。
  • 负样本
    • Hard Negatives:语义相近但答案不同的QA对,通过相似度筛选生成。
    • Random Negatives:随机采样其他问题的答案。
  • 数据增强策略
    • 同义词替换和句式变换,提升数据多样性。

4. 数据集划分

  • 将数据划分为训练集、验证集和测试集,确保模型训练和评估的科学性。

由于数据过少,我的划分比例为:

  • 训练集:80%
  • 验证集:10%
  • 测试集:10% 过拟合其实也可以接受,毕竟数据量太少,训练集和验证集的loss差距不大,我们的场景比较单一,过拟合问题不大。

四、训练流程设计

1. 模型初始化

  • 加载预训练Embedding模型,并根据数据规模决定是否冻结底层参数。
  • 加载BGE-Gemma2-Reranker模型,用于精细化排序。

transformer 模型初始化:

  • 加载conna-embedding-text-v1模型
  • 加载BGE-Gemma2-Reranker模型

2. 训练配置

  • 设置合理的批量大小、学习率、温度参数和序列长度,确保训练效率和效果。
  • 使用早停策略,基于验证集Loss监控模型训练过程。

训练配置:

  • 学习率:1e-5
  • 批量大小:128
  • 温度参数:0.07
  • 序列长度:512

3. 训练策略优化

  • 难负例挖掘:利用模型生成的难负例,增强模型对相似但不同答案的区分能力,这里的核心在于难负例的生成,以及难负例的筛选,比如找到相似度大于 0.9 的,但是答案不同的,然后进行筛选,但是又同时不能筛选太多,否则会导致训练集和验证集的 loss 差距太大,导致过拟合。
  • 混合精度训练:使用FP16加速训练,降低显存占用。

五、评估与验证

1. 内部评估指标

  • 使用召回率@K、准确率和聚类效果等指标评估模型性能。
  • 结合Reranker模块,评估精细化排序对最终效果的影响。
  • 简单的采用了针对不同 k 值的召回率,以及准确率进行了划分,数据这里我没有保存,在之前的 jupyter 里。

六、部署与应用

  1. 模型压缩
    • 使用量化技术减少模型体积,提升推理效率。
  2. API服务
    • 提供xinference 作为模型的管理,启动轻量级的API服务,支持实时语义匹配和精细化排序。
    1# 使用Reranker进行精细化排序  
    2scores = reranker_model.compute_score([["问题1", "答案1"], ["问题2", "答案2"]])  
    
  3. 业务集成
    • 将模型集成到客服系统和工单分类场景中,提升业务效率。
    • 结合Embedding模型和Reranker模块,实现多阶段语义匹配。

七、总结

  1. 数据构建创新
    • 结合大模型清洗与领域知识增强,解决噪声数据问题,思想其实就是先收集整个的客服数据,然后用大模型从不同的角度,利用不同的 prompt 进行知识蒸馏,划分训练集、验证集、测试集,然后进行清洗,清洗后的数据进行对比学习训练。
  2. 训练策略优势
    • 动态温度参数和难负例挖掘,提升细粒度语义区分能力,使用的是 InfoNCE Loss 和 Triplet Loss 损失函数。
  3. Reranker模块价值
    • 通过精细化排序进一步提升语义匹配精度,reranker 由于过大没有进行过多处理,但是其效果很不错,针对单一的 embedding 模型,效果提升很明显。