A nagy nyelvi modellek (LLM-ek) mindenhol megtalálhatók, a mindennapi alkalmazásoktól a fejlett eszközökig. Könnyű őket használni. De mi van, ha saját modellt kell futtatnia? Függetlenül attól, hogy finoman illeszkedik-e az egyikhez, vagy magánéletre érzékeny adatokkal foglalkozik, a komplexitás növekszik. Ebben a bejegyzésben megosztjuk, amit saját LLM következtetési rendszerünk építése során megtanultunk. Beszámolunk a modellek tárolásáról és telepítéséről, a szolgáltatás architektúrájának megtervezéséről és a valós problémák megoldásáról, mint például az útválasztás, a streaming és a mikroszolgáltatások kezelése. A folyamat kihívásokat jelentett, de végül megbízható rendszert építettünk Bevezetés Az LLM-ek széles körű alkalmazásokat hajtanak végre - a chatbotoktól és a munkafolyamat-ügynököktől az intelligens automatizálási eszközökig.Míg a keresési fokozott generáció, a szerszámhívás és a több ügynök protokollok fontosak, az alapmotort meghaladó szinten működnek: alapvető LLM. Számos projekt külső szolgáltatókra támaszkodik, mint például az , vagy , ami elegendő a legtöbb használat esetén. De bizonyos alkalmazások esetében ez gyorsan problémává válik. Mi van, ha a szolgáltató leáll? Mi van, ha teljes ellenőrzésre van szüksége a késleltetés, az árképzés vagy az üzemidő felett? A legfontosabb - mi van, ha törődik a magánélet védelmével, és nem engedheti meg magának, hogy felhasználói adatokat küldjön harmadik félnek? megnyitó Kettős Anthropic megnyitó Kettős Antropológus Ez az, ahol az önkiszolgálás létfontosságúvá válik. Az előképzett vagy finoman beállított modell kiszolgálása ellenőrzést, biztonságot és a modell egyedi üzleti igényekhez való igazításának képességét biztosítja. Egy ilyen rendszer építése nem igényel nagy csapatot vagy kiterjedt erőforrásokat. Szerény költségvetéssel, kis csapatgal és csak néhány csomópontgal építettük fel. Ez a korlátozás befolyásolta építészeti döntésünket, és megkövetelte, hogy a gyakorlatiasságra és a hatékonyságra összpontosítsunk. Általános áttekintés Ezek az alapvető elemek képezik a rendszer gerincét. Formátumok és kódolás A szolgáltatások közötti megosztott nyelv elengedhetetlen, ami következetes kérés/válasz formátumokat, generációs paraméterrendszereket, párbeszéd-történeti struktúrákat és sorozást jelent, amely mindenhol működik – a frontendtől a backendig a modell futókig. Streaming és útválasztás. A több modell, kérés típusa és a fogadó prioritásainak kezelése szándékos útválasztási döntéseket igényel. Megmutatjuk, hogy a bejövő felhasználói kérelmek hogyan kerülnek útválasztásra a rendszerben – a kezdeti bemeneti ponttól a megfelelő munkavállalói csomópontig – és hogyan kerülnek visszaküldésre a válaszok. Modellek tárolása és telepítése. Hol élnek a modellek, és hogyan készülnek fel a termelési felhasználásra? Megvitatjuk a végrehajtandó legfontosabb teszteket, beleértve a modell megbízhatóságának biztosítását is. Megfigyelhetőség. Honnan tudod, hogy a dolgok működnek? megmutatjuk, milyen mutatókat követünk, hogyan figyelemmel kísérjük a meghibásodásokat, és a szondákat, amelyeket a rendszer egészségének és megbízhatóságának biztosítására használunk. Schema és adatkódolás A megfelelő adatátviteli rendszer kiválasztása kulcsfontosságú.A szolgáltatások közötti megosztott formátum egyszerűsíti az integrációt, csökkenti a hibákat és javítja az alkalmazkodóképességet.A célunk az volt, hogy a rendszert úgy alakítsuk ki, hogy az zökkenőmentesen működjön mind az önállóan üzemeltetett modellekkel, mind a külső szolgáltatókkal – anélkül, hogy a felhasználó számára különbségeket tárnánk fel. Miért fontos a tervezés Nincs univerzális szabvány az LLM adatcserére. Sok szolgáltató hasonló rendszereket követ Míg mások – mint vagy Sok ilyen szolgáltató olyan OpenAI-kompatibilis SDK-kat kínál, amelyek ugyanazt a rendszert tartják fenn, bár gyakran korlátozásokkal vagy csökkentett funkciókkal rendelkeznek (pl. az , Egyéb projektek, mint például A cél az, hogy egyesítsük ezeket a variációkat egy OpenAI-kompatibilis felületbe csomagolva. Az OpenAI Claire Kettős Az Anthropic OpenAI-kompatibilis SDK Gemini OpenAI kompatibilitási rétege Az OpenRouter Az OpenAI Claire Kettős Az Anthropic OpenAI-kompatibilis SDK Gemini OpenAI kompatibilitási rétege Az OpenRouter Az egyetlen előre meghatározott szolgáltatói rendszerhez való ragaszkodásnak előnyei vannak: You get a . well-tested, stable API Meglévő SDK és eszközökre támaszkodhat. De vannak valódi hátrányai is: Ez létrehozza a beszállító zárolását, ami megnehezíti a többszolgáltató támogatását. Ez korlátozza a rugalmasságot, hogy kiterjessze a rendszert az üzleti igényekhez vagy az adatkutatási csapat követelményeihez szükséges egyéni funkciókkal. Ön ki van téve a megszakító változásoknak vagy leértékeléseknek, amelyek kívül esnek az Ön irányításán. Ezek a rendszerek gyakran hordoznak örökletes korlátozásokat, amelyek korlátozzák a finom szemek ellenőrzését. Ennek megoldása érdekében úgy döntöttünk, hogy a - igényeink köré tervezett rendszer, amelyet szükség esetén különböző külső formátumokba térképezhetünk. own internal data model belső tervek tervezése Mielőtt a kihívásokkal foglalkoznánk, határozzuk meg a problémát, és vázoljuk fel a megoldásra vonatkozó elvárásainkat: Easy conversion to formats required by external providers and in reverse. Teljes körű támogatás az üzleti és adatkutatási csapatainkra jellemző funkciókhoz. Ensure the schema is easily extendable to accommodate future requirements. Elkezdtük a főbb LLM rendszerek felülvizsgálatát, hogy megértsük, hogyan strukturálják a szolgáltatók az üzeneteket, a paramétereket és a kimeneteket. Közös a legtöbb rendszerben, beleértve: core domain entities Üzenetek (például gyors, történelem) Generációs paraméterek (például hőmérséklet, top_p, beam_search) We identified certain parameters, such as az , vagy , mint a szolgáltató belső konfigurációjának és üzleti logikájának sajátosságait. Ezek az elemek az LLM alapvető tartományán kívül helyezkednek el, és nem képezik a megosztott rendszer részét. Ehelyett opcionális kiterjesztéseként kezelik őket. Amikor egy funkció széles körben elfogadhatóvá válik vagy szükségessé válik a szélesebb körű interoperabilitás érdekében, értékeljük az alapvető rendszerbe való integrálását. service_tier usage_metadata reasoning_mode At a high level, our input schema is structured with these key components: Modell – útválasztási kulcsként használják, útválasztási azonosítóként működik, lehetővé téve a rendszer számára, hogy a kérést a megfelelő munkavállalói csomóponthoz irányítsa. Generációs paraméterek – Core modellbeállítások (például hőmérséklet, top_p, max_tokens) Üzenetek – Beszélgetések előzményei és azonnali kifizetések. Eszközök – Az eszközök meghatározása, amelyeket a modell használhat. Ezzel az alábbi ábrához vezetünk, melyet a A tervezés szerkezetét és szándékát illusztrálja, bár néhány végrehajtási részletet az egyszerűség érdekében kihagynak. Pydantic-like Pydantic-like class ChatCompletionRequest(BaseModel): model: str # Routing key to select the appropriate model or service messages: list[Message] # Prompt and dialogue history generation_parameters: GenerationParameters # Core generation settings tools: list[Tool] # Optional tool defenitions class GenerationParameters(BaseModel): temperature: float top_p: float max_tokens: int beam_search: BeamSearchParams # Optional, non-core fields specific to certain providers provider_extensions: dict[str, Any] = {} ... # Other parameters A generációs paramétereket szándékosan elkülönített mezőbe helyeztük ahelyett, hogy a gyökérszinten helyeznénk el őket. paraméterek (például hőmérséklet, top-p, modellbeállítások) és Sok csapat az ökoszisztémánkban ezeket az állandó paramétereket külső konfigurációs rendszerekben tárolja, így ez a szétválasztás praktikus és szükséges. állandó Változó Egy további mezőt, az úgynevezett belül a class. These parameters vary significantly across different LLM providers, validation and interpretation of these fields is — az a komponens, amely tudja, hogyan kommunikáljon egy adott modellszolgáltatóval. Így elkerüljük a felesleges átviteli párosítást, amelyet a többszolgáltatás közötti redundáns adatok érvényesítése okoz. provider_extensions GenerationParameters delegated to the final module that handles model inference A visszamenőleges kompatibilitás biztosítása érdekében új kimeneti rendszerfunkciók kerülnek bevezetésre: Ezek a mezők a funkció zászlóként működnek – a felhasználóknak be kell állítaniuk őket, hogy választhassanak bizonyos viselkedésekre. Ez a megközelítés stabilan tartja az alaptervet, miközben fokozatos fejlődést tesz lehetővé. Például az érvelési nyomok csak akkor kerülnek bele a kimenetbe, ha a megfelelő mező be van állítva a kérésbe. explicit, optional fields Ezeket a rendszereket egy megosztott Python-könyvtárban tartják fenn, és a szolgáltatások között használják a kérések és válaszok következetes kezelésének biztosítására. Harmadik fél szolgáltatókkal való együttműködés We began by outlining how we built our own platform — so why bother with compatibility across external providers? Despite relying on our internal infrastructure, there are still several scenarios where external models play a role: Szintetikus adatgyártás prototípusok készítéséhez és kísérletezéséhez adattudományi csapataink által. Általános célú feladatok, ahol egyes szabadalmaztatott modellek jobban teljesítenek a dobozból. where privacy, latency, or infrastructure control are less critical. Non-sensitive use cases A külső szolgáltatókkal folytatott átfogó kommunikációs folyamat a következőképpen összegezhető: Ez a folyamat magában foglalja a következő lépéseket: Special responsible for communication with provider receives user request in our schema-format. LLM-Gateway Service The request is converted into the provider-specific format, including any . provide_extensions A külső szolgáltató feldolgozza a kérést és visszaküldi a választ. The receives the response and maps it back into our standardized response schema. LLM-Gateway Service Ez egy magas szintű vázlat, amely néhány egyedi mikroszolgáltatást távolít el. Részletek az egyes komponensekről és a streaming válaszformátumról az alábbi szakaszokban találhatók. Streaming formátum Az LLM válaszokat fokozatosan generálják - token per token - majd összesítik A felhasználó szemszögéből, akár böngészőn, mobilalkalmazáson vagy terminálon keresztül, a tapasztalatnak meg kell maradnia. Szükség van egy olyan rendszerre, amely támogatja a . chunks fluid and responsive low-latency, real-time streaming Ennek eléréséhez két fő lehetőség van: WebSockets: Teljes duplex kommunikációs csatorna, amely lehetővé teszi a folyamatos kétirányú interakciót a kliens és a szerver között. Server-Sent Events (SSE): Egyirányú, HTTP-alapú streaming protokoll, amelyet széles körben használnak valós idejű frissítésekhez. Webáruházak Webáruházak Server-Sent Events (SSE) Server küldött események (SSE) Why SSE over WebSockets? Bár mindkét lehetőség megvalósítható, — különösen az OpenAI-kompatibilis API-k és hasonló rendszerek esetében. Ez számos gyakorlati előnnyel jár: SSE is the more commonly used solution for standard LLM inference : SSE runs over standard HTTP, requiring no special . Simplicity Fejlesztés vagy tárgyalás Kompatibilitás: minden főbb böngészőben nativ módon működik, további könyvtárak nélkül. : Most LLM responses flow only from server to client, which aligns with SSE’s design. Unidirectional Flow Proxy-barátság: Az SSE jól működik a standard HTTP infrastruktúrával, beleértve a fordított proxy-okat is. Fejlesztés vagy tárgyalás Ezen előnyök miatt, . SSE is typically chosen for text-only, prompt-response streaming use cases Néhány feltörekvő felhasználási eset azonban gazdagabb, alacsony késleltetésű, kétirányú kommunikációt igényel – például valós idejű transzkripciót vagy beszéd-szóbeli interakciókat. Ezeknek az igényeknek a kielégítése a használatával Ezek a protokollok jobban alkalmasak a folyamatos multimodális bemenetekre és kimenetekre. OpenAI’s Realtime API WebSockets OpenAI’s Realtime API Mivel a rendszer kizárólag a Mi ragaszkodunk a Az egyszerűségéért, kompatibilitásáért és a streaming modellünkkel való összhangért. text-based interactions SSE Response Stream Content Azokkal kiválasztották a közlekedési rétegként, a következő lépés a A hatékony streaming többre van szüksége, mint pusztán nyers szövegre – elegendő to support downstream consumers such as user interfaces and automation tools. The stream must include the following information: SSE what structure, metadata, and context Címszintű metaadatok: alapvető azonosító információk, például kérelemazonosító. Az alapvető kimenet – a modell által generált tokenek vagy szálak – fokozatosan kerülnek kiadásra, mivel a (n) szekvenciákat visszaküldik, részről részre. Minden generáció több szekvenciából állhat (például n = 2, n = 4).Ezek a szekvenciák függetlenül generálódnak és párhuzamosan továbbítódnak, mindegyik a saját fokozatos részekből áll. Használati és token szintű metaadatok. Ez magában foglalja a generált tokenek számát, az időzítési adatokat és az opcionális diagnosztikákat, mint például a logprobs vagy az érvelési nyomok. Ezek számlázáshoz, hibakereséshez vagy modellértékeléshez használhatók. A streamelt válasz szerkezetének meghatározása után számos nem funkcionális követelményt is figyelembe vettünk, amelyek elengedhetetlenek a megbízhatóság és a jövőbeli fejlődés szempontjából. A stream design célja, hogy: Strukturált – világosan megkülönbözteti a tartalomtípusokat és az eseményhatárokat. — capable of carrying optional metadata without breaking existing clients. Extensible Robusztus – ellenáll a rossz formátumú, késleltetett vagy részleges adatoknak. Számos alkalmazásban – például or — multiple sequences (completions) are generated in parallel as part of a single generation request. side-by-side comparison diverse sampling A streaming válaszok legátfogóbb formátumát a A specifikációnak megfelelően az egyetlen generációs részecske több szekvenciát is tartalmazhat a Az array: OpenAI API referenciák choices OpenAI API referenciák Választás array A csevegés befejezésének lehetőségeinek listája. Több mint egy elemet tartalmazhat, ha n nagyobb, mint 1. Az utolsó rész is üres lehet. choices array A csevegés befejezésének lehetőségeinek listája. Több mint egy elemet tartalmazhat, ha n nagyobb, mint 1. Az utolsó rész is üres lehet. Although, in practice, individual chunks usually contain only a single delta, the format allows for multiple sequence updates per chunk. It’s important to account for this, as future updates might make broader use of this capability. Notably, even the is designed to support this structure. official Python SDK official Python SDK We chose to follow the same structure to ensure compatibility with a wide range of potential features. The diagram below illustrates an example from our implementation, where a single generation consists of three sequences, streamed in six chunks over time: Ez a szakasz az egész generáció kezdetét jelöli. nem tartalmaz semmilyen tényleges tartalmat, de magában foglalja a megosztott metaadatokat, például a generációs azonosítót, az időbélyeget és a szerepet (például asszisztenst stb.). Two sequences begin streaming in parallel. Each is tagged with a unique identifier to distinguish it from others. Chunk 2 — Sequence Start (Green & Purple). A harmadik szekvencia kezdődik (kék), míg az első két szekvencia (zöld és lila) fokozatos tartalmat sugároz delta eseményeken keresztül. The green and blue sequences continue streaming deltas. The purple sequence finishes — this includes a structured finish_reason (like stop, length, etc.). Chunk 4 — Midstream Updates & Finish (Purple). Chunk 5 – Remaining Sequence Finishes. mind a zöld, mind a kék szekvenciák befejeződnek. Ez a szakasz lezárja a generációt, és magában foglalhatja a globális felhasználási statisztikákat, a végső token számokat, a késleltetési információkat vagy más diagnosztikákat. Ahogy láthatja, hogy az áram robusztus és könnyebben elemezhető legyen, úgy döntöttünk, hogy , rather than relying on implicit mechanisms such as null checks, EOFs, or magic tokens. This structured approach simplifies downstream parsing, especially in environments where multiple completions are streamed in parallel, and also improves debuggability and fault isolation during development and runtime inspection. explicitly signal Start and Finish events for both the overall generation and each individual sequence Moreover, we introduce an additional chunk that carries structured information about failures. Some errors — such as malformed requests or authorization issues — can be surfaced directly via standard HTTP response codes. However, if an error occurs , we have two options: either abruptly terminate the HTTP stream or emit a well-formed SSE error event. We chose the latter. Abruptly closing the connection makes it hard for clients to distinguish between network issues and actual model/service failures. By using a dedicated error chunk, we enable more reliable detection and propagation of issues during streaming. Error during the generation process Backend Services and Request Flow At the center of the system is a single entrypoint: . It handles basic concerns like authentication, usage tracking and quota enforcement, request formatting, and routing based on the specified model. While it may look like the Gateway carries a lot of responsibility, each task is intentionally simple and modular. For external providers, it adapts requests to their APIs and maps responses back into a unified format. For self-hosted models, requests are routed directly to internal systems using our own unified schema. This design allows seamless support for both external and internal models through a consistent interface. LLM-Gateway Self-Hosted Models As mentioned earlier, alkalmas a végfelhasználókra adott válaszok streamelésére, de nem praktikus választás a . When a request arrives, it must be routed to a suitable worker node for model inference, and the result streamed back. While some systems handle this using chained HTTP proxies and header-based routing, in our experience, this approach becomes difficult to manage and evolve as the logic grows in complexity. Server-Sent Events (SSE) internal backend communication Belső infrastruktúráinknak támogatniuk kell: Prioritás-tudatos ütemezés – A kéréseknek eltérő sürgősségi szintje lehet (például interaktív vs. tétel), és a magas prioritású feladatokat először kell kezelni. — Certain nodes run on higher-performance GPUs and should be preferred; others serve as overflow capacity. Hardware-aware routing Modell-specifikus disztribúció – Minden munkatárs úgy van konfigurálva, hogy a hardverkompatibilitás és az erőforrás-korlátozások alapján csak a modellek egy alcsoportját támogassa. To address these requirements, we use a to decouple task routing from result delivery. This design provides better flexibility and resilience under varying load and routing conditions. We use for this purpose, though other brokers could also be viable depending on your latency, throughput, and operational preferences. RabbitMQ was a natural fit given its maturity and alignment with our existing tooling. message broker RabbitMQ nyúl nyúl Most nézzük meg közelebbről, hogyan működik ez a rendszer a gyakorlatban: We use , amely lehetővé teszi számunkra, hogy a modellkompatibilitáson és a csomópontok képességein alapuló kérelmeket irányítsuk. dedicated queues per model Az LLM-Gateway szolgáltatás (a felhasználó) egy HTTP-kérelmet kezdeményez egy szöveges generálási feladat kiváltására. A kérést a Scheduler kezeli, aki a kívánt modelltől függően kiválasztja a megfelelő sorszámot (a képen zöld színnel jelölve) és mellékeli az üzenetet. An appropriate (only one worker is shown for simplicity, but there are many) subscribed to the queue picks up the task and begins processing. This worker runs the selected model locally. Worker Picks Up Task. Inference Worker The worker streams the response chunk-by-chunk into the , to which the . Streaming the Response. Response Queue Scheduler replica handling the request is subscribed A programozó meghallgatja a válaszsorozatot, és megérkezéskor megkapja a válaszcsomagokat. SSE Streaming. A darabokat SSE formátumra konvertálják, és az ügyfélnek közvetítik. To handle , elkerüljük az üzenet bróker túlterhelését: large payloads Ahelyett, hogy nagy bemeneti vagy kimeneti adatokat helyeznénk be közvetlenül a feladatba, feltöltjük azt egy külső S3-kompatibilis áruházba. A hivatkozás (például URL vagy erőforrás-azonosító) szerepel a feladat metaadataiban, és a munkavállaló a tényleges tartalmat szükség esetén visszaszerzi. A design alkalmazása a RabbitMQ-vel Amikor a Minden egyes Rendszeres RabbitMQ Egyetlen típusú modell kezelésére van szükségünk. , which can be achieved using . In this setup, messages with higher priority values are delivered and processed before lower priority ones. For , where messages should be directed to the most performant available nodes first, can help. Consumers with higher priority receive messages as long as they are active; lower-priority consumers only receive messages when the higher-priority ones are blocked or unavailable. routing and publishing messages Request Queue Kövér priority-aware scheduling Üzenet prioritások hardware-aware routing Fogyasztói prioritások Kövér Üzenet prioritások Fogyasztói prioritások Ha az üzenet elvesztése elfogadhatatlan, a következőket kell tartalmaznia: A kiadó megerősíti, hogy a bróker megkapta és tárolta az üzenetet. and so data survives restarts. Durable queues persistent messages Quorum sorok erősebb tartósság a replikáció révén.Ezek szintén támogatják az egyszerűsített üzeneteket és a fogyasztói prioritásokat a RabbitMQ 4.0-tól. A kiadó megerősítette A kiadó megerősítette Quorum queues Quorum sorozatok egyszerűsített üzenetek és fogyasztói prioritások a RabbitMQ 4.0-tól kezdve Eddig azt fedeztük, hogy a feladatok hogyan kerülnek közzétételre - de hogyan Az első lépés az, hogy megértsük, hogyan work in RabbitMQ. The broker supports a concept called , amelyek egyetlen kapcsolathoz vannak kötve, és automatikusan törlődnek, amikor ez a kapcsolat bezárul. streamed response temporary queues Exkluzív sorok exclusive queues Exkluzív sorok Mi teremtünk , ensuring it’s automatically cleaned up when the replica shuts down. However, this introduces a challenge: while each service replica has a single RabbitMQ queue, it must handle . one exclusive queue per Scheduler service replica many requests in parallel Ennek megoldására a RabbitMQ sorrendet úgy kezeljük, mint egy , a válaszokat a helyes Scheduler-replikára irányítja. Minden felhasználói kéréshez egy amely minden egyes válaszban szerepel. belül a , we maintain an additional with short-lived in-memory queues — one per active request. Incoming chunks are matched to these queues based on the identifier and forwarded accordingly. These in-memory queues are discarded once the request completes, while the RabbitMQ queue persists for the lifetime of the service replica. transport layer unique identifier Scheduler in-memory routing layer Schematically this looks as follows: A Scheduler központi disztribútora a darabokat a megfelelő memóriában lévő sorba küldi, mindegyiket egy dedikált kezelő kezeli, majd a kezelő az SSE-protokoll használatával továbbítja a darabokat a felhasználóknak. következtetés Számos érett keretrendszer áll rendelkezésre a hatékony LLM következtetéshez, például and Ezeket a rendszereket úgy tervezték, hogy és valós időben reagáló tokeneket generálnak, gyakran olyan funkciókkal, mint a folyamatos tétel és a GPU memória optimalizálása. mint az alapvető következtetési motor, néhány egyéni módosítással: Veszprém Megállapodás process multiple sequences in parallel vLLM Veszprém Veszprém Megállapodás SGLANG Egyéni sugárkeresési megvalósítás – hogy jobban megfeleljen generációs logikánknak és támogatja a strukturált korlátozásokat. Strukturált kimeneti rendszerek támogatása – lehetővé teszi a modellek számára, hogy az üzleti formátumoknak megfelelő kimenetet adjanak vissza. A tapasztalatok alapján megtanultuk, hogy még a kisebb könyvtári frissítések is — whether in output quality, determinism, or concurrency behavior. Because of this, we’ve established a robust testing pipeline: significantly alter model behavior Stressz tesztelés a párhuzamos problémák, a memória szivárgások vagy a stabilitási regressziók feltárására. A determinizmus tesztelése következetes kimeneteket biztosít a rögzített magok és paraméterkészletek esetében. Paraméter hálózati tesztelés a generációs beállítások széles skálájának lefedése érdekében, anélkül, hogy túllépnénk. Storage and deployment Most modern systems run in — either in the cloud or within Kubernetes (K8s). While this setup works well for typical backend services, it introduces challenges around Az LLM modellek lehetnek , and baking model weights directly into Docker images — quickly becomes problematic: containerized environments model weight storage tens or even hundreds of gigabytes in size — Even with multi-stage builds and caching, transferring large model files during the build phase can dramatically increase CI time. Slow builds — Each rollout requires pulling massive images, which can take several minutes and cause downtime or delays. Slow deployments — Neither Docker registries nor Kubernetes nodes are optimized for handling extremely large images, resulting in bloated storage usage and bandwidth strain. Resource inefficiency Ennek megoldása érdekében elválasztjuk a a Docker-kép életciklusából. modelljeink egy , and fetched just before inference service startup. To improve startup time and avoid redundant downloads, we also use a modell súlyainak mindegyik csomóponton történő tárolása. model storage external S3-compatible object storage Helyi állandó térfogat (PVC) Helyi állandó térfogat (PVC) local persistent volumes (PVCs) Observability Egy ilyen rendszer – építve - igényel A megbízhatóság és a teljesítmény biztosítása a skálán. streaming, message queues, and real-time token generation robust observability In addition to standard service-level metrics (CPU, memory, error rates, etc.), we found it essential to monitor the following: A sorok mélysége, az üzenetek visszaszorítása és a fogyasztók száma – a várakozó üzenetek számának, az aktuális sorok méretének és az aktív fogyasztók számának figyelemmel kísérése segít felismerni a feladatok elosztásának üresedéseit és az egyensúlyhiányokat a munkavállalók kihasználásában. Token/chunk átviteli sebesség – a másodpercenként generált tokenek vagy válaszcsomók számának nyomon követése segít azonosítani a késleltetést vagy az átviteli regressziót. Elosztott nyomkövetés – annak meghatározására, hogy a kérelmek hol nem működnek, vagy a komponensek (kapu, bróker, munkavállalók stb.) között megállnak. — since inference processes can crash under rare conditions (e.g., bad input or extreme parameter values), proactive monitoring of liveness and readiness is critical. Inference engine health checks Elosztott nyomkövetés Elosztott nyomkövetés Further Improvements Míg rendszerünk gyártásra kész, még mindig vannak fontos kihívások és lehetőségek az optimalizáláshoz: Using a to boost inference performance. distributed KV-cache Támogatja a kérelem törlését, hogy megőrizze a számítógépet, amikor a kimenetek már nem szükségesek. Egyszerű modellszállítási csővezeték létrehozása az adatkutatási csapatok számára. következtetés Bár egy megbízható és a szolgáltatótól független LLM kiszolgáló rendszer kialakítása kezdetben bonyolultnak tűnhet, nem igényli a kerék újrafeldolgozását. Minden komponens - az SSE-n keresztül történő streaming, az üzenetközvetítőkön keresztül történő feladatelosztás és a futási időkkel kezelt következtetés - egyértelmű célt szolgál, és a meglévő, jól támogatott eszközökön alapul. A következő posztban olyan fejlettebb témákat fogunk feltárni, mint például az elosztott KV-caching, több modell kezelése a replikák között, és az ML-orientált csapatok számára megfelelő telepítési munkafolyamatok. szerzők Tochka , Sztálin Shimovolos Sztálin Shimovolos Sztálin Shimovolos Tochka , Maxim Afanasyev Maxim Afanasjev Maxim Afanasjev elismerések , work done at Tochka Dmitry Kryukov Dmitrij Kryukov Dmitrij Kryukov