paint-brush
কীভাবে আপনার নিজের RAG তৈরি করবেন এবং কীভাবে এটি স্থানীয়ভাবে চালাবেন তার একটি টিউটোরিয়াল: ল্যাংচেইন + ওল্লামা + স্ট্রিমলিটদ্বারা@vndee
6,792 পড়া
6,792 পড়া

কীভাবে আপনার নিজের RAG তৈরি করবেন এবং কীভাবে এটি স্থানীয়ভাবে চালাবেন তার একটি টিউটোরিয়াল: ল্যাংচেইন + ওল্লামা + স্ট্রিমলিট

দ্বারা Duy Huynh8m2023/12/15
Read on Terminal Reader

অতিদীর্ঘ; পড়তে

RAG এর সাথে পরিচিত হওয়ার জন্য, আমি এই নিবন্ধগুলি দিয়ে যাওয়ার পরামর্শ দিই। যাইহোক, এই পোস্টটি মৌলিক বিষয়গুলি এড়িয়ে যাবে এবং ডেটা গোপনীয়তা এবং টোকেন খরচ সম্পর্কে কোনও উদ্বেগ ছাড়াই আপনার ল্যাপটপে স্থানীয়ভাবে চালানো যেতে পারে এমন আপনার নিজস্ব RAG অ্যাপ্লিকেশন তৈরিতে সরাসরি আপনাকে গাইড করবে। আমরা এমন একটি অ্যাপ্লিকেশন তৈরি করব যা ChatPDF-এর মতো কিন্তু সহজ। যেখানে ব্যবহারকারীরা একটি পিডিএফ ডকুমেন্ট আপলোড করতে পারে এবং একটি সহজবোধ্য UI এর মাধ্যমে প্রশ্ন জিজ্ঞাসা করতে পারে৷ Langchain, Ollama, এবং Streamlit এর সাথে আমাদের টেক স্ট্যাক খুবই সহজ।
featured image - কীভাবে আপনার নিজের RAG তৈরি করবেন এবং কীভাবে এটি স্থানীয়ভাবে চালাবেন তার একটি টিউটোরিয়াল: ল্যাংচেইন + ওল্লামা + স্ট্রিমলিট
Duy Huynh HackerNoon profile picture

লার্জ ল্যাঙ্গুয়েজ মডেলের উত্থান এবং তাদের চিত্তাকর্ষক ক্ষমতার সাথে, অনেক অভিনব অ্যাপ্লিকেশন ওপেনএআই এবং অ্যানথ্রপিকের মতো বিশাল LLM প্রদানকারীদের উপরে তৈরি করা হচ্ছে। এই ধরনের অ্যাপ্লিকেশনের পিছনে পৌরাণিক কাহিনী হল RAG ফ্রেমওয়ার্ক, যা নিম্নলিখিত নিবন্ধগুলিতে পুঙ্খানুপুঙ্খভাবে ব্যাখ্যা করা হয়েছে:


RAG এর সাথে পরিচিত হওয়ার জন্য, আমি এই নিবন্ধগুলি দিয়ে যাওয়ার পরামর্শ দিই। যাইহোক, এই পোস্টটি মৌলিক বিষয়গুলি এড়িয়ে যাবে এবং ডেটা গোপনীয়তা এবং টোকেন খরচ সম্পর্কে কোনও উদ্বেগ ছাড়াই আপনার ল্যাপটপে স্থানীয়ভাবে চালানো যেতে পারে এমন আপনার নিজস্ব RAG অ্যাপ্লিকেশন তৈরিতে সরাসরি আপনাকে গাইড করবে।


আমরা এমন একটি অ্যাপ্লিকেশন তৈরি করব যা ChatPD F এর মতই কিন্তু সহজ। যেখানে ব্যবহারকারীরা একটি পিডিএফ ডকুমেন্ট আপলোড করতে পারে এবং একটি সহজবোধ্য UI এর মাধ্যমে প্রশ্ন জিজ্ঞাসা করতে পারে৷ Langchain, Ollama, এবং Streamlit এর সাথে আমাদের টেক স্ট্যাক খুবই সহজ।

  • এলএলএম সার্ভার : এই অ্যাপের সবচেয়ে গুরুত্বপূর্ণ উপাদান হল এলএলএম সার্ভার। ধন্যবাদ ওল্লামা , আমাদের কাছে একটি শক্তিশালী LLM সার্ভার রয়েছে যা স্থানীয়ভাবে এমনকি একটি ল্যাপটপেও সেট আপ করা যায়৷ যখন llama.cpp একটি বিকল্প, আমি Go-তে লেখা ওল্লামা খুঁজে পাই, সেট আপ করা এবং চালানো সহজ।


  • RAG : নিঃসন্দেহে, এলএলএম ডোমেনে দুটি নেতৃস্থানীয় লাইব্রেরি ল্যাংচেইন এবং LLamIndex . এই প্রকল্পের জন্য, আমি ল্যাংচেইন ব্যবহার করব কারণ আমার পেশাদার অভিজ্ঞতা থেকে এটির সাথে আমার পরিচিতি রয়েছে। যেকোনো RAG কাঠামোর একটি অপরিহার্য উপাদান হল ভেক্টর স্টোরেজ। আমরা ব্যবহার করা হবে ক্রোমা এখানে, যেহেতু এটি ল্যাংচেইনের সাথে ভালভাবে সংহত করে।


  • চ্যাট UI : ইউজার ইন্টারফেসও একটি গুরুত্বপূর্ণ উপাদান। যদিও অনেক প্রযুক্তি উপলব্ধ আছে, আমি ব্যবহার করতে পছন্দ করি স্ট্রিমলিট , একটি পাইথন লাইব্রেরি, মনের শান্তির জন্য।


ঠিক আছে, এর সেট আপ করা শুরু করা যাক।

ওল্লামা সেটআপ করুন

উপরে উল্লিখিত হিসাবে, ওল্লামা সেট আপ এবং চালানো সোজা। প্রথম, পরিদর্শন করুন ollama.ai এবং আপনার অপারেটিং সিস্টেমের জন্য উপযুক্ত অ্যাপটি ডাউনলোড করুন।


এর পরে, আপনার টার্মিনাল খুলুন, এবং সর্বশেষ টানতে নিম্নলিখিত কমান্ডটি চালান Mistral-7B . যদিও অন্যান্য অনেক আছে এলএলএম মডেল উপলব্ধ , আমি এর কমপ্যাক্ট আকার এবং প্রতিযোগিতামূলক মানের জন্য Mistral-7B বেছে নিই।


 ollama pull mistral


এর পরে, মডেলটি সঠিকভাবে টানা হয়েছে কিনা তা যাচাই করতে ollama list চালান। টার্মিনাল আউটপুট নিম্নলিখিত অনুরূপ হওয়া উচিত:

এখন, যদি LLM সার্ভার ইতিমধ্যেই চালু না হয়, তাহলে ollama serve দিয়ে শুরু করুন। আপনি যদি "Error: listen tcp 127.0.0.1:11434: bind: address already in use" মতো একটি ত্রুটির বার্তার সম্মুখীন হন, তাহলে এটি নির্দেশ করে যে সার্ভারটি ইতিমধ্যেই ডিফল্টরূপে চলছে এবং আপনি পরবর্তী ধাপে যেতে পারেন৷

RAG পাইপলাইন তৈরি করুন

আমাদের প্রক্রিয়ার দ্বিতীয় ধাপ হল RAG পাইপলাইন তৈরি করা। আমাদের আবেদনের সরলতার পরিপ্রেক্ষিতে, আমাদের প্রাথমিকভাবে দুটি পদ্ধতির প্রয়োজন: ingest এবং ask


ingest পদ্ধতিটি একটি ফাইল পাথ গ্রহণ করে এবং এটি দুটি ধাপে ভেক্টর স্টোরেজে লোড করে: প্রথমত, এটি LLM-এর টোকেন সীমা মিটমাট করার জন্য নথিটিকে ছোট খণ্ডে বিভক্ত করে; দ্বিতীয়ত, এটি Qdrant FastEmbeddings ব্যবহার করে এই অংশগুলিকে ভেক্টরাইজ করে এবং ক্রোমাতে সংরক্ষণ করে।


ask পদ্ধতি ব্যবহারকারীর প্রশ্নগুলি পরিচালনা করে। ব্যবহারকারীরা একটি প্রশ্ন উত্থাপন করতে পারে, এবং তারপর RetrievalQAChain ভেক্টর সাদৃশ্য অনুসন্ধান কৌশল ব্যবহার করে প্রাসঙ্গিক প্রসঙ্গ (ডকুমেন্ট খণ্ড) পুনরুদ্ধার করে।


ব্যবহারকারীর প্রশ্ন এবং পুনরুদ্ধার করা প্রসঙ্গে, আমরা একটি প্রম্পট রচনা করতে পারি এবং LLM সার্ভার থেকে একটি পূর্বাভাসের অনুরোধ করতে পারি।

 from langchain.vectorstores import Chroma from langchain.chat_models import ChatOllama from langchain.embeddings import FastEmbedEmbeddings from langchain.schema.output_parser import StrOutputParser from langchain.document_loaders import PyPDFLoader from langchain.text_splitter import RecursiveCharacterTextSplitter from langchain.schema.runnable import RunnablePassthrough from langchain.prompts import PromptTemplate from langchain.vectorstores.utils import filter_complex_metadata class ChatPDF: vector_store = None retriever = None chain = None def __init__(self): self.model = ChatOllama(model="mistral") self.text_splitter = RecursiveCharacterTextSplitter(chunk_size=1024, chunk_overlap=100) self.prompt = PromptTemplate.from_template( """ <s> [INST] You are an assistant for question-answering tasks. Use the following pieces of retrieved context to answer the question. If you don't know the answer, just say that you don't know. Use three sentences maximum and keep the answer concise. [/INST] </s> [INST] Question: {question} Context: {context} Answer: [/INST] """ ) def ingest(self, pdf_file_path: str): docs = PyPDFLoader(file_path=pdf_file_path).load() chunks = self.text_splitter.split_documents(docs) chunks = filter_complex_metadata(chunks) vector_store = Chroma.from_documents(documents=chunks, embedding=FastEmbedEmbeddings()) self.retriever = vector_store.as_retriever( search_type="similarity_score_threshold", search_kwargs={ "k": 3, "score_threshold": 0.5, }, ) self.chain = ({"context": self.retriever, "question": RunnablePassthrough()} | self.prompt | self.model | StrOutputParser()) def ask(self, query: str): if not self.chain: return "Please, add a PDF document first." return self.chain.invoke(query) def clear(self): self.vector_store = None self.retriever = None self.chain = None

প্রম্পটটি ল্যাংচেইন হাব থেকে নেওয়া হয়েছে: মিস্ট্রালের জন্য ল্যাংচেইন RAG প্রম্পট . এই প্রম্পটটি হাজার হাজার বার পরীক্ষিত এবং ডাউনলোড করা হয়েছে, যা এলএলএম প্রম্পটিং কৌশল সম্পর্কে শেখার জন্য একটি নির্ভরযোগ্য সংস্থান হিসেবে কাজ করে।


আপনি এলএলএম প্রম্পটিং কৌশল সম্পর্কে আরও জানতে পারেন এখানে .


বাস্তবায়ন সম্পর্কে আরও বিশদ:


  • ingest : ব্যবহারকারীর দ্বারা আপলোড করা PDF ফাইল লোড করতে আমরা PyPDFLloader ব্যবহার করি। Langchain দ্বারা প্রদত্ত Recursive CharacterSplitter, তারপর এই PDF কে ছোট ছোট খন্ডে বিভক্ত করে। Langchain থেকে filter_complex_metadata ফাংশন ব্যবহার করে ChromaDB দ্বারা সমর্থিত নয় এমন জটিল মেটাডেটা ফিল্টার করা গুরুত্বপূর্ণ।


    ভেক্টর স্টোরেজের জন্য, ক্রোমা ব্যবহার করা হয়, এর সাথে মিলিত Qdrant FastEmbed আমাদের এমবেডিং মডেল হিসাবে। এই লাইটওয়েট মডেলটি 0.5 এবং k=3 এর স্কোর থ্রেশহোল্ড সহ একটি পুনরুদ্ধারকারীতে রূপান্তরিত হয়, যার অর্থ এটি 0.5 এর উপরে সর্বোচ্চ স্কোর সহ শীর্ষ 3টি অংশ প্রদান করে। অবশেষে, আমরা ব্যবহার করে একটি সাধারণ কথোপকথন চেইন তৈরি করি এলইসিএল .


  • ask : এই পদ্ধতিটি ব্যবহারকারীর প্রশ্নকে আমাদের পূর্বনির্ধারিত চেইনে পাস করে এবং তারপর ফলাফল প্রদান করে।


  • clear : এই পদ্ধতিটি একটি নতুন PDF ফাইল আপলোড করার সময় পূর্ববর্তী চ্যাট সেশন এবং স্টোরেজ সাফ করতে ব্যবহৃত হয়।

একটি সাধারণ UI খসড়া

একটি সাধারণ ইউজার ইন্টারফেসের জন্য, আমরা ব্যবহার করব স্ট্রিমলিট , AI/ML অ্যাপ্লিকেশনগুলির দ্রুত প্রোটোটাইপিংয়ের জন্য ডিজাইন করা একটি UI ফ্রেমওয়ার্ক৷

 import os import tempfile import streamlit as st from streamlit_chat import message from rag import ChatPDF st.set_page_config(page_title="ChatPDF") def display_messages(): st.subheader("Chat") for i, (msg, is_user) in enumerate(st.session_state["messages"]): message(msg, is_user=is_user, key=str(i)) st.session_state["thinking_spinner"] = st.empty() def process_input(): if st.session_state["user_input"] and len(st.session_state["user_input"].strip()) > 0: user_text = st.session_state["user_input"].strip() with st.session_state["thinking_spinner"], st.spinner(f"Thinking"): agent_text = st.session_state["assistant"].ask(user_text) st.session_state["messages"].append((user_text, True)) st.session_state["messages"].append((agent_text, False)) def read_and_save_file(): st.session_state["assistant"].clear() st.session_state["messages"] = [] st.session_state["user_input"] = "" for file in st.session_state["file_uploader"]: with tempfile.NamedTemporaryFile(delete=False) as tf: tf.write(file.getbuffer()) file_path = tf.name with st.session_state["ingestion_spinner"], st.spinner(f"Ingesting {file.name}"): st.session_state["assistant"].ingest(file_path) os.remove(file_path) def page(): if len(st.session_state) == 0: st.session_state["messages"] = [] st.session_state["assistant"] = ChatPDF() st.header("ChatPDF") st.subheader("Upload a document") st.file_uploader( "Upload document", type=["pdf"], key="file_uploader", on_change=read_and_save_file, label_visibility="collapsed", accept_multiple_files=True, ) st.session_state["ingestion_spinner"] = st.empty() display_messages() st.text_input("Message", key="user_input", on_change=process_input) if __name__ == "__main__": page()


এটি কেমন দেখাচ্ছে তা দেখতে streamlit run app.py কমান্ড দিয়ে এই কোডটি চালান।

ঠিক আছে, এটা! আমাদের এখন একটি ChatPDF অ্যাপ্লিকেশন রয়েছে যা সম্পূর্ণরূপে আপনার ল্যাপটপে চলে। যেহেতু এই পোস্টটি মূলত কীভাবে আপনার নিজস্ব RAG অ্যাপ্লিকেশন তৈরি করতে হয় তার একটি উচ্চ-স্তরের ওভারভিউ প্রদানের উপর ফোকাস করে, তাই এমন বেশ কয়েকটি দিক রয়েছে যার জন্য সূক্ষ্ম-টিউনিং প্রয়োজন। আপনার অ্যাপটি উন্নত করতে এবং আপনার দক্ষতা আরও বিকাশ করতে আপনি নিম্নলিখিত পরামর্শগুলি বিবেচনা করতে পারেন:


  • কথোপকথন চেইনে মেমরি যোগ করুন : বর্তমানে, এটি কথোপকথনের প্রবাহ মনে রাখে না। অস্থায়ী মেমরি যোগ করা আপনার সহকারীকে প্রসঙ্গ সম্পর্কে সচেতন হতে সাহায্য করবে।


  • একাধিক ফাইল আপলোডের অনুমতি দিন : একবারে একটি নথির বিষয়ে চ্যাট করা ঠিক। কিন্তু কল্পনা করুন যদি আমরা একাধিক নথি সম্পর্কে চ্যাট করতে পারি — আপনি সেখানে আপনার পুরো বুকশেলফ রাখতে পারেন। যে সুপার শান্ত হবে!


  • অন্যান্য এলএলএম মডেল ব্যবহার করুন : মিস্ট্রাল কার্যকর হলেও, অন্যান্য অনেক বিকল্প উপলব্ধ রয়েছে। আপনি এমন একটি মডেল খুঁজে পেতে পারেন যা আপনার প্রয়োজনের সাথে আরও ভালভাবে ফিট করে, যেমন ডেভেলপারদের জন্য LlamaCode। যাইহোক, মনে রাখবেন যে মডেলের পছন্দ আপনার হার্ডওয়্যারের উপর নির্ভর করে, বিশেষ করে আপনার কাছে কতটা RAM আছে 💵


  • RAG পাইপলাইন উন্নত করুন : RAG-এর মধ্যে পরীক্ষা-নিরীক্ষার জায়গা আছে। আপনি পুনরুদ্ধার মেট্রিক, এমবেডিং মডেল,.. পরিবর্তন করতে চাইতে পারেন বা ফলাফল উন্নত করতে পুনরায় র‌্যাঙ্কারের মতো স্তর যুক্ত করতে চাইতে পারেন।


পরিশেষে, পড়ার জন্য আপনাকে ধন্যবাদ. যদি আপনি এই তথ্য দরকারী খুঁজে, আমার সদস্যতা বিবেচনা করুন সাবস্ট্যাক অথবা আমার ব্যক্তিগত ব্লগ . আমি আরএজি এবং এলএলএম অ্যাপ্লিকেশনগুলি সম্পর্কে আরও লেখার পরিকল্পনা করছি, এবং নীচে একটি মন্তব্য রেখে বিষয়গুলির পরামর্শ দেওয়ার জন্য আপনাকে স্বাগত জানাই৷ চিয়ার্স!


সম্পূর্ণ উৎস কোড: https://github.com/vndee/local-rag-example