۲۹ شهریور ۱۴۰۳

Techboy

اخبار و اطلاعات روز تکنولوژی

تولید کاملاً محلی با بازیابی، گام به گام

نحوه پیاده سازی یک سیستم RAG محلی با استفاده از مدل زبان بزرگ LangChain، SQLite-vss، Ollama و Meta’s Llama 2.

نحوه پیاده سازی یک سیستم RAG محلی با استفاده از مدل زبان بزرگ LangChain، SQLite-vss، Ollama و Meta’s Llama 2.

در «نسل تقویت‌شده بازیابی، گام به گام»، یک مثال RAG بسیار ساده را بررسی کردیم. برنامه کوچک ما یک مدل زبان بزرگ (LLM) را با اسناد خودمان تقویت کرد و مدل زبان را قادر ساخت تا به سؤالات مربوط به محتوای خود پاسخ دهد. آن مثال از یک مدل تعبیه‌شده از OpenAI استفاده می‌کرد که به این معنی بود که ما باید محتوای خود را به سرورهای OpenAI ارسال می‌کردیم – یک نقض احتمالی حریم خصوصی داده‌ها، بسته به برنامه. ما همچنین از LLM عمومی OpenAI استفاده کردیم.

این بار با استفاده از یک مدل جاسازی محلی و یک LLM محلی، یک نسخه کاملاً محلی از یک سیستم نسل تقویت‌شده بازیابی خواهیم ساخت. همانطور که در مقاله قبلی، ما از LangChain برای به هم پیوستن اجزای مختلف برنامه خود استفاده می کنیم. به‌جای FAISS (جستجوی شباهت هوش مصنوعی فیس‌بوک)، از SQLite-vss برای ذخیره داده های برداری ما. SQLite-vss دوست آشنای ما SQLite با پسوندی است که آن را قادر به جستجوی شباهت می کند.

به یاد داشته باشید که جستجوی شباهت برای متن با استفاده از جاسازی‌ها، که نمایش‌های عددی کلمات یا عبارات در یک فضای برداری هستند، بهترین تطابق را با معنا (یا معناشناسی) دارد. هرچه فاصله بین دو تعبیه در فضای برداری کمتر باشد، دو کلمه یا عبارت از نظر معنایی نزدیکتر هستند. بنابراین، برای تغذیه اسناد خود به یک LLM، ابتدا باید آنها را به جاسازی تبدیل کنیم، که تنها ماده خامی است که یک LLM می تواند به عنوان ورودی دریافت کند.

ما جاسازی را در فروشگاه برداری محلی ذخیره می کنیم و سپس آن ذخیره بردار را با LLM خود ادغام می کنیم. ما از Llama 2 به عنوان LLM خود استفاده می کنیم، که به صورت محلی با استفاده از برنامه ای به نام Ollama اجرا می کنیم، که در دسترس است macOS، Linux، و Windows (دومی در پیش نمایش). می‌توانید در این مقاله InfoWorld درباره نصب Ollama بخوانید.

Deno تبدیل JSX، پشتیبانی WebAssembly را بهبود می بخشد

در اینجا لیستی از مؤلفه هایی است که برای ساختن یک سیستم RAG ساده و کاملاً محلی به آن نیاز داریم:

  1. یک مجموعه سند. در اینجا ما فقط از یک سند استفاده خواهیم کرد، متن ۷ فوریه ۲۰۲۳ رئیس جمهور بایدن، آدرس ایالت اتحادیه. می توانید این متن را در لینک زیر دانلود کنید.
  2. یک لودر برای سند. این کد متن را از سند استخراج می کند و آن را به تکه هایی برای ایجاد یک جاسازی از قبل پردازش می کند.
  3. یک مدل تعبیه شده. این مدل تکه‌های سند از پیش پردازش‌شده را به‌عنوان ورودی می‌گیرد و یک جاسازی (یعنی مجموعه‌ای از بردارها که تکه‌های سند را نشان می‌دهند) خروجی می‌دهد.
  4. ذخیره محلی داده برداری با نمایه ای برای جستجو.
  5. یک LLM که برای دنبال کردن دستورالعمل‌ها تنظیم شده و روی دستگاه شما اجرا می‌شود. این دستگاه می تواند یک دسکتاپ، یک لپ تاپ یا یک VM در فضای ابری باشد. در مثال من یک مدل Llama 2 است که روی Olama در Mac من اجرا می شود.
  6. الگوی چت برای پرسیدن سوال. این الگو چارچوبی را برای LLM ایجاد می کند تا در قالبی پاسخ دهد که انسان ها آن را درک کنند.

اکنون کد با توضیحات بیشتر در نظرات.

مثال RAG کاملاً محلی—کد بازیابی

# LocalRAG.py
# LangChain is a framework and toolkit for interacting with LLMs programmatically

from langchain.embeddings.sentence_transformer import SentenceTransformerEmbeddings
from langchain.text_splitter import CharacterTextSplitter
from langchain.vectorstores import SQLiteVSS
from langchain.document_loaders import TextLoader

# Load the document using a LangChain text loader
loader = TextLoader("./sotu2023.txt")
documents = loader.load()

# Split the document into chunks
text_splitter = CharacterTextSplitter (chunk_size=1000, chunk_overlap=0)
docs = text_splitter.split_documents(documents)
texts = [doc.page_content for doc in docs]

# Use the sentence transformer package with the all-MiniLM-L6-v2 embedding model
embedding_function = SentenceTransformerEmbeddings(model_name="all-MiniLM-L6-v2")

# Load the text embeddings in SQLiteVSS in a table named state_union
db = SQLiteVSS.from_texts(
    texts = texts,
    embedding = embedding_function,
    table = "state_union",
    db_file = "/tmp/vss.db"
)

# First, we will do a simple retrieval using similarity search
# Query
question = "What did the president say about Nancy Pelosi?"
data = db.similarity_search(question)

# print results
print(data[0].page_content)

مثال RAG کاملاً محلی—خروجی بازیابی

آقای بلندگو. خانم معاون رئیس جمهور بانوی اول و آقای دوم ما.

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

اعضای کنگره و کابینه. رهبران ارتش ما.

آقای رئیس دادگستری، قضات وابسته، و قضات بازنشسته دیوان عالی کشور.

و شما، هموطنان آمریکایی من.

امشب را با تبریک به اعضای کنگره ۱۱۸ و رئیس جدید مجلس، کوین مک کارتی، آغاز می کنم.

آقای سخنران، من مشتاقانه منتظر همکاری با یکدیگر هستم.

من همچنین می‌خواهم به رهبر جدید دموکرات‌های مجلس و اولین رهبر اقلیت کاخ سیاه در تاریخ، حکیم جفریس، تبریک بگویم.

به میچ مک کانل، طولانی ترین رهبر سنا در تاریخ، تبریک می گویم.

و به چاک شومر برای یک دوره دیگر به عنوان رهبر اکثریت سنا، این بار با اکثریت بیشتر، تبریک می گویم.

و من می‌خواهم به کسی که فکر می‌کنم بزرگترین سخنران در تاریخ این کشور به حساب می‌آید، نانسی پلوسی، تجلیل کنم.

توجه داشته باشید که نتیجه شامل یک تکه متن واقعی از سند است که به پرس و جو مرتبط است. این همان چیزی است که با جستجوی شباهت پایگاه داده برداری برگردانده می شود، اما پاسخی به پرس و جو نیست. آخرین خط خروجی پاسخ به پرس و جو است. بقیه خروجی زمینه پاسخ است.

توجه داشته باشید که اگر یک جستجوی تشابه خام در پایگاه داده برداری انجام دهید، تکه هایی از اسناد شما همان چیزی است که به دست خواهید آورد. بسته به سوال شما و اینکه چقدر گسترده یا باریک است، اغلب بیش از یک تکه دریافت خواهید کرد. از آنجایی که سؤال مثال ما نسبتاً محدود بود، و از آنجایی که فقط یک مورد از نانسی پلوسی در متن ذکر شده است، ما فقط یک تکه برگشت دریافت کردیم.

اکنون از LLM برای جذب تکه‌ای از متن که از جستجوی شباهت به دست آمده است استفاده می‌کنیم و یک پاسخ فشرده برای پرس و جو ایجاد می‌کنیم.

قبل از اینکه بتوانید کد زیر را اجرا کنید، اوللاما باید نصب شده و مدل llama2:7b دانلود شود. توجه داشته باشید که در macOS و Linux، Olama مدل را در زیر شاخه .ollama در فهرست اصلی کاربر ذخیره می‌کند.

زبان برنامه نویسی سال را پایتون انتخاب می کند

کد پرس و جو RAG کاملاً محلی

# LLM
from langchain.llms import Ollama
from langchain.callbacks.manager import CallbackManager
from langchain.callbacks.streaming_stdout import StreamingStdOutCallbackHandler
llm = Ollama(
    model = "llama2:7b",
    verbose = True,
    callback_manager = CallbackManager([StreamingStdOutCallbackHandler()]),
)

# QA chain
from langchain.chains import RetrievalQA
from langchain import hub

# LangChain Hub is a repository of LangChain prompts shared by the community
QA_CHAIN_PROMPT = hub.pull("rlm/rag-prompt-llama")
qa_chain = RetrievalQA.from_chain_type(
    llm,
    # we create a retriever to interact with the db using an augmented context
    retriever = db.as_retriever(), 
    chain_type_kwargs = {"prompt": QA_CHAIN_PROMPT},
)

result = qa_chain({"query": question})

مثال RAG کاملاً محلی—خروجی پرس و جو

در زمینه بازیابی شده، رئیس جمهور بایدن از نانسی پلوسی به عنوان 

یاد می کند

“کسی که به نظر من بزرگترین سخنران در تاریخ این کشور محسوب می شود.”

این نشان می‌دهد که رئیس‌جمهور نسبت به مهارت‌ها و دستاوردهای رهبری پلوسی به عنوان رئیس مجلس نظر بالایی دارد.

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

برای استفاده از RAG در برنامه های کاربردی، باید چندین نوع سند مانند PDF، DOCX، RTF، XLSX و PPTX را وارد کنید. هر دو LangChain و LlamaIndex (یکی دیگر از چارچوب‌های محبوب برای ساخت برنامه‌های LLM) دارای لودرهای تخصصی برای انواع مختلفی از اسناد است.

علاوه بر این، ممکن است بخواهید فروشگاه های برداری دیگری را به جز FAISS و SQLite-vss کاوش کنید. مانند مدل های زبان بزرگ و سایر حوزه های هوش مصنوعی مولد، فضای پایگاه داده برداری به سرعت در حال تکامل است. در مقاله‌های آینده در اینجا به گزینه‌های دیگر در همه این جبهه‌ها می‌پردازیم.