现在基于自然语言和文档进行对话的背后都是使用的基于嵌入的向量搜索。OpenAI在这方面做的很好,它的Cookbook(github.com/openai/openai-cookbook)上有很多案例,最近他们对文档做了一些更新。
GPT擅长回答问题,但是只能回答它以前被训练过的问题,如果是没有训练过的数据,比如一些私有数据或者最新的数据该怎么办呢?
这种情况下通常有两种办法,一种是微调(fine-tuning),一种是嵌入(embedding)。
微调就是在大模型的数据基础上做二次训练,事先准备好一批prompt-complition(类似于问答Q&A)的数据,生成新的模型,这个模型将会包含微调后的数据。
而嵌入则是每次向ChatGPT发送消息(prompt)的时候,把你自己数据结果带上。
王建硕老师对于微调和嵌入有过精妙的比喻:
ChatGPT就像一个已经训练好的家政阿姨,她懂中文,会做家务,但是对你家里的情况不了解。
微调就相当于阿姨第一次到你家干活的时候,你要花一小时时间告诉她家里的情况,比如物件的摆放、哪些地方不能动,哪些地方要重点照顾。
嵌入就相当于你省去了对阿姨进行二次培训的,而是在家里贴满纸条,这样阿姨一看到纸条就知道该怎么做了。
OpenAI的Cookbook也有类似的比喻
微调就像你通过学习准备考试,是一种长期记忆,但过了一周后考试来临,模型可能会忘记袭击,或者记错它从来没有读过的事实。
嵌入就像记笔记,是一种短期记忆,当考试的时候,你把笔记带上,随时翻看笔记,对于笔记上有的内容可以得到准确的答案。
另外嵌入的搜索提问方式相对于微调有一个缺点就是它每次附带的文本数量是有限制的,因为除了原始的问题,它还需要带上搜索出来的问题,GPT-3.5是4K(大约5页),GPT-4最大是32K(大约40页)。
就好比你有成书架的教科书可以借鉴,但每次却只能翻看其中几页笔记。
如果你想构建一个对大量文本问答的系统,OpenAI建议“搜索-问”(Search-Ask)的方法。
也就是先在本地文档库中Search,拿到本地的数据结果,再去Ask,把搜索结果和问题一起交给GPT,这样GPT可以根据你提供的内容以及它模型中的数据,一起将结果返还给你。
至于如何搜索,并非一定要基于向量的搜索,可以有多重搜索方式:
- 基于关键字搜索
- 基于图形的搜索
- 基于向量的搜索
至于在技术上如何实现,OpenAI的Cookbook上也有详细的介绍。
更多细节建议参考:
github.com/openai/openai-cookbook/blob/main/examples/Question_answering_using_embeddings.ipynb