बड़े पैमाने पर प्रोडक्शन RAG: प्रतिदिन 10,000+ लिस्टिंग से सीखे गए सबक
मैंने एक जॉब बोर्ड के लिए एक RAG पाइपलाइन बनाई। यह स्टेजिंग में तो ठीक काम कर रही थी, लेकिन वास्तविक लोड (real load) के दौरान संघर्ष करने लगी। प्रतिदिन हजारों लिस्टिंग को प्रोसेस करने के लिए केवल एक अच्छे वेक्टर स्टोर से कहीं अधिक की आवश्यकता होती है। आपको यह समझना होगा कि सिस्टम कहाँ विफल होता है।
यहाँ चंकिंग (chunking), एम्बेडिंग्स (embeddings), लागत और ऑब्जर्वेबिलिटी (observability) पर मेरे अनुभव और सबक दिए गए हैं।
1. अपनी चंकिंग रणनीति का अंदाज़ा न लगाएं
अधिकांश ट्यूटोरियल चंकिंग को एक साधारण सेटिंग की तरह मानते हैं। प्रोडक्शन में, आपकी रणनीति ही सटीकता और लागत तय करती है।
मैंने जॉब लिस्टिंग के लिए तीन तरीकों का परीक्षण किया:
- Fixed-size chunks: ये विफल रहे। इन्होंने "requirements" और "benefits" जैसे सेक्शन को रैंडम पॉइंट्स पर विभाजित कर दिया। इससे रिट्रीवल (retrieval) में शोर (noise) पैदा होता है।
- Semantic chunking: यह बेहतर था लेकिन असंगत (inconsistent) था। कुछ चंक्स बहुत लंबे थे और कुछ बहुत छोटे।
- Recursive character splitting with overlap: यह सबसे अच्छा काम कर गया। मैंने न्यूलाइन्स (newlines) और वाक्यों के आधार पर विभाजन किया। मैंने 50 टोकन ओवरलैप के साथ 400 टोकन साइज का उपयोग किया। इससे यह सुनिश्चित होता है कि दो चंक्स में फैले हुए वाक्य आपस में जुड़े रहें।
प्रो टिप: चंकिंग से पहले अपने डेटा को नॉर्मलाइज़ (normalize) करें। Greenhouse या Lever जैसे विभिन्न स्रोत अलग-अलग फॉर्मेट में डेटा देते हैं। टेक्स्ट को पहले साफ करें ताकि आपका चंकर एक सुसंगत (consistent) स्ट्रक्चर देख सके।
2. एम्बेडिंग्स: लागत बनाम सटीकता
मैंने OpenAI text-embedding-3-small के मुकाबले Ollama के माध्यम से Llama 3.1 का परीक्षण किया।
लोकल मॉडल मुफ्त था लेकिन "equity compensation" जैसे डोमेन-विशिष्ट शब्दों के साथ संघर्ष कर रहा था। इसने शोर वाले (noisy) परिणाम दिए।
OpenAI की लागत अधिक थी लेकिन इसने सटीक मैच प्रदान किए। मैंने OpenAI को चुना क्योंकि खराब रिट्रीवल के कारण बाद में LLM कॉल्स पर अधिक खर्च होता है।
समय बचाने के लिए, मैं अपनी रिक्वेस्ट को बैच (batch) में भेजता हूँ। मैं एक ही कॉल में 100 तक चंक्स भेजता हूँ। इससे लेटेंसी (latency) कम होती है और पाइपलाइन तेज़ बनी रहती है।
3. वेक्टर स्टोर का ट्रेड-ऑफ (Trade-off)
मैंने प्रोटोटाइपिंग के लिए Pinecone का उपयोग किया क्योंकि इसे सेटअप करना तेज़ है। हालाँकि, बड़े पैमाने पर इसकी लागत बहुत अधिक बढ़ गई।
मैं PostgreSQL के अंदर pgvector पर स्विच कर गया।
- इसे सेटअप करने में अधिक मेहनत लगी।
- इसने भारी मात्रा में पैसे बचाए।
- इसने ट्रांजेक्शनल कंसिस्टेंसी (transactional consistency) प्रदान की।
चूंकि एम्बेडिंग्स उसी डेटाबेस में रहते हैं जिसमें जॉब डेटा होता है, इसलिए आपके पास 'वन सोर्स ऑफ ट्रुथ' (one source of truth) होता है। आपको दो अलग-अलग सिस्टम को सिंक करने की आवश्यकता नहीं होती है।
4. LLM लागत को नियंत्रित करना
हर लिस्टिंग को GPT-4o के साथ स्कोर करना महंगा है। मैंने लागत कम करने के लिए तीन रणनीतियों का उपयोग किया:
- OpenAI Batch API: मैं स्कोरिंग जॉब्स को रात भर में प्रोसेस करता हूँ। इससे भारी छूट मिलती है।
- Caching: मैं बार-बार आने वाले कैंडिडेट प्रोफाइल्स के लिए परिणामों को कैश (cache) कर लेता हूँ।
- Model tiering: मैं "Sales Representative" जैसे सामान्य रोल्स के लिए GPT-4o-mini का उपयोग करता हूँ। मैं GPT-4o का उपयोग केवल उन विशिष्ट (niche) रोल्स के लिए करता हूँ जहाँ सटीकता अत्यंत महत्वपूर्ण है।
5. पहले ऑब्जर्वेबिलिटी (Observability) बनाएँ
मेरी पाइपलाइन एक बार बिना किसी चेतावनी के विफल हो गई थी। खराब डेटा (malformed data) के कारण खाली चंक्स बन गए, जिन्हें सिस्टम ने बिना किसी एरर के छोड़ दिया।
मैंने इसे एक कोरिलेशन आईडी (correlation ID) के साथ स्ट्रक्चर्ड लॉगिंग जोड़कर ठीक किया। इससे मुझे इनजेशन (ingestion) से लेकर स्कोरिंग तक एक लिस्टिंग को ट्रैक करने की सुविधा मिली। अंततः मैं देख सका कि कौन से डेटा सोर्स विफलताओं का कारण बन रहे थे।
सबसे बड़ा सबक: अधिकांश समस्याएँ AI से नहीं, बल्कि अव्यवस्थित (messy) डेटा से आती हैं। पहले अपने डेटा प्लंबिंग (data plumbing) को ठीक करें।
Optional learning community: https://t.me/GyaanSetuAi
