Mélytanulási gépi modellek alkalmazásánál ismert működési paraméter a batch_size (magyarul kb. “kötegméret”, de mivel ilyen formán nem igazán használjuk). Ez a hiperparaméter a tréningfolyamatban is használatos, ez a cikk most azonban csak az inferencia aspektusaival foglalkozik, méghozzá speciális összefüggésben.
Autoregresszív vagy iteratív-inkrementális modelltípusok esetén (mint tipikusan az LLM-ek, az olyan szekvenciális architektúrák, mint a transzformerek vagy akár RNN és különféle változatai) a köteg ugyanis sajátosan értelmezhető: az egyes, jellemzően különböző hosszúsági feldolgozandó szekvenciák (pl. mondatok vagy idősorozat-lépések) egységét jelenti, amelyek inferencia esetén egy menetben szeretnénk a már kész modellbe beküldeni. Alkalmazásának fő indoka gazdasági jellegű: predikció esetében (sem) célszerű egyesével betölteni és átküldeni a modelleken az adatokat, olcsóbb, ha egyszerre több példányt futtatunk át rajta egyszerre, így több munkát adunk a GPU-nak, jobban ki van használva a memóriája. A kötegelésre jellemzően az ún. statikus (static batching) módszer az alapértelmezett és elterjedt, amikor előre meghatározott (jellemzően egy-két tucattól száz-kétszáz közötti) számú kérést álltunk össze előre, de léteznek további, fejlettebb lehetőségek is – ezek közül mutatjuk be most a dinamikus és folyamatos kötegelés módszereit.
De mi a probléma a statikus batching paradigmájával? Olyan esetekben, ahol nagy számú input áll eleve rendelkezésre, és a predikciónál egyébként sem a sebesség vagy válaszidő számít, jó választás, hiszen itt nem szükséges a beérkező megfigyelésekre külön várakozni, a tömeges, egy körben történő lineárisalgebra-műveletek alkalmazása pedig mindig a leghatékonyabb. A nehézségek online, folyamatos inferencia esetén jelentkeznek, ilyenkor ugyanis a batchhoz előre meghatározott számú rekord összegyűjtése hosszabb, meghatározhatatlan ideig tart, az első és utolsó elem beérkezése között akár számottevő idő is eltelhet, vagy a különböző hosszúságú tokenszekvenciák feldolgozása nem egyszerre ér véget, így az egész működés kiszámíthatatlan, gazdaságtalanabb, ráadásul még az ügyfélélményt is negatívan befolyásolhatja. Ezt a problémát több módon is orvosolni lehet.
Dinamikus kötegelés (dynamic batching)
Ez a megközelítés egyetlen koncepcionális javítást tartalmaz: nem fix elemszámot vár a batch feldolgozásának elindításához (ami, ahogy fentebb írtuk, kiszámíthatatlanul hosszú ideig is eltarthat), hanem két paraméter – a maximális elemszám és egy timeout időtartam (utóbbi az első elem beérkezésekor indul) – bevezetésével dinamizálja a folyamatot. A predikció akkor indul be, amikor a két (igény szerint beállítható) paraméter közül az egyik teljesül. A megoldás így elejét veszi a túl hosszú várakozásnak azon a kompromisszumos áron, hogy kevesebb (szélsőséges esetben akár egyetlen) szekvenciával, gazdaságtalanabbul is elindul az inferencia. Viszont fennáll az a hátrány, hogy a kötegben lévő szekvenciák közül a rövidebbeknek minden esetben meg kell továbbra is várniuk a leghosszabb feldolgozását – erre kínál megoldást a következő eljárástípus.
Folyamatos kötegelés (continuous batching)
Ez a paradigma a fix kötegfeldolgozás helyett az egyes dekódolási lépéseket veszi alapul az ütemezésnél. Tehát nem szükséges megvárni az adott batchben lévő valamennyi, eltérő hosszúságú szekvencia feldolgozását, hanem abban az esetben, ha a egy rövidebb szekvencia feldolgozása befejeződött, az kikerül a kötegből és bekerül helyére a következő várakozó sorozat. Lényegében tehát gördülő szabad helyekről van szó, amelyekkel ugyan a hosszabb sorozatok feldolgozása nem lesz gyorsabb, de több sorozatot tudunk hamarabb feldolgozni, hamarabb végzünk az egész feladattal. Mivel ez a koncepció talán az előzőnél kevésbé jobban érthető szövegesen, álljon itt egy ábra szemléltetésül, ahol jól látható, hogy milyen logika és dinamika szerint történik a feladatvégzés (A-I egy-egy, különböző tokenszámú szekvenciát jelöl):
A: █
B: █
C: █
D: ███████████████████████████████
E: █████
F: ███
G: ███████
H: █████
I: ███████
Több LLM-modellek használatára szolgáló specifikus framework (pl. a TensorRT-LLM) egyébként alapértelmezetten már ezt, nem pedig a static batching a megoldást használja. RNN-modelleknél is megvalósítható mindkét fenti mechanizmus, de saját scheduler írása szükséges hozzá.