本文介绍了通过对比学习训练本地Embedding模型并结合Reranker模块,提升客服场景下问答对语义匹配能力的方法。文章详细阐述了项目背景、核心技术、数据构造流程、训练流程设计、评估与验证、部署与应用等内容。
CrashSight 客服场景下问答对的语义召回方法
一、项目背景与目标
目标:通过对比学习训练本地Embedding模型,并结合Reranker模块,提升客服场景下问答对的语义匹配能力。
核心价值:
- 领域适配:解决垂直领域(客服对话)的语义理解问题。
- 数据安全:通过本地化部署保障数据隐私。
- 成本优化:降低大模型API调用成本,提升性价比。
- 效果提升:通过对比学习训练本地Embedding模型,并结合Reranker精排,能够极大的提升客服场景下问答对的语义匹配能力。
二、核心技术与框架
模型架构
- Embedding模型:由腾讯实验室提供的
conna-embedding-text-v1模型,基于中文优化的 Sentence-BERT 架构,结合了 instruction 指令,效果比 sentence-bert 好很多。 - Reranker模型:使用
BGE-Gemma2-Reranker,对候选答案进行精细化排序,由于 v100 是比较老的 Turing 架构,不支持最新的 LLM-reranker,所以选用这个模型。,综合考虑效果和成本都是最合适的。 - 框架:使用
FlagEmbedding框架,支持对比学习的轻量级训练框架,这个框架比较全面,结合了很多训练方法,采用的对比学习进行训练,利用了InfoNCE损失函数,结合instruction指令。 - 任务类型:dense retrieval 语义召回,根据用户的问题,召回相似度最高的qa对,是一个不对称的任务。
- Embedding模型:由腾讯实验室提供的
对比学习核心
- 目标:拉近相似QA对的向量距离,推开不相关QA对的向量距离。
- 损失函数:
- 使用InfoNCE Loss或Triplet Loss,根据实验效果选择最佳方案。
- 通过温度参数控制相似度分布,优化模型对困难样本的区分能力,温度参数是 0.07,这个参数是用来控制相似度分布的,越小越难区分,越大越容易区分。
- 使用 InfoNCE Loss 和 Triplet Loss 损失函数,InfoNCE Loss 是用来计算相似度分布的,Triplet Loss 是用来计算相似度分布的。
三、数据构造流程
1. 原始数据来源
- 客服对话日志(需脱敏处理)。
- 文档数据生成。
2. 数据清洗与QA对生成
- 大模型辅助清洗:
- 使用大语言模型对原始对话进行结构化提取,生成标准化
(问题, 答案)对。 - 过滤低质量数据,如重复、模糊表述、非完整问答。
- 使用大语言模型对原始对话进行结构化提取,生成标准化
- 示例:
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 里。
六、部署与应用
- 模型压缩
- 使用量化技术减少模型体积,提升推理效率。
- API服务
- 提供xinference 作为模型的管理,启动轻量级的API服务,支持实时语义匹配和精细化排序。
1# 使用Reranker进行精细化排序 2scores = reranker_model.compute_score([["问题1", "答案1"], ["问题2", "答案2"]]) - 业务集成
- 将模型集成到客服系统和工单分类场景中,提升业务效率。
- 结合Embedding模型和Reranker模块,实现多阶段语义匹配。
七、总结
- 数据构建创新:
- 结合大模型清洗与领域知识增强,解决噪声数据问题,思想其实就是先收集整个的客服数据,然后用大模型从不同的角度,利用不同的 prompt 进行知识蒸馏,划分训练集、验证集、测试集,然后进行清洗,清洗后的数据进行对比学习训练。
- 训练策略优势:
- 动态温度参数和难负例挖掘,提升细粒度语义区分能力,使用的是 InfoNCE Loss 和 Triplet Loss 损失函数。
- Reranker模块价值:
- 通过精细化排序进一步提升语义匹配精度,reranker 由于过大没有进行过多处理,但是其效果很不错,针对单一的 embedding 模型,效果提升很明显。