【教程】LLM集成进LangChain工具,并实现本地知识库的问答

0. Introduction:

LangChain提供了丰富的生态,可以非常方便的封装自己的工具,并接入到LangcChain的生态中,从而实现语言模型的交互,将多个组件链接在一起,并集成额外的资源,例如 API 和数据库。

本文将介绍下如何将本地的大模型服务集成进LangChain工具链中。

1. 在本地部署LLM,并搭建API服务

利用FastAPI和uvicorn构建本地化部署大语言模型的接口服务,实现大模型的API接口调用。

参考我的另一篇文章:【FastAPI】利用FastAPI构建大模型接口服务

2. 测试API服务

在这里插入图片描述

测试完成,API成功返回LLM的回答,接下来进入下一步,将API以自定义LLM的方式封装进LangChain。

3. 封装LLM到LangChain工具

参考官方文档 How to write a custom LLM wrapper,只需要继承LangChain的LLM方法,并且实现_call方法即可。

官方提供的一个简单的示例:

from langchain.llms.base import LLM
from typing import Optional, List, Mapping, Any

class CustomLLM(LLM):
  n:int
  
  @property
  def _llm_type(self) -> str:
    return "custom"

  def _call(self,prompt:str,stop:Optional[List[str]]=None) -> str:
    if stop is not None:
      raise ValueError("stop kwargs are not permitted")
    return prompt[:self.n]
  
  @property
  def _identifying_params(self) -> Mapping[str, Any]:
        """Get the identifying parameters."""
        return {"n": self.n}

我们根据自己实际的API接口,修改这个示例的call方法:

class BaiChuan(LLM):
    history = []
    def __init__(self):
        super().__init__()
        
    @property
    def _llm_type(self) -> str:
        return "BaiChuan"

    def _call(self, prompt: str, stop: Optional[List[str]] = None) -> str:
        data={'text':prompt}
        url = "http://0.0.0.0:6667/chat/"
        response = requests.post(url, json=data)
        if response.status_code!=200:
            return "error"
        resp = response.json()
        if stop is not None:
            response = enforce_stop_tokens(response, stop)
        self.history = self.history+[[None, resp['result']]]
        return resp['result']

测试一下是否封装成功:

llm = BaiChuan()
llm('你好,你是谁?')

output:

'您好!作为一个大语言模型,我可以回答您的各种问题并帮助您解决问题。请问有什么我可以帮到您的吗?'

好了,到这里我们成功将BaiChuan13B模型给封装进LangChain工具链中。接下来我们将利用LangChain实现本地知识库问答功能。

4. 实现本地知识库问答:

LangChain实现基于本地私有知识库问答的流程:

加载文件 → 读取文件 → 文本分割 → 文本向量化 → 问题向量化 → 在文本向量中匹配与问题最相近的TopK → 匹配出的文本作为上下文与问题一起添加进prompt → 提交给LLM生成回答

4.1 载入本地文档,并切片成若干小片段

LangChain提供了Docx、PPT、PDF等格式文件的加载器、分片器:

from langchain.document_loaders import Docx2txtLoader
from langchain.document_loaders import UnstructuredFileLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter

loader = Docx2txtLoader("新闻.docx")
data = loader.load()

# 初始化加载器
text_splitter = RecursiveCharacterTextSplitter(chunk_size=256, chunk_overlap=128)

# 切割加载的 document
split_docs = text_splitter.split_documents(data)

这里LangChain提供的RecursiveCharacterTextSplitter文本分片器将该Word文档切分为了每段有256个tokens,片段与片段之间有128个Tokens重叠的文本小片段。chunk_size是片段长度,chunk_overlap是片段之间的重叠长度。设置重叠部分是为了避免在切片的过程中,丢失一部分信息。

拿出一个小片段看看:

在这里插入图片描述

4.2 文本向量化

基于开源的预训练的Embedding语言模型,对文本进行向量化

Embedding方法分类为:

  • word2vec(基于seq2seq的神经网络结构)
  • Glove(词共现矩阵)
  • Item2Vec(推荐中的双塔模型)
  • FastText(浅层神经网络)
  • ELMo(独立训练双向,stacked Bi-LSTM架构)
  • GPT(从左到右的单向Transformer)
  • BERT(双向transformer的encoder,attention联合上下文双向训练)

开源的预训练Embedding模型有:

  • Text2vec文本表征及相似度计算:包括text2vec-large-chinese(LERT,升级版)、base(CoSENT方法训练,MacBERT)两个模型。这个模型也使用了word2vec(基于腾讯的800万中文词训练)、SBERT(Sentence-BERT)、CoSENT(Cosine Sentence)三种表示方法训练
  • OpenAI的Embeddings:这是OpenAI官方发布的Embeddings的API接口。目前有2代产品。目前主要是第二代模型:text-embedding-ada-002。它最长的输入是8191个tokens,输出的维度是1536
  • 百度的ernie-3.0-base-zh:https://github.com/PaddlePaddle/PaddleNLP、ERNIE三个版本进化史
  • SimCSE:https://github.com/princeton-nlp/SimCSE
  • 其他模型:embedding模型 · 魔搭社区
  • M3E:Moka Massive Mixed Embedding的缩写,由MokaAI训练,训练脚本使用 uniem,评测BenchMark使用MTEB-zh,通过千万级 (2200w+) 的中文句对数据集进行训练。

这里我们使用HuggingFace社区里面的ERNIE模型,并且使用HuggingFaceEmbeddings,对文本进行向量化。

from langchain.vectorstores import Chroma
from langchain.embeddings.huggingface import HuggingFaceEmbeddings
import IPython
import sentence_transformers

EMBEDDING_MODEL = "/workdir/model/text2vec_ernie/"

embeddings = HuggingFaceEmbeddings(model_name=EMBEDDING_MODEL)
embeddings.client = sentence_transformers.SentenceTransformer(embeddings.model_name, device='cuda')

4.3 FAISS向量数据库

Faiss的全称是Facebook AI Similarity Search。是一个开源库,针对高维空间中的海量数据,提供了高效且可靠的检索方法。

在本文中,我们将用FAISS向量数据库,存储每个文本片段的向量,并实现后续的向量相似度的高效计算。

Step1:将切分好的文本片段转换为向量,并存入FAISS中:

from langchain.vectorstores import FAISS

db = FAISS.from_documents(split_docs, embeddings)
db.save_local("/workdir/temp/faiss/") # 指定Faiss的位置

Step2:载入FAISS数据库:

db = FAISS.load_local("/workdir/temp/chroma/",embeddings=embeddings)

Step3:将问题也转换为文本向量,并在FAISS中查找最为相近的TopK

question = "新能源行业发展了多久?"

similarDocs = db.similarity_search(question, include_metadata=True, k=2)

for x in similarDocs:
    print(x)

输出如下,可见找出的信息与用户提出的问题匹配度还是挺高的。

在这里插入图片描述

4.4 LLM基于本地知识库回答

直接调用LangChain的RetrievalQA,实现基于上下文的问答。省去了写prompt的步骤。

from langchain.chains import RetrievalQA
import IPython

retriever = db.as_retriever()
qa = RetrievalQA.from_chain_type(llm=llm, chain_type="stuff", retriever=retriever)

query = "新能源行业发展了多久?"
print(qa.run(query))

输出及知识库中的原文如下,可见回答的非常准确~

Word中的原文:
![在这里插入图片描述](https://img-blog.csdnimg.cn/a9c4c6ecf768403d9fff5e8180580525.png
LLM的回答:
在这里插入图片描述

  • 14
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Chatglm 是一个基于语言链 (Langchain) 集成LLm 类。LLm (Language Learning Model) 类是一种用于语言学习的模型。Langchain 是一种集成各种语言学习资源和工具的平台,通过 Chatglm 类将 LLm 类与 Langchain 集成起来,可以提供更丰富、更高效的语言学习体验。 Chatglm 类基于 LLm 模型,具有一定的机器学习算法和自然语言处理能力,可以根据用户提供的输入行语言学习的交互。通过与 Chatglm 行对话,用户可以获取语法、词汇、语音、听力等方面的练习与学习。 通过集成 Langchain,Chatglm 类可以从各种语言学习资源中获取学习材料和练习题目,例如词汇表、语法规则、口语练习、听力练习、阅读材料等。用户可以通过与 Chatglm 行对话,选择不同的学习资源和练习类型,并获取个性化的学习推荐。 Chatglm 类还可以与其他学习者行交流,促语言学习的互动。通过与其他学习者的对话,用户可以分享学习经验、交流问题,相互学习、互相帮助。这种社交化学习的形式可以增加学习的趣味性和参与度。 总之,Chatglm 类集成Langchain 的各种语言学习资源和工具,通过 LLm 模型提供个性化的语言学习交互。它不仅可以提供丰富的学习材料和练习题目,还可以与其他学习者行交流,加强学习的互动性。通过与 Chatglm 类的对话,用户可以更有效地提升语言学习能力。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值