Kunstmatige intelligentie
SGLang: Efficiënte uitvoering van gestructureerde taalmodelprogramma’s
Grote taalmodellen (LLM’s) worden steeds vaker gebruikt voor complexe taken die meerdere generatieaanroepen, geavanceerde prompttechnieken, controle van de uitvoerstroom en gestructureerde invoer/uitvoer vereisen. Er ontbreekt echter aan efficiënte systemen voor het programmeren en uitvoeren van deze toepassingen. SGLang, een nieuw geïntroduceerd systeem, probeert dit aan te pakken door efficiënte uitvoering van complexe taalmodelprogramma’s te bieden. SGLang bestaat uit een frontendtaal en een runtime. De frontend vereenvoudigt het programmeren met primitieven voor generatie en parallelle controle, terwijl de runtime de uitvoering versnelt door middel van nieuwe optimalisaties zoals RadixAttention voor het hergebruik van de KV-cache en compressie van eindige toestandsautomaten voor snellere gestructureerde uitvoerdecoding. Experimenten laten zien dat SGLang een tot 6,4 keer hogere doorvoer bereikt in vergelijking met state-of-the-art-inferentiesystemen op diverse grote taal- en multimodale modellen, waarmee taken zoals agentcontrole, logische redenering, few-shot learningbenchmarks, JSON-decoding, retrieval-versterkte generatiepijplijnen en multi-turn chat worden aangepakt.
Recente vooruitgang in de mogelijkheden van LLM’s heeft hun bruikbaarheid uitgebreid, waardoor ze een bredere reeks algemene taken kunnen uitvoeren en als autonome agenten kunnen functioneren. In deze toepassingen voeren LLM’s meerdere plannings-, redeneer- en interactierondes met externe omgevingen uit. Dit wordt gefaciliteerd door het gebruik van tools, meerdere invoermodi en diverse prompttechnieken, zoals few-shot learning, zelfconsistentie, skelet van gedachten en boom van gedachten. Deze nieuwe use cases vereisen meerdere, vaak afhankelijke, LLM-generatieaanroepen, wat een trend aanduidt van het gebruik van multi-call structuren om complexe taken te voltooien.
Deze verschuiving markeert een overgang van eenvoudig chatten naar een meer geavanceerd programmatisch gebruik van LLM’s, waarbij programma’s de generatieprocessen van LLM’s plannen en controleren. Deze programma’s worden “Taalmodelprogramma’s” (LM-programma’s) genoemd. Geavanceerde prompttechnieken en agente workflows vallen binnen het bereik van LM-programma’s. Er zijn twee veelvoorkomende eigenschappen van LM-programma’s: (1) LM-programma’s omvatten meestal meerdere LLM-aanroepen die worden afgewisseld met controle van de uitvoerstroom om complexe taken te voltooien en de algehele kwaliteit te verbeteren. (2) LM-programma’s ontvangen gestructureerde invoer en produceren gestructureerde uitvoer, waardoor ze kunnen worden samengesteld en geïntegreerd in bestaande software-systemen.
In dit artikel zullen we dieper ingaan op het SGLang-framework, de architectuur ervan onderzoeken, de prestaties analyseren en het vergelijken met state-of-the-art-frameworks. Laten we beginnen.
Een introductie tot SGLang
Ondanks het wijdverbreide gebruik van LM-programma’s, blijven de huidige systemen voor het uitdrukken en uitvoeren ervan inefficiënt. SGLang identificeert twee primaire uitdagingen die verband houden met het efficiënte gebruik van LM-programma’s:
- Programmeercomplexiteit: Het ontwikkelen van LM-programma’s is omslachtig en moeilijk vanwege de niet-deterministische aard van LLM’s. Dit omvat uitgebreide tekenreeksmanipulatie, experimentele afstemming van prompts, broze uitvoerparse, het omgaan met meerdere invoermodi en het implementeren van parallelle mechanismen. Deze complexiteit vermindert de leesbaarheid van zelfs eenvoudige programma’s aanzienlijk.
- Uitvoerinefficiëntie: Het uitvoeren van LM-programma’s is inefficiënt vanwege overtollige berekeningen en geheugengebruik. State-of-the-art-inferentiesystemen, geoptimaliseerd om latentie te verminderen en doorvoer te verbeteren, ontbreken directe kennis van de workload, waardoor significante inefficiënties ontstaan. Een opvallend voorbeeld is het hergebruik van de Key-Value (KV)-cache, die bestaat uit herbruikbare tussenliggende tensors die essentieel zijn voor generatieve inferentie. Huidige systemen ontbreken effectieve mechanismen om KV-cachehergebruik over meerdere LLM-aanroepen te faciliteren die een gemeenschappelijk voorvoegsel delen, waardoor onnodige berekeningen en verspilde geheugen ontstaan. Bovendien is beperkte decoding voor gestructureerde uitvoer, zoals JSON-modus, suboptimaal, omdat bestaande systemen alleen één token tegelijk decoderen.
Om deze uitdagingen aan te pakken, introduceert SGLang een gestructureerde generatietaal voor LLM’s. Het kernidee is om systematisch de multi-call structuur in LM-programma’s te exploiteren voor efficiënte uitvoering. Zoals weergegeven in de volgende figuur, bestaat SGLang uit twee delen: een frontendtaal en een backend-runtime.

De frontend vereenvoudigt het programmeren van LM-programma’s, en de runtime versnelt de uitvoering. Deze delen kunnen samenwerken voor betere prestaties of onafhankelijk functioneren.
SGLang is een domeinspecifieke taal die is ingebed in Python, met primitieven voor generatie (bijv. extend, gen, select) en parallelle controle (bijv. fork, join). Het is compatibel met Python’s controle van de uitvoerstroom en bibliotheken, waardoor gebruikers gemakkelijk geavanceerde promptworkflows kunnen ontwikkelen met native Python-syntaxis. SGLang bevat een interpreter en een compiler. De interpreter beheert de promptstatus als een stroom en verzendt primitive bewerkingen naar de stroom voor asynchrone uitvoering, waardoor een correcte controle over synchronisatie en intra-programmaparallelle verwerking wordt gewaarborgd. Bovendien kunnen SGLang-programma’s worden getraceerd en gecompileerd voor verdere optimalisaties. De runtime van SGLang stelt verschillende nieuwe optimalisaties voor om de uitvoering van LM-programma’s te versnellen:
- RadixAttention: Deze techniek maakt het automatische hergebruik van de KV-cache over meerdere generatieaanroepen mogelijk. In bestaande inferentiesystemen wordt de KV-cache van een aanvraag verwijderd na verwerking, waardoor hergebruik over meerdere aanroepen wordt voorkomen en de uitvoering wordt vertraagd. SGLang onderhoudt een LRU-cache van de KV-cache in een radixboom, waardoor de KV-cache als een traditionele cache wordt beheerd en de radixboom voor efficiënte matching, invoeging en verwijdering wordt gebruikt. Dit stelt de runtime in staat om verschillende hergebruikspatronen efficiënt te verwerken.
- Compressie van eindige toestandsautomaten: Deze techniek maakt snellere beperkte decoding voor gestructureerde uitvoer mogelijk. Bestaande systemen volgen beperkingen alleen voor het volgende token, waardoor ze slechts één token tegelijk kunnen decoderen. In plaats daarvan analyseert SGLang de beperkingen en bouwt een compressie van eindige toestandsautomaten om ze te vertegenwoordigen, waardoor een multi-tokenpad in één stap kan worden gecomprimeerd wanneer dit mogelijk is, waardoor meerdere tokens tegelijk kunnen worden gedecodeerd voor een snellere snelheid.
- API-speculatieve uitvoering: Voor API-only-modellen zoals OpenAI’s GPT-4 introduceert SGLang API-speculatieve uitvoering om multi-call-programma’s te optimaliseren.
Met SGLang zijn verschillende LLM-toepassingen geïmplementeerd, waaronder agentcontrole, logische redenering, few-shot learningbenchmarks, JSON-decoding, retrieval-versterkte generatiepijplijnen, multi-turn chat en multi-modale verwerking. De prestaties werden getest op modellen zoals Llama-7B/70B, Mistral-8x7B, LLaVA-v1.5-7B (afbeelding) en LLaVA-NeXT-34B (video) op NVIDIA A10G- en A100-GPU’s. Experimentele resultaten laten zien dat SGLang een tot 6,4 keer hogere doorvoer bereikt over een breed scala aan workloads, modellen en hardwareconfiguraties, in vergelijking met bestaande programmerings- en inferentiesystemen, waaronder Guidance, vLLM en LMQL.
SGLang: Programmeringsmodel en methodologie
Het SGLang-programmeringsmodel wordt geïntroduceerd via een lopend voorbeeld, waarin de taalprimitieven en uitvoermodi worden beschreven en de runtime-optimalisatiemogelijkheden worden geschetst. Dit model vereenvoudigt omslachtige bewerkingen in multi-call workflows (bijv. tekenreeksmanipulatie, API-aanroepen, beperkingsspecificatie, parallelle verwerking) door flexibele en samengestelde primitieven te bieden. SGLang is een domeinspecifieke taal die is ingebed in Python. De volgende figuur toont een programma dat een essay over een afbeelding evalueert met behulp van de branch-solve-merge-promptmethode.

De functie multi_dimensional_judge neemt drie argumenten: `s`, `path`, en `essay`. s beheert de promptstatus, path is het afbeeldingsbestandspad en essay is de essaytekst. Nieuwe tekenreeksen en SGLang-primitieven kunnen worden toegevoegd aan de staat s voor uitvoering met behulp van de +=-operator. Eerst voegt de functie de afbeelding en het essay toe aan de prompt. Vervolgens controleert het of het essay verband houdt met de afbeelding met behulp van select, waarbij het resultaat in s[“related”] wordt opgeslagen. Als het verband houdt, wordt de prompt gesplitst in drie kopieën voor parallelle evaluatie vanuit verschillende dimensies, met behulp van gen om resultaten op te slaan in f[“judgment”]. Vervolgens worden de oordelen samengevoegd, wordt een samenvatting gegenereerd en wordt een lettercijfer toegewezen. Ten slotte retourneert het de resultaten in JSON-formaat, volgens een schema dat wordt gedefinieerd door een reguliere expressiebeperking regex. SGLang vereenvoudigt dit programma aanzienlijk, aangezien een equivalent programma met een OpenAI API-achtig interface 2,1 keer zoveel regels code zou vereisen vanwege handmatige tekenreeksmanipulatie en parallelle controle.
SGLang biedt primitieven voor het controleren van de promptstatus, generatie en parallelle verwerking, die kunnen worden gebruikt met Python-syntaxis en -bibliotheken. Hier zijn de primitieven:
gen: roept een model aan om te genereren en slaat de resultaten op in een variabele met de naam die is opgegeven in het eerste argument. Het ondersteunt een `regex`-argument om de uitvoer te beperken tot een grammatica die wordt gedefinieerd door een reguliere expressie (bijv. een JSON-schema).
- select: roept een model aan om de optie met de hoogste waarschijnlijkheid te kiezen uit een lijst.
- += of extend: voegt een tekenreeks toe aan de prompt.
- [variabele_naam]: haalt de resultaten van een generatie op.
- fork: maakt parallelle forks van de promptstatus.
- join: herenigt de promptstatus.
- image en video: nemen afbeeldings- en videoinvoer.
De eenvoudigste manier om een SGLang-programma uit te voeren is via een interpreter, waarbij een prompt wordt behandeld als een asynchrone stroom. Primitieven zoals extend, gen en select worden naar de stroom gestuurd voor asynchrone uitvoering. Deze niet-blokkerende aanroepen stellen Python-code in staat om te blijven uitvoeren zonder te wachten tot de generatie is voltooid, vergelijkbaar met het asynchroon lanceren van CUDA-kernels. Elke prompt wordt beheerd door een stroomuitvoerder in een achtergrondthread, waardoor intra-programmaparallelle verwerking mogelijk wordt. Het ophalen van generatieresultaten zal worden geblokkeerd totdat ze klaar zijn, waardoor correcte synchronisatie wordt gewaarborgd. Alternatief kunnen SGLang-programma’s worden gecompileerd als computationele grafieken en worden uitgevoerd met een grafiekuitvoerder, waardoor meer optimalisaties mogelijk worden. Dit artikel gebruikt interpretermodus als standaard en bespreekt compilermodusresultaten in Bijlage D. SGLang ondersteunt open-gewichtmodellen met zijn eigen SGLang-runtime (SRT), evenals API-modellen zoals OpenAI en Anthropic-modellen.
Programmeersystemen voor LLM’s kunnen worden ingedeeld in hoog niveau (bijv. LangChain, DSPy) en laag niveau (bijv. LMQL, Guidance, SGLang). Hoog-niveausystemen bieden vooraf gedefinieerde of automatisch gegenereerde prompts, zoals DSPy’s promptoptimizer. Laag-niveausystemen veranderen prompts meestal niet, maar stellen directe manipulatie van prompts en primitieven toe. SGLang is een laag-niveausysteem, vergelijkbaar met LMQL en Guidance. De volgende tabel vergelijkt hun functies.

SGLang richt zich meer op runtime-efficiëntie en komt met zijn eigen co-ontworpen runtime, waardoor nieuwe optimalisaties mogelijk worden. Hoog-niveautalen (bijv. DSPy) kunnen worden gecompileerd naar laag-niveautalen (bijv. SGLang). De integratie van SGLang als backend in DSPy voor betere runtime-efficiëntie wordt later gedemonstreerd.

Het bovenstaande voorbeeld illustreert RadixAttention-bewerkingen met een LRU-verwijderingsbeleid over negen tijdpunten, waarbij de dynamische evolutie van de radixboom als reactie op verschillende aanvragen wordt getoond. Deze aanvragen omvatten twee chatsessies, een batch few-shot learningaanvragen en zelfconsistentiesampling. Elke boomrand draagt een label dat een deeltekenreeks of een reeks tokens aanduidt. De knooppunten zijn gekleurd om verschillende staten aan te geven: groen voor nieuw toegevoegde knooppunten, blauw voor gecachte knooppunten die tijdens het tijdstip worden geopend, en rood voor knooppunten die zijn verwijderd.
Stap 1: De radixboom is aanvankelijk leeg.
Stap 2: De server verwerkt een binnenkomende gebruikersbericht “Hallo” en reageert met de LLM-uitvoer “Hoi”. De systeemprompt “U bent een behulpzame assistent”, het gebruikersbericht “Hallo!” en de LLM-reactie “Hoi!” worden samengevoegd in de boom als één rand die is verbonden met een nieuw knooppunt.
Stap 3: Een nieuwe prompt arriveert en de server vindt het voorvoegsel van de prompt (d.w.z. de eerste ronde van het gesprek) in de radixboom en hergebruikt de KV-cache. De nieuwe ronde wordt toegevoegd aan de boom als een nieuw knooppunt.
Stap 4: Een nieuwe chatsessie begint. Het knooppunt uit stap 3 wordt gesplitst in twee knooppunten om de twee chatsessies in staat te stellen het systeemprompt te delen.
Stap 5: De tweede chatsessie gaat verder. Echter, vanwege geheugengrenzen, moet een knooppunt uit stap 4 worden verwijderd. De nieuwe ronde wordt toegevoegd na het resterende knooppunt uit stap 4.
Stap 6: De server ontvangt een few-shot learningaanvraag, verwerkt deze en voegt deze toe aan de boom. De rootknoop wordt gesplitst omdat de nieuwe aanvraag geen voorvoegsel deelt met bestaande knooppunten.
Stap 7: De server ontvangt een batch aanvullende few-shot learningaanvragen. Deze aanvragen delen hetzelfde set few-shot voorbeelden, dus een knooppunt uit stap 6 wordt gesplitst om delen mogelijk te maken.
Stap 8: De server ontvangt een nieuw bericht van de eerste chatsessie. Het verwijdert alle knooppunten van de tweede chatsessie, omdat ze het minst recent zijn gebruikt.
Stap 9: De server ontvangt een aanvraag om meer antwoorden te genereren voor de vragen in een knooppunt uit stap 8, waarschijnlijk voor zelfconsistentieprompting. Om ruimte te maken voor deze aanvragen, worden meerdere knooppunten verwijderd.
Dit voorbeeld illustreert hoe RadixAttention de dynamische toewijzing en verwijdering van knooppunten in reactie op verschillende aanvragen afhandelt, waardoor efficiënt hergebruik van de KV-cache en geheugenbeheer worden gewaarborgd.
SGLang: Evaluatie en resultaten
Resultaten op open-gewichtmodellen
De latentie- en doorvoerresultaten worden weergegeven in de volgende figuren. SGLang verbetert de doorvoer met maximaal 6,4 keer en vermindert de latentie met maximaal 3,7 keer. Deze verbeteringen zijn het resultaat van KV-cachehergebruik, het exploiteren van parallelle verwerking binnen een enkel programma en snellere beperkte decoding.

Op deze benchmarks varieert de cache-treffersnelheid van 50% tot 99%. Figuur 13 (Bijlage) vermeldt de behaalde en optimale cache-treffersnelheden voor alle benchmarks, waaruit blijkt dat SGLang’s cache-gevoelige planningsbenadering gemiddeld 96% van de optimale trefferfrequentie bereikt.

Resultaten op grotere modellen met tensorparallelle verwerking
Grotere modellen, Mixtral-8x7B en Llama-70B, werden getest met tensorparallelle verwerking op dezelfde set benchmarks, en de resultaten worden gerapporteerd in de volgende figuur. De snelheidswinst bij grotere modellen toont een trend die vergelijkbaar is met die waargenomen bij kleinere modellen, wat aangeeft dat SGLang’s optimalisatie goed generaliseert naar grotere modellen. Guidance en LMQL werden weggelaten vanwege het ontbreken van efficiënte implementaties van tensorparallelle verwerking.

Resultaten op multi-modale modellen
SGLang heeft native ondersteuning voor multi-modale modellen met de image- en video-primitieven. De optimalisaties in dit artikel zijn compatibel met multi-modale modellen. Voor RadixAttention wordt de hash van de invoerafbeeldingen berekend en gebruikt als sleutel in de radixboom, waardoor hergebruik van de KV-cache van de afbeeldingstokens van dezelfde afbeelding mogelijk wordt. LLaVA-v1.5-7B (afbeelding) werd uitgevoerd op llava-bench-in-the-wild en LLaVA-NeXT-34B (video) op ActivityNet. Omdat deze modellen niet goed worden ondersteund door andere basissystemen, werd de oorspronkelijke implementatie van de modelauteurs in Hugging Face Transformers gebruikt als baseline. Zoals weergegeven in de volgende tabel, biedt SGLang een doorvoer tot 6 keer hoger op deze benchmarks. In llava-bench-in-the-wild werden meerdere vragen over dezelfde afbeelding afgehandeld en hergebruikte SGLang de KV-cache in dit geval.

Productie-implementatie
SGLang is geïmplementeerd in Chatbot Arena om open-gewichtmodellen te bedienen. Vanwege lage verkeer voor sommige modellen, dient slechts één SGLang-werker elk model. Na één maand werd een RadixAttention-cache-treffersnelheid van 52,4% voor LLaVA-Next-34B en 74,1% voor Vicuna-33B waargenomen. Cache-treffers kwamen van gemeenschappelijke systeemboodschappen, vaak hergebruikte voorbeeldafbeeldingen en multi-turn chatgeschiedenissen. Dit vermindert de latentie van het eerste token met gemiddeld 1,7 keer voor Vicuna-33B.

Slotgedachten
In dit artikel hebben we het over SGLang gehad, een nieuw geïntroduceerd systeem dat is ontworpen om efficiënte uitvoering van complexe taalmodelprogramma’s te bieden. SGLang bestaat uit een frontendtaal en een runtime. De frontend vereenvoudigt het programmeren met primitieven voor generatie en parallelle controle, terwijl de runtime de uitvoering versnelt door middel van nieuwe optimalisaties zoals RadixAttention voor KV-cachehergebruik en compressie van eindige toestandsautomaten voor snellere gestructureerde uitvoerdecoding. Experimenten laten zien dat SGLang een tot 6,4 keer hogere doorvoer bereikt in vergelijking met state-of-the-art-inferentiesystemen op diverse grote taal- en multimodale modellen, waarmee taken zoals agentcontrole, logische redenering, few-shot learningbenchmarks, JSON-decoding, retrieval-versterkte generatiepijplijnen en multi-turn chat worden aangepakt.












