RAG ও LLM Serving
- ●RAG (Retrieval-Augmented Generation) প্রথমে relevant ডকুমেন্ট খুঁজে এনে LLM-এর prompt-এ ঢুকিয়ে দেয়, যাতে উত্তর তথ্যভিত্তিক ও আপ-টু-ডেট হয়।
- ●RAG hallucination কমায় এবং মডেল রি-ট্রেইন না করেই নতুন/গোপন ডেটা ব্যবহার করতে দেয়।
- ●LLM serving-এ KV cache, batching, token streaming আর GPU খরচই মূল ইঞ্জিনিয়ারিং চ্যালেঞ্জ।
সমস্যাটা কী?
একটা LLM যেমন GPT বা Claude প্রচুর জ্ঞান নিয়ে ট্রেইন হয়, কিন্তু তার দুটো বড় সীমাবদ্ধতা আছে। প্রথমত, তার জ্ঞান একটা নির্দিষ্ট তারিখে আটকে—training cutoff-এর পরের ঘটনা সে জানে না। দ্বিতীয়ত, সে তোমার কোম্পানির ভেতরের ডকুমেন্ট, ইউজারের অর্ডার হিস্ট্রি, বা গোপন নীতিমালা কিছুই জানে না, কারণ সেগুলো ট্রেনিং ডেটায় ছিল না।
আরও খারাপ—না জানলেও LLM প্রায়ই আত্মবিশ্বাসের সাথে ভুল উত্তর বানিয়ে দেয়, যাকে বলে hallucination। গ্রাহক সহায়তা চ্যাটবটে এটা ভয়ংকর।
সমাধান কী? প্রতিবার নতুন তথ্যের জন্য পুরো মডেল রি-ট্রেইন করা প্রচণ্ড খরচ ও সময়সাপেক্ষ। RAG এই সমস্যার চটপটে সমাধান। আর একবার RAG বানালে সেটাকে দ্রুত ও সস্তায় সার্ভ করা—সেটাই LLM serving-এর চ্যালেঞ্জ।
মূল ধারণা
RAG (Retrieval-Augmented Generation) হলো এমন একটি পদ্ধতি যেখানে LLM-কে উত্তর দেওয়ার আগে একটি knowledge base থেকে প্রশ্ন-সম্পর্কিত প্রাসঙ্গিক তথ্য খুঁজে এনে prompt-এর সাথে যুক্ত করা হয়, যাতে মডেল সেই তথ্যের ভিত্তিতে উত্তর দেয়।
মূল অন্তর্দৃষ্টি: LLM-কে সবকিছু "মনে রাখতে" বাধ্য না করে, আমরা তাকে একটা ওপেন-বুক পরীক্ষার সুযোগ দিই। প্রশ্ন এলে আগে সঠিক "বইয়ের পৃষ্ঠা" বের করে দিই, তারপর LLM সেই পৃষ্ঠা পড়ে উত্তর সাজায়। এতে—
- উত্তর grounded হয়, অর্থাৎ বাস্তব ডকুমেন্টে ভিত্তি করা।
- নতুন তথ্য যোগ করতে শুধু knowledge base আপডেট করলেই হয়, মডেল ছুঁতে হয় না।
- উত্তরের সাথে citation দেওয়া যায়—"এই তথ্য কোন ডকুমেন্ট থেকে এসেছে"।
কীভাবে কাজ করে
RAG পাইপলাইন: ধাপে ধাপে
RAG-এর দুটি অংশ—ইনডেক্সিং (একবার, আগে থেকে) আর retrieval + generation (প্রতি query-তে)।
| ধাপ | কী হয় | কখন |
|---|---|---|
| Chunk | বড় ডকুমেন্টকে ছোট অংশে ভাগ (যেমন ৫০০ token করে) | ইনডেক্সিং |
| Embed | প্রতিটি chunk-কে embedding vector-এ রূপান্তর | ইনডেক্সিং |
| Store | vector + মূল টেক্সট vector DB-তে রাখা | ইনডেক্সিং |
| Retrieve | query embed করে কাছের top-k chunk আনা (ANN) | প্রতি query |
| Prompt | retrieved chunk + ইউজারের প্রশ্ন মিলিয়ে prompt | প্রতি query |
| Generate | LLM সেই prompt পড়ে উত্তর দেয় | প্রতি query |
Chunking কেন দরকার? একটা ১০০ পাতার PDF পুরোটা prompt-এ দেওয়া যায় না (context window সীমিত, খরচও বেশি)। তাই ছোট অর্থপূর্ণ টুকরোয় ভাগ করা হয়, যেন শুধু relevant টুকরোটাই আনা যায়। chunk খুব বড় হলে অপ্রাসঙ্গিক তথ্য ঢোকে, খুব ছোট হলে প্রসঙ্গ হারায়—তাই balance দরকার, প্রায়ই overlap রেখে।
LLM Serving: token, KV cache, batching
LLM শব্দ নিয়ে কাজ করে না, করে Token নিয়ে—শব্দ বা শব্দাংশের ছোট একক (যেমন "খেলছি" ভেঙে কয়েকটা token)। মডেল একবারে একটা করে token জেনারেট করে, প্রতিটি নতুন token আগের সবগুলোর ওপর নির্ভর করে (autoregressive)।
এখানেই KV Cache গুরুত্বপূর্ণ। নতুন প্রতিটি token-এর জন্য attention হিসাব করতে আগের সব token-এর key/value লাগে। প্রতিবার নতুন করে হিসাব করলে ভয়ানক ধীর হতো। তাই আগের token-গুলোর key/value GPU memory-তে cache করে রাখা হয়—শুধু নতুন token-এর অংশটুকু হিসাব হয়। এতে generation নাটকীয়ভাবে দ্রুত হয়, তবে memory খায় বেশি।
Batching: একটা GPU অনেক বড় শক্তিশালী। একজন ইউজারের request চালালে GPU প্রায় খালি বসে থাকে—টাকার অপচয়। তাই একাধিক ইউজারের request একসাথে batch করে চালানো হয়। আধুনিক সার্ভার (যেমন vLLM) continuous batching করে—একটা request শেষ হলেই নতুন ঢুকিয়ে দেয়, GPU কখনো খালি বসে না। এতে throughput কয়েকগুণ বাড়ে।
Streaming: ChatGPT-তে উত্তর একটু একটু করে আসে কেন? কারণ পুরো উত্তর তৈরি হওয়ার অপেক্ষা না করে প্রতিটি token তৈরি হওয়ামাত্র ইউজারকে পাঠানো হয় (server-sent events দিয়ে)। এতে perceived latency কমে—ইউজার দ্রুত প্রতিক্রিয়া দেখে।
RAG হলো ওপেন-বুক পরীক্ষা। LLM ছাত্রটি সব মুখস্থ না রেখে, প্রশ্ন পেয়ে আগে বইয়ের সঠিক পাতা (retrieve) বের করে, তারপর পড়ে উত্তর লেখে। আর KV cache হলো—অঙ্ক করার সময় আগের ধাপের হিসাব খাতার পাশে রেখে দেওয়া, যাতে প্রতি লাইনে শুরু থেকে আবার না কষতে হয়। Batching হলো রিকশায় একজনকে নিয়ে না গিয়ে শেয়ার-রিকশায় কয়েকজনকে একসাথে নেওয়া—জ্বালানি একই, যাত্রী বেশি।
কৌশল
RAG-এর মান বাড়ানোর কিছু কৌশল:
- Hybrid search: শুধু semantic (vector) নয়, keyword search (BM25)-ও মিলিয়ে—তাতে নির্দিষ্ট নাম/কোড ভালো ম্যাচ করে।
- Re-ranking: retrieve করা top-২০ chunk-কে একটা ছোট মডেল দিয়ে আবার সাজিয়ে সেরা ৩-৫টা LLM-কে দেওয়া—precision বাড়ে।
- Prompt engineering: "শুধু নিচের context থেকে উত্তর দাও, না জানলে বলো জানি না"—hallucination ঠেকাতে।
- Quantization (serving): মডেলকে ৪-বিট/৮-বিটে কমপ্রেস করে GPU memory ও খরচ কমানো, সামান্য মানের বিনিময়ে।
কখন ব্যবহার করবে / করবে না
RAG ব্যবহার করবে যখন—তোমার নিজস্ব/গোপন/দ্রুত বদলানো ডেটার ওপর প্রশ্নের উত্তর দরকার (কোম্পানির ডক, প্রোডাক্ট ক্যাটালগ, সাপোর্ট আর্টিকেল), অথবা citation দরকার।
করবে না / যথেষ্ট নয় যখন—কাজটা সাধারণ যুক্তি/সৃজনশীলতা (গল্প লেখা) যেখানে বাইরের তথ্য লাগে না, অথবা যখন আচরণ/স্টাইল গভীরভাবে বদলাতে হবে—সেখানে fine-tuning ভালো। RAG জ্ঞান যোগ করে, আচরণ শেখায় না।
RAG "জাদুর কাঠি" নয়—retrieval খারাপ হলে আউটপুটও খারাপ ("garbage in, garbage out")। ভুল chunk আনলে LLM আত্মবিশ্বাসের সাথে ভুল উত্তর দেবে। তাই retrieval quality (recall) আলাদা করে মাপা ও মনিটর করা জরুরি, শুধু LLM-এর দোষ দিলে চলবে না।
বাস্তব উদাহরণ
- ChatGPT-এর "browse"/file-upload: তুমি PDF আপলোড করলে সেটা chunk + embed হয়, প্রশ্নে relevant অংশ retrieve করে উত্তর দেয়—ক্লাসিক RAG।
- গ্রাহক সাপোর্ট চ্যাটবট: কোম্পানির সাপোর্ট ডক থেকে retrieve করে ইউজারকে সঠিক, citation-সহ উত্তর দেয়।
- Perplexity / GitHub Copilot Chat: ওয়েব বা কোডবেস থেকে relevant টুকরো এনে grounded উত্তর তৈরি করে।
- vLLM / TGI: এই serving ইঞ্জিনগুলো KV cache, continuous batching, streaming দিয়ে প্রোডাকশন-স্কেলে LLM সার্ভ করে।
ইন্টারভিউতে দেখাও তুমি দুটো অংশ আলাদা বোঝো: "RAG-এর মান নির্ভর করে retrieval-এর ওপর—আমি retrieval recall আর end-to-end answer quality আলাদা মাপব। আর serving-এ খরচ কমাতে continuous batching আর KV cache ব্যবহার করব, latency কমাতে streaming।" এই দুই দিকের ট্রেড-অফ (মান বনাম খরচ-গতি) একসাথে বলতে পারলে তুমি আলাদা হয়ে যাবে।
মিনি কুইজ
1. RAG কেন ব্যবহার করা হয়?
2. LLM serving-এ KV cache কী কাজ করে?
3. RAG পাইপলাইনের সঠিক ক্রম কোনটি?