ナレッジグラフ抽出LLM

背景

chatglm に基づいた agnet の構築: Chatglm はエージェント制御を実装します - Zhihu

ベクトル検索強化 LLM:ベクトル検索強化 chatglm 生成 - Zhihu

大規模言語モデル (LLM) は、さまざまなアプリケーションで目覚ましい成功を収め、普及してきました。しかし、事実の知識を把握して獲得することができないことがよくあります。ナレッジ グラフ (KG) は、豊富な事実知識を明示的に保存する構造化データ モデルです。ただし、ナレッジ グラフは構築が難しく、ナレッジ グラフの既存の方法では、現実世界のナレッジ グラフの不完全で動的に変化する性質を処理するには不十分です。したがって、LLM と KG をそれぞれの長所を生かしながら組み合わせるのは自然なことです。

LLM は多くの成功した申請を行っていますが、事実に関する知識が不足しているために批判されてきました。具体的には、LLM はトレーニング コーパスに含まれる事実と知識を記憶します。しかし、さらなる研究により、LLMは事実を思い出すことができず、しばしば幻覚の問題、つまり虚偽の事実を含む表現を生成するという問題が発生することが示されました。たとえば、LLM に「アインシュタインはいつ重力を発見しましたか?」と尋ねると、「アインシュタインは 1687 年に重力を発見しました。」と答えるかもしれません。しかし実際には、重力理論を提案したのはアイザック アイザックスです。このような問題は、LLM の信頼性に重​​大な損害を与える可能性があります。

LLM は解釈可能性に欠けるブラックボックス モデルとして批判されています。LLM はパラメータを通じて暗黙的に知識を表します。したがって、LLM によって得られた知識を解釈して検証することは困難です。さらに、LLM は、非決定プロセスである確率モデルを通じて推論を実行します。LLM が予測結果や決定を導き出すために使用する特定のモードや関数の詳細や説明を人間が直接入手することは困難です。

上記の問題を解決するには、ナレッジ グラフ (KG) を LLM に統合することが考えられます。ナレッジ グラフは、トリプル (先頭エンティティ、関係性、末尾エンティティ) の形式で膨大な量の事実を保存できるため、ナレッジ グラフは構造化された決定的な形式の知識表現となります (例には、Wikidata、YAGO、NELL など)。

LLM と KG を統合する 3 つの一般的なフレームワーク: 1) KG 強化 LLM、2) LLM 強化 KG、および 3) 協調 LLM + KG。

LLM とナレッジ グラフ間のコラボレーションのための一般的なフレームワーク。データ、コラボレーション モデル、テクノロジー、アプリケーションの 4 つのレイヤーが含まれます。

この記事では、既存の LLM を事前トレーニングする方法、ナレッジ グラフ LLM を抽出するための sft を構築する方法、LLM エージェントが使用するツールにナレッジ グラフ LLM をカプセル化する方法など、強力なナレッジ抽出機能を備えた LLM モデルを構築する方法を紹介します。後の記事では、構築されたナレッジ グラフを使用して LLM モデルを強化し、モデルの検索および意図の理解機能を向上させ、ナレッジ グラフを使用して LLM モデルの生成能力を強化し、ファントムの確率を低減する方法を紹介する特別記事を用意する予定です。書き込み。

技術的なポイントの紹介

この記事の知識抽出モデルは「インテリジェント分析」モデルを選択しています。このモデルはラマ 13b に基づいており、独自のデータと公開データを使用してモデルを事前トレーニングし、命令コーパスを使用してその上にある lora を微調整します。事前訓練モデル。

固有表現認識 (NER)、イベント抽出 (EE)、関係抽出 (RE) などの情報抽出機能があり、簡単に使用できるようにプロンプ​​トが提供されており、独自のプロンプトを使用してみることもできます。

以下の図は、トレーニング プロセス全体とデータセットの構築を示しています。トレーニング プロセス全体は 2 つの段階に分かれています。

(1) 完全な事前トレーニング段階。この段階の目的は、モデルの中国語能力と知識の蓄積を高めることです。

(2) LoRA の命令微調整フェーズを使用します。この段階では、モデルが人間の指示を理解し、適切なコンテンツを出力できるようになります。

事前トレーニング モデルは、5500K の中国語サンプル、1500K の英語サンプル、900K のコード サンプルで事前トレーニングされています。Deepspeed ZeRO3 でトランス トレーナーを使用し (実際には、マルチマシンおよびマルチカードのシナリオでは ZeRO2 を使用すると速度が遅くなります)、3 つのノード (各ノードに 8 枚の 32GB V100 カード) でマルチマシンおよびマルチカードのトレーニングを実施しました。

sft トレーニングは命令データ セットを構築しました。情報抽出 (IE) データ セットの場合、英語部分は CoNLL ACE CASIS などのオープンソース IE データ セットを使用して、対応する英語命令データ セットを構築します。中国語部分: DuEE、PEOPLE DAILY、DuIE などのオープンソース データ セットが使用され、対応する中国語命令データ セットの構築には自己構築された KG2struct も使用されます。具体的には、KG2struct ( InstructIE ) は、中国語の Wikipedia および Wikidata のリモート監視を通じて取得された中国語の情報抽出データセットであり、実際の抽出ニーズを満たす幅広い分野をカバーしています。1 つのノードでマルチカード トレーニングを実行します。

データセットの種類 アイテム数
COT (中国語と英語) 202,333
ユニバーサル データセット (中国語と英語) 105,216
コードデータセット(中国語、英語) 44,688
英語指示抽出データセット 537,429
中国語命令抽出データセット 486,768

トレーニング部分はこの記事の焦点では​​ありません。この部分に興味がある学生は、https: //github.com/zjunlp/KnowLM/blob/main/README_ZH.mdを参照してください。

次に、このモデルを LLM エージェントが使用するツールにカプセル化する方法を紹介します。 1. 環境の展開 2. カプセル化サービス。

#环境部署
#下载智析项目代码
git clone https://github.com/zjunlp/KnowLM.git
cd KnowLM
#下载zhixi fp16模型参数
python tools/download.py --download_path ./zhixi-diff-fp16 --only_base --fp16
#下载llama参数
git clone https://huggingface.co/huggyllama/llama-13b

#把zhixi模型参数和llama参数做数值合并得到实际可用的zhixi推理参数“./converted”这个地址换成llama参数地址
python tools/weight_diff.py recover --path_raw ./converted --path_diff ./zhixi-diff-fp16 --path_tuned ./zhixi --is_fp16 True

#指令微调后的lora参数下载
python tools/download.py --download_path ../lora --only_lora

梱包サービス:

#封装prompt模版
import sys
import json
import fire
import os.path as osp
from typing import Union
import torch
import transformers
from peft import PeftModel
from transformers import GenerationConfig, LlamaForCausalLM, LlamaTokenizer

class Prompter(object):
    __slots__ = ("template", "_verbose")

    def __init__(self, template_name: str = "", verbose: bool = False):
        self._verbose = verbose
        # file_name = osp.join("templates", f"{template_name}.json")
        file_name = template_name
        if not osp.exists(file_name):
            raise ValueError(f"Can't read {file_name}")
        with open(file_name) as fp:
            self.template = json.load(fp)
        if self._verbose:
            print(
                f"Using prompt template {template_name}: {self.template['description']}"
            )

    def generate_prompt(
        self,
        instruction: str,
        input: Union[None, str] = None,
        label: Union[None, str] = None,
    ) -> str:
        # returns the full prompt from instruction and optional input
        # if a label (=response, =output) is provided, it's also appended.
        if input:
            res = self.template["prompt_input"].format(
                instruction=instruction, input=input
            )
        else:
            res = self.template["prompt_no_input"].format(
                instruction=instruction
            )
        if label:
            res = f"{res}{label}"
        if self._verbose:
            print(res)
        return res

    def get_response(self, output: str) -> str:
        return output.split(self.template["response_split"])[1].strip()
#封装tool
from transformers import LlamaTokenizer, LlamaForCausalLM, GenerationConfig
import torch
from typing import Optional, Type
from langchain.base_language import BaseLanguageModel
from langchain.tools import BaseTool
from langchain.callbacks.manager import (
    AsyncCallbackManagerForToolRun,
    CallbackManagerForToolRun,
)


class functional_Tool(BaseTool):
    name: str = ""
    description: str = ""
    url: str = ""

    def _call_func(self, query):
        raise NotImplementedError("subclass needs to overwrite this method")

    def _run(
            self,
            query: str,
            run_manager: Optional[CallbackManagerForToolRun] = None,
    ) -> str:
        return self._call_func(query)

    async def _arun(
            self,
            query: str,
            run_manager: Optional[AsyncCallbackManagerForToolRun] = None,
    ) -> str:
        raise NotImplementedError("APITool does not support async")

class LLM_KG_Generator(functional_Tool):
    
    model: LlamaForCausalLM #BaseLanguageModel
    tokenizer:LlamaTokenizer
    max_length:int
    prompter:Prompter

                 
    def _call_func(self, query) -> str:
        #self.get_llm_chain()
        self.model.config.pad_token_id = self.tokenizer.pad_token_id = 0  # same as unk token id
        self.model.config.bos_token_id = self.tokenizer.bos_token_id = 1
        self.model.config.eos_token_id = self.tokenizer.eos_token_id = 2
        
        prompter = self.prompter
        prompt_temple = "我将给你个输入,请根据事件类型列表:['旅游行程'],论元角色列表:['旅游地点', '旅游时间', '旅游人员'],从输入中抽取出可能包含的事件,并以(事件触发词,事件类型,[(事件论元,论元角色)])的形式回答。"
        prompt  = prompter.generate_prompt(prompt_temple,query)
        inputs = self.tokenizer(prompt, return_tensors="pt")
        input_ids = inputs["input_ids"].to("cuda")
        s = self.model.generate(input_ids,max_length=self.max_length)
        resp = self.tokenizer.decode(s[0])
        return resp
#测试例子
model = LlamaForCausalLM.from_pretrained(
            "/root/autodl-tmp/KnowLM/zhixi",
            load_in_8bit=False,
            torch_dtype=torch.float16,
            device_map="auto",
        )
tokenizer = LlamaTokenizer.from_pretrained("/root/autodl-tmp/llm_model/llama-13b-hf")
prompter = Prompter("../finetune/lora/templates/alpaca.json")
KG_tool = LLM_KG_Generator(model = model,tokenizer = tokenizer,max_length =4096,prompter = prompter )
input="John昨天在纽约的咖啡馆见到了他的朋友Merry。他们一起喝咖啡聊天,计划着下周去加利福尼亚(California)旅行。他们决定一起租车并预订酒店。他们先计划在下周一去圣弗朗西斯科参观旧金山大桥,下周三去洛杉矶拜访Merry的父亲威廉。"
KG_tool.run(input)

#和llm agent配合使用
from langchain.agents import AgentExecutor
from custom_search import DeepSearch
from tool_set import *
from intent_agent imprt IntentAgent
from llm_model import  ChatGLM

#model_path换成自己的模型地址
llm = ChatGLM(model_path="/root/autodl-tmp/ChatGLM2-6B/llm_model/models--THUDM--chatglm2-6b/snapshots/8eb45c842594b8473f291d0f94e7bbe86ffc67d8")
llm.load_model()
agent = IntentAgent(tools=tools, llm=llm)

tools = [KG_tool]

agent_exec = AgentExecutor.from_agent_and_tools(agent=agent, tools=tools, verbose=True, max_iterations=1)
agent_exec.run(input)

テスト例によって生成された結果は次のとおりです。

理論的には、上記で抽出されたナレッジは、neo4j、gstore、TuGraph などのさまざまなグラフ データベースに保存できます...ビジネスでナレッジを使用する必要がある場合、入力された検索語を通じて必要な関連情報をグラフ データベースから見つけることができます。は、コンテキストとして、または知識を通じて、LLM モデルが最終的な答えを生成するための推論戦略を構築するために使用されます。

まとめ

1. LLM と KG を組み合わせる 3 つのモードを導入しました。LLM は、KG のナレッジ グラフの抽出および構築能力を強化します。KG は、LLM の検索および生成推論能力を強化します。KG と LLM は連携します。

2. LLM 拡張 KG 抽出モデルと、モデルの構築に必要な 2 つのプロセス (事前トレーニング、sft、事前トレーニングに必要なデータと sft に必要な命令セット) を説明する「スマート分析」プロジェクトを紹介します。

3. 「インテリジェント分析」をツールにカプセル化し、LLM エージェントがアプリケーション エコシステムを構築するためのツールにする方法を紹介しました。

4. 理論的には、ナレッジ構築プロセスには時間がかかりますが、事前に構築することができます。ナレッジを使用する必要があるときに、ナレッジ グラフを取得して呼び出すことで、さまざまなアプリケーション シナリオを構築できます。もちろん、ユーザー入力意味理解中に瞬時に知識を構築するためにも使用できます。

プロジェクトコード: https://github.com/liangwq/Chatglm_lora_multi-gpu/tree/main/APP_example/chatglm_agent

おすすめ

転載: blog.csdn.net/liangwqi/article/details/131893520