首页 > 数据库 > 数据库开发技术 > CCF对话式检索增强生成Top1赛后方案
❝作者
Winnie; 马千里
说在前面
不知不觉已经坚持大模型比赛逾半年,期间学习和收获了很多。非常幸运,在最近的CCF BDCI中荣获全赛道特等奖。遂将方案分享,期望能和大家共同进步。
比赛链接
https://www.datafountain.cn/competitions/1074
赛题针对对话式检索增强进行,简单来说就是给出了多轮历史对话以及最新的问题,期望选手检索相关文档,然后用大模型给出回答。相对于经典的检索增强,该赛题基于多轮对话场景。
赛题使用CORAL基准测试数据集,并且提供了来源于wikipedia的相关知识库,相关论文链接为:
https://arxiv.org/pdf/2410.23090
对话结构主要分为以下四种类型:
分析完赛题和数据,接下来我们将深入探讨实现方案。
结合行业经验,本次比赛我们遵循对话式检索增强最常见的实现流程:
在完成问题改写后,我们以召回-精排的方式检索到相关文档。先做检索召回(pointwise),以多种方式召回相关文档,本题中我们最终使用了两种召回方式:
from joblib import Parallel, delayed
import spacy
def process_ent(row):
nlp = spacy.load("en_core_web_sm")
return nlp(row['rewrite'])
def process_ref(row):
if len(row['entity']) == 0:
return []
ref_pattern = '|'.join(re.escape(entity) for entity in row['entity'])
return df_doc.loc[df_doc['ref_string'].str.contains(ref_pattern), 'idx'].tolist()
# 找到关键实体(仅支持英文)
entitys = Parallel(n_jobs=-1)(delayed(process_ent)(row) for _, row in tqdm(df.iterrows(), total=len(df)))
df['entity'] = [list(set([e.text for e in x.ents if e.label_ in ['PERSON','ORG', 'WORK_OF_ART']])) for x in entitys]
# 检索有该实体的所有文档
ref_ids = Parallel(n_jobs=-1)(delayed(process_ref)(row) for _, row in tqdm(df.iterrows(), total=len(df)))
df['ent_docs'] = ref_ids
召回文档过多会导致模型难以感知关键信息,所以需要对结果进行筛选。我们将召回文档和问题一起放入交叉编码模型(pairwise):
这是我们拿到赛道一等奖和全赛道特等奖的关键。本节算法目的是重排截取的文档,让最终文档的信息连续且互补(contextual):
Prompt设计是大模型竞赛重要的一环。有一些常用的技术,这里我们简单给出多轮对话下常用的Prompt格式:
❝联系
如有疑问或反馈,欢迎联系944632634@qq.com。
讲在后面
希望我们的方案能够对大家学习大模型有帮助,未来也会继续分享我们在其他比赛的优质方案,希望能跟大家共同进步!
原文作者:ChallengeHub;如有侵权,请联系管理员删除。