BigDL-LLM实践(8):Bigit实践——后端设计

Bigit是一款基于BigDl-LLM和LangChain的Web服务。结合区块链技术,其可以实现针对知识图谱的问答,实现让个人拥有自己的“专用大模型”。

1.后端设计思路

  • ChatGo的后端主要功能是实现基于BigDl-LLM和LangChain的大模型问答服务,为ChatGo的核心组件。
  • 知识图谱采用Neo4j aura云部署的形式,方便个人用户使用
  • ChatGo的后端主要使用了LangChain的Agent模型来实现知识图谱的问答
  • 问答步骤为:根据用户的问题生成Cypher语句——Cypher语句查询知识图谱——根据知识图谱的查询结果返回最终的问答结结果

2.后端实现

2.1 根据问题生成Cypher语句

# 示例生成查询的语句
from env import getEnv
from database import Neo4jDatabase
from pydantic import BaseModel, Extra
from langchain.prompts.base import BasePromptTemplate
from langchain.chains.llm import LLMChain
from langchain.chains.base import Chain
from langchain.memory import ReadOnlySharedMemory, ConversationBufferMemory
from langchain.prompts import (
    ChatPromptTemplate,
    SystemMessagePromptTemplate,
    HumanMessagePromptTemplate,
)
from typing import Dict, List, Any

from logger import logger

with open('examples.txt', 'r') as file:
    examples = file.read()


SYSTEM_TEMPLATE = """
您是一名助手,能够根据示例Cypher查询生成Cypher查询。
示例Cypher查询是:\n""" + examples + """\n
不要回复除Cypher查询以外的任何解释或任何其他信息。
您永远不要为你的不准确回复感到抱歉,并严格根据提供的Cypher示例生成Cypher语句。
不要提供任何无法从密码示例中推断出的Cypher语句。
"""

SYSTEM_CYPHER_PROMPT = SystemMessagePromptTemplate.from_template(SYSTEM_TEMPLATE)

HUMAN_TEMPLATE = "{question}"
HUMAN_PROMPT = HumanMessagePromptTemplate.from_template(HUMAN_TEMPLATE)


class LLMCypherGraphChain(Chain, BaseModel):
    """Chain that interprets a prompt and executes python code to do math.
    """

    llm: Any
    """LLM wrapper to use."""
    system_prompt: BasePromptTemplate = SYSTEM_CYPHER_PROMPT
    human_prompt: BasePromptTemplate = HUMAN_PROMPT
    input_key: str = "question"  #: :meta private:
    output_key: str = "answer"  #: :meta private:
    graph: Neo4jDatabase
    memory: ReadOnlySharedMemory

    class Config:
        """Configuration for this pydantic object."""

        extra = Extra.forbid
        arbitrary_types_allowed = True

    @property
    def input_keys(self) -> List[str]:
        """Expect input key.
        :meta private:
        """
        return [self.input_key]

    @property
    def output_keys(self) -> List[str]:
        """Expect output key.
        :meta private:
        """
        return [self.output_key]

    def _call(self, inputs: Dict[str, str]) -> Dict[str, str]:
        logger.debug(f"Cypher generator inputs: {inputs}")
        chat_prompt = ChatPromptTemplate.from_messages(
            [self.system_prompt] + inputs['chat_history'] + [self.human_prompt]
        )
        cypher_executor = LLMChain(
            prompt=chat_prompt, llm=self.llm, callback_manager=self.callback_manager
        )
        cypher_statement = cypher_executor.predict(
            question=inputs[self.input_key], stop=["Output:"])
        self.callback_manager.on_text(
            "Generated Cypher statement:", color="green", end="\n", verbose=self.verbose
        )

        self.callback_manager.on_text(
            cypher_statement, color="blue", end="\n", verbose=self.verbose
        )

        print(cypher_statement)
        # If Cypher statement was not generated due to lack of context

        if not "MATCH" in cypher_statement:
            return {'answer': 'Missing context to create a Cypher statement'}
        
        try:
            context = self.graph.query(cypher_statement)
            return {'answer': context}

        except: 
            logger.debug('Cypher generator context:')
            return {'answer': 'No match Cypher statement'}



if __name__ == "__main__":
    from langchain.chat_models import ChatOpenAI
    from bigdl.llm.langchain.llms import TransformersLLM
    llm = TransformersLLM.from_model_id(
            model_id="lmsys/vicuna-7b-v1.5",
            model_kwargs={"temperature": 0, "max_length": 1024, "trust_remote_code": True},
        )
    
    database = Neo4jDatabase(host="neo4j://localhost:7687",
                             user="neo4j", password="aowang")

    memory = ConversationBufferMemory(
        memory_key="chat_history", return_messages=True)
    readonlymemory = ReadOnlySharedMemory(memory=memory)


    print('query scuess')
    chain = LLMCypherGraphChain(llm=llm, verbose=True, graph=database, memory=readonlymemory)

    output = chain.run(
        "演唱兰亭序的歌手是"
    )

    print(output)

2.2 根据Cpyher语句进行本地图谱的查询

from typing import List, Optional, Dict
from neo4j import GraphDatabase
from logger import logger


class Neo4jDatabase:
    def __init__(self, host: str = "neo4j://localhost:7687",
                 user: str = "neo4j",
                 password: str = "aowang"):
        """Initialize the movie database"""
        self.driver = GraphDatabase.driver(host, auth=(user, password))
        print('driver sucess'+host)

    def query(
        self,
        cypher_query: str,
        params: Optional[Dict] = {}
    ) -> List[Dict[str, str]]:
        logger.debug(cypher_query)
        with self.driver.session() as session:
            result = session.run(cypher_query, params)
            # Limit to at most 50 results
            return [r.values()[0] for r in result][:50]


if __name__ == "__main__":
    database = Neo4jDatabase(host="neo4j://localhost:7687",
                             user="neo4j", password="aowang")

    a = database.query("""
    MATCH (n) RETURN {count: count(*)} AS count
    """)

    print(a)

2.3 生成最后的答案,前端调用

# 路由处理

import logging

from agent import GraphAgent
from env import getEnv
from database import Neo4jDatabase
from fastapi import APIRouter, HTTPException, Query
from run import get_result_and_thought_using_graph

neo4j_host = getEnv("NEO4J_URL")
neo4j_user = getEnv("NEO4J_USER")
neo4j_password = getEnv("NEO4J_PASS")
# build router
router = APIRouter()
logger = logging.getLogger(__name__)
graph = Neo4jDatabase(
    host=neo4j_host, user=neo4j_user, password=neo4j_password)
print(neo4j_host)
# 不使用记忆组件功能,每次接口初始化
# agent_graph = GraphAgent.initialize(
#     graph=graph, model_name=model_name)


@router.get("/predict")
def get_load(message: str = Query(...)):
    try:
        agent_graph = GraphAgent.initialize(
            graph=graph, model_name=model_name)   
        print(neo4j_host)
        return get_result_and_thought_using_graph(agent_graph, message)
    except Exception as e:
        # Log stack trace
        logger.exception(e)
        raise HTTPException(status_code=500, detail=str(e)) from e

3.后端使用

1. 后端在项目的/backend文件夹中,首先安装项目的依赖库

pip install langchain==0.0.2

pip install openai==0.27.4

pip install neo4j-driver==1.7.6

pip install neo4j

pip install fastapi

pip install uvicorn

2. 其次完成环境配置,设置node4j数据库等信息,我们提供.env的实例,可以照此填写

cp .env.example .env

3. 环境变量设置完后,即可开启后端,进入backend/src/中运行

python3 main.py
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
GPT (Generative Pre-trained Transformer)是由OpenAI公司开发的一系列自然语言处理模型。它采用多层Transformer结构来预测下一个单词的概率分布,通过在大型文本语料库中学习到的语言模式来生成自然语言文本。GPT系列模型包括多个版本,如GPT-2和GPT-3等。\[2\]这些模型在不同任务中展现了出色的性能,包括零样本学习和少样本学习等。GPT使用Transformer的Decoder结构,并对其进行了一些改动,保留了Mask Multi-Head Attention。\[3\]通过这些改进,GPT模型在自然语言处理领域取得了显著的成果。 #### 引用[.reference_title] - *1* [深入理解深度学习——GPT(Generative Pre-Trained Transformer):基础知识](https://blog.csdn.net/hy592070616/article/details/131341012)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [【LLM系列之GPT】GPT(Generative Pre-trained Transformer)生成式预训练模型](https://blog.csdn.net/yanqianglifei/article/details/130756814)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值