شبکه و فناوری, مقالات

چگونه ChatGPT را به کامپیوترهای شخصی خود بیاوریم؟

How to use GPT4All on a computer with Python

آموزش بکارگیری GPT4All بر روی کامپیوتر شخصی با استفاده از پایتون؛ چگونه ChatGPT را به کامپیوترهای شخصی خود بیاوریم؟ آموزش استفاده از GPT4All موضوعی است که در این مطلب به آن خواهیم پرداخت. احتمالاً این روزها اسم ChatGPT به گوشتان خورده است. چت جی پی تی یک هوش مصنوعی قدرتمند است که می‌توانید به صورت محاوره‌ای با آن گفتگو کنید. ChatGPT با استفاده از منابع موجود در وب و حتی منابعی که دسترسی به آن‌ها در وب فراهم نیست، آموزش دیده و می‌تواند پاسخگوی بسیاری از سؤالات کاربران اینترنت باشد. این چت بات، حتی می‌تواند مسائل پیچیده ریاضی و فیزیک را نیز به شما آموزش دهد، یا درباره یک شکست عاطفی به شما مشاوره دهد! طراحی و اجرای این هوش مصنوعی قدرتمند، به منابع مالی فراوان و سخت افزارهای بسیار قوی نیاز داشته است.

حال فرض کنید که بخواهید یک چت بات روی کامپیوتر یا سرور شخصی خود نصب و اجرا کنید و تنها با استفاده از منابعی که در اختیار دارید، آن را آموزش دهید! در این مطلب قرار است یک چت بات شبیه ChatGPT را روی کامپیوتر شخصی خود نصب و اجرا کنیم، آن را با استفاده از اسنادیی (Documents) که در اختیار داریم آموزش دهیم و در نهایت از آن استفاده کنیم! پس با ما همراه باشید.

GPT4All چیست؟

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

مدلی که ما قرار است از آن استفاده کنیم، در قالب یک فایل ۴ گیگابایتی است که می‌توانید آن را دانلود کرده و در نرم‌افزار متن باز GPT4All از آن استفاده کنید. سازمان‌ها و اشخاص می‌توانند به کمک GPT4All، مدل‌های زبانی یا همان Language Model های خود را طراحی، پیاده‌سازی و تست کنند.

GPT4All چگونه کار می کند؟

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

  • بارگذاری مدل GPT4All
  • استفاده از چارچوب نرم‌افزاری LangChain برای بازیابی و بارگذاری اسناد
  • تقسیم اسناد به قطعات قابل پردازش برای Embedding ها (دگرنمای واژه، یعنی انتقال واژه‌ها به فضای برداری به منظور تجزیه و تحلیل متن).
  • استفاده از کتابخانه FAISS برای ساخت پایگاه داده‌ای از بردارها به وسیله Embedding ها.
  • اجرای جستجوی معنای در پایگاه داده‌ بردارها بر اساس پرسشی که قرار است از GPT4All داشته باشیم. این جستجو، بستر متن سؤالی که قرار است بپرسیم را فراهم می‌کند.
  • فراهم کردن سؤال و بستر متن به GPT4All با استفاده از فریم ورک LangChain

بنابراین، چیزی که ما به آن نیاز داریم، Embeddingها هستند. Embedding در واقع، نمایش عددی قسمتی از اطلاعات (متن، سند، تصویر، صوت و…) است. این نمایش، معنای لغوی کلمه را به در اختیار ما قرار می‌دهد و این دقیقاً همان چیزی است که به آن نیاز داریم. در پروژه پیش‌رو، نمی‌توانیم به مدل‌هایی که نیاز به قدرت پردازشی بالا دارند اتکا داریم، بنابراین مدل Alpaca native را دانلود کردیم و از کتابخانه LlamaCppEmbeddings که فریم ورک Langchain در اختیارمان قرار می‌دهد، استفاده خواهیم کرد.

کدزنی را شروع کنید

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

mkdir GPT4ALL_Fabio
cd GPT4ALL_Fabio

شما می‌توانید به جای Fabio، نام خودتان را بنویسید. قدم بعدی، ساخت محیط مجازی پایتون است. اگر نسخه‌های مختلفی از پایتون را روی سیستم خود نصب داشته باشید، باید نسخه پایتون مورد نظر خود را مشخص کنید. برای مثال ما می‌خواهیم از پایتون نسخه سوم برای ساخت محیط مجازی استفاده کنیم، پس دستور زیر را در خط فرمان تایپ می‌کنیم:

python3 -m venv .

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

در محیط مجازی، شما یک فضای ایزوله شده را در اختیار خواهید داشت که می‌توانید در آن، تنها پکیج‌ها و کتابخانه‌هایی را که برای پروژه موردنظرتان به آن‌ها نیاز دارید، نصب کنید. وجود این فضا کمک می‌کند تا نصب کتابخانه‌های موردنیاز، تأثیری بر فایل‌های مرتبط با پایتون و سایر پروژه‌ها نداشته باشد و عملکرد آن‌ها را با اختلال مواجه نکند. ایجاد فضای مجازی جدید، برای جلوگیری از تداخل‌های احتمالی بین پروژه‌های مختلف، یک ضرورت محسوب می‌شود. پس از ساخته شدن فضای مجازی جدید، آن را با استفاده از دستور زیر، فعال کنید:

source .venv/bin/activate

کتابخانه‌های مورد نیاز در آموزش استفاده از GPT4All

برای این پروژه، به پکیج‌های زیادی نیاز نداریم و تنها لازم است تا پکیج‌های زیر را نصب کنید:

  • پکیج‌های لازم برای فراخوانی کتابخانه‌های GPT4All
  • پکیج Langchain برای به‌کارگیری اسناد

چارچوب نرم‌افزاری LangChain، یک فریم ورک قدرت گرفته از مدل‌های زبانی است که برای توسعه اپلیکیشن‌های مختلف استفاده می‌شود. به کمک LangChain، می‌توانید یک مدل زبانی را از طریق یک رابط برنامه‌نویسی کاربردی (API) فراخوانی کنید و آن مدل زبانی را به سایر منابع داده نیز متصل کنید. این کار اجازه می‌دهد تا مدل زبانی با محیط خود در تعامل باشد.

برای نصب کتابخانه‌های لازم، دستورات زیر را در خط فرمان اجرا کنید:

pip install pygpt4all
pip install langchain==0.0.149
pip install unstructured
pip install pdf2image
pip install pytesseract
pip install pypdf
pip install faiss-cpu

همانطور که می‌بینید، برای نصب LangChain، نسخه آن را نیز ذکر کرده‌ایم. این کتابخانه با بروزرسانی‌های متعددی همراه است، بنابراین برای این که از عملکرد پروژه خود در آینده نزدیک نیز اطمینان حاصل کنیم، بهتر است شماره نسخه‌ای که می‌دانیم به خوبی کار می‌کند را مشخص کنیم. کتابخانه Unstructured، یک وابستگی مورد نیاز برای کتابخانه‌های PDF، pytesseract و pdf2image است.

دانلود مدل‌ها بر روی کامپیوتر شخصی

این مرحله، مرحله مهم و حساسی است. برای پروژه پیش رو، به طور قطع به GPT4All نیاز خواهیم داشت. آموزش استفاده از GPT4All که توسط سازنده‌اش یعنی Nomic AI ارائه شده، بسیار پیچیده و دشوار است. همچنین نیاز به سخت‌افزاری دارد که بیشتر ما از داشتن آن محرومیم. به همین علت، لینک دانلود مدل تبدیل شده و آماده استفاده را برای شما قرار داده‌ایم. کافیست بر روی آن کلیک کرده و فایل مدل را دانلود کنید:

 همانطور که در مقدمه گفتیم، ما به یک مدل برای Embedding ها با قابلیت اجرا روی کامپیوتری که مجهز به یک پردازنده معمولی است، نیاز داریم. برای دانلود یک مدل برای Embedding ها، alpaca native را از لینک زیر دانلود کنید:

چرا به Embedding ها نیاز داریم؟ پس از جمع‌آوری اسنادی که قرار است پایگاه دانش ما باشند، اولین قدم، تبدیل لغات به بردار یا همان Embed کردن است. به کمک کتابخانه LLamaCPP embeddings و با استفاده از مدل Alpaca، می‌توانیم این کار را به بهترین شیوه ممکن انجام دهیم. این مدل، یک مدل نسبتاً کوچک است و حجم آن چهار گیگابایت است. از مدل Alpaca می‌توان برای ساخت پرسش‌های متداول یا همان Q&A نیز استفاده کرد.

پس از اتمام دانلودها، باید این دو مدل را در پوشه models قرار دهیم:

تعامل اولیه با GPT4All

در این بخش از آموزش استفاده از GPT4All یک تعامل ابتدایی با آن خواهیم داشت. از آنجایی که می‌خواهیم تعامل ما با مدل زبانی مدنظرمان به صورت کنترل شده باشد، باید یک فایل پایتون به نام pygpt4all_test.py ایجاد کرده، وابستگی‌ها موردنیاز را در آن وارد کنیم و دستورات لازم را در مدل اعمال کنیم. این کار به سادگی قابل انجام است:

from pygpt4all.models.gpt4all import GPT4All

این کار، امکان استفاده از کتابخانه‌های GPT4All در پایتون را برای ما فراهم می‌کند. حال می‌توان به تعامل با GPT4All پرداخت.

یک تابع می‌نویسیم که بتواند callback دریافتی از مدل را بخواند (کال بک تابعی است که به عنوان آرگومان یک تابع دیگر استفاده می‌شود). سپس از GPT4All می‌خواهیم تا جمله ما را تمام کند.

def new_text_callback(text):
    print(text, end="")

model = GPT4All('./models/gpt4all-converted.bin')
model.generate("Once upon a time, ", n_predict=55, new_text_callback=new_text_callback)

دستور اول، به برنامه، محل ذخیره شده مدل را نشان می‌دهد. دستور دوم نیز از مدل می‌خواهد تا یک پاسخ را برای جمله «Once upon a time» مشخص کند.

برای اجرای برنامه، مطمئن شوید که محیط مجازی که قبلاً ساخته‌اید، هنوز فعال است. سپس برنامه را با استفاده از دستور زیر اجرا کنید:

python3 pygpt4all_test.py

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

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

قالب LangChain در GPT4All

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

در این قسمت، قصد داریم یک قالب Prompt یا به عبارتی، Prompt Template را ایجاد کنیم. متنی که مدل‌های زبانی به عنوان ورودی دریافت می‌کنند، اغلب با نام Prompt یاد می‌شود. این ورودی، حتماً یک رشته ثابت نیست، بلکه می‌تواند ترکیبی از قالب، مثال‌ها و متن نوشته شده توسط کاربر باشد. LangChain، کلاس‌ها و توابع زیادی را در اختیار دارد که کار با Prompt را بسیار ساده می‌کند. در ادامه آموزش استفاده از GPT4All، تعدادی از این کلاس‌ها و توابع را به‌کار خواهیم گرفت.

یک فایل با نام my_langchain.py ایجاد می‌کنیم.

# Import of langchain Prompt Template and Chain
from langchain import PromptTemplate, LLMChain
# Import llm to be able to interact with GPT4All directly from langchain
from langchain.llms import GPT4All
# Callbacks manager is required for the response handling
from langchain.callbacks.base import CallbackManager
from langchain.callbacks.streaming_stdout import StreamingStdOutCallbackHandler

local_path = './models/gpt4all-converted.bin'
callback_manager = CallbackManager([StreamingStdOutCallbackHandler()])

کتابخانه‌های Prompt Template، LLMChain را وارد برنامه کردیم تا بتوانیم به صورت مستقیم با مدل مولد تبدیل‌کننده قبلاً آموزش دیده (GPT Model) خود تعامل برقرار کنیم.

سپس، مسیر مدل‌ها را مشخص کرده و نمونه‌ای از مدیریت‌کننده‌های Callback را می‌سازیم تا به وسیله آن قادر به انتخاب پاسخ مناسب برای پرس‌وجوی خود باشیم.

ساخت یک قالب، واقعاً آسان است:

template = """Question: {question}

Answer: Let's think step by step on it.

"""
prompt = PromptTemplate(template=template, input_variables=["question"])

متغیر template، یک رشته چند خطی است که حاوی ساختار تعامل ما با مدل است. در میان براکت‌ها، متغیر خارجی را درون قالب خود قرار می‌دهیم، که در این جا همان سؤال موردنظرمان است.

از آنجایی که می‌توانید تصمیم بگیرید متغیر شما یک رشته ثابت باشد یا متن ورودی نوشته شده توسط کاربر باشد، دو مثال را پیش‌روی شما قرار داده‌ایم.

# Hardcoded question
question = "What Formula 1 pilot won the championship in the year Leonardo di Caprio was born?"

# User input question...
question = input("Enter your question: ")

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

template = """Question: {question}

Answer: Let's think step by step on it.

"""
prompt = PromptTemplate(template=template, input_variables=["question"])
# initialize the GPT4All instance
llm = GPT4All(model=local_path, callback_manager=callback_manager, verbose=True)
# link the language model with our prompt template
llm_chain = LLMChain(prompt=prompt, llm=llm)

# Hardcoded question
question = "What Formula 1 pilot won the championship in the year Leonardo di Caprio was born?"

# User imput question...
# question = input("Enter your question: ")

#Run the query and get the results
llm_chain.run(question)

حتماً به یاد داشته باشید تا فعال بودن محیط مجازی خود را بررسی کنید و سپس برنامه را اجرا کنید:

python3 my_langchain.py

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

پاسخ به سؤالاتی درباره اسناد خودتان با استفاده از LangChain و GPT4All

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

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

ساخت پایگاه داده‌ای از بردارها

در این قسمت از آموزش استفاده از GPT4All ابتدا یک فایل پایتون جدید ایجاد کرده و نام آن را my_knowledge_qna.py می‌گذاریم.

from langchain import PromptTemplate, LLMChain
from langchain.llms import GPT4All
from langchain.callbacks.base import CallbackManager
from langchain.callbacks.streaming_stdout import StreamingStdOutCallbackHandler
# function for loading only TXT files
from langchain.document_loaders import TextLoader
# text splitter for create chunks
from langchain.text_splitter import RecursiveCharacterTextSplitter
# to be able to load the pdf files
from langchain.document_loaders import UnstructuredPDFLoader
from langchain.document_loaders import PyPDFLoader
from langchain.document_loaders import DirectoryLoader
# Vector Store Index to create our database about our knowledge
from langchain.indexes import VectorstoreIndexCreator
# LLamaCpp embeddings from the Alpaca model
from langchain.embeddings import LlamaCppEmbeddings
# FAISS  library for similaarity search
from langchain.vectorstores.faiss import FAISS
import os  #for interaaction with the files
import datetime

در این قسمت، کتابخانه‌هایی که قبلاً هم از آن‌ها استفاده کرده بودیم را مشاهده می‌کنید. علاوه بر آن‌ها، از LangChain برای ساخت بردار استفاده می‌شود تا با استفاده از آن‌ها بتوانیم با مدل Alpaca تعامل کنیم. این کار با استفاده از کتابخانه LlamaCppEmbeddings انجام می‌شود. مدل Alpaca نیز به صورت ۴ بیتی کوانتیزه شده و به همراه کتابخانه سی‌پلاس‌پلاس، کامپایل می‌شود.

یک مسیر مربوط به Embedding ها و مسیری برای ساخت متن را نیز در مدل زبانی بزرگ خود بارگذاری می‌کنیم.

# assign the path for the 2 models GPT4All and Alpaca for the embeddings
gpt4all_path = './models/gpt4all-converted.bin'
llama_path = './models/ggml-model-q4_0.bin'
# Calback manager for handling the calls with  the model
callback_manager = CallbackManager([StreamingStdOutCallbackHandler()])

# create the embedding object
embeddings = LlamaCppEmbeddings(model_path=llama_path)
# create the GPT4All llm object
llm = GPT4All(model=gpt4all_path, callback_manager=callback_manager, verbose=True)

در این قسمت از آموزش استفاده از GPT4All می‌بینیم که آیا قادر به خواندن تمامی پی‌دی‌اف‌ها هستیم یا نه. در قدم اول، سه تابع را تعریف می‌کنیم که هر کدام از آن‌ها قرار است در هر سند به کار گرفته شود. اولین تابع برای تقسیم‌بندی متن استخراج شده از سند، به قسمت‌های قابل تجزیه و تحلیل است. دومین تابع برای ساخت برداری شامل فراداده‌هایی (متادیتا یا همان Metadata) از قبیل شماره صفحه و… به کار گرفته می‌شود. تابع سوم نیز برای آزمایش جستجوی شباهت به کار گرفته خواهد شد.

# Split text
def split_chunks(sources):
    chunks = []
    splitter = RecursiveCharacterTextSplitter(chunk_size=256, chunk_overlap=32)
    for chunk in splitter.split_documents(sources):
        chunks.append(chunk)
    return chunks


def create_index(chunks):
    texts = [doc.page_content for doc in chunks]
    metadatas = [doc.metadata for doc in chunks]

    search_index = FAISS.from_texts(texts, embeddings, metadatas=metadatas)

    return search_index


def similarity_search(query, index):
    # k is the number of similarity searched that matches the query
    # default is 4
    matched_docs = index.similarity_search(query, k=3)
    sources = []
    for doc in matched_docs:
        sources.append(
            {
                "page_content": doc.page_content,
                "metadata": doc.metadata,
            }
        )

    return matched_docs, sources

حالا، تولید شاخص‌ها برای اسناد موجود در پوشه docs را آزمایش می‌کنیم. باید تمامی فایل‌های پی‌دی‌اف را در این پوشه قرار دهیم. در LangChain، متودی برای بارگذاری تمامی فایل‌های موجود در یک پوشه وجود دارد (فارغ از نوع فایل‌ها). توابع خود را بر روی اولین سند،‌اعمال می‌کنیم.

# get the list of pdf files from the docs directory into a list  format
pdf_folder_path = './docs'
doc_list = [s for s in os.listdir(pdf_folder_path) if s.endswith('.pdf')]
num_of_docs = len(doc_list)
# create a loader for the PDFs from the path
loader = PyPDFLoader(os.path.join(pdf_folder_path, doc_list[0]))
# load the documents with Langchain
docs = loader.load()
# Split in chunks
chunks = split_chunks(docs)
# create the db vector index
db0 = create_index(chunks)

در خط اول، از کتابخانه docs برای فراهم آوردن لیست فایل‌های پی‌دی‌اف موجود در پوشه استفاده می‌کنیم. سپس با استفاده از LangChain، اولین سند موجود در پوشه را بارگذاری می‌کنیم و سپس آن را به Chunkها (قسمت‌های قابل تجزیه) تقسیم می‌کنیم. حال بردار مربوط به این سند را با استفاده از Embeddingهای Llama، می‌سازیم.

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

می‌توانیم فایل پایتون را از طریق خط فرمان و دستور زیر، اجرا کنیم:

python3 my_knowledge_qna.py

پس از اجرای مدل مربوط به Embeddingها، فرآیند توکنیزه شدن (Tokenize) را مشاهده خواهید کرد. این کار ممکن است چند دقیقه طول بکشد. از آنجایی که ما داریم این پروژه را روی یک کامپیوتر معمولی اجرا می‌کنیم، طول کشیدن چند دقیقه‌ای این فرآیند، امری طبیعی است.

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

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

# merge dbi with the existing db0
db0.merge_from(dbi)

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

# Save the databasae locally
db0.save_local("my_faiss_index")

کد کامل شده را می‌توانید در زیر مشاهده کنید. البته در زمان کار با GPT4All، قسمت زیادی از آن، کامنت خواهد شد.

# get the list of pdf files from the docs directory into a list  format
pdf_folder_path = './docs'
doc_list = [s for s in os.listdir(pdf_folder_path) if s.endswith('.pdf')]
num_of_docs = len(doc_list)
# create a loader for the PDFs from the path
general_start = datetime.datetime.now() #not used now but useful
print("starting the loop...")
loop_start = datetime.datetime.now() #not used now but useful
print("generating fist vector database and then iterate with .merge_from")
loader = PyPDFLoader(os.path.join(pdf_folder_path, doc_list[0]))
docs = loader.load()
chunks = split_chunks(docs)
db0 = create_index(chunks)
print("Main Vector database created. Start iteration and merging...")
for i in range(1,num_of_docs):
    print(doc_list[i])
    print(f"loop position {i}")
    loader = PyPDFLoader(os.path.join(pdf_folder_path, doc_list[i]))
    start = datetime.datetime.now() #not used now but useful
    docs = loader.load()
    chunks = split_chunks(docs)
    dbi = create_index(chunks)
    print("start merging with db0...")
    db0.merge_from(dbi)
    end = datetime.datetime.now() #not used now but useful
    elapsed = end - start #not used now but useful
    #total time
    print(f"completed in {elapsed}")
    print("-----------------------------------")
loop_end = datetime.datetime.now() #not used now but useful
loop_elapsed = loop_end - loop_start #not used now but useful
print(f"All documents processed in {loop_elapsed}")
print(f"the daatabase is done with {num_of_docs} subset of db index")
print("-----------------------------------")
print(f"Merging completed")
print("-----------------------------------")
print("Saving Merged Database Locally")
# Save the databasae locally
db0.save_local("my_faiss_index")
print("-----------------------------------")
print("merged database saved as my_faiss_index")
general_end = datetime.datetime.now() #not used now but useful
general_elapsed = general_end - general_start #not used now but useful
print(f"All indexing completed in {general_elapsed}")
print("-----------------------------------")

آموزش استفاده از GPT4All و پرسیدن سؤال از آن

در این قسمت از آموزش استفاده از GPT4All، می‌توانیم به تعامل با این هوش مصنوعی بپردازیم. ابتدا با یک رشته ثابت، کار خود را آغاز می‌کنیم.

کد زیر را در فایل db_loading.py قرار داده و آن را اجرا کنید.

from langchain import PromptTemplate, LLMChain
from langchain.llms import GPT4All
from langchain.callbacks.base import CallbackManager
from langchain.callbacks.streaming_stdout import StreamingStdOutCallbackHandler
# function for loading only TXT files
from langchain.document_loaders import TextLoader
# text splitter for create chunks
from langchain.text_splitter import RecursiveCharacterTextSplitter
# to be able to load the pdf files
from langchain.document_loaders import UnstructuredPDFLoader
from langchain.document_loaders import PyPDFLoader
from langchain.document_loaders import DirectoryLoader
# Vector Store Index to create our database about our knowledge
from langchain.indexes import VectorstoreIndexCreator
# LLamaCpp embeddings from the Alpaca model
from langchain.embeddings import LlamaCppEmbeddings
# FAISS  library for similaarity search
from langchain.vectorstores.faiss import FAISS
import os  #for interaaction with the files
import datetime

# TEST FOR SIMILARITY SEARCH

# assign the path for the 2 models GPT4All and Alpaca for the embeddings
gpt4all_path = './models/gpt4all-converted.bin'
llama_path = './models/ggml-model-q4_0.bin'
# Calback manager for handling the calls with  the model
callback_manager = CallbackManager([StreamingStdOutCallbackHandler()])

# create the embedding object
embeddings = LlamaCppEmbeddings(model_path=llama_path)
# create the GPT4All llm object
llm = GPT4All(model=gpt4all_path, callback_manager=callback_manager, verbose=True)

# Split text
def split_chunks(sources):
    chunks = []
    splitter = RecursiveCharacterTextSplitter(chunk_size=256, chunk_overlap=32)
    for chunk in splitter.split_documents(sources):
        chunks.append(chunk)
    return chunks


def create_index(chunks):
    texts = [doc.page_content for doc in chunks]
    metadatas = [doc.metadata for doc in chunks]

    search_index = FAISS.from_texts(texts, embeddings, metadatas=metadatas)

    return search_index


def similarity_search(query, index):
    # k is the number of similarity searched that matches the query
    # default is 4
    matched_docs = index.similarity_search(query, k=3)
    sources = []
    for doc in matched_docs:
        sources.append(
            {
                "page_content": doc.page_content,
                "metadata": doc.metadata,
            }
        )

    return matched_docs, sources

# Load our local index vector db
index = FAISS.load_local("my_faiss_index", embeddings)
# Hardcoded question
query = "What is a PLC and what is the difference with a PC"
docs = index.similarity_search(query)
# Get the matches best 3 results - defined in the function k=3
print(f"The question is: {query}")
print("Here the result of the semantic search on the index, without GPT4All..")
print(docs[0])

متن چاپ شده، لیستی از ۳ منبع متناسب با پرس‌وجوی ما است. نام سند و شماره صفحه نیز ذکر شده است.

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

# Load our local index vector db
index = FAISS.load_local("my_faiss_index", embeddings)

# create the prompt template
template = """
Please use the following context to answer questions.
Context: {context}
---
Question: {question}
Answer: Let's think step by step."""

# Hardcoded question
question = "What is a PLC and what is the difference with a PC"
matched_docs, sources = similarity_search(question, index)
# Creating the context
context = "\n".join([doc.page_content for doc in matched_docs])
# instantiating the prompt template and the GPT4All chain
prompt = PromptTemplate(template=template, input_variables=["context", "question"]).partial(context=context)
llm_chain = LLMChain(prompt=prompt, llm=llm)
# Print the result
print(llm_chain.run(question))

نتیجه کدهای نوشته شده در آموزش استفاده از GPT4All شبیه زیر خواهد بود:

Please use the following context to answer questions.
Context: 1.What is a PLC
2.Where and Why it is used
3.How a PLC is different from a PC
PLC is especially important in industries where safety and reliability are
critical, such as manufacturing plants, chemical plants, and power plants.
How a PLC is different from a PC
Because a PLC is a specialized computer used in industrial and
manufacturing applications to control machinery and processes.,the
hardware components of a typical PLC must be able to interact with
industrial device. So a typical PLC hardware include:
---
Question: What is a PLC and what is the difference with a PC
Answer: Let's think step by step. 1) A Programmable Logic Controller (PLC),
also called Industrial Control System or ICS, refers to an industrial computer
that controls various automated processes such as manufacturing
machines/assembly lines etcetera through sensors and actuators connected
with it via inputs & outputs. It is a form of digital computers which has
the ability for multiple instruction execution (MIE), built-in memory
registers used by software routines, Input Output interface cards(IOC)
to communicate with other devices electronically/digitally over networks
or buses etcetera
2). A Programmable Logic Controller is widely utilized in industrial
automation as it has the ability for more than one instruction execution.
It can perform tasks automatically and programmed instructions, which allows
it to carry out complex operations that are beyond a
Personal Computer (PC) capacity. So an ICS/PLC contains built-in memory
registers used by software routines or firmware codes etcetera but
PC doesn't contain them so they need external interfaces such as
hard disks drives(HDD), USB ports, serial and parallel
communication protocols to store data for further analysis or
report generation.

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

question = "What is a PLC and what is the difference with a PC"

با چیزی شبیه زیر جایگزین کنید:

question = input("Your question: ")

کلام پایانی

در این مطلب به آموزش استفاده از GPT4All پرداختیم. می‌توانید با استفاده از پروژه‌ای که خلق کرده‌اید، سؤالات مختلفی را درباره موضوعات موجود در سندهایتان، مطرح کنید و خود و پروژه‌تان را به چالش بکشید.

منبع: artificialcorner.com