基于InternLM和LangChain搭建你的知识库(书生浦语实战训练营第三期笔记作业)

1. 课程笔记
RAG和Fine-tuning其实都是大模型应用开发的重点,那两者的话也优缺点很明显。

RAG的话其实就是比较成本低,因为不用花费额外的算力资源去弄模型,外挂数据就可以了。并且知识库的内容可以随时随地的增加,不会说更新一次就要跑一次模型。但是问题就是假如基座模型比较弱的话,其效果可能就会大打折扣了。并且由于模型传入的上下文有限制,并且输入太长成本也高,因此单次回答的知识就很有限了。

那对于Fine-tuning而言的话,其实重点就是可以个性化微调。外挂知识库的方法并不改变模型,而微调的话是真的能够彻底改变模型的参数。并且微调的数据集可以做得很大很多范围,模型微调完就能够学到(当然可能会出现知识坍塌的现象,就是说微调把前面的知识给忘了)。但是缺点就是成本很高,全量微调大模型可能一个A100都打不住,并且每次更新知识都需要重新训练,不像外挂知识库这么方便。

当然在实际应用我们可以结合起来一起做,微调一部分知识再对专业知识或者实时知识来外挂,这样其实就能兼顾两者的优劣势。

那对于 外搭数据库的话,其实一般我们都会考虑通过langchain来实现。课程里这个图其实就是非常清晰了。我们其实就是本地的文件传入到一个langchain指定的dataloader里面从而获取文本,然后我们把文本先通过格式切割分成一块块,然后把这一块块的文本进行向量化(embedding)然后传入了VectorDB里(这里选择的是Chroma,当然我们也可以考虑使用其他像是FAISS之类的)。这个就是文档的处理了。那用户提取的问题同样也会经过向量化,然后获取到一个向量,通过近似度搜寻的方式找到向量数据库中最相近的几条数据。然后传给设计好的提示词中完成提示词的构建。最后将整个提示词传给InternLM获取最后的回复。这个就是完整的链条。

然后课程中还提到了对RAG方案的优化建议。RAG的核心受限于检索精度和prompt性能。所以在检索方面提升的点就是精确化的切分chunk,保证整体语义是完整的。或者是给chunk生成概括性的索引,在检索时进行匹配(这个如何具体实现还需要进一步查找,之前没有接触过)。那prompt方面其实自然就是自行优化迭代prompt找到最优的prompt了。

2. 学习到的新知识

虽然我之前也玩过langchain,也部署过一些基于OpenAI的实例项目,但是这次的课程同样会给我带来一些新的突破性知识。

- 比如说下载NLTK的资源

cd /root
git clone https://gitee.com/yzy0612/nltk_data.git  --branch gh-pages
cd nltk_data
mv packages/*  ./
cd tokenizers
unzip punkt.zip
cd ../taggers
unzip averaged_perceptron_tagger.zip

- 调用开源的词向量模型而非OpenAI的embedding模型

from langchain.embeddings.huggingface import HuggingFaceEmbeddings

embeddings = HuggingFaceEmbeddings(model_name="/root/data/model/sentence-transformer")

- 如何自定义LLM的类并接入到Langchain当中(这个特别牛!)

from langchain.llms.base import LLM
from typing import Any, List, Optional
from langchain.callbacks.manager import CallbackManagerForLLMRun
from transformers import AutoTokenizer, AutoModelForCausalLM
import torch

class InternLM_LLM(LLM):
    # 基于本地 InternLM 自定义 LLM 类
    tokenizer : AutoTokenizer = None
    model: AutoModelForCausalLM = None

    def __init__(self, model_path :str):
        # model_path: InternLM 模型路径
        # 从本地初始化模型
        super().__init__()
        print("正在从本地加载模型...")
        self.tokenizer = AutoTokenizer.from_pretrained(model_path, trust_remote_code=True)
        self.model = AutoModelForCausalLM.from_pretrained(model_path, trust_remote_code=True).to(torch.bfloat16).cuda()
        self.model = self.model.eval()
        print("完成本地模型的加载")

    def _call(self, prompt : str, stop: Optional[List[str]] = None,
                run_manager: Optional[CallbackManagerForLLMRun] = None,
                **kwargs: Any):
        # 重写调用函数
        system_prompt = """You are an AI assistant whose name is InternLM (书生·浦语).
        - InternLM (书生·浦语) is a conversational language model that is developed by Shanghai AI Laboratory (上海人工智能实验室). It is designed to be helpful, honest, and harmless.
        - InternLM (书生·浦语) can understand and communicate fluently in the language chosen by the user such as English and 中文.
        """
        
        messages = [(system_prompt, '')]
        response, history = self.model.chat(self.tokenizer, prompt , history=messages)
        return response
        
    @property
    def _llm_type(self) -> str:
        return "InternLM"

 - 还有就是定义类来负责加载并存储检索问答链,并响应 Web 界面里调用检索问答链进行回答的动作(类其实是我python中比较弱的部分,我还是常用函数实现)。

class Model_center():
    """
    存储检索问答链的对象 
    """
    def __init__(self):
        # 构造函数,加载检索问答链
        self.chain = load_chain()

    def qa_chain_self_answer(self, question: str, chat_history: list = []):
        """
        调用问答链进行回答
        """
        if question == None or len(question) < 1:
            return "", chat_history
        try:
            chat_history.append(
                (question, self.chain({"query": question})["result"]))
            # 将问答结果直接附加到问答历史中,Gradio 会将其展示出来
            return "", chat_history
        except Exception as e:
            return e, chat_history

3. 作业展示

- langchain的gradio demo

  • 22
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值