目录
接入自己的LLM
搭建ChatGLM的api
封装ChatGLM的LLM
测试
总结
参考
最新一段时间一直在学习LangChain相关的文档,发现LangChain提供了非常丰富的生态,并且也可以让业务非常方便的封装自己的工具,接入到LangcChain的生态中,比如切换不同向量存储(Vectorstores)、文件分片(Text Splitters)和文件加载器(Document Loaders)等。 本文将简单介绍下如何将自己搭建的ChatGLM集成进LangChain工具链中,当然如果有其他的自己搭建的LLM模型也可以采用类似的方式集成。
接入自己的LLM
参考官方文档# How to write a custom LLM wrapper,只需要集成LLM方法,并且实现_call方法即可。一个简单的自定义LLM如下:
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}
上面虽然只是一个最简单的实现,但是进一步思考,如果有自己的LLM,是不是也可以通过类似的方式接入到LangChain的生态中呢?
正好最近也在搭建ChatGLM,于是在想是不是可以将ChatGLM加入到LangChain工具链中来,利用其提供的工具方便做更深入的研究。于是搜索了一番,果然有类似开源实现,比如thomas-yanxin/LangChain-ChatGLM-Webui,一种利用 ChatGLM-6B + langchain 实现的基于本地知识的 ChatGLM 应用。但是研究了一下代码,发现其是将ChatGLM-6B和LangChain部署在一起的。但是由于资源有限,目前只有少量的显卡,不能每个人都能部署一套ChatGLM。
进一步思考,是否ChatGLM也提供了类似于openai的api接口呢,只需要进行http调用就可以使用ChatGLM的能力?这样就可以将:ChatGLM和上层的应用解耦,每个人都可以在自己本地通过api调用来进行实验。
搭建ChatGLM的api
查阅ChatGLM-6B文档,也发现了其确实可以通过API方式提供服务。 具体如下:
- 首先需要安装额外的依赖 pip install fastapi uvicorn ,然后运行仓库中的 api.py: python api.py
- 默认部署在本地的 8000 端口,通过 POST 方法进行调用
curl -X POST "http://{your_host}:8000" \ -H 'Content-Type: application/json' \ -d '{"prompt": "你好", "history": []}' 复制代码
- 得到的返回值为
{ "response":"你好👋!我是人工智能助手 ChatGLM-6B,很高兴见到你,欢迎问我任何问题。", "history":[["你好","你好👋!我是人工智能助手 ChatGLM-6B,很高兴见到你,欢迎问我任何问题。"]], "status":200, "time":"2023-03-23 21:38:40" }
封装ChatGLM的LLM
有了API之后,就可以参照上面的自定义LLM的方式封装ChatGLM了,具体代码如下:
from langchain.llms.base import LLM from langchain.llms.utils import enforce_stop_tokens from typing import Dict, List, Optional, Tuple, Union import requests import json class ChatGLM(LLM): max_token: int = 10000 temperature: float = 0.1 top_p = 0.9 history = [] def __init__(self): super().__init__() @property def _llm_type(self) -> str: return "ChatGLM" def _call(self, prompt: str, stop: Optional[List[str]] = None) -> str: # headers中添加上content-type这个参数,指定为json格式 headers = {'Content-Type': 'application/json'} data=json.dumps({ 'prompt':prompt, 'temperature':self.temperature, 'history':self.history, 'max_length':self.max_token }) # print("ChatGLM prompt:",prompt) # 调用api response = requests.post("{your_host}/api",headers=headers,data=data) # print("ChatGLM resp:",response) if response.status_code!=200: return "查询结果错误" resp = response.json() if stop is not None: response = enforce_stop_tokens(response, stop) self.history = self.history+[[None, resp['response']]] return resp['response']
上面只是简单的调用ChatGLM API,让程序跑起来,当然也可以参照LangChain封装openai的方式来做更加复杂的封装,比如提供重试、限频退让重试等功能。
测试
llm = ChatGLM() print(llm("你会做什么"))
输出如下:
ChatGLM prompt: 你会做什么 我是一个大型语言模型,被训练来回答人类提出的问题。我不能做任何实际的事情,只能通过文字回答问题。如果你有任何问题,我会尽力回答。
验证通过,可以通过封装的ChatGLM类来访问ChatGLM API。这样就可以将需要用到OpenAI的LLM类替换成自己封装的ChatGLM了。
总结
本文简单介绍下如何将自己搭建的ChatGLM集成进LangChain工具链中,并且进行简单的试验的效果。当然如果有其他自己搭建的LLM模型也可以采用类似的方式集成。后续将使用ChatGLM来实现一个本地知识库做问答系统。
参考
thomas-yanxin/LangChain-ChatGLM-Webui
使用langchain配合chatglm搭建本地的知识库,但是langchain和chatglm是部署在一起的,耦合性比较高
ChatGLM-6B
chatglm的api搭建