背景知识
目前大语言模型(LLM)的能力已经非常强大,ChatGPT 等通用模型可以很好地解决日常通用型问题。然而,在处理垂直专业领域的问题时,通用模型往往表现不够理想。如果希望利用 LLM 结合已有的特定领域知识,推理出该领域特定问题的答案,将是一种极具价值的应用方向。
例如,在医疗领域或法律领域,通用的问答助手可能缺乏专业知识,无法提供准确的回答。因此,我们需要实现自己的私有 GPT 助手,使其具备特定领域的专业知识。
可选方案
假设我们已经拥有了所在特定领域的数据集,比如积累或收集到的医疗数据、金融数据等。经过调研和测试,目前通常有三种实现方案。
1. 基于大模型的全参数训练
全参数训练是将我们自己的数据集与现有 LLM 大模型数据一起进行训练,从而生成一个新的模型。这种方式需要大量的计算资源,如高性能 GPU,显存消耗巨大,通常需要几十 GB 的显存起步。
缺点:
- 许多大模型(如 GPT 系列)不开源,无法进行全量训练。
- 即使使用开源模型(如 LLaMA、ChatGLM),全量训练成本高昂。
- 如果自有数据集规模不大,训练效果微乎其微,模型回答仍主要依赖原有预训练内容。
2. 基于大模型的微调(Fine-tuning)
目前流行的微调方法是 LoRA(Low-Rank Adaptation)。其基本原理是额外训练一个小模型(仅几 MB 大小),叠加在原有大模型的基础上,类似于一个特定领域的补丁。
优点: 在特定领域确实有不错的效果。例如,可以使用《甄嬛传》台词脚本训练出的机器人模仿角色语气回答问题。
缺点: 实际测试中会遇到'遗忘'问题。微调后的问答助手可能会丧失原有大模型的通用能力,导致原本能回答的通用问题效果变差。这种修修补补的方式在平衡通用性与专业性上存在挑战。
3. 基于 Prompt 上下文的方式(RAG)
Prompt 上下文,即提示词,是在要求大模型回答问题时给出一定的要求、语境、提示等,使之得到符合我们要求的答案。我们可以把这种提示想象成球员身边的教练,有了教练的提示,球员一般也能发挥得更好。
示例:
- 角色扮演 Prompt: 设定模型为面试官,引导其按特定流程提问。
- 知识注入 Prompt: 在问题前提供特定领域的背景知识,辅助模型理解。
Prompt 提示的限制
通过将本地知识以 Prompt 的形式喂给大模型,可以实现回答特定垂直领域问题的需求。但是,这种方案有一个比较大的限制:大模型 LLM 对输入长度有限制。例如,ChatGPT 普遍有 4096 个 token 的限制。如果本地知识文档很大,无法全部喂给大模型。
解决方案: 通过搜索将问题中的关键字与本地知识库进行匹配,找到相关度比较高的部分,然后将这些长度有限、相关度高的信息作为大模型的 Prompt。
基于知识库搜索的 Prompt 上下文的方案
该方案的核心在于如何通过问题在本地知识库中搜索出相关知识。单纯的关键词搜索往往难以匹配语义相似但字面不同的信息。例如,'上海有什么好吃的?'与文档中的'上海美食介绍'在语义上接近,但关键词硬性搜索可能失效。
在自然语言处理(NLP)中,有一种称为 Embedding(嵌入)的方式来解决语义相似性问题。
Embedding
Embedding 是将高维数据(如文字、图像)转化为低维数字的过程。其特性是'相似的事物'由相近的数表示。通过 OpenAI 提供的 embedding 模型(如 text-embedding-ada-002),可以将文本转换为向量,便于在低维度层面进行比较。
文本分割
在实际搜索前,需要将文档切分成一个个的段落。因为无论是提交给 LLM 还是 Embedding 模型,文本长度都有限制。
常用的分割方式包括:
- LangChain 的 text_splitter: 基于标点符号(句号、分号)分割。
- 阿里达摩院 AliTextSplitter: 基于语义分析的分割算法,能保证段落的完整性,测试效果通常更好。
完整流程
- 预处理:


