𝗜 𝗕𝘂𝗶𝗹𝘁 𝗥𝗔𝗚 𝗙𝗿𝗼𝗺 𝗦𝗰𝗿𝗮𝘁𝗰𝗵 𝗶𝗻 𝗣𝘆𝘁𝗵𝗼𝗻 𝘁𝗼 𝗨𝗻𝗱𝗲𝗿𝘀𝘁𝗮𝗻𝗱 𝗜𝘁
ആറ് മാസത്തോളം ഞാൻ പ്രൊഡക്ഷനിൽ LangChain ഉപയോഗിച്ചിരുന്നു. അത് എങ്ങനെയാണ് പ്രവർത്തിക്കുന്നതെന്ന് എനിക്ക് വിശദീകരിക്കാൻ കഴിഞ്ഞില്ല. ഞാൻ എന്തുകൊണ്ടാണ് പ്രത്യേക മെട്രിക്സുകൾ തിരഞ്ഞെടുത്തത് എന്നോ അല്ലെങ്കിൽ ടെക്സ്റ്റ് എങ്ങനെയാണ് വെക്റ്ററുകളായി (vectors) മാറിയതെന്നോ എനിക്ക് അറിയില്ലായിരുന്നു. ആ ലൈബ്രറി അതിന്റെ ലോജിക് മറച്ചുവെച്ചിരുന്നു.
ഇത് പരിഹരിക്കാനായി, ഞാൻ ആ ഫ്രെയിംവർക്ക് ഒഴിവാക്കി. വെറും 500 വരി പൈത്തൺ (Python) ഉപയോഗിച്ച് ഞാൻ പൂജ്യത്തിൽ നിന്ന് ഒരു RAG പൈപ്പ്ലൈൻ എഴുതി.
ഈ സ്റ്റാക്ക് (stack) നേരിട്ട് നിർമ്മിച്ചപ്പോൾ ഞാൻ പഠിച്ച കാര്യങ്ങൾ ഇതാ.
ബ്ലാക്ക് ബോക്സുകളുമായുള്ള പ്രശ്നം
നിങ്ങൾ ഹൈ-ലെവൽ ലൈബ്രറികൾ ഉപയോഗിക്കുമ്പോൾ, നിങ്ങൾക്ക് നിയന്ത്രണം നഷ്ടപ്പെടുന്നു. മോഡലുകൾ തെറ്റായ വിവരങ്ങൾ നൽകുന്നതോ (hallucinate) തെറ്റായ സൈറ്റേഷനുകൾ നൽകുന്നതോ ഞാൻ കണ്ടു. പിശക് ചങ്കറിലാണോ (chunker), എംബെഡിംഗ് മോഡലിലാണോ (embedding model), അതോ പ്രോംപ്റ്റിലാണോ (prompt) എന്ന് എനിക്ക് തിരിച്ചറിയാൻ കഴിഞ്ഞില്ല.
നിങ്ങൾ ഇത് സ്വയം നിർമ്മിക്കുമ്പോൾ, ഓരോ ലെയറും പരിശോധിക്കാൻ സാധിക്കും. LLM-ലേക്ക് അയക്കുന്ന കൃത്യമായ ചങ്കുകൾ (chunks) നിങ്ങൾക്ക് പ്രിന്റ് ചെയ്ത് കാണാം. ഒരു വാചകം എവിടെയാണ് മുറിയുന്നതെന്ന് നിങ്ങൾക്ക് കൃത്യമായി കാണാൻ കഴിയും.
RAG-ന്റെ അഞ്ച് ലെയറുകൾ
RAG എന്നത് ഒരു അൽഗോരിതം മാത്രമല്ല. അത് ഒന്നിനു മുകളിൽ ഒന്നായി അടുക്കിവെച്ചിരിക്കുന്ന അഞ്ച് വ്യത്യസ്ത പ്രക്രിയകളാണ്:
- Chunking: ടെക്സ്റ്റ് എങ്ങനെ വിഭജിക്കണമെന്ന് തീരുമാനിക്കുന്നു.
- Embedding: ടെക്സ്റ്റിനെ ഗണിത രൂപത്തിലേക്ക് മാറ്റുന്നു.
- Retrieval: ശരിയായ ഭാഗങ്ങൾ കണ്ടെത്തുന്നു.
- Prompt Construction: മോഡൽ എങ്ങനെ പെരുമാറണമെന്ന് നിർദ്ദേശിക്കുന്നു.
- Generation: അന്തിമ ഉത്തരം ലഭിക്കുന്നു.
നിർമ്മാണത്തിൽ നിന്നുള്ള പാഠങ്ങൾ
1. Chunking ആണ് ഏറ്റവും പ്രധാനപ്പെട്ട ഘട്ടം മിക്ക ട്യൂട്ടോറിയലുകളും ഇത് ഒഴിവാക്കാറുണ്ട്. നിങ്ങൾ ഓവർലാപ്പ് (overlap) ഉപയോഗിച്ചില്ലെങ്കിൽ, അതിരുകളിൽ വെച്ച് സന്ദർഭങ്ങൾ (context) നഷ്ടപ്പെടും. ഞാൻ ക്യാരക്ടർ ലെവൽ ഓവർലാപ്പോടു കൂടിയ ഒരു സ്ലൈഡിംഗ് വിൻഡോ (sliding window) ഉപയോഗിച്ചു. ഇത് രണ്ട് ചങ്കുകൾ തമ്മിലുള്ള ബന്ധം മോഡൽ കാണുന്നുണ്ടെന്ന് ഉറപ്പാക്കുന്നു.
2. ഡിസ്റ്റൻസ് മെട്രിക്സുകൾ (Distance metrics) പ്രധാനമാണ് മോശം സെർച്ച് റിസൾട്ടുകൾ ശരിയാക്കാൻ ഞാൻ മണിക്കൂറുകൾ ചിലവഴിച്ചു. പ്രശ്നം ഡാറ്റയിലായിരുന്നില്ല, മറിച്ച് മെട്രിക്സിലായിരുന്നു. ChromaDB ഡിഫോൾട്ട് ആയി ഉപയോഗിക്കുന്നത് L2 ഡിസ്റ്റൻസ് ആണ്. സെമാന്റിക് സെർച്ചിന് (semantic search) നിങ്ങൾക്ക് കോസൈൻ സിമിലാരിറ്റി (Cosine similarity) ആവശ്യമാണ്. ഒരു വരി കോഡ് എല്ലാം മാറ്റിമറിച്ചു.
3. പ്രോംപ്റ്റുകൾക്ക് നിയന്ത്രണങ്ങൾ ആവശ്യമാണ് ഒരു LLM എന്നത് ഒരു വിവരദാതാവ് (oracle) അല്ല, മറിച്ച് ഒരു വാചകം പൂർത്തിയാക്കുന്ന സംവിധാനമാണ്. നിങ്ങൾ അവ്യക്തമായ ഒരു ചോദ്യം ചോദിച്ചാൽ, അത് ഒരു ഉത്തരം ഉണ്ടാക്കിയെടുക്കും. കർശനമായ ഒരു റിഫ്യൂസൽ ടെംപ്ലേറ്റ് (refusal template) ഉപയോഗിക്കാൻ ഞാൻ പഠിച്ചു. ഞാൻ മോഡലിനോട് പറഞ്ഞു: "സന്ദർഭത്തിൽ (context) ഉത്തരം ഇല്ലെങ്കിൽ, അറിയില്ല എന്ന് പറയുക." ഇത് ഹാലുസിനേഷനുകൾ (hallucinations) 40 ശതമാനത്തിൽ നിന്ന് 5 ശതമാനമായി കുറച്ചു.
4. റിക്വസ്റ്റുകൾ ബാച്ച് (batch) ചെയ്യുക ഓരോ ചങ്കിനും ഓരോ HTTP റിക്വസ്റ്റ് അയക്കുന്നത് സാവധാനമാണ്. അവ ബാച്ചുകളായി അയക്കുന്നത് വളരെ വേഗതയുള്ളതാണ്. ഇത് ലോക്കൽ മോഡലിന് ജോലികൾ പൈപ്പ്ലൈൻ ചെയ്യാൻ അനുവദിക്കുന്നു.
5. താഴെ നിന്ന് മുകളിലേക്ക് ടെസ്റ്റ് ചെയ്യുക അവസാനം പോയി ടെസ്റ്റ് എഴുതരുത്. ആദ്യം നിങ്ങളുടെ ചങ്കർ (chunker) ടെസ്റ്റ് ചെയ്യുക. പിന്നെ എംബെഡർ (embedder) ടെസ്റ്റ് ചെയ്യുക. അതിനുശേഷം സ്റ്റോർ (store) ടെസ്റ്റ് ചെയ്യുക. നിങ്ങൾ അവസാനം മാത്രം ടെസ്റ്റ് ചെയ്യുകയാണെങ്കിൽ, ലോജിക് എന്നതിലുപരി ബഗുകൾ (bugs) മാത്രമാണ് നിങ്ങൾ ടെസ്റ്റ് ചെയ്യുന്നത്.
നിങ്ങളുടെ AI സ്റ്റാക്കിനെക്കുറിച്ച് നിങ്ങൾക്ക് ശരിയായ ധാരണയില്ലെന്ന് തോന്നുന്നുണ്ടെങ്കിൽ, അത് സ്വയം നിർമ്മിച്ചു നോക്കൂ. കോഡ് ലക്ഷ്യമല്ല, ചിന്താരീതിയാണ് ലക്ഷ്യം.
Optional learning community: https://t.me/GyaanSetuAi
