വേർപെടുത്തിയ പ്രീഫില്ലും ഡീകോഡും
ഡിവൈസുകളിലുടനീളം പ്രീഫില്ലും ഡീകോഡും വേർപെടുത്തുന്നത് LLM ഇൻഫറൻസ് വേഗത്തിലാക്കുകയും പ്രകടനം മെച്ചപ്പെടുത്തുകയും ചെയ്യുന്നു
ഇൻപുട്ട് പ്രോംപ്റ്റിൽ നിന്ന് ഔട്ട്പുട്ട് ടോക്കണുകൾ ജനറേറ്റുചെയ്യുന്നതിന്, LLM ഇൻഫറൻസ് പ്രീഫിൽ, ഡീകോഡ് എന്നിങ്ങനെ രണ്ട് ഘട്ടങ്ങളായി തിരിച്ചിരിക്കുന്നു. ടോക്കണുകൾ ഓരോന്നായി ജനറേറ്റുചെയ്യുന്ന ഡീകോഡ് ഘട്ടത്തിലേക്ക് പ്രവേശിക്കുന്നതിന് മുൻപ്, പ്രീഫിൽ ഇൻപുട്ട് ടോക്കണുകളിൽ പ്രവർത്തിക്കുകയും KV കാഷുകൾ പോപ്പുലേറ്റ് ചെയ്യുകയും ചെയ്യുന്നു. ഒരു ഡീകോഡ് ഘട്ടം സാധാരണയായി പത്ത് മില്ലിസെക്കൻഡുകൾ മാത്രമെടുക്കുമ്പോൾ, പ്രീഫിൽ അതിനേക്കാൾ വളരെ കൂടുതൽ സമയം എടുക്കുന്നു. ഒരേ ഉപകരണങ്ങളിൽ പ്രവർത്തിപ്പിക്കുകയാണെങ്കിൽ, പ്രീഫില്ലും ഡീകോഡും ഒരുമിച്ച് ചേർക്കുന്നത് ഡീകോഡ് പ്രകടനത്തെ കുറയ്ക്കുന്നു. പ്രീഫിൽ ത്രൂപുട്ട് പരമാവധിയാക്കാനും ഡീകോഡ് ലേറ്റൻസി കുറയ്ക്കാനുമായി അവയെ വ്യത്യസ്ത ഉപകരണങ്ങളിൽ പ്രവർത്തിപ്പിച്ചുകൊണ്ടുള്ള, വേർപെടുത്തിയ പ്രീഫില്ലും ഡീകോഡും (disaggregated prefill and decode) എന്ന സ്ഥാപിത പരിഹാരമാണ് ഈ ലേഖനത്തിൽ ഞങ്ങൾ പരിശോധിക്കുന്നത്.
പ്രീഫിൽ വേഴ്സസ് ഡീകോഡ് പ്രകടനം
ഒരു സാധാരണ LLM സെർവിങ് എൻജിനിൽ, ഒരു മോഡലിന്റെ ഓരോ എക്സിക്യൂഷൻ ഘട്ടത്തിലും പ്രോസസ്സ് ചെയ്യേണ്ട അഭ്യർത്ഥനകൾ ബാച്ച് ഷെഡ്യൂലർ തിരഞ്ഞെടുക്കുന്നു. ഒരു ഒറ്റപ്പെട്ട ഉപകരണത്തിലോ നോഡിലോ പ്രവർത്തിക്കുമ്പോൾ, പ്രീഫിൽ, ഡീകോഡ് അഭ്യർത്ഥനകൾ രണ്ടും ഒരുമിച്ച് ബാച്ച് ചെയ്യുന്നു. സീക്വൻസ് നീളത്തിനനുസരിച്ച് വർദ്ധിക്കുന്ന അറ്റൻഷന്റെ ചെലവ്, KV കാഷിലെ എൻട്രികളുടെ നീളത്തിന് (kv_len) ആനുപാതികമായി പ്രീഫില്ലിനും ഡീകോഡിനും വർദ്ധിക്കുന്നു. ഡീകോഡ് അഭ്യർത്ഥനകൾ സാധാരണയായി ഒരു ഒറ്റ ടോക്കൺ (qo_len=1) ഫോർവേഡ് ചെയ്യുന്നു, സീക്വൻസിന്റെ ടോക്കണുകളിൽ സ്വതന്ത്രമായി പ്രവർത്തിക്കുന്ന മറ്റ് ലെയറുകളിലൂടെ കുറഞ്ഞ ചെലവിൽ ഇത് സാധ്യമാകുന്നു. പ്രീഫിൽ അഭ്യർത്ഥനകൾ ഡെൻസ് ലെയറുകളിലൂടെ വലിയ ചെലവിൽ (വലിയ qo_len) ആയിരക്കണക്കിനോ പതിനായിരക്കണക്കിനോ ടോക്കണുകൾ ഫോർവേഡ് ചെയ്യുന്നു.
അറ്റൻഷൻ സമയത്ത് KV കാഷിൽ നിന്ന് വീണ്ടെടുക്കുന്ന ടോക്കണുകളുടെ എണ്ണത്തേക്കാൾ (kv_len), ഡെൻസ് ലെയറുകളിലൂടെ കടന്നുപോകുന്ന സ്വതന്ത്ര ടോക്കണുകളുടെ എണ്ണമാണ് (qo_len) ഒരു ഫോർവേഡ് പാസിന്റെ ലേറ്റൻസിയെ കൂടുതൽ സ്വാധീനിക്കുന്നത്. അഭ്യർത്ഥനകളുടെ എണ്ണത്തിലും സീക്വൻസ് നീളത്തിന് ആനുപാതികമായ kv_len-ലും അറ്റൻഷൻ പാരലൽ ചെയ്യാൻ കഴിയും, ഇത് മികച്ച യൂട്ടിലൈസേഷൻ കൈവരിക്കുന്നു. പ്രീഫിൽ കമ്പ്യൂട്ട് ബൗണ്ട് ആണ്: qo_len ഉയർന്നതായതിനാൽ, ആധുനിക GPU-കളുടെ കമ്പ്യൂട്ട് ശേഷി പൂർണ്ണമായി ഉപയോഗപ്പെടുത്തുന്നതിന് GEMM കെർണലുകൾക്ക് M ഡയമൻഷനിൽ മതിയായ ബ്ലോക്കുകൾ അലോക്കേറ്റ് ചെയ്യാൻ കഴിയും. ഡീകോഡ് മെമ്മറി ബൗണ്ട് ആണ്: സാധാരണയായി കുറഞ്ഞ ബാച്ച് വലുപ്പങ്ങൾ കാരണം, M-ലെ ഇൻപുട്ടുകളുടെ എണ്ണം സാധാരണയായി ചെറുതാണ്, ഇത് ഒരു ബ്ലോക്കിന് മാത്രം പര്യാപ്തമാണ്. കുറഞ്ഞ ടോക്കൺ ബാച്ച് വലുപ്പങ്ങൾക്കായി Split-K GEMM കെർണലുകൾക്ക് SM യൂട്ടിലൈസേഷൻ മെച്ചപ്പെടുത്താൻ കഴിയുമെങ്കിലും, കാഷുകളും മാട്രിക്സ് മൾട്ടിപ്ലിക്കേഷൻ യൂണിറ്റുകളും സാധാരണയായി കുറഞ്ഞ തോതിലായിരിക്കും ഉപയോഗിക്കപ്പെടുന്നത്.
ഒരുമിച്ച് ചേർക്കുമ്പോൾ, പ്രീഫീലിനായുള്ള അഭ്യർത്ഥനകൾ അടങ്ങിയ ബാച്ചുകൾ ഫോർവേഡ് പാസിൽ ഉയർന്ന ലേറ്റൻസി വരുത്തുകയും, മുഴുവൻ ഇൻസ്റ്റൻസിന്റെയും ഡീകോഡ് ത്രൂപുട്ടിനെ പ്രതികൂലമായി ബാധിക്കുകയും ചെയ്യുന്നു. പ്രീഫിൽ അഭ്യർത്ഥനകൾ ഡീകോഡ് അഭ്യർത്ഥനകളുമായി മിക്സ് ചെയ്യുകയോ ചങ്ക്ഡ് പ്രീഫിൽ ഉപയോഗിക്കുകയോ ചെയ്യുന്നത് ഡീകോഡ് പ്രകടനം ചെറുതായി മെച്ചപ്പെടുത്തുമെങ്കിലും, ഡീകോഡ് ത്രൂപുട്ട് പരമാവധിയാക്കാൻ പോന്നത്രയും അഭ്യർത്ഥനകൾ ഒരു ഇൻസ്റ്റൻസിൽ പ്രോസസ്സ് ചെയ്യാൻ ആവശ്യമായ പ്രീഫിൽ ത്രൂപുട്ട് നിലനിർത്തുക ബുദ്ധിമുട്ടാണ്. വലിയ ഔട്ട്പുട്ട് നീളമുള്ള വലിയ മോഡലുകളുടെ കാര്യത്തിൽ, ഡീകോഡിനായി വലിയ ബാച്ച് വലുപ്പം നിലനിർത്താൻ, പ്രീഫിൽ ഇടയ്ക്കിടെ നടത്തേണ്ടതുണ്ട്, ഇത് ശരാശരി ലേറ്റൻസി ഗണ്യമായി കുറയ്ക്കുകയും ഔട്ട്പുട്ടിൽ തടസ്സങ്ങൾ ഉണ്ടാക്കുകയും ചെയ്യുന്നു.
പ്രീഫില്ലും ഡീകോഡും നിർവഹിക്കാൻ പ്രത്യേക നോഡുകൾ ഉപയോഗിച്ച് ഈ പ്രശ്നങ്ങൾ പരിഹരിക്കാവുന്നതാണ്. ഒരു പ്രീഫില്ലർ നോഡിനെ ഒന്നിലധികം ഡീകോഡർ നോഡുകളുമായി ബന്ധിപ്പിക്കുന്നതിലൂടെ, ത്രൂപുട്ട് പരമാവധിയാക്കാനും ഡീകോഡ് ത്രൂപുട്ട് പരമാവധിയാക്കാൻ ഡീകോഡർ നോഡുകളിൽ ആവശ്യത്തിന് ഒരേസമയത്തുള്ള അഭ്യർത്ഥനകളുടെ എണ്ണം നിലനിർത്താനും ആവശ്യമായ അഭ്യർത്ഥനകൾ പ്രീഫില്ലിനായി ഷെഡ്യൂൾ ചെയ്യാൻ കഴിയും. പ്രീഫില്ലർ നോഡുകൾ KV കാഷുകൾ പോപ്പുലേറ്റ് ചെയ്യുന്നു, തുടർന്ന് അവ ഡീകോഡർ നോഡുകളിലേക്ക് കൈമാറുന്നു. ഡീകോഡറുകൾക്ക് ഇനി പ്രീഫില്ലിനായി നിർത്തേണ്ടി വരാത്തതിനാൽ, സജീവമായ അഭ്യർത്ഥനകളുടെ വർദ്ധിച്ചുവരുന്ന kv_len-ന്റെ മൊത്തത്തിലുള്ള ആഘാതം വളരെ കുറവായിരിക്കുന്നതിനാൽ ലേറ്റൻസി കൂടുതൽ പ്രവചനാതീതമായി മാറുന്നു. നെറ്റ്വർക്ക് വഴിയുള്ള KV കാഷുകളുടെ കൈമാറ്റം പത്ത് മുതൽ നൂറുകണക്കിന് മില്ലിസെക്കൻഡ് വരെ എടുത്തേക്കാവുന്നതിനാൽ, Time to First Token (TTFT) വർദ്ധിക്കുന്നു എന്നതാണ് ഇതിന്റെ വില.
കെവി മെസ്സഞ്ചർ
Perplexity-ൽ, വേർപെടുത്തിയ പ്രീഫില്ലിനും ഡീകോഡിനുമുള്ള ഞങ്ങളുടെ നടപ്പാക്കൽ ഒരു KV മെസ്സഞ്ചറിനെ കേന്ദ്രീകരിച്ചാണ് നിർമ്മിച്ചിരിക്കുന്നത്. ഇത് LLM എൻജിനുമായി സംവദിച്ചുകൊണ്ട്, ഒരു നെറ്റ്വർക്ക് വഴി പ്രീഫില്ലർ നോഡുകളിൽ നിന്ന് ഡീകോഡർ നോഡുകളിലേക്കുള്ള KV കാഷ് കൈമാറ്റങ്ങളെ ഏകോപിപ്പിക്കുന്നു. പ്രീഫില്ലർ വശത്ത്, മെസ്സഞ്ചർ ഡീകോഡർ നോഡുകളിൽ നിന്നുള്ള അഭ്യർത്ഥനകൾ സ്വീകരിക്കുകയും, അവ ബാച്ച് ഷെഡ്യൂളർക്ക് കൈമാറുകയും, ഏറ്റവും കുറഞ്ഞ ലേറ്റൻസിയോടെ KV കാഷുകൾ അയക്കുന്നതിനായി ഫോർവേഡ് പാസ് എക്സിക്യൂഷൻ ട്രാക്ക് ചെയ്യുകയും ചെയ്യുന്നു. ഡീകോഡർ വശത്ത്, മാറ്റാനാവാത്ത പേജുകൾ അലോക്കേറ്റ് ചെയ്ത ശേഷം, KV കാഷും ഡീകോഡർ കോൺടെക്സ്റ്റ് കൈമാറ്റങ്ങളും പൂർത്തിയായതായി അറിയിപ്പ് ലഭിക്കുന്നത് വരെ ഡീകോഡിനായി ഷെഡ്യൂൾ ചെയ്യുന്നതിൽ നിന്ന് മെസ്സഞ്ചർ അഭ്യർത്ഥനയെ തടയുന്നു.
പ്രീഫിൽ വേർപെടുത്തുന്നതിന് ഉയർന്ന ത്രൂപുട്ടും കുറഞ്ഞ ലേറ്റൻസിയുമുള്ള കണക്ഷനുകൾ ആവശ്യമാണ്, അതിനാൽ EFA, ConnectX നെറ്റ്വർക്ക് ഇന്റർഫേസ് കൺട്രോളറുകൾ (NIC-കൾ) എന്നിവയെ പിന്തുണച്ചുകൊണ്ട് ഞങ്ങളുടെ നടപ്പാക്കൽ RDMA-യ്ക്കായി രൂപകൽപ്പന ചെയ്തിരിക്കുന്നു. റിമോട്ട് ഡയറക്ട് മെമ്മറി ആക്സസ് (RDMA) പ്രിമിറ്റീവുകളിൽ ഉയർന്ന തലത്തിലുള്ള കുറഞ്ഞ ലേറ്റൻസി അബ്സ്ട്രാക്ഷനുകൾ നൽകുന്നതിന് ഞങ്ങളുടെ fabric-lib റാപ്പറുകൾ ഉപയോഗിച്ച് libfabric-ന്റെ മുകളിലാണ് KV മെസ്സഞ്ചർ നിർമ്മിച്ചിരിക്കുന്നത്, ഇത് കാര്യക്ഷമമായ പേജ്, മെറ്റാഡാറ്റ കൈമാറ്റങ്ങൾക്കൊപ്പം കുറഞ്ഞ ലേറ്റൻസി സിഗ്നലിംഗും നടപ്പിലാക്കുന്നു. പശ്ചാത്തലത്തിൽ, പ്രീഫില്ലർ നോഡിൽ നിന്ന് ഡീകോഡർ നോഡിലേക്ക് ഡാറ്റ പകർത്താൻ fabric-lib ഒരു GPU-വിനെയും അതിലേക്ക് നേരിട്ട് ബന്ധിപ്പിച്ചിട്ടുള്ള NIC-കളെയും ഏകോപിപ്പിക്കുന്നു.
സന്ദേശം ലഭിച്ച ഉടൻ, prefiller node അനുയോജ്യമായ source KV പേജുകളുടെ ഒരു സമുച്ചയം അനുവദിക്കുകയും തന്റെ local engine ഉപയോഗിച്ച് prefill നടത്തുന്നതിനായി request ഷെഡ്യൂൾ ചെയ്യുകയും ചെയ്യുന്നു. latency കുറഞ്ഞതാക്കാൻ, transfers forward pass പൂർത്തിയാകുന്നതുവരെ കാത്തിരിക്കില്ല: പകരം, individual layers-ലേക്കുള്ള KV cache-ലേക്ക് model KV cache entries ചേർക്കൽ പൂർത്തിയാക്കുന്ന ഉടനെ KV page copies ആരംഭിക്കുന്നു. prefill requests chunk ചെയ്യാനാകുന്നതിനാൽ, നിർവഹണത്തിനു മുമ്പ് നിലവിൽ ഷെഡ്യൂൾ ചെയ്തിരിക്കുന്ന chunks സംബന്ധിച്ച് batch scheduler KV messenger-നെ അറിയിക്കുന്നു. CUDA graphs പിന്തുണയ്ക്കുകയും അതേസമയം layers ട്രാക്ക് ചെയ്യാനുമാകുന്നതിനായി, attention-ന്റെ output projection കഴിഞ്ഞ് വർധിക്കുന്ന ഒരു counter polling ചെയ്യുന്ന സമർപ്പിത ഒരു ത്രെഡ് messenger സൂക്ഷിക്കുന്നു. sharded environment-ൽ ഈ counter lead node-ൽ മാത്രമാണ് നിലനിർത്തുന്നത്: KV cache entries append ചെയ്തശേഷവും attention-ന് മുമ്പും സാധുവായിരുന്നാലും, output projection ranks across reduced ചെയ്യപ്പെടുന്നു, അതുവഴി അവ സ്വാഭാവികമായി synchronize ചെയ്യപ്പെടുന്നു. counter-ൽ ഒരു മാറ്റം കണ്ടെത്തുമ്പോൾ, messenger-നെ അറിയിക്കുന്നു, തുടർന്ന് layer-ന്റെ transfer ആരംഭിക്കാൻ അത് fabric-lib വിളിക്കുന്നു.
അവസാന ചങ്കിന്റെ കൈമാറ്റം പൂർത്തിയായ ശേഷം, അധിക മെറ്റാഡാറ്റയും പകർത്തപ്പെടുന്നു: സ്പെക്കുലേറ്റീവ് ഡീകോഡിംഗിന് അല്ലെങ്കിൽ MTP-ക്ക് ലോഗിറ്റുകളും ഹിഡൻ സ്റ്റേറ്റുകളും ഡീകോഡറിലേക്ക് നീക്കേണ്ടതുണ്ട്. മുൻകൂട്ടി അലോക്കേറ്റ് ചെയ്ത ബഫറുകളിലേക്ക് RDMA വഴിയാണ് ഈ പകർപ്പുകളും നടത്തുന്നത്.
അവസാന ചങ്കിന്റെ തീർച്ചപ്പെടുത്താത്ത എല്ലാ കൈമാറ്റങ്ങളും പൂർത്തിയായ ശേഷം, പ്രീഫില്ലർ നോഡ് KV പേജുകൾ ഡീ-അലോക്കേറ്റ് ചെയ്യുകയും അഭ്യർത്ഥന പൂർത്തിയാക്കുകയും ചെയ്യുന്നു. ഡീകോഡർ നോഡിനെ വ്യക്തമായി അറിയിക്കുന്നില്ല; പകരം, പൂർത്തിയായ പ്രവർത്തനങ്ങളുടെ എണ്ണം ട്രാക്ക് ചെയ്യാൻ ഇത് ഉടനടി കൗണ്ടറുകൾ ഉപയോഗിക്കുന്നു. പ്രീഫില്ലർ വശത്തെ RDMA പ്രവർത്തനങ്ങളുടെ എണ്ണം കൈമാറ്റം ചെയ്യപ്പെട്ട പേജുകളുടെ എണ്ണത്തിന് ആനുപാതികമാണ്. അറിയപ്പെടുന്ന പേജ്, കോൺടെക്സ്റ്റ് പകർപ്പുകളുടെ എണ്ണം പൂർത്തിയായ ശേഷം, ഒരു അഭ്യർത്ഥന ഡീകോഡിംഗിന് തയ്യാറാണെന്ന് സൂചിപ്പിക്കാൻ fabric-lib KV മെസ്സഞ്ചറെ വിളിക്കുന്നു. മെസ്സഞ്ചർ ഏതെങ്കിലും കോൺടെക്സ്റ്റ് ഡീ-അലോക്കേറ്റ് ചെയ്യുകയും LLM എൻജിന് അഭ്യർത്ഥന കൈമാറുകയും ചെയ്യുന്നു.
ഷാർഡ് ചെയ്ത KV കാഷ് കൈമാറ്റങ്ങൾ
പ്രീഫില്ലറും ഡീകോഡറും ടെൻസർ പാരലലിസത്തെ (TP) ആശ്രയിക്കുകയും KV കാഷുകൾ സമാനമായി ഷാർഡ് ചെയ്യുകയോ റെപ്ലിക്കേറ്റ് ചെയ്യുകയോ ചെയ്യുകയാണെങ്കിൽ, എല്ലാ റെപ്ലിക്കകളുടെയും പേജുകൾ അയക്കാനും സ്വീകരിക്കാനും ഒരു സിംഗിൾ ട്രാൻസ്ഫർ എൻജിൻ ഒന്നിലധികം ഉപകരണങ്ങളെ ഏകോപിപ്പിക്കുന്നു. മോഡലിന്റെ എക്സിക്യൂട്ടർ ഒന്നിലധികം ഉപകരണങ്ങളിലും പ്രോസസ്സുകളിലുമായി റെപ്ലിക്കേറ്റ് ചെയ്യപ്പെട്ടിട്ടും ഒരു ഒറ്റപ്പെട്ട മെസ്സഞ്ചറും ട്രാൻസ്ഫർ എൻജിനും ഉപയോഗിക്കാൻ കഴിയുന്നതിനായി, KV കാഷുകളെ പിന്തുണയ്ക്കുന്ന ഡിവൈസ് മെമ്മറി അലോക്കേറ്റ് ചെയ്യാനും പ്രധാന പ്രോസസ്സിലേക്ക് മാപ്പ് ചെയ്യാനും cuMem, cuMemImportFromShareableHandle എന്നിവ ഉപയോഗിക്കുന്നു. ഓരോ KV കാഷ് സ്ലൈസുകളുടെയും കൈമാറ്റത്തിനായി ഉപയോഗിക്കുന്നതിന് ഏറ്റവും അടുത്തുള്ള NUMA നോഡിലെ NIC-കളെയും CPU-കളെയും കണ്ടെത്താൻ ട്രാൻസ്ഫർ എൻജിൻ നോഡിന്റെ ടോളോജി പരിശോധിക്കുന്നു.
ഉറവിടവും ലക്ഷ്യസ്ഥാനവും സമാനമായി ഷാർഡ് ചെയ്തിട്ടുണ്ടെങ്കിൽ, ഉറവിടത്തിന്റെയും ലക്ഷ്യസ്ഥാനത്തിന്റെയും ഉപകരണങ്ങളും പേജുകളും തമ്മിൽ വൺ-ടു-വൺ മാപ്പിംഗ് ഉള്ളതിനാൽ കൈമാറ്റങ്ങൾ വളരെ ലളിതമാണ്. ഈ സാഹചര്യത്തിൽ, ഷാർഡിങ് കൈമാറ്റ ലേറ്റൻസിയെ പരോക്ഷമായി സഹായിക്കുന്നു: കൂടുതൽ GPU-കൾ ഉപയോഗിക്കുന്നതിലൂടെ, കൂടുതൽ ബന്ധപ്പെട്ട NIC-കൾ ഉപയോഗപ്പെടുത്താം, ഇത് പൂർണ്ണ ബാൻഡ്വിഡ്ത്ത് യൂട്ടിലൈസേഷനോട് അടുത്തെത്തുന്നു. എന്നിരുന്നാലും, പൊരുത്തക്കേട് ഉണ്ടെങ്കിൽ, ഉറവിട, ലക്ഷ്യസ്ഥാന സ്ലൈസുകൾ തമ്മിലുള്ള അനുപാതത്തെ ആശ്രയിച്ച് ട്രാൻസ്ഫർ എൻജിൻ പേജുകൾ വിഭജിക്കുകയോ പുനർനിർമ്മിക്കുകയോ വേണം.
പ്രീഫില്ലർ KV കാഷ് കൂടുതൽ ഉപകരണങ്ങളിലായി വിഭജിക്കുകയാണെങ്കിൽ, പ്രീഫില്ലർ ഉപകരണങ്ങളിൽ നിന്ന് അനുയോജ്യമായ പകുതികൾ അയച്ചുകൊണ്ട് ഡീകോഡറിൽ മുഴുവൻ പേജുകളും പുനർനിർമ്മിക്കപ്പെടുന്നു. ഡീകോഡറിന് കൂടുതൽ ഷാർഡുകൾ ഉണ്ടെങ്കിൽ, അത് ഒന്നിലധികം ഉറവിടങ്ങളിൽ നിന്ന് പേജുകൾ സ്വീകരിക്കുന്നു. ലഭിക്കുമെന്ന് പ്രതീക്ഷിക്കുന്ന RDMA റൈറ്റുകളുടെ എണ്ണം കണക്കാക്കാൻ ഡീകോഡറിന് പ്രീഫില്ലറുടെ ഷാർഡിങ് സ്കീമിനെക്കുറിച്ച് അറിയേണ്ടതുണ്ട്. റെപ്ലിക്കേഷൻ ഉൾപ്പെട്ടിട്ടുണ്ടെങ്കിൽ, പ്രീഫില്ലർ ഉപകരണങ്ങളെ അവയ്ക്കുള്ളിൽ മുഴുവൻ KV കാഷും റെപ്ലിക്കേറ്റ് ചെയ്യുന്ന റെപ്ലിക്ക സെറ്റുകളായി ഗ്രൂപ്പ് ചെയ്യുന്നു. ലഭ്യമായ എല്ലാ ഉപകരണങ്ങളും ഉപയോഗിച്ച് RDMA റൈറ്റുകൾ ആരംഭിക്കുന്നതിനായി ലക്ഷ്യസ്ഥാന റെപ്ലിക്ക സെറ്റുകൾക്ക് സോഴ്സ് സെറ്റുകളിൽ ഒന്ന് യാദൃശ്ചികമായി നൽകപ്പെടുന്നു.
ഷാർഡ് ചെയ്ത കൈമാറ്റങ്ങൾക്ക് KV കാഷുകളിൽ ചെറിയൊരു മാറ്റം ആവശ്യമാണ്. ഡിഫോൾട്ടായി, ഫ്ലാഷ് ഇൻഫർ NHD ലേഔട്ടിനെ ആശ്രയിക്കുന്നു, ഇത് ഒരു പേജിനുള്ളിലെ ടോക്കണുകളെ ഹെഡുകൾക്കുള്ളിൽ ക്രമീകരിക്കുന്നു. കാഷുകൾ മിക്കവാറും അറ്റൻഷൻ ഹെഡുകളുടെ എണ്ണത്തിനനുസരിച്ച് ഷാർഡ് ചെയ്യപ്പെട്ടിരിക്കുന്നതിനാൽ, ഇത് ഹെഡിനുള്ളിൽ കൃത്യതയില്ലായ്മ ഉണ്ടാക്കുന്നു. RDMA കൈമാറ്റങ്ങൾ സ്ട്രൈഡഡ് റൈറ്റുകളെ പരോക്ഷമായി പിന്തുണയ്ക്കുന്നില്ല, കൈമാറ്റം നടത്താൻ ഓരോ ഹെഡിനും ഒരു പ്രവർത്തനം ആവശ്യമാണ്. പകരം, libfabric ഡുമായുള്ള ഇടപെടലുകളുടെ എണ്ണം കുറയ്ക്കുന്നതിന്, ഹെഡ് ഡയമൻഷനെ ടോക്കണുകളുടെ എണ്ണത്തിന് മുമ്പായി സ്ഥാപിക്കുന്ന HND ലേഔട്ട് ഉപയോഗിച്ച് ഞങ്ങൾ KV കാഷുകൾ ഓർഗനൈസ് ചെയ്യുന്നു. ഇത് തുടർച്ച ഉറപ്പാക്കുകയും ഒറ്റ റൈറ്റിലൂടെ ഒരു പേജ് പകർത്താൻ അനുവദിക്കുകയും ചെയ്യുന്നു.
സ്പെക്കുലേറ്റീവ് ഡീകോഡിംഗ്
സ്പെക്കുലേറ്റീവ് ഡീകോഡിംഗിന് വേർപെടുത്തിയ പ്രീഫിൽ-ഡീകോഡിൽ ചെറിയ മാറ്റങ്ങൾ ആവശ്യമാണ്. ഞങ്ങളുടെ നടപ്പാക്കലിൽ, ടോക്കണുകൾ സാമ്പിൾ ചെയ്യാൻ പ്രീഫില്ലർ നോഡുകളെ അനുവദിക്കുന്നില്ല. Perplexity-യുടെ Sonar മോഡലുകൾ ഘടനാപരമായ ഔട്ട്പുട്ടിനെ പിന്തുണയ്ക്കുന്നതിനാൽ, പ്രീഫില്ലറുകളിലും ഡീകോഡറുകളിലുടനീളം സ്കീമ പ്രൊസസർ നടപ്പാക്കലുകൾ സമന്വയിപ്പിക്കുന്നതിന്റെ സങ്കീർണ്ണത വരുത്താൻ ഞങ്ങൾ ആഗ്രഹിക്കുന്നില്ല. MTP, സ്പെക്കുലേറ്റീവ് ഡീകോഡിംഗ് മെക്കാനിസങ്ങളിൽ, അവസാന ടോക്കൺ വരെ ഡ്രാഫ്റ്റ് മോഡൽ പ്രീഫിൽ ചെയ്യുന്നത് ടാർഗെറ്റ് മോഡലിൽ നിന്ന് ടോക്കണുകൾ സാമ്പിൾ ചെയ്യുന്നത് ഉൾക്കൊള്ളുന്നു.
ഈ പ്രശ്നങ്ങൾ പരിഹരിക്കുന്നതിന്, പ്രീഫിലിൽ ഇൻപുട്ട് സീക്വൻസിന്റെ അവസാന ടോക്കൺ ഉൾപ്പെടുന്നില്ല. പകരം, അവസാന ടോക്കണിന് മുമ്പുള്ള പ്രീഫിലിൽ നിന്നുള്ള ഹിഡൻ സ്റ്റേറ്റുകളോ ലോഗിറ്റുകളോ കൈമാറുകയും ഡീകോഡറിലെ അടുത്ത ഘട്ടത്തിൽ അതൊരു ഡീകോഡ് ടോക്കണായി കണക്കാക്കുകയും ചെയ്യുന്നു. പ്രീഫില്ലിന് ശേഷം ആദ്യത്തെ ടോക്കൺ നൽകുന്നതിന് പൂർണ്ണമായ ഒരു ഡീകോഡ് ഘട്ടം നിർവഹിക്കേണ്ടി വരുന്നതിനാൽ ഇത് ലേറ്റൻസി ചെറുതായി വർദ്ധിപ്പിക്കുമെങ്കിലും, നടപ്പാക്കലിന്റെ സങ്കീർണ്ണത ഗണ്യമായി കുറയ്ക്കപ്പെടുന്നു.
വേർപെടുത്തിയ വിന്യാസങ്ങൾ
പ്രൊഡക്ഷൻ ട്രാഫിക്കോ ഇൻ-ഹൗസ് ഇവാലുവേഷൻ വർക്ക്ലോഡുകളോ പിന്തുണയ്ക്കുന്നതിനായി, ഞങ്ങൾ വ്യത്യസ്ത മോഡലുകൾ ഉപയോഗിച്ച് ഒന്നിലധികം വേർപെടുത്തിയ കോൺഫിഗറേഷനുകൾ വിന്യവിക്കുകയോ പരീക്ഷിക്കുകയോ ചെയ്തിട്ടുണ്ട്. മോഡലുകളുടെ വലുപ്പത്തിന്റെയും അറ്റൻഷൻ മെക്കാനിസത്തിന്റെയും അടിസ്ഥാനത്തിൽ, GPU-കൾ ഏറ്റവും മികച്ച രീതിയിൽ ഉപയോഗപ്പെടുത്തുന്നതിന് പ്രീഫില്ലർ, ഡീകോഡർ നോഡുകൾക്കായി ഞങ്ങൾ അനുയോജ്യമായ ഷാർഡിങ് സ്കീമുകൾ തിരഞ്ഞെടുത്തു.
ഡീപ്സീക്ക്-ആർ1 (DeepSeek-R1)
DeepSeek ഉപയോഗിച്ച്, ഞങ്ങൾ ടെൻസർ-പാരലൽ (TP), ഡാറ്റാ-പാരലൽ (DP) വിന്യാസങ്ങൾ പരിഗണിച്ചു. മുൻ ബ്ലോഗ് പോസ്റ്റുകളിൽ ചർച്ച ചെയ്തതുപോലെ, TP വിന്യാസങ്ങൾ മികച്ച ലേറ്റൻസി നൽകുകയും കുറഞ്ഞ ത്രൂപുട്ടിന്റെ ചിലവിൽ വരികയും ചെയ്യുന്നു, കൂടാതെ കനത്ത ട്രാഫിക് സേവനം നൽകുന്നതിന് കൂടുതൽ GPU-കൾ ആവശ്യമായി വരുന്നു. ലോഡിനനുസരിച്ച് DP വിന്യാസങ്ങൾ വളരെ നന്നായി സ്കെയിൽ ചെയ്യുന്നു, എന്നിരുന്നാലും ഡിവൈസ്-ടു-ഡിവൈസ് അല്ലെങ്കിൽ നോഡ്-ടു-നോഡ് ആശയവിനിമയത്തിന്റെ ചിലവ് കാരണം അവയുടെ പീക്ക് ത്രൂപുട്ട് കുറവാണ്.
DeepSeek മൾട്ടി-ഹെഡ് ലേറ്റന്റ് അറ്റൻഷനെ ആശ്രയിക്കുന്നു, ഇത് KV കാഷുകൾ കംപ്രസ് ചെയ്യുന്നു. എല്ലാ KV ഹെഡുകളും ഒരൊറ്റ ലേറ്റന്റ് വെക്ടറിലേക്ക് കംപ്രസ് ചെയ്തിരിക്കുന്നതിനാൽ, KV കാഷുകൾ ഷാർഡ് ചെയ്യാൻ TP-ക്ക് കഴിയില്ല, പകരം അത് എല്ലാ റാങ്കുകളിലും ലേറ്റന്റ് വെക്ടറുകൾ റെപ്ലിക്കേറ്റ് ചെയ്യേണ്ടതുണ്ട്. ഓരോ റാങ്കിനും ഒരേ ലേറ്റന്റ് റെപ്രസന്റേഷനിൽ നിന്ന് വ്യത്യസ്ത ഹെഡുകൾ എക്സ്ട്രാക്റ്റ് ചെയ്യാൻ കഴിയുന്നതിനാൽ, ഡീകംപ്രഷന് ശേഷമാണ് ഷാർഡിങ് സംഭവിക്കുന്നത്. തൽഫലമായി, പ്രീഫില്ലർ, ഡീകോഡർ ഷാർഡുകൾ ഉടനീളം എല്ലാ KV കാഷ് ഷാർഡുകളും സമാനമായിരിക്കും.
ഒരു ഇൻട്രാസോൺ TP സജ്ജീകരണത്തിൽ, പ്രീഫില്ലറുകളും ഡീകോഡറുകളും സമാനമായി ഷാർഡ് ചെയ്യപ്പെടുന്നു. ലഭ്യമായ എല്ലാ NIC-കളും പൂർണ്ണമായി ഉപയോഗപ്പെടുത്തുന്നതിനായി എല്ലാ റാങ്കുകളിൽ നിന്നും കൈമാറ്റങ്ങൾ അയക്കപ്പെടുന്നു. എന്നിരുന്നാലും, DP വിന്യാസത്തിൽ, TP റാങ്ക് വലുപ്പം കുറവായിരിക്കുമ്പോഴോ അല്ലെങ്കിൽ ഓരോ DP റാങ്കും ഒരു GPU-ലേക്ക് അസൈൻ ചെയ്യുമ്പോഴോ, KV കാഷിന്റെ റെപ്ലിക്കേറ്റ് ചെയ്ത പകർപ്പ് കൈവശം വച്ചിരിക്കുന്ന ഏതൊരു പ്രീഫില്ലർ ഉപകരണത്തിനും അത് അയക്കാൻ കഴിയും. ലഭ്യമായ എല്ലാ NIC-കളിലുടനീളം അഭ്യർത്ഥനകൾ ബാലൻസ് ചെയ്യുന്നതിന്, പ്രീഫില്ലറിൽ നിന്ന് ഡീകോഡറിലേക്ക് KV കാഷ് അയക്കാൻ ഞങ്ങൾ യാദൃശ്ചികമായി ഒരു GPU ഉം ഒരു NIC ഉം തിരഞ്ഞെടുക്കുന്നു.
മിക്സ്ഡ് പ്രീഫിൽ-ഡീകോഡ് ഉപയോഗിച്ച്, നൂറുകണക്കിന് മില്ലിസെക്കൻഡ് ക്രമത്തിലുള്ള ഇടയ്ക്കിടെയുള്ള പ്രീഫിൽ തടസ്സങ്ങൾ കാരണം ഞങ്ങളുടെ R1 വിന്യാസം സ്ഥിരമായി 50 TPS കവിയാൻ പാടുപെടുകയായിരുന്നു. ഇതിനു വിപരീതമായി, പ്രീഫിൽ വേർതിരിക്കുന്നതിലൂടെ, ഓരോ അഭ്യർത്ഥനയ്ക്കും TTFT-ലേക്ക് ഏകദേശം 100ms പെനാൽറ്റി ഞങ്ങൾ വരുത്തിവച്ചു, എന്നാൽ ഒരു പ്രീഫില്ലർ നോഡിന് 3 ഡീകോഡർ നോഡുകളിൽ സ്ഥിരമായ ബാച്ച് വലുപ്പങ്ങൾ നിലനിർത്താൻ കഴിഞ്ഞു, ഓരോ ഡീകോഡർ നോഡിനും ഏകദേശം 1 QPS ലോഡ് കൈകാര്യം ചെയ്യുമ്പോൾ 90 TPS-ൽ അധികം ത്രൂപുട്ട് നൽകുകയും ചെയ്തു. ഡാറ്റാ-പാരലൽ വിന്യാസങ്ങൾ ഉപയോഗിച്ച്, TPS ഏകദേശം 50 ആയി അല്പം കുറവായിരുന്നു, എന്നിരുന്നാലും ഒരൊറ്റ നോഡിൽ 8 റാങ്കുകൾ വീതം, ഓരോ റാങ്കിനും 1 QPS ലോഡ് ഇൻസ്റ്റൻസുകൾക്ക് കൈകാര്യം ചെയ്യാൻ കഴിയുമായിരുന്നു.
ക്യൂവൺ3-കോഡർ (Qwen3-Coder)
ഈ 480B മോഡൽ ഗ്രൂപ്പ്ഡ്-ക്വറി അറ്റൻഷൻ (GQA) ഉപയോഗിക്കുന്നു, അതിനാൽ അറ്റൻഷൻ എളുപ്പത്തിൽ ഷാർഡ് ചെയ്യാൻ കഴിയും കൂടാതെ KV കാഷുകൾക്കായി മെമ്മറി നഷ്ടപ്പെടുത്താതെ ടെൻസർ പാരലലിസത്തിന്റെ പ്രയോജനം നേടാനും കഴിയും. തൽഫലമായി, പ്രീഫില്ലിനും ഡീകോഡിനുമായി 8 GPU-കളിലുടനീളം ഞങ്ങൾക്ക് മോഡൽ ഷാർഡ് ചെയ്യാൻ കഴിഞ്ഞു, ഏകദേശം 3 ഡീകോഡർ നോഡുകളെ ഒരൊറ്റ പ്രീഫില്ലർ നോഡുമായി ജോടിയാക്കുന്നു. അറ്റൻഷൻ ഷാർഡ് ചെയ്തിരിക്കുന്നതിനാൽ, പ്രീഫില്ലർ, ഡീകോഡർ KV കാഷുകൾ ഷാർഡ് ചെയ്യാൻ ഞങ്ങൾ HND KV കാഷ് ലേഔട്ടിനെ ആശ്രയിക്കുന്നു, പ്രീഫില്ലർ റാങ്കുകളെ ഡീകോഡർ റാങ്കുകളുമായി ജോടിയാക്കുകയും സ്ലൈസുകൾ സമാന്തരമായി കൈമാറാൻ എല്ലാ NIC-കളും പൂർണ്ണമായി ഉപയോഗിക്കുകയും ചെയ്യുന്നു.
ഉദ്ധരണി
@online{perplexity2025DisaggregatedPrefillAndDecode,
author = {{Perplexity} and Nandor Licker and Lequn Chen and Kevin Hu and Erin McKnight and Phi Hoang},
title = {{Disaggregated prefill and decode}},
date = {2025-08-01},
url = {https://perplexity.coolkeypoint.com/hub/blog/disaggregated-prefill-and-decode}
}