Graph RAG with Property Graphs: A Quick Foray


نویسنده(های): کوندان جوشی

در ابتدا منتشر شد به سمت هوش مصنوعی.

همانطور که فریم ورک‌های Retrieval Augmentation Generation به سرعت تکامل می‌یابند، نمودار RAG نیز سرعت خود را حفظ می‌کند و به عنوان پاسخی به سؤالات مطرح شده در مورد دقت افزایش بازیابی ظاهر شده است. رویکردهای سنتی مبتنی بر تعبیه برداری برای RAG در استخراج محتوای بدون ساختار مبتنی بر شباهت بسیار خوب عمل می‌کنند، اما نمی‌توانند بر محدودیت‌های ذاتی «بدون ساختار» غلبه کنند. با ظهور نمودارهای دانش، پشتیبانی از پرس و جو برای هوش مصنوعی توسط یک مکمل منبع خارجی فعال می شود که صرفاً بر اساس شباهت نیست، بلکه اساساً بر اساس روابط منطقی با یک نمایش سازمان یافته از ارتباط متقابل بین موجودیت ها ساخته شده است.
Graph RAG به دلیل طراحی ذاتی خود، با توانمندسازی LLM برای درک زمینه گسترده تر و ارائه یک رویکرد بینش آمیز برای حل سؤال.

این پارادایم یک مفهوم ساده اما مؤثر از سه گانه را به کار گرفته است که اساس نمودار دانش را تشکیل می دهد – مدل سازی روابط به عنوان یک تریاژ موضوع – محمول – شی. با این حال، اگرچه این ممکن است برای موارد استفاده استاندارد مبتنی بر QnA عالی باشد، اما می‌تواند در پویایی‌های پیچیده یا در میان پایگاه‌های دانش دنیای واقعی که هر گره اطلاعاتی احتمالاً می‌تواند دارای ویژگی‌های مختلفی باشد، کوتاه بیاید، و در مواقعی نیاز به هستی‌شناسی‌های پیچیده برای فعال کردن ابزار گراف دارد.
برای پرداختن به این موضوع، نمودارهای ویژگی، که بر روی گره ها و روابط قرار دارند، ضریب ابزار را بیشتر گسترش می دهند. هر گره دارای قابلیت برچسب گذاری مرتبط با برچسب ها و قابلیت ذخیره ویژگی به عنوان جفت کلید-مقدار است. روابط بین گره ها نیز می تواند دارای ویژگی باشد
و ناوبری را فعال کنید. بعلاوه، جمعیت ابرداده، نمودارهای Property را با ارائه یک حرکت کل نگر برای استنتاج کلی افزایش می دهد.

پس با این همه پیش درآمد، مراسم را آغاز کنیم –

ما از چارچوب LlamaIndex از طریق این مثال برای نشان دادن ادغام Graph DB همراه با سایر اجزای منبع باز استفاده خواهیم کرد. برای شروع با محیط مجازی مرسوم-

python3 -m venv grenv
source grenv/bin/activate

به دنبال آن


pip install -r requirements.txt

الزامات.txt در حال گسترش به llama-index llama-index-embeddings-huggingface llama_index.graph_stores.neo4j llama-index-readers-file
pydantic_settings

به عنوان یک مطالعه موردی، یکی از سخنرانی های فدرال رزرو را در نظر می گیریم که به اقتصاد می پردازد و ارقامی را به عنوان معیاری برای شاخص های اقتصادی ارائه می دهد.

سخنرانی فرماندار کوک در مورد چشم انداز اقتصادی

متشکرم کریستا بودن با شما در محوطه زیبای دانشگاه ویرجینیا فوق العاده است. این من…

www.federalreserve.gov

زمینه را برای دریافت داده ها و انجام برخی از گرد و غبارهای اولیه داده ها آماده کنید.

علاوه بر ضدعفونی کردن، ما باید داده ها را تکه تکه کنیم – باید توجه داشت که اندازه تکه باید بین ثبت روابط کامل تر با قطعات متن بزرگتر در مقابل سرعت تجزیه و تحلیل گره گراف برای تکه های کوچکتر معامله شود. متناوبا می توانید از یک معنایی نیز استفاده کنید تکه تکه شدن استراتژی که از یک مدل جاسازی برای تقسیم تکه ها بر اساس شباهت استفاده می کند.

import re
import nest_asyncio
import os, sys, logging
from llama_index.core import Settings
from llama_index.core import PromptTemplate
from llama_index.embeddings.huggingface import HuggingFaceEmbedding
from llama_index.core import SimpleDirectoryReader, PropertyGraphIndex, Document
from llama_index.core.indices.property_graph import SimpleLLMPathExtractor, ImplicitPathExtractor, SchemaLLMPathExtractor, DynamicLLMPathExtractor
from llama_index.core.node_parser import (
SentenceSplitter,
SemanticSplitterNodeParser,
)
from llama_index.llms.llama_cpp import LlamaCPP
from typing import Literal, List
from llama_index.core.ingestion import IngestionPipeline, IngestionCache
from llama_index.graph_stores.neo4j import Neo4jPropertyGraphStore

nest_asyncio.apply()
logging.basicConfig(stream=sys.stdout, level=logging.INFO)

embed_model = HuggingFaceEmbedding()

Settings.embed_model = embed_model
Settings.chunk_size = 512
Settings.chunk_overlap = 50

content = SimpleDirectoryReader(input_files=["./fedspeech.txt"]).load_data()
document = Document(text=content[0].text, metadata={"title": 'Federal Reserve Speech on Economic Policy'})

splitter = SentenceSplitter(
chunk_size=256,
chunk_overlap=50,
paragraph_separator='\n\n',
secondary_chunking_regex=r'\n[\dA-Za-z]\.'
)

from llama_index.core.schema import TransformComponent

class TextSanitizer(TransformComponent):
def __call__(self, nodes, **kwargs):
for node in nodes:
node.text = re.sub(r'\n\s*\n',"\n\n",node.text)
node.text = re.sub(r'[ ]+'," ",node.text)
node.text = re.sub(r'\b \.',".",node.text)
return nodes

pipeline = IngestionPipeline(
transformations=[
splitter,
TextSanitizer(),
embed_model,
]
)

nodes = pipeline.run(documents=[document])

در نهایت قهرمان نمایش – LLM. ما از Mistral 7B-0.3 استفاده می کنیم زیرا در مقایسه با سایر مدل های کوچکتر برای فراخوانی عملکرد مجهزتر است. انتخاب LLM برای Graph RAG حیاتی است زیرا نیاز به تولید عبارات Cypher و شناسایی گره ها/روابط گراف دارد، علاوه بر این که در زنجیره پردازش توابع LlamaIndex مناسب باشد.
7B در اینجا یک محدودیت است فقط در صورتی که نیاز داشته باشیم در یک محیط محدود با منابع CPU قرار بگیریم. می‌توانیم به طور متناوب با هر یک از مدل‌های LLM بدون سرور بسیار در دسترس و بسیار بزرگ‌تر که آداپتورهای یکپارچه LlamaIndex دارند اجرا کنیم.

def completion_to_prompt(completion):
return f"system\n\nuser\n{completion}\nassistant\n"

def messages_to_prompt(messages):
prompt = ""
for message in messages:
if message.role == "system":
prompt += f"system\n{message.content}\n"
elif message.role == "user":
prompt += f"user\n{message.content}\n"
elif message.role == "assistant":
prompt += f"assistant\n{message.content}\n"

if not prompt.startswith("system"):
prompt = "system\n" + prompt

prompt = prompt + "assistant\n"
return prompt

llm = LlamaCPP(
model_url='https://huggingface.co/lmstudio-community/Mistral-7B-Instruct-v0.3-GGUF/resolve/main/Mistral-7B-Instruct-v0.3-Q5_K_M.gguf',
temperature=0.1,
max_new_tokens=512,
context_window=2048,
generate_kwargs={},
model_kwargs={"n_gpu_layers": -1},
messages_to_prompt=messages_to_prompt,
completion_to_prompt=completion_to_prompt,
verbose=False,
)
Settings.llm = llm

LlamaIndex با تعدادی استخراج کننده همراه است که فرآیند تولید گره ها را برای Graph DB تعریف می کند. ما DynamicLLMPathExtractor را انتخاب می کنیم زیرا بیشترین انعطاف را ارائه می دهد.
همچنین می‌توانید با SimpleLLMPathExtractor یا SchemaLLMPathExtractor با طرحواره‌تر آزمایش کنید.

kg_extractor = DynamicLLMPathExtractor(
llm=llm,
max_triplets_per_chunk=10, # feel free to raise this
num_workers=4, # if multi core
# Let the LLM infer relationships on the fly
allowed_entity_types=None,
allowed_relation_types=None,
allowed_relation_props=[],
allowed_entity_props=[],
)

در نهایت، wingman حزب GraphRAG/LLM خود پایگاه داده Graph است. در میان گزینه‌های پایگاه‌های داده گراف، گزینه‌هایی مانند NebulaGraph، Ontotext و غیره وجود دارد. یکی از معدود گزینه‌هایی که مجازترین مجوزهای منبع باز برای استقرار تجاری را دارد احتمالا Memgraph است، با این حال، ما پیشرو Graphdb Neo4j را برای این نسخه نمایشی انتخاب کردیم. صرفاً به این دلیل که Neo4j و درایورهای آن راحت‌تر با LlamaIndex ادغام می‌شوند و گزینه‌های متعددی برای استقرار دارد.
با این حال، به عنوان یک هشدار مهم، لازم به ذکر است که اگر یک Graph DB منبع باز راه شما برای یک شرکت تجاری است، نسخه جامعه Neo4j دارای مجوز GPL v3 است – که کپی لفت قوی است.
اما ما بحث در مورد قابلیت قانونی آن را به زمان دیگری موکول می کنیم و فعلاً به موارد فنی پایبند هستیم.

اگر Neo4j نیاز به نصب دارد، لطفاً به چند تغییر با الزامات مربوط به فایل neo4j.conf و APOC jar در انتهای سرور توجه کنید — برای آن به آخرین دستورالعمل‌های استقرار Neo4j مراجعه کنید.
اما اجازه ندهیم که آزمایش استقرار مانع آزمایش شود و با نسخه رایگان Neo4j Aura پیش برویم (https://neo4j.com/product/auradb/).

برای ایجاد یک فروشگاه PropertyGraph به نمونه Neo4j متصل شوید.

username = os.environ.get('NEOUSER') # your DB username (default "neo4j")
password = os.environ.get('NEOPWD') # your DB password
url = "neo4j+s://{#redacted#}.databases.neo4j.io" # Specify the connection URL for Aura

graph_store = Neo4jPropertyGraphStore(
username=username,
password=password,
url=url,
)

در اینجا، PropertyGraphIndex با استفاده از گره هایی که از خط لوله مصرف تقطیر شده اند، نمونه سازی می شود.
همچنین می‌توانیم به جای گره‌ها از اسناد برای شروع GraphIndex استفاده کنیم.

index = PropertyGraphIndex(
nodes=nodes,
property_graph_store=graph_store,
embed_model=embed_model,
kg_extractors=[kg_extractor],
show_progress=True)

اگر از یک LLM محلی استفاده می کنید، این مرحله ممکن است کمی طول بکشد، زیرا گره های Graph توسط LLM در اینجا استخراج می شوند.

پس از اتمام، می توانید گره های ایجاد شده در پایگاه داده را با Cypher، زبان پرس و جوی تعیین شده برای نمودارهای Property بررسی کنید.

MATCH p=()-[]-() RETURN p;

استنباط:

هنگامی که ذخیره گراف را ایجاد کردید یا اگر از یک Graphstore قبلاً ایجاد شده استفاده می کنید، می توانیم به سادگی آن را (در برنامه دیگری مانند نقطه پایانی سرور FastAPI) با استفاده از – نمونه سازی کنیم.

index = PropertyGraphIndex.from_existing(
property_graph_store=graph_store,
show_progress=True,
)

به دنبال استنباط به یک سوال:

retriever = index.as_retriever(
include_text=False, # include source text in returned nodes, default True
)
nodes = retriever.retrieve("how is continued disinflation justified in the speech?")

for node in nodes:
print(f'node............{node.text}')

query_engine = index.as_query_engine(
include_text=True,
similarity_top_k=3)

response = query_engine.query("how is continued disinflation justified in the speech?")
print(response)

پاسخ سوال آخر متن مفصل زیر بود….

تداوم کاهش تورم در سخنرانی به دلایل زیر قابل توجیه است:

1. تورم، همانطور که با شاخص قیمت هزینه های مصرف شخصی (PCE) اندازه گیری می شود، به طور قابل توجهی از اوج 7.2 درصد در ژوئن 2022 کاهش یافته است. برآوردها بر اساس شاخص قیمت مصرف کننده و سایر داده های منتشر شده در هفته گذشته نشان می دهد که قیمت کل PCE 2.3 افزایش یافته است. درصد در 12 ماه منتهی به اکتبر. قیمت‌های اصلی PCE – که دسته‌های مواد غذایی و انرژی فرار را حذف می‌کنند – 2.8 درصد افزایش یافت که نسبت به اوج 5.6 درصدی در فوریه 2022 کاهش یافت.

2. بازار کار در موقعیت خوبی قرار دارد – با عرضه و تقاضای کارگران تقریباً متعادل – به طوری که دیگر منبع فشار تورمی در اقتصاد نیست.

3. فعالیت اقتصادی با سرعتی قوی در حال حرکت است و تولید ناخالص داخلی واقعی (GDP) با نرخ سالانه 2.8 درصد در سه ماهه سوم افزایش یافته است.

4. مصرف‌کنندگان آمریکایی انعطاف‌پذیر باقی می‌مانند، با دستاوردهای گسترده در هزینه‌های خانوار برای کالاها و خدمات. این امر از رشد اقتصادی بیشتر حمایت می کند زیرا مخارج مصرف کننده تقریباً دو سوم تولید ناخالص داخلی را تشکیل می دهد.

5. خدمات مسکن بیشتر مازاد تورم اصلی را نسبت به هدف تشکیل می دهد، و انتظار می رود که تورم خدمات مسکن به تدریج طی دو سال آینده کاهش یابد زیرا کاهش زودتر رشد اجاره بهای مستاجران جدید به نرخ کلی منتهی می شود. .

همانطور که می بینیم، بازیابی مقدار قابل توجهی از زمینه را پوشش می دهد که به سؤال در بازی صحبت می کند.

گره های بازیابی شده در طول ساخت نمودار می توانند حاصل چندین عامل مانند سه قلوها در هر تکه، استخراج کننده های مورد استفاده، طرحواره مشخص شده باشند.
و البته، LLM استفاده می شود. به طور مشابه، صفحه دیگ رتریور در آخرین بلوک کد را می توان با مکانیسم های بازیابی سفارشی جایگزین کرد.
بازیابی برداری با قابلیت خاص بازیابی Cypher که احتمالاً بهتر می تواند با مورد استفاده خاص شما صحبت کند.

بنابراین ما این یادداشت را در حالی به پایان می بریم که مشتاقانه منتظر عبور از لبه های بیشتر در نمودار این میدان در حال تکامل سریع هستیم!

عکس توسط گروتیکا در پاشیدن

اسناد:

  1. https://www.federalreserve.gov/ برای سخنرانی فرماندار کوک در 20 نوامبر 2024 با عنوان چشم انداز اقتصادی.
  2. تصویر از Unsplash

منتشر شده از طریق به سمت هوش مصنوعی



منبع: https://towardsai.net/p/machine-learning/graph-rag-with-property-graphs-a-quick-foray-2

پاسخی بگذارید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *