લોકલ લાર્જ લેંગ્વેજ મોડલ્સ (LLMs) શરૂઆતમાં વીજળીથી પણ ઝડપી લાગે છે. તમે 7B અથવા 13B પેરામીટર વાળું મોડલ લોડ કરો છો, એક નાનો પ્રોમ્પ્ટ આપો છો, અને ટોકન્સ સ્ક્રીન પર આરામદાયક ઝડપે વહેવા લાગે છે. પછી તમે લાંબો કોડ બ્લોક પેસ્ટ કરો છો, અથવા તમારી ચેટ હિસ્ટ્રી ઘણા ટર્ન્સ સુધી વધી જાય છે, અને મોડલ ધીમું પડવા લાગે છે. આ ધીમા પડવાની પ્રક્રિયા ભાગ્યે જ ધીમેથી થાય છે. તે એકાએક પતન (cliff) જેવું હોય છે. એક ક્ષણે GPU ટોકન્સ બનાવી રહ્યું હોય છે; અને બીજી જ ક્ષણે, તમારું સિસ્ટમ મોનિટર મેમરી પ્રેશર વધતું બતાવે છે અને જનરેશન અટકી-અટકીને ચાલવા લાગે છે. તમે કોઈ ચોક્કસ સૂત્ર દ્વારા આ ક્યારે થશે તે જાણી શકતા નથી. તમારો એકમાત્ર વિશ્વસનીય માર્ગદર્શક પોતે હાર્ડવેર જ છે.

કોન્ટેક્સ્ટ (Context) ની છુપી કિંમત

તમે જે દરેક ટોકન જનરેટ કરો છો તે KV cache માં સ્ટેટ ઉમેરે છે. આ કેશ (cache) પ્રીફિલ (prefill) અને જનરેશન તબક્કા દરમિયાન ગણતરી કરેલા કી (keys) અને વેલ્યુઝ (values) ને સ્ટોર કરે છે, અને તે તમારા મોડલ વેટ્સ (weights), એટેન્શન બફર્સ (attention buffers) અને રનટાઇમ ઓવરહેડ (runtime overhead) ની સાથે મેમરીમાં રહે છે. 12 GB અથવા 16 GB VRAM ધરાવતા સામાન્ય કન્ઝ્યુમર GPU પર, KV cache અંતે અન્ય તમામ વસ્તુઓ સાથે જગ્યા માટે સ્પર્ધા કરે છે. જ્યારે ડેડિકેટેડ વિડિયો મેમરી ભરાઈ જાય છે, ત્યારે ઓપરેટિંગ સિસ્ટમ કોઈ એરર આપીને અટકી જતી નથી. તે શાંતિથી વધારાના ડેટાને શેર્ડ મેમરીમાં (shared memory) મોકલી દે છે, અને PCIe બસ દ્વારા GPU અને સિસ્ટમ RAM વચ્ચે ડેટાની અવરજવર કરે છે. તે બસ ફાઇલ ટ્રાન્સફર માટે ઝડપી છે, પરંતુ ગ્રાફિક્સ કાર્ડની અંદરની મેમરી બેન્ડવિડ્થની સરખામણીમાં તે અત્યંત ધીમી છે. પરિણામ એ પરફોર્મન્સમાં નાનો ઘટાડો નથી, પરંતુ તે સંપૂર્ણ પતન (collapse) છે.

ત્રણ સંકેતો જે દર્શાવે છે કે પતન (Cliff) આવી ગયું છે

જ્યારે મોડલ ચાલતું હોય ત્યારે તમારા હાર્ડવેર મોનિટર પર નજર રાખો. એકવાર પરફોર્મન્સમાં મોટો ઘટાડો થાય એટલે તમને ત્રણ સ્પષ્ટ સંકેતો જોવા મળશે.

  • Shared VRAM વધે છે. આ એવી મેમરી છે જેને GPU ડ્રાઇવરે ડેડિકેટેડ વિડિયો RAM માંથી હોસ્ટ ઓપરેટિંગ સિસ્ટમ દ્વારા સંચાલિત પૂલમાં ખસેડી દીધી છે. જે ક્ષણે આ મેટ્રિક શૂન્યથી ઉપર જાય છે, તેનો અર્થ છે કે તમે મર્યાદા ઓળંગી ગયા છો.
  • System RAM નો વપરાશ વધે છે. વધારાનો ડેટા ક્યાંક તો જવું જ પડે છે, અને તે સ્થળ તમારી મુખ્ય મેમરી છે. જો મોડલ ટોકન્સ જનરેટ કરતી વખતે તમારો RAM વપરાશ વધતો હોય, તો તેનો અર્થ છે કે ડેટા GPU માંથી બહાર કાઢવામાં આવી રહ્યો છે.
  • Eval સ્પીડ અડધી અથવા તેનાથી વધુ ઘટી જાય છે. 10% નો ઘટાડો થર્મલ થ્રોટલિંગ (thermal throttling) અથવા બેકગ્રાઉન્ડ પ્રોસેસ હોઈ શકે છે. 50% નો ઘટાડો, અથવા તેનાથી વધુ ખરાબ પરિસ્થિતિનો અર્થ એ છે કે બોટલનેક (bottleneck) ટેન્સર કોર્સ (tensor cores) માંથી બદલાઈને મેમરી બેન્ડવિડ્થ અને PCIe લેટન્સી (latency) માં આવી ગયો છે. જ્યારે તમે જુઓ કે જનરેશન ડબલ ડિજિટ્સમાંથી સિંગલ ડિજિટ્સમાં આવી જાય છે, ત્યારે તમે પહેલેથી જ પતનનો અનુભવ કરી રહ્યા છો.

તમારું ઝડપી બેન્ચમાર્ક કદાચ ખોટું કહી રહ્યું છે

એક નાનો ટેસ્ટ તમને ખોટો આત્મવિશ્વાસ આપી શકે છે. જો તમે સો ટોકનવાળા પ્રોમ્પ્ટ સાથે મોડલનું બેન્ચમાર્ક કરો છો, સારો થ્રુપુટ (throughput) જુઓ છો અને માની લો છો કે બધું બરાબર છે, તો તમે માત્ર શરૂઆતના સુખદ તબક્કાને (honeymoon phase) માપ્યો છે. KV cache લગભગ ખાલી હોય છે. લાંબા પ્રીફિલ (prefill) દ્વારા લેયર્સ પર દબાણ આવ્યું હોતું નથી. સાચું પરિણામ ત્યારે જ ખબર પડે છે જ્યારે મોડલ એક મોટો પ્રોમ્પ્ટ પ્રોસેસ કરે છે અને કેશ તેની વાસ્તવિક કાર્યકારી સાઈઝ સુધી ભરાઈ જાય છે. તમારે ઊંડા પ્રીફિલ (deep prefill) અને લાંબા જનરેશન રન સાથે ટેસ્ટ કરવું જોઈએ. કોન્ટેક્સ્ટને ખરેખર એકત્રિત થવા દો. તો જ મેમરી પ્રેશર સ્થિર થશે અને તમને સાચી મર્યાદા બતાવશે.

llama.cpp સાથે તમારી મર્યાદા શોધો

જો તમે llama.cpp દ્વારા મોડલ્સ ચલાવી રહ્યા છો, તો તમે સાદા અંકગણિત અને ધીરજપૂર્ણ ટેસ્ટ રન દ્વારા તમારી મર્યાદા માપી શકો છો.

1. શેર્ડ મેમરી વપરાશ માપો.
એક લઘુત્તમ પ્રોમ્પ્ટ સાથે તમારા બેઝલાઇન ડેડિકેટેડ VRAM ને રેકોર્ડ કરો, પછી લાંબા કોન્ટેક્સ્ટ વાળું કાર્ય ચલાવો અને તેની પીક (peak) નોંધો. પીકમાંથી બેઝલાઇન બાદ કરો. જે તફાવત મળે છે તે તમારો ડેટા GPU માંથી શેર્ડ સિસ્ટમ મેમરીમાં ફેલાયો છે.

2. તમારો RAM ડેલ્ટા (delta) ગણો.
સિસ્ટમ RAM માટે પણ આ જ બાદબાકી કરો. લાંબા રન દરમિયાન પીક RAM માંથી તમારી બેઝલાઇન RAM બાદ કરો. આ સંખ્યા તમને ચોક્કસ જણાવશે કે વિડિયો કાર્ડમાંથી તમારી મુખ્ય મેમરીમાં કેટલો ડેટા ખસેડવામાં આવ્યો છે. તે બસ દ્વારા થતા ડેટા લીકેજનું પ્રમાણ દર્શાવે છે.

3. Eval સ્પીડના પતનને સમય આપો.
મોડલ લાંબો દસ્તાવેજ પ્રોસેસ કર્યા પછીની ઝડપની સરખામણી તમારા બેઝલાઇન ટોકન્સ-પર-સેકન્ડ રેટ સાથે કરો. તમે જોઈ શકો છો કે જ્યારે કોન્ટેક્સ્ટ નવું હોય ત્યારે મોડલ સેકન્ડ દીઠ સત્તર ટોકન્સની ઝડપે ચાલે છે, પરંતુ કેશ ભરાઈ ગયા પછી તે માત્ર સેકન્ડ દીઠ બે ટોકન્સ જ આપે છે. આ પંદર-ટોકનનો ઘટાડો એ તમારા માટે ચેતવણીનો સંકેત છે.

બ્રેકિંગ પોઈન્ટનું ટ્રાયન્ગ્યુલેશન (Triangulating)

વળાંકને સચોટ રીતે મેપ કરવા માટે, માત્ર એક જ ડેટા પોઈન્ટ પર સંતોષ ન માનો. 16,000 tokens, 32,000 tokens, અને 65,000 tokens પર ત્રણ અલગ-અલગ ટ્રાયલ ચલાવો. બે પોઈન્ટ્સ એક રેખા સૂચવી શકે છે, પરંતુ બે ટપકાં માત્ર એક અનુમાન છે. ત્રીજો પોઈન્ટ એ સાબિત કરે છે કે તમે મેઝરમેન્ટ નોઈઝ (measurement noise) જોઈ રહ્યા છો કે વાસ્તવિક મેમરી વોલ (memory wall). તમારા મોડેલ, ક્વોન્ટાઈઝેશન લેયર (quantization layer) અને GPU ના ચોક્કસ સંયોજન પર દરેક વધારાના હજાર ટોકન્સ કેટલા વધારાના મેમરીનો વપરાશ કરે છે તે ગણવા માટે રન વચ્ચેના પરિણામો બાદ કરો.

એકવાર તમારી પાસે તે સ્લોપ (slope) આવી જાય, પછી તમે આગળનું અનુમાન કરી શકો છો. તમારી પ્રતિ-ટોકન કિંમત લો, તેને લક્ષિત કોન્ટેક્સ્ટ લંબાઈ (target context length) સાથે ગુણો, યુનિટ્સ બદલવા માટે 1024 વડે ભાગો, અને પરિણામને તમારા બેઝ મોડેલ VRAM લોડમાં ઉમેરો. સમીકરણ આ મુજબ દેખાશે:

Model VRAM load + (tokens × memory per token ÷ 1024) = Theoretical VRAM usage

આ પ્રોજેક્શન કોઈ ભવિષ્યવાણી નથી. તે વાસ્તવિક વર્તણૂક પરથી મેળવેલ એક માર્ગદર્શક છે. સંપૂર્ણ પ્રોડક્શન રન માટે પ્રતિબદ્ધ થતા પહેલા તમારી મર્યાદા (ceiling) અંદાજવા માટે તેનો ઉપયોગ કરો.

પેપર ફોર્મ્યુલા કેમ નિષ્ફળ જાય છે, અને ક્વોન્ટાઈઝેશન શું સુધારી શકે