最近在搭一个RAG系统,用的bge-large做向量召回,top50召回率还行,但精排阶段用了ChatGLM3-6B做rerank,发现中文长文本(比如企业财报、论文摘要)效果特别拉胯,经常把不相关的排到前面。试过直接拼接query和doc,也试过加特殊分隔符,但感觉模型根本没理解长文本里的关键信息。
RAG里用大模型做精排,但中文长文本检索效果差,有救吗?
全部回复
共 167 条你这个情况我大概有类似经历。ChatGLM3-6B做rerank其实有个坑,它的预训练目标不是专门为相关性打分的,你直接拿来做精排等于让它干不擅长的活,长文本下注意力被稀释得厉害,关键句可能就淹没在几千token里了。我试过用bge-reranker-large替代,虽然也是cross-encoder但专门训过排序任务,中文长文本上比拿生成模型硬做要稳不少,你可以先拿top50跑个对比看看差距。另外你说拼接query和doc效果不好,可以试试把长文档先切块,让reranker对每个块单独打分再聚合,而不是整篇塞进去,财报这种结构化的东西切完效果提升挺明显的。还有个思路是用LLM做精排时别让它输出分数,改成让它从候选里选最相关的几条并给理由,用生成式的方式绕开打分不稳定的问题,不过这个延迟会高一些。你top50召回率还行的话,其实瓶颈大概率就在精排这一步,换模型或者换粒度应该能救回来。
长文本做rerank确实容易被截断坑到,ChatGLM3-6B的上下文窗口虽然够,但注意力在长文档里很容易散掉。你可以试试先把长文本切块,让模型对每个chunk单独打分再聚合,或者换个专门做中文rerank的小模型比如bge-reranker-large,比拿生成式大模型硬做排序稳不少。另外query那边也可以做点改写或关键词抽取,光靠原始query去匹配财报这种信息密度低的长文本,模型很难抓到重点。
长文本精排确实是个坑,ChatGLM3-6B本身上下文窗口够但注意力容易稀释,塞整篇财报进去它基本在瞎猜。你可以试试先做段落切分,让rerank模型对每个chunk单独打分再聚合,别硬塞全文。另外bge-reranker-large在中文长文本上比生成式rerank稳不少,虽然上限低但不容易翻车。
ChatGLM3-6B做rerank确实有点吃力,它本身上下文窗口和长文本理解就不是强项。我们之前试过用bge-reranker-large专门做精排,比拿生成模型硬做效果好不少,尤其是财报这种信息密度不均的文本。另外你可以试试把长文档按段落切了分别打分再聚合,别整篇塞进去,模型根本抓不住重点。
长文本别硬塞给6B模型,先切块再精排效果会好很多,或者换bge-reranker这种专门做排序的。
刚入门,这个对我帮助很大。
刚入门,这个对我帮助很大。