背景介绍
其实不仅是自然语言处理,只要是模型,或者说神经网络,提取数据间的相关性是一个绕不过的问题。对于LLM来说,提取数据特征也如此。那么就要考虑到模型的输入数据。 在Langchain中文档处理有很多种方法, 文档加载器: langchain_community.document_loaders数据的拆分处理: langchain_text_splitters等等。 在阅读学习中,理解到,总结文档信息的策略: Stuff、MapReduce、Refine以及Map ReRank
我们预设一个文档为Document,分割后的数据为Docs[i],
则Document = Sum{Docs[i]}
Stuff-直接合并
这种就是把分割后的Docs[i]直接合并输入
output = Merge(Docs[i]) | llm | outputParser
MapReduce-并行处理
简单来说,我们已经有了分割后的多个子文档Docs[i],那么对每个Docs[i]都去做一次计算,然后把所有计算结果合并,生成最终的结果,这样的好处就是,并行处理,不需要持续等待。
output_1 = Map(Docs[1]) | llm | outputParser
output_2 = Map(Docs[2]) | llm | outputParser
...
output_n = Map(Docs[n]) | llm | outputParser
output = Reduce(output_1,output_2,...,output_n)
Refine - 迭代
这很像是迭代算法中利用一个等式,这次的输出= 下一次的输入,这样每一次的输出结果都会取决于前次的计算,直到收敛。但是对于llm计算来说,计算成本较高,迭代多少轮才能收敛是未知的。
Context初始化: Context(0) = Docs[1] | first_prompt | llm | outputParser
建立迭代相关的提示词prompt = Relation(first_prompt)
for i in (1,N):
Context(i) = Context(i-1) | prompt | llm | outputParser
return Context(N)
Map-Rerank 重新排序
这不是一个基于合并的方法,更像是筛选出最佳输入的方法。 这个我没找到合适的案例代码学习,贴一个别人的结论
- 将查询词与候选文档进行匹配,生成一个初始排序的文档集合。
- 通过 Rerank 函数对初始排序的文档集合进行再次排序。
- 得到最终的文档排序结果。
参考
- Map-Rerank学习笔记
- 张海立 / 曹士圯 / 郭祖龙. LangChain实战:从原型到生产,动手打造 LLM 应用[M]. 电子工业出版社, 2024.