LLM और पुनर्प्राप्ति पाइपलाइनों के लिए PDF तैयार करना
अंतिम समीक्षा
भाषा मॉडल को PDF खिलाना — पुनर्प्राप्ति-संवर्धित उत्पादन के लिए, सारांश के लिए, या केवल किसी लंबी संदर्भ खिड़की में चिपकाने के लिए — आज दस्तावेज़ बदलने के सबसे आम कारणों में से एक है।
यही वह उपयोग भी है जहाँ रूपांतरण की गुणवत्ता सबसे अधिक मायने रखती है और सबसे कम दिखती है, क्योंकि पुनर्प्राप्ति पाइपलाइन चुपचाप विफल होती है। खराब बदला गया दस्तावेज़ कोई त्रुटि नहीं फेंकता। वह बस गलत अंश लौटा देता है, या ऐसा अंश जिसकी तालिका बिगड़ चुकी है, और मॉडल उसी के आधार पर आत्मविश्वास से उत्तर दे देता है।
9 मिनट का पाठ
केवल कच्चा पाठ क्यों न निकालें
कोई भी PDF लाइब्रेरी दो पंक्तियों के कोड में दस्तावेज़ का पाठ दे देगी, और एकल-स्तंभ ज्ञापन के लिए वह सचमुच पर्याप्त है। बाकी किसी भी चीज़ के लिए नहीं, और इसके तीन कारण हैं जो सभी पुनर्प्राप्ति की गुणवत्ता खाते हैं।
पहला, पढ़ने का क्रम। कच्चा निष्कर्षण पाठ उसी क्रम में लौटाता है जिसमें अक्षर-चिह्न बनाए गए थे, जो दो-स्तंभ वाले पृष्ठ पर स्तंभों को गूँथ देता है। आपके आधे chunk असंबद्ध अनुच्छेदों के बीच बदलते वाक्यांश बन जाते हैं, और वे सदिश समष्टि में ऐसे बिंदु पर embed होते हैं जो किसी चीज़ से मेल नहीं खाता।
दूसरा, सीमाएँ। शीर्षकों के बिना अक्षर-गणना के अलावा बाँटने को कुछ नहीं होता, इसलिए chunk वाक्य के बीच और तालिका के बीच टूटते हैं, और जो chunk किसी व्याख्या के बीच से शुरू होता है वह अपने आप में समझ में नहीं आता — जबकि पुनर्प्राप्त chunk को यही करना होता है।
तीसरा, तालिकाएँ। कच्चे पाठ के रूप में निकाली गई तालिका संख्याओं की धारा बन जाती है, बिना किसी संकेत के कि कौन-सी संख्या किस स्तंभ से आई। उसे पढ़ने वाला मॉडल आपके प्रश्न का उत्तर फिर भी देगा। बस वह उत्तर गलत होगा।
Markdown पाइपलाइन को क्या देता है
यहाँ Markdown अच्छा मध्यवर्ती प्रारूप है, और इसके कारणों का उसके सुंदर होने से कोई लेना-देना नहीं।
- शीर्षक आपको अर्थपूर्ण chunk सीमाएँ देते हैं, जिससे chunk एक खंड बनता है, हज़ार अक्षरों की खिड़की नहीं।
- शीर्षक-पथ हर chunk को उसका संदर्भ देता है — embed करने से पहले आप "अध्याय 3 › दर सीमाएँ › बर्स्ट व्यवहार" जोड़ सकते हैं, जो उन दस्तावेज़ों में पुनर्प्राप्ति को मापने योग्य ढंग से बेहतर करता है जहाँ एक ही शब्द अलग-अलग खंडों में अलग अर्थ रखता है।
- Pipe तालिकाएँ पंक्तियों और स्तंभों को जोड़े रखती हैं, जिससे पुनर्प्राप्त तालिका पढ़ने वाला मॉडल बता सकता है कि कौन-सा आँकड़ा किस शीर्ष का है।
- यह संक्षिप्त है। Markdown प्रति तत्व कुछ अक्षरों की कीमत पर संरचना ढोता है, जबकि HTML या JSON विन्यास प्रारूप ऐसे मार्कअप पर token खर्च करते हैं जो मॉडल को कुछ नहीं बताता।
- यह ऐसा प्रारूप है जिसे हर मौजूदा मॉडल ने प्रशिक्षण में बहुत भारी मात्रा में देखा है, इसलिए prompt में इसकी व्याख्या नहीं करनी पड़ती।
Chunking, ठोस रूप में
बदले हुए दस्तावेज़ों पर जो तरीका चलता है वह यह है: पहले शीर्षकों पर बाँटिए, और आकार की सीमा पर तभी लौटिए जब कोई खंड बहुत बड़ा हो।
मोटे मान जो अधिकांश दस्तावेज़ प्रकारों पर टिकते हैं:
| प्राथमिक विभाजन | H2 पर, लंबे खंडों में H3 पर |
|---|---|
| लक्ष्य chunk आकार | 500–1,000 token |
| कठोर अधिकतम | जितना संदर्भ में कई chunk के लिए जगह छोड़े |
| ओवरलैप | 1–2 वाक्य, या शीर्षक-सीमित chunk हों तो कुछ नहीं |
| Chunk उपसर्ग | दस्तावेज़ शीर्षक और पूरा शीर्षक-पथ |
| तालिकाएँ | कभी न बाँटें — पूरी रखें, भले आकार से बड़ी हों |
तालिका कभी मत बाँटिए
यही वह नियम है जिसे अधिकांश पाइपलाइनें तोड़ती हैं, क्योंकि सीधा-सादा विभाजक जानता ही नहीं कि वह किसी तालिका के भीतर है।
बीच से बँटी GFM तालिका दो chunk देती है, और दोनों में से कोई मान्य तालिका नहीं है: पहले में शीर्ष और कुछ पंक्तियाँ हैं, दूसरे में बिना किसी शीर्ष के पंक्तियाँ। दूसरा बेकार से भी बुरा है, क्योंकि उसकी संख्याओं पर कोई लेबल नहीं है और मॉडल अनुमान से लेबल लगा देगा।
बाँटने से पहले तालिका खंड पहचानिए और हर एक को अखंड रखिए, भले उससे chunk लक्ष्य आकार से बड़ा हो जाए। यदि कोई तालिका सचमुच एक chunk के लिए बहुत बड़ी है, तो हर टुकड़े में शीर्ष पंक्ति दोहराइए।
स्कैन किए दस्तावेज़ कहाँ बैठते हैं
स्कैन में पाठ है ही नहीं, इसलिए बाँटने को कुछ नहीं। पाठ पहचान पहले होनी चाहिए — और उसके परिणाम के ऐसे गुण हैं जिनका हिसाब पाइपलाइन को रखना पड़ता है, क्योंकि पहचान प्रतिलिपि नहीं, अनुमान है।
दो बातें ख़ास तौर पर। विश्वास पृष्ठ दर पृष्ठ बदलता है, इसलिए दस्तावेज़ चालीस पृष्ठों तक लगभग निर्दोष और तीन पृष्ठों पर अविश्वसनीय हो सकता है; यदि आपका पहचान चरण प्रति पृष्ठ विश्वास बताता है, तो उसे chunk के मेटाडेटा में ले जाइए ताकि कम विश्वास वाला उत्तर चिह्नित किया जा सके। और जो शब्द पढ़े नहीं जाते वे चिह्नित होने के बजाय गिरा दिए जाते हैं, यानी पाठ प्रवाहमय और पूर्ण दिखता है जबकि उसमें ठीक वही चीज़ें नहीं होतीं जो इंजन को सबसे कठिन लगीं — अक्सर नाम, संदर्भ कोड और आँकड़े।
जहाँ गलती के परिणाम होते हों, वहाँ पहचाने गए पाठ को मूल से मिलाकर जाँचने लायक सुराग मानना चाहिए, अभिलेख का स्रोत नहीं।
कोष अनुक्रमित करने से पहले क्या जाँचें
अनुक्रमण महँगा, धीमा और मुश्किल से पलटने वाला चरण है, इसलिए पहले किसी नमूने पर बीस मिनट लगाना उचित है। आपस में अलग-अलग चुने गए पाँच दस्तावेज़ बदलिए और Markdown पढ़िए।
- क्या शीर्षक कोई समझदार सीढ़ी बनाते हैं? यदि वे सपाट हैं, तो आपके विभाजक के पास बाँटने को कुछ नहीं है और आप पूरे कोष में निश्चित आकार की खिड़कियों पर लौट आएँगे।
- क्या तालिकाएँ बचीं? दो-तीन में स्तंभ मूल के सामने गिनिए।
- बहु-स्तंभ पृष्ठों पर पढ़ने का क्रम सही है? गुँथे हुए स्तंभ देखते ही स्पष्ट होते हैं और अनुक्रमित हो जाने पर अदृश्य।
- क्या कोई खाली या लगभग खाली रूपांतरण हैं? वे स्कैन हैं, और उनके लिए अलग रास्ता चाहिए।
- क्या हर दस्तावेज़ में वही बनी-बनाई सामग्री दोहराई गई है? दोहराए गए हेडर और फ़ुटर लगभग एक जैसे chunk बन जाते हैं जो परिणामों में असली सामग्री को पीछे धकेल देते हैं।
गोपनीयता का पहलू, जो गौण नहीं है
RAG के कोष ठीक उन्हीं दस्तावेज़ों से बनते हैं जिन्हें संस्थाएँ किसी तीसरे पक्ष को सौंपने में सबसे कम इच्छुक होती हैं: अनुबंध, आंतरिक रिपोर्टें, ग्राहक अभिलेख, अब तक अप्रकाशित शोध।
यह सोच-समझकर तय करना उचित है कि आपकी पाइपलाइन के कौन-से चरण उन दस्तावेज़ों को कहीं भेजते हैं। रूपांतरण को उनमें से एक होना ज़रूरी नहीं है: ब्राउज़र-आधारित कनवर्टर फ़ाइल को उसी मशीन पर संसाधित करता है जहाँ वह पहले से है, इसलिए रूपांतरण चरण शृंखला में कोई नया पक्ष नहीं जोड़ता। आगे के चरण जोड़ते हैं या नहीं, यह अलग निर्णय है — पर वह निर्णय आप अलग से ले सकते हैं।