1. 不要使用 DeepSeek R1 进行检索
尽管 DeepSeek R1 具有出色的推理能力,但它并不适合生成嵌入,至少目前还不行。
我们发现了一些例子,说明 DeepSeek R1 生成的嵌入与专门的嵌入模型 Alibaba-NLP/gte-Qwen2-7B-instruct 相比有多糟糕,Qwen 2 是 MTEB 排行榜上目前最好的嵌入模型。
我们使用这两个模型为数据集生成嵌入,并组成两个向量数据库。然后,我们对这两个模型使用相同的查询,并在相应模型生成的向量数据库中找到前 5 个最相似的嵌入。
关于解除租约的问答
简单翻译下
关于小额赔偿
简单翻译下
在上表中,DeepSeek R1 的检索结果明显更差。为什么?
我们认为根本问题在于 DeepSeek-R1 的训练方式。DeepSeek-R1 主要被设计为推理引擎,专注于顺序思维和逻辑连接。这意味着 DeepSeek-R1 不会将文档映射到语义空间。
相比之下,Qwen2 模型变体 (gte-Qwen2-7B-instruct) 专门针对语义相似性任务进行训练,创建了一个高维空间,其中概念相似的文档无论具体措辞如何都紧密聚集在一起。
这种训练过程的差异意味着 Qwen 擅长捕捉查询背后的意图,而 DeepSeek-R1 有时会遵循导致主题相关但实际上不相关的结果的推理路径。
除非 DeepSeek-R1 针对嵌入进行了微调,否则不应将其用作 RAG 的检索嵌入模型。
2. 务必使用 R1 进行生成:推理令人印象深刻
虽然 R1 在嵌入方面遇到困难,但我们发现它的生成能力非常出色。通过利用 R1 的思维链方法,我们看到:
让我们看几个例子:
从这些例子中,我们观察到了 DeepSeek R1 卓越的推理能力。它的思考过程清楚地表明了如何从源法律文件中得出结论:
R1 首先构建了一个连贯的法律问题模型,其详细的思考过程就是明证:首先,我记得读过关于提前终止罚款的内容……文件 1 提到……这种推理优先的方法允许模型在检索之前有条不紊地将多个来源的概念联系起来。
在处理租约终止或小额索赔法庭问题等复杂场景时,我们观察到 R1 明确地理解了每份文件(将所有这些放在一起……),没有幻觉。
最后,推理大模型用精确的引文来解释其推理,将结论与来源联系起来。这建立了从问题到推理再到答案的明确联系,确保了严谨性和可访问性。
我们用各种法律查询尝试了该模型,该模型始终表现出不仅能够从源文件中提取信息,而且还能从中学习和推理的能力。
要点:对于问答和总结,R1 是循序渐进的法律逻辑的金矿。将其保留在生成答案的阶段,肯定没问题。
3.提示工程仍然很重要
高级推理并不能消除对精心设计的提示的需求。我们发现提示中的明确指导对于以下方面至关重要:
鼓励在生成的答案中引用文档。
使用“引用或说你不知道”的方法防止幻觉。
以用户友好的方式构建最终答案。
我们在整个实验过程中构建了以下提示:
YouareahelpfulAIassistantanalyzinglegaldocumentsandrelatedcontent.Whenresponding,pleasefollowtheseguidelines:-Inthesearchresultsprovided,eachdocumentisformattedas[DocumentXbegin]...[DocumentXend],whereXrepresentsthenumericalindexofeachdocument.-Citeyourdocumentsusing[citation:X]formatwhereXisthedocumentnumber,placingcitationsimmediatelyaftertherelevantinformation.-Includecitationsthroughoutyourresponse,notjustattheend.-Ifinformationcomesfrommultipledocuments,usemultiplecitationslike[citation:1][citation:2].-Notallsearchresultsmayberelevant-evaluateanduseonlypertinentinformation.-Structurelongerresponsesintoclearparagraphsorsectionsforreadability.-Ifyoucannotfindtheanswerintheprovideddocuments,sayso-donotmakeupinformation.-Somedocumentsmaybeinformaldiscussionsorredditposts-adjustyourinterpretationaccordingly.-Putcitationasmuchaspossibleinyourresponse.First,explainyourthinkingprocessbetween<think>tags.Thenprovideyourfinalanswerafterthethinkingprocess.
4. 文档分块
此外,我们发现有效的文档分块对于准确的文档检索非常重要。对文档进行分块有助于使每个嵌入更简洁地表示特定主题,并减少每个嵌入生成需要处理的标记数量。
我们使用句子感知拆分(通过 NLTK)对文档应用分块。我们还让每个块的开头和结尾包含与附近块重叠的内容。它有助于模型更好地解释部分引用而不会丢失全局。文档分块代码:
defchunk_document(document,chunk_size=2048,overlap=512):"""Splitdocumentintooverlappingchunksusingsentence-awaresplitting."""text=document['text']chunks=[]#Splitintosentencesfirstsentences=nltk.sent_tokenize(text)current_chunk=[]current_length=0forsentenceinsentences:sentence_len=len(sentence)#Ifaddingthissentencewouldexceedchunksize,savecurrentchunkifcurrent_length+sentence_len>chunk_sizeandcurrent_chunk:chunk_text=''.join(current_chunk)chunks.append({'id':document['id'],'name':document['name'],'content':document['text'],'chunk_start':len(''.join(current_chunk[:-(2ifoverlap>0else0)]))ifoverlap>0else0,#Additionalmetadatafields...})#Keeplastfewsentencesforoverlapoverlap_text=''.join(current_chunk[-2:])#Keeplast2sentencescurrent_chunk=[overlap_text]ifoverlap>0else[]current_length=len(overlap_text)ifoverlap>0else0current_chunk.append(sentence)current_length+=sentence_len+1#+1forspace要点:
5. vLLM 高效快速
由于法律文件包含大量数据,因此生成 RAG 的嵌入可能需要很长时间。
最初,我们使用默认的 HuggingFace 库 sentence_transformer。我们首先使用典型的 Nvidia L4 GPU 运行,但遇到了“最常见”的错误:CUDA 内存不足。在 Nvidia A100 上尝试后,我们发现 sentence_transformer 需要 57GB DRAM 才能加载完整的 Alibaba-NLP/gte-Qwen2-7B-instruct 模型。

我们改用了 vLLM,这是一种高吞吐量、内存高效的 LLM 推理和服务引擎。
使用 vLLM,我们可以使用标准 Nvidia L4 GPU 运行模型,vllm 大约需要 24G DRAM GPU。L4 也比 A100 便宜得多:在 GCP 上,Nvidia L4 每小时花费超过 0.7 美元,而 Nvidia A100 每小时至少花费 2.9 美元。
在配备 80GB DRAM 的 Nvidia A100 上比较 vllm 和句子转换器时,我们发现与句子转换器相比,使用 vLLM 为 Qwen2 模型生成嵌入的速度提高了 5.5 倍。
对于包含 15000 个块的 10000 份法律文件的语料库,处理时间为:

结论
为法律文件构建 DeepSeek R1 RAG 教会了我们一些重要的经验教训: