ഒരു ലാംഗ്വേജ് മോഡലിനോട് “strawberry” എന്ന വാക്കിൽ എത്ര അക്ഷരങ്ങളുണ്ടെന്ന് ചോദിക്കുക. അത് തെറ്റായി പറയാനാണ് സാധ്യത കൂടുതൽ. അത് പത്ത് എന്ന് പറഞ്ഞേക്കാം. പതിനൊന്ന് എന്ന് ഊഹിച്ചേക്കാം. അത് വളരെ ആത്മവിശ്വാസത്തോടെ പറയും, എങ്കിലും അത് തെറ്റായിരിക്കും. അതേ മോഡലിനോട് ഒരു ലോണിന്റെ കോമ്പൗണ്ട് ഇൻട്രസ്റ്റ് കണക്കാക്കാൻ പറയുകയോ, അല്ലെങ്കിൽ രണ്ട് വലിയ സംഖ്യകൾ കൂട്ടാൻ പറയുകയോ, അല്ലെങ്കിൽ രണ്ട് തീയതികൾക്കിടയിലുള്ള ബിസിനസ്സ് ദിവസങ്ങൾ എണ്ണാൻ പറയുകയോ ചെയ്താൽ, അക്കങ്ങളിൽ ചെറിയ വ്യത്യാസങ്ങളുള്ള, എന്നാൽ ശരിയാണെന്ന് തോന്നിക്കുന്ന ഒരു ഉത്തരം നിങ്ങൾക്ക് ലഭിച്ചേക്കാം.
ലാർജ് ലാംഗ്വേജ് മോഡലുകൾ മനുഷ്യരെപ്പോലെ സംഖ്യകളെക്കുറിച്ച് ചിന്തിക്കാത്തതുകൊണ്ടാണ് ഇത് സംഭവിക്കുന്നത്. അവ പ്രവചിക്കുന്നത് ടോക്കണുകളെയാണ് (tokens). ഒരു ടോക്കൺ എന്നത് ഒരു പൂർണ്ണ വാക്കോ, വാക്കിന്റെ ഭാഗമോ, അല്ലെങ്കിൽ ഒരു ഒറ്റ അക്കമോ ആകാം. മോഡൽ “strawberry” കാണുമ്പോൾ, അത് വരിവരിയായി നിൽക്കുന്ന എട്ട് അക്ഷരങ്ങളായിട്ടല്ല കാണുന്നത്. പകരം അത് കുറച്ച് കഷണങ്ങളായിട്ടാണ് (chunks) കാണുന്നത്. അക്ഷരങ്ങൾ എണ്ണാൻ അതിനെ പഠിപ്പിച്ചിട്ടില്ല, പകരം അടുത്തതായി വരാൻ സാധ്യതയുള്ള ടെക്സ്റ്റ് കഷണങ്ങൾ പ്രവചിക്കാനാണ് അതിനെ പഠിപ്പിച്ചിട്ടുള്ളത്. ഇതേ പരിമിതി ഗണിതക്രിയകൾക്കും ബാധകമാണ്. മോഡലിന് ഉള്ളിൽ ഒരു കാൽക്കുലേറ്റർ ഇല്ല. അതിന് കരി ലോജിക് (carry logic) ഇല്ല. സ്ഥാനവിലയെ (place value) കുറിച്ച് അതിന് യഥാർത്ഥമായ ധാരണയുമില്ല. അത് 148-നെ 279 കൊണ്ട് ഗുണിക്കുമ്പോൾ, അത് ഗുണനക്രിയ നടത്തുകയല്ല ചെയ്യുന്നത്. പകരം ട്രെയിനിംഗിനിടെ കണ്ട സമാനമായ പ്രയോഗങ്ങളുമായി അത് പാറ്റേൺ മാച്ച് (pattern-matching) ചെയ്യുകയാണ്, ഏത് അക്കങ്ങളുടെ ക്രമമാണ് വരാൻ സാധ്യത എന്ന് ഊഹിക്കുകയാണ് ചെയ്യുന്നത്. ചെറിയ തുകകൾക്ക് ഈ പാറ്റേൺ കൃത്യമായി പ്രവർത്തിക്കും. എന്നാൽ കൃത്യത ആവശ്യമായ കാര്യങ്ങളിൽ ഈ ഊഹം പരാജയപ്പെടും.
രണ്ട് ജോലികൾ, ഒരു ബോട്ട്
സാധാരണ പ്രോംപ്റ്റിംഗ് രീതികൾ ഒരു സിസ്റ്റത്തോട് ഒരേസമയം രണ്ട് വ്യത്യസ്ത കാര്യങ്ങൾ ചെയ്യാൻ ആവശ്യപ്പെടുന്നു. ഒന്നാമതായി, പ്രശ്നത്തിന്റെ ലോജിക് മനസ്സിലാക്കുക. രണ്ടാമതായി, കൃത്യമായ കണക്കുകൂട്ടൽ നടത്തുക. ആദ്യത്തെ കാര്യത്തിൽ മോഡൽ ശരിക്കും മികച്ചതാണ്. ഒരു വേർഡ് പ്രോബ്ലം വായിക്കാനും, അതിലെ വേരിയബിളുകൾ വേർതിരിച്ചെടുക്കാനും, അവ തമ്മിലുള്ള ബന്ധം കണ്ടെത്താനും, ഒരു പരിഹാര പാത ആസൂത്രണം ചെയ്യാനും അതിന് കഴിയും. എന്നാൽ പിന്നീട് അതിന് സ്വന്തം കാൽക്കുലേറ്ററായി പ്രവർത്തിക്കേണ്ടി വരുന്നു. അവിടെയാണ് പിഴവ് സംഭവിക്കുന്നത്. മൂന്നാമത്തെ ഘട്ടത്തിൽ ഒരു അക്കം തെറ്റിയാൽ അത് തുടർന്നുള്ള എല്ലാ ഘട്ടങ്ങളെയും ബാധിക്കും. ലോജിക് കൃത്യമായിരിക്കാമെങ്കിലും, മോഡൽ തെറ്റായി കൂട്ടിയതുകൊണ്ട് അവസാന ഉത്തരം തെറ്റായി വരുന്നു.
Program-Aided Language Models അഥവാ PAL, ജോലികളെ വിഭജിച്ചുകൊണ്ട് ഈ പ്രശ്നം പരിഹരിക്കുന്നു. മോഡലിനോട് ഉത്തരം ചോദിക്കുന്നതിന് പകരം, ഒരു പ്രോഗ്രാം ആവശ്യപ്പെടുകയാണ് നിങ്ങൾ ചെയ്യുന്നത്.
ഇതിന്റെ പ്രവർത്തനരീതി ഇതാ: നിങ്ങൾ പ്രശ്നം അവതരിപ്പിക്കുന്നു. മോഡൽ അതിന്റെ ലോജിക് കണ്ടെത്തുകയും, വേരിയബിളുകൾ നിർവചിക്കുകയും, അൽഗോരിതം തയ്യാറാക്കുകയും ചെയ്യുന്നു. തുടർന്ന്, ഫലം സ്വയം കണക്കാക്കുന്നതിന് പകരം, അത് സാധാരണയായി Python ഉപയോഗിച്ച് ഒരു ചെറിയ സ്ക്രിപ്റ്റ് എഴുതുന്നു. ആ സ്ക്രിപ്റ്റ് ഒരു യഥാർത്ഥ കോഡ് ഇന്റർപ്രെറ്റർക്ക് (code interpreter) കൈമാറുന്നു. ഇന്റർപ്രെറ്റർ ലോജിക് പ്രവർത്തിപ്പിക്കുകയും കൃത്യമായ, നിശ്ചിതവുമായ (deterministic) ഫലം നൽകുകയും ചെയ്യുന്നു. മോഡൽ കണക്കുകൾ വിവരിക്കുന്നു. Python ആണ് കണക്കുകൾ ചെയ്യുന്നത്.
പ്രായോഗികമായ എക്സിക്യൂട്ടബിൾ റീസണിംഗ് (Executable Reasoning)
PAL-നെ എക്സിക്യൂട്ടബിൾ റീസണിംഗ് ആയി കരുതുക. ഒരു സ്ക്രിപ്റ്റിന് ഒരു പ്രശ്നം പരിഹരിക്കാൻ കഴിയുമെങ്കിൽ, ആ സ്ക്രിപ്റ്റ് എഴുതാൻ മോഡലിനെ അനുവദിക്കുക.
ഒരു ഉദാഹരണം നോക്കാം. ₹50,000 രൂപയുടെ ഫിക്സഡ് ഡിപ്പോസിറ്റിന് 8.5 ശതമാനം വാർഷിക പലിശ നിരക്കിൽ, ക്വാർട്ടർലി (quarterly) കോമ്പൗണ്ട് ചെയ്ത് ഏഴ് വർഷത്തേക്ക് ലഭിക്കുന്ന മെച്യൂരിറ്റി തുക കണക്കാക്കണം. ഒരു ലാംഗ്വേജ് മോഡലിനോട് നേരിട്ട് ചോദിച്ചാൽ, അത് ഒരു ഫോർമുല എഴുതി, മൂല്യങ്ങൾ നൽകി, chain of thought വഴി ഫലം കണക്കാക്കിയേക്കാം. എന്നാൽ സൂക്ഷിച്ചു നോക്കിയാൽ, ക്വാർട്ടർലി കോമ്പൗണ്ടിംഗിൽ പലിശ നിരക്ക് തെറ്റായി ഭാഗിച്ചോ, അല്ലെങ്കിൽ ഇടയിലുള്ള ഒരു ഘട്ടത്തിൽ റൗണ്ട് ഓഫ് ചെയ്തത് കാരണം തെറ്റായ ഉത്തരം ലഭിച്ചോ എന്ന് കാണാൻ സാധിക്കും. ഉത്തരം ശരിയാണെന്ന് തോന്നുമെങ്കിലും നൂറുകണക്കിന് രൂപയുടെ വ്യത്യാസം ഉണ്ടാകാം.
PAL ഉപയോഗിക്കുമ്പോൾ രീതി മാറുന്നു. principal = 50000, rate = 0.085, time = 7, n = 4 എന്നിങ്ങനെ നിർവചിച്ചും, amount = principal * (1 + rate/n) ** (n * time) എന്ന് കണക്കാക്കിയും ഒരു Python കോഡ് നിർമ്മിക്കാൻ നിങ്ങൾ മോഡലിനോട് നിർദ്ദേശിക്കുന്നു. മോഡൽ കോഡ് നൽകുന്നു. ഒരു Python runtime അത് പ്രവർത്തിപ്പിക്കുന്നു. ഓരോ തവണയും അവസാനത്തെ ദശാംശ സംഖ്യ വരെ കൃത്യമായ ഫലം നിങ്ങൾക്ക് ലഭിക്കുന്നു. ഗുണനത്തിൽ ഊഹങ്ങൾ ഇല്ല, തെറ്റായ ശിഷ്ടങ്ങൾ (remainder) ഇല്ല, ആത്മവിശ്വാസത്തോടെയുള്ള റൗണ്ടിംഗ് പിഴവുകളും ഇല്ല.
ഇതേ രീതി തന്നെ തീയതികൾ കണക്കാക്കുന്നതിനും ബാധകമാണ്. വാരാന്ത്യങ്ങൾ ഒഴിവാക്കി ഇന്ന് മുതൽ കൃത്യം 120 ബിസിനസ്സ് ദിവസങ്ങൾക്ക് ശേഷം ഏത് തീയതിയാണെന്ന് ഒരു മോഡലിനോട് ചോദിക്കുക. ഒരു ടെക്സ്റ്റ് മോഡൽ ദിവസങ്ങൾ എണ്ണുന്നതിനിടയിൽ ശനിയാഴ്ചകളിൽ തെറ്റിച്ചേക്കാം. എന്നാൽ PAL രീതിയിൽ, datetime, calendar ലോജിക് ഉപയോഗിച്ച് ഒരു സ്ക്രിപ്റ്റ് എഴുതാൻ മോഡലിനോട് ആവശ്യപ്പെടുകയും, ഇന്റർപ്രെറ്റർ അത് കൃത്യമായി പ്രവർത്തിപ്പിക്കുകയും ചെയ്യുന്നു. ഡാറ്റാ മാനിപുലേഷൻ രീതിയും ഇതുതന്നെയാണ്. നിങ്ങൾക്ക് ഒരു സങ്കീർണ്ണമായ CSV ഫയൽ വിശകലനം ചെയ്യാനോ, ഫിൽട്ടർ ചെയ്യാനോ, അല്ലെങ്കിൽ ഒരു സ്റ്റാറ്റിസ്റ്റിക്കൽ ട്രാൻസ്ഫോം നടത്താനോ ആവശ്യമുണ്ടെങ്കിൽ, മോഡൽ ലോജിക് തയ്യാറാക്കുകയും ഇന്റർപ്രെറ്റർ അത് പ്രവർത്തിപ്പിക്കുകയും വേണം.
എന്തുകൊണ്ടാണ് ഇത് പ്രസക്തമാകുന്നത്
വിവരണാത്മകമായ ഉത്തരങ്ങളിൽ നിന്ന് എക്സിക്യൂട്ടബിൾ കോഡിലേക്കുള്ള ഈ മാറ്റം മൂന്ന് പ്രായോഗിക നേട്ടങ്ങൾ നൽകുന്നു.
നിശ്ചിതത്വം (Determinism). ഒരേ ചോദ്യം രണ്ടുതവണ ചോദിക്കുമ്പോൾ ഒരു ലാംഗ്വേജ് മോഡൽ അതിന്റെ പദപ്രയോഗങ്ങളിൽ മാറ്റം വരുത്തുകയോ ഒരു അക്കം മാറ്റുകയോ ചെയ്തേക്കാം. എന്നാൽ ഒരു ഇന്റർപ്രെറ്റർ (interpreter) ഒരേ ഇൻപുട്ടിന് എപ്പോഴും ഒരേ ഔട്ട്പുട്ട് തന്നെ നൽകുന്നു. അക്കൗണ്ടിംഗ്, ലോജിസ്റ്റിക്സ്, ഷെഡ്യൂളിംഗ്, സ്ഥിരത നിർബന്ധമായും വേണ്ട ഏതൊരു എഞ്ചിനീയറിംഗ് കണക്കുകൂട്ടലുകൾ എന്നിവയിൽ ഈ സ്ഥിരതയ്ക്ക് വലിയ പ്രാധാന്യമുണ്ട്.
പരിശോധനാക്ഷമത (Verifiability). ഒരു മോഡൽ നിങ്ങൾക്ക് മൂന്ന് ഖണ്ഡികകളിലായി യുക്തിപരമായ വിശദീകരണം നൽകുമ്പോൾ, അതിലെ ഒരു തെറ്റായ നമ്പർ കണ്ടെത്താനായി നിങ്ങൾ ഓരോ വാചകവും വായിക്കേണ്ടി വരും. എന്നാൽ അത് നിങ്ങൾക്ക് പത്ത് വരികളുള്ള ഒരു സ്ക്രിപ്റ്റ് നൽകുമ്പോൾ, നിങ്ങൾക്ക് ആ കോഡ് പരിശോധിക്കാവുന്നതാണ്. ഇന്റർപ്രെറ്റർ പ്രവർത്തിക്കുന്നതിന് മുമ്പ് തന്നെ കോമ്പൗണ്ട് ഇൻട്രസ്റ്റ് (compound-interest) ഫോർമുല ശരിയാണോ എന്ന് നിങ്ങൾക്ക് ഉറപ്പുവരുത്താം. നിങ്ങൾക്ക് വേരിയബിൾ പേരുകൾ പരിശോധിക്കാനും, 'off-by-one' പിശകുകൾ കണ്ടെത്താനും, പരിഹാരത്തിന്റെ വേർഷൻ കൺട്രോൾ (version-control) പോലും നടത്താനും സാധിക്കും. ഇതിലൂടെ ഒളിഞ്ഞിരിക്കുന്ന തെറ്റുകൾ സംഭവിക്കാനുള്ള സാധ്യത ഗണ്യമായി കുറയുന്നു.
വിശ്വസനീയത (Reliability). മോഡൽ അതിന്റെ പരിധിയിൽ നിൽക്കുന്നു. ഘടന (structure), അർത്ഥതലങ്ങൾ (semantics), പ്രശ്നത്തിന്റെ വിഭജനം (problem decomposition) എന്നിവയെക്കുറിച്ച് യുക്തിപരമായി ചിന്തിക്കുക എന്നതായിരുന്നു അതിന്റെ ലക്ഷ്യം, അത് കൃത്യമായി ചെയ്യുന്നു. യന്ത്രം അതിന്റെ ലക്ഷ്യമായ കൃത്യമായ കണക്കുകൂട്ടലുകൾ നടത്തുന്നു. ഉത്തരവാദിത്തങ്ങളുടെ ഈ വേർതിരിക്കലാണ് (separation of concerns) വിശ്വസനീയമായ സോഫ്റ്റ്വെയറുകൾ നിർമ്മിക്കുന്നതിന്റെ അടിസ്ഥാനം. മോണോലിത്തിക് ഡിസൈനിനേക്കാൾ (monolithic design) മികച്ചതാണ് കോമ്പോസിഷൻ (composition).
വിശ്വസിക്കാൻ കഴിയാത്ത കോഡ് പോലെ പ്രവർത്തിപ്പിക്കുക
ഒരു മുന്നറിയിപ്പ് നൽകേണ്ടതുണ്ട്. നിർമ്മിക്കപ്പെട്ട കോഡിനെ വിശ്വസിക്കാൻ കഴിയാത്ത ഇൻപുട്ട് ആയിട്ടാണ് കാണേണ്ടത്. മോഡൽ ഒരു ഇൻഫിനിറ്റ് ലൂപ്പ് (infinite loop), അനാവശ്യമായ നെറ്റ്വർക്ക് റിക്വസ്റ്റ്, അല്ലെങ്കിൽ നിങ്ങൾ ആവശ്യപ്പെടാത്ത ഫയൽസിസ്റ്റം ഓപ്പറേഷൻ എന്നിവയുള്ള ഒരു സ്ക്രിപ്റ്റ് എഴുതിയേക്കാം. ഇത്തരം പ്രോഗ്രാമുകൾ എപ്പോഴും ഒരു ഐസൊലേറ്റഡ് സാൻഡ്ബോക്സിനുള്ളിൽ (isolated sandbox) മാത്രം പ്രവർത്തിപ്പിക്കുക. നിയന്ത്രിത അവകാശങ്ങളുള്ള കണ്ടെയ്നറുകൾ (containers), നെറ്റ്വർക്ക് ആക്സസ് ഇല്ലാത്ത സെർവ്ലെസ് ഫംഗ്ഷനുകൾ (serverless functions), അല്ലെങ്കിൽ പരിമിതമായ സിപിയു (CPU) സമയവും സ്ഥിരമായ സ്റ്റോറേജും ഇല്ലാത്ത കർശനമായി നിയന്ത്രിക്കപ്പെട്ട സാഹചര്യങ്ങൾ എന്നിവ ഉപയോഗിക്കുക. ഇവിടെ സുരക്ഷ എന്നത് വെറുമൊരു കുറിപ്പല്ല, മറിച്ച് സിസ്റ്റം ഡിസൈനിന്റെ തന്നെ ഭാഗമാണ്.
PAL എവിടെ തിളങ്ങുന്നു, എവിടെ അവസാനിക്കുന്നു
കണക്ക്, തീയതികൾ, ഘടനാപരമായ ഡാറ്റാ കൈകാര്യം ചെയ്യൽ (structured data manipulation) എന്നിവയിൽ PAL മികച്ച രീതിയിൽ പ്രവർത്തിക്കുന്നു. ടെക്സ്റ്റ് അടിസ്ഥാനമാക്കിയുള്ള യുക്തിചിന്തകളിൽ സംഭവിക്കുന്ന യന്ത്രപരമായ പിശകുകളെ ഇത് ഒഴിവാക്കുന്നു.
എന്നിരുന്നാലും, ഇത് തെറ്റായ ലോജിക്കുകളെ പരിഹരിക്കുന്നില്ല. മോഡൽ തെറ്റായ ഫോർമുലയാണ് തിരഞ്ഞെടുക്കുന്നതെങ്കിൽ,
