Langchain-Chatchat项目:2.1-通过GPT2模型来检索NebulaGraph

langchain,chatchat,项目,通过,gpt2,模型,检索,nebulagraph · 浏览次数 : 18

小编点评

## 生成内容时需要带简单的排版 以下内容需要带简单的排版: * **模型名称**: GPT2LMHeadModel,GPT2Tokenizeros.environ[\"CUDA_VISIBLE_DEVICES\"] * **数据格式**: request.get_data(),json.loads(data_seq) * **结果格式**: json.dumps(result_dict, ensure_ascii=False) 以下示例需要带简单的排版: ```python model_name = "GPT2LMHeadModel" data_format = request.get_data() result_format = json.dumps(result_dict, ensure_ascii=False) print(f"模型名称: {model_name}") print(f"数据格式: {data_format}") print(f"结果格式: {result_format}") ``` **排版建议**: * 使用缩进来使代码更易读 * 使用空格来使代码更易读 * 使用换行来使代码更易读 * 使用缩进来使代码更易读 例如: ```python model_name = "GPT2LMHeadModel" data_format = request.get_data() result_format = json.dumps(result_dict, ensure_ascii=False) print(f"\n模型名称: {model_name}") print(f"\n数据格式: {data_format}") print(f"\n结果格式: {result_format}") ``` **希望这些建议能帮助您生成内容时更易读!**

正文

  在官方例子中给出了通过chain = NebulaGraphQAChain.from_llm(ChatOpenAI(temperature=0), graph=graph, verbose=True)来检索NebulaGraph图数据库。本文介绍了通过GPT2替换ChatOpenAI的思路和实现,暂时不考虑效果。之所以没用ChatGLM2是因为加载模型太慢,调试不方便,不过将GPT2替换为ChatGLM2也很方便。

一.通过ChatOpenAI来检索NebulaGraph
1.NebulaGraph_OpenAI.py代码实现
  如果没有ChatGPT的key和proxy是没法运行的,如下所示:

"""langchain连接NebulaGraph的例子"""from langchain.chat_models import ChatOpenAIfrom langchain.chains import NebulaGraphQAChainfrom langchain.graphs import NebulaGraphgraph = NebulaGraph(    space="basketballplayer",    username="root",    password="nebula",    address="172.21.31.166",    port=9669,    session_pool_size=30,  # 设置连接池大小)print(graph.get_schema)chain = NebulaGraphQAChain.from_llm(  # 从语言模型创建问答链    ChatOpenAI(temperature=0), graph=graph, verbose=True)chain.run("Who played in The Godfather II?")
复制

2.NebulaGraphQAChain默认prompt
  基本思路是介绍、举例、图Schema和限制,如下所示:

> Entering new NebulaGraphQAChain chain...Generated nGQL:Task:Generate NebulaGraph Cypher statement to query a graph database.Instructions:First, generate cypher then convert it to NebulaGraph Cypher dialect(rather than standard):1. it requires explicit label specification only when referring to node properties: v.`Foo`.name2. note explicit label specification is not needed for edge properties, so it's e.name instead of e.`Bar`.name3. it uses double equals sign for comparison: `==` rather than `=`For instance:diff< MATCH (p:person)-[e:directed]->(m:movie) WHERE m.name = 'The Godfather II'< RETURN p.name, e.year, m.name;---> MATCH (p:`person`)-[e:directed]->(m:`movie`) WHERE m.`movie`.`name` == 'The Godfather II'> RETURN p.`person`.`name`, e.year, m.`movie`.`name`;Use only the provided relationship types and properties in the schema.Do not use any other relationship types or properties that are not provided.Schema:Node properties: [{'tag': 'player', 'properties': [('name','string'), ('age', 'int64')]}, {'tag': 'team', 'properties': [('name','string')]}]Edge properties: [{'edge': 'follow', 'properties': [('degree', 'int64')]}, {'edge':'serve', 'properties': [('start_year', 'int64'), ('end_year', 'int64')]}]Relationships: ['(:player)-[:follow]->(:player)', '(:player)-[:serve]->(:team)']Note: Do not include any explanations or apologies in your responses.Do not respond to any questions that might ask anything else than for you to construct a Cypher statement.Do not include any text except the generated Cypher statement.The question is:player100'age is what?Full Context:{}
复制

二.通过GPT2来检索NebulaGraph
1.NebulaGraph_GPT2.py代码实现
  使用自定义的GPT2()替换ChatOpenAI(temperature=0)即可,如下所示:

"""langchain连接NebulaGraph的例子"""from langchain.chains import NebulaGraphQAChainfrom langchain.graphs import NebulaGraphfrom examples.GPT2 import GPT2graph = NebulaGraph(  # 连接NebulaGraph    space="basketballplayer",    username="root",    password="nebula",    address="172.24.211.214",    port=9669,    session_pool_size=30,  # 设置连接池大小)print(graph.get_schema)  # 获取图的schemachain = NebulaGraphQAChain.from_llm(  # 从语言模型创建问答链    GPT2(), graph=graph, verbose=True)chain.run("player100'name is what?")  # 运行问答链chain.run("player100'age is what?")  # 运行问答链
复制

2.GPT2.py代码实现
  主要是继承LLM类,并且实现def _call(self, prompt: str, stop: Optional[List[str]] = None) -> str:函数,如下所示:

import timeimport loggingimport requestsfrom typing import Optional, List, Dict, Mapping, Anyimport langchainfrom langchain.llms.base import LLMfrom langchain.cache import InMemoryCachelogging.basicConfig(level=logging.INFO)# 启动llm的缓存,如果同一个问题被第二次提问,模型可以快速给出答案,而不用再次调用模型,节省时间langchain.llm_cache = InMemoryCache()class GPT2(LLM):    # 模型服务url    url = "http://127.0.0.1:8595/chat"    @property  # 这个装饰器的作用是将一个方法变成一个属性来使用    def _llm_type(self-> str:        return "gpt2"    def _construct_query(self, prompt: str-> Dict:        """        构造请求体        """        query = {            "human_input": prompt        }        return query    @classmethod  # 这个装饰器的作用是将一个方法变成一个类方法来使用    def _post(cls, url: str, query: Dict) -> Any:        """        POST请求        """        _headers = {"Content_Type""application/json"}        with requests.session() as sess:  # 这个with语句的作用是在这个语句块中创建的对象,会在执行完语句块后自动销毁            resp = sess.post(url, json=query, headers=_headers, timeout=60)        return resp    def _call(self, prompt: str, stop: Optional[List[str]] = None-> str:        """        注释:这个方法是用来调用模型的,这个方法的参数是prompt和stop,prompt是用户输入的内容,stop是用户输入的结束标志        """        query = self._construct_query(prompt=prompt)  # 构造请求体        resp = self._post(url=self.url, query=query)  # post请求        if resp.status_code == 200:  # 判断请求是否成功            resp_json = resp.json()  # 获取返回结果            predictions = resp_json['response']  # 获取返回结果中的response字段            return predictions  # 返回模型结果        else:            return "请求模型"    @property  # 这个装饰器的作用是将一个方法变成一个属性来使用    def _identifying_params(self-> Mapping[str, Any]:        """        这个方法的作用是获取识别参数        """        _param_dict = {            "url"self.url        }        return _param_dictif __name__ == "__main__":    llm = GPT2()  # 实例化GPT2类    while True:  # 这个while循环的作用是让用户可以一直输入        human_input = input("Human: ")  # 获取用户输入        begin_time = time.time() * 1000  # 获取当前时间        response = llm(human_input, stop=["you"])  # 调用模型        end_time = time.time() * 1000  # 获取当前时间        used_time = round(end_time - begin_time, 3)  # 计算模型调用时间        logging.info(f"GPT2 process time: {used_time}ms")  # 打印模型调用时间        print(f"GPT2: {response}")  # 打印模型返回结果
复制

3.GPT2_Flask.py代码实现
  主要是通过Flask将GPT2进行API封装,如下所示:

import osimport jsonimport torchfrom flask import Flaskfrom flask import requestfrom transformers import GPT2LMHeadModel, GPT2Tokenizeros.environ["CUDA_VISIBLE_DEVICES"] = "0"  # 指定GPU,0表示使用第一个GPUpretrained_model_name_or_path = "L:/20230713_HuggingFaceModel/gpt2"tokenizer = GPT2Tokenizer.from_pretrained(pretrained_model_name_or_path, trust_remote_code=True)model = GPT2LMHeadModel.from_pretrained(pretrained_model_name_or_path, trust_remote_code=True).half().cuda()model.eval()app = Flask(__name__)@app.route("/", methods=["POST""GET"])def root():    return "Welcome to gpt2 model"@app.route("/chat", methods=["POST"])def chat():    data_seq = request.get_data()  # 获取请求数据    data_dict = json.loads(data_seq)  # 将请求数据转换为字典    human_input = data_dict["human_input"]  # 获取请求数据中的human_input字段    # response, _ = model.chat(tokenizer, human_input, history=[])  # ChatGLM可使用这个方法    # 将输入文本编码为令牌    input_ids = tokenizer.encode(human_input, return_tensors="pt")    input_ids = input_ids.cuda()    # 进行模型推理    with torch.no_grad():  # 这个with语句的作用是在这个语句块中创建的对象,会在执行完语句块后自动销毁        output = model.generate(input_ids, max_length=50, num_return_sequences=1)  # 生成模型输出,max_length表示生成的最大长度,num_return_sequences表示生成的序列数    output = output.cuda()    # 将生成的令牌解码为字符串,skip_special_tokens=True表示跳过特殊字符,clean_up_tokenization_spaces=True表示清理分词空格    response = tokenizer.decode(output[0], skip_special_tokens=True, clean_up_tokenization_spaces=True)    result_dict = {  # 构造返回结果        "response": response    }    result_seq = json.dumps(result_dict, ensure_ascii=False)  # 将返回结果转换为json字符串    return result_seq  # 返回结果if __name__ == "__main__":    app.run(host="0.0.0.0", port=8595, debug=False)
复制

  因为通用LLM通过prompt将text转换为nGQL并不专业,觉得以后的发展思路应该还是专用LLM作为agent来做这个事情。

参考文献:
[1]https://huggingface.co/gpt2
[2]使用LLMs模块接入自定义大模型:https://blog.csdn.net/zhaomengsen/article/details/130585397
[3]https://github.com/ai408/Langchain-Chatchat/blob/master/examples/NebulaGraph_GPT2.py
[4]https://github.com/ai408/Langchain-Chatchat/blob/master/examples/GPT2.py
[5]https://github.com/ai408/Langchain-Chatchat/blob/master/examples/GPT2_Flask.py

与Langchain-Chatchat项目:2.1-通过GPT2模型来检索NebulaGraph相似的内容:

Langchain-Chatchat项目:2.1-通过GPT2模型来检索NebulaGraph

在官方例子中给出了通过chain = NebulaGraphQAChain.from_llm(ChatOpenAI(temperature=0), graph=graph, verbose=True)来检索NebulaGraph图数据库。本文介绍了通过GPT2替换ChatOpenAI的思路和实现,暂

Langchain-Chatchat项目:1.2-Baichuan2项目整体介绍

由百川智能推出的新一代开源大语言模型,采用2.6万亿Tokens的高质量语料训练,在多个权威的中文、英文和多语言的通用、领域benchmark上取得同尺寸最佳的效果,发布包含有7B、13B的Base和经过PPO训练的Chat版本,并提供了Chat版本的4bits量化。 一.Baichuan2模型 B

Langchain-Chatchat项目:1.1-ChatGLM2项目整体介绍

ChatGLM2-6B是开源中英双语对话模型ChatGLM-6B的第2代版本,引入新的特性包括更长的上下文(基于FlashAttention技术,将基座模型的上下文长度由ChatGLM-6B的2K扩展到了32K,并在对话阶段使用8K的上下文长度训练);更高效的推理(基于Multi-QueryAtte

Langchain-Chatchat项目:1-整体介绍

基于Langchain与ChatGLM等语言模型的本地知识库问答应用实现。项目中默认LLM模型改为THUDM/chatglm2-6b[2],默认Embedding模型改为moka-ai/m3e-base[3]。 一.项目介绍 1.实现原理 本项目实现原理如下图所示,过程包括加载文件->读取文本->文

Langchain-Chatchat项目:3-Langchain计算器工具Agent思路和实现

本文主要讨论Langchain-Chatchat项目中自定义Agent问答的思路和实现。以"计算器工具"为例,简单理解就是通过LLM识别应该使用的工具类型,然后交给相应的工具(也是LLM模型)来解决问题。一个LLM模型可以充当不同的角色,要把结构化的Prompt模板写好,充分利用LLM的Zero/O

拆解LangChain的大模型记忆方案

之前我们聊过如何使用LangChain给LLM(大模型)装上记忆,里面提到对话链ConversationChain和MessagesPlaceholder,可以简化安装记忆的流程。下文来拆解基于LangChain的大模型记忆方案。

LangChain转换链:让数据处理更精准

在开发AI Agent(智能体)时,我们经常需要对输入数据进行预处理,这样可以更好地利用LLM。LangChain提供了一个强大的工具——转换链(TransformChain),它可以帮我们轻松实现这一任务。

5分钟了解LangChain的路由链

路由链(RouterChain)是由LLM根据输入的Prompt去选择具体的某个链。路由链中一般会存在多个Prompt,Prompt结合LLM决定下一步选择哪个链。

5分钟明白LangChain 的输出解析器和链

本文介绍 LangChain 的输出解析器OutputParser的使用,和基于LangChain的LCEL构建链。 1. 输出解析器OutputParser 1.1、为什么需要OutputParser 常规的使用LangChain构建LLM应用的流程是:Prompt 输入、调用LLM 、LLM输出

Langchain 与 LlamaIndex:LLM 应用开发框架的比较与使用建议

Langchain 和 Llamaindex 是两种广泛使用的主流 LLM 应用开发框架。两者有什么不同?我们该如何使用?以下我根据各类资料和相关文档做了初步选型。 一、Langchain 1. 适用场景 (1)需要构建灵活、可扩展的通用应用程序。 (2)需要复杂的工作流程支持。 (3)需要复杂的交