Umělá inteligence
SGLang: Efektivní provádění strukturovaných programů jazykových modelů
Velké jazykové modely (LLM) se stále více využívají pro komplexní úkoly, které vyžadují více generativních volání, pokročilé techniky vyvolání, řízení toku a strukturované vstupy/výstupy. Nicméně, efektivní systémy pro programování a provádění těchto aplikací chybí. SGLang, nově zavedený systém, se snaží tento problém vyřešit poskytováním efektivního provádění komplexních programů jazykových modelů. SGLang se skládá z frontendového jazyka a runtime. Frontend zjednodušuje programování pomocí primitiv pro generaci a řízení paralelismu, zatímco runtime urychluje provádění prostřednictvím novými optimalizacemi, jako je RadixAttention pro opětovné použití KV cache a komprimované konečné automaty pro rychlejší dekódování strukturovaných výstupů. Experimenty prokázaly, že SGLang dosahuje až 6,4× vyšší propustnosti ve srovnání se stávajícími systémy inference na různých velkých jazykových a multimodálních modelech, řešících úkoly, jako je řízení agentů, logické uvažování, few-shot learning benchmarky, JSON dekódování, retrieval-augmented generativní potrubí a multi-turn chat.
Poslední pokroky v možnostech LLM rozšířily jejich využitelnost, umožňující jim zvládat širší rozsah obecných úkolů a fungovat jako autonomní agenti. V těchto aplikacích LLM provádějí multi-kolové plánování, uvažování a interakci s externími prostředími. To je usnadněno prostřednictvím použití nástrojů, více vstupních modalit a různých technik vyvolání, jako je few-shot learning, self-konzistence, skeleton-of-thought a tree-of-thought. Tyto nové použití vyžadují více, často závislých, LLM generativních volání, ukazující trend používání multi-volání struktur pro dokončení komplexních úkolů.
Tento posun označuje přechod od jednoduchého chatu k více sofistikovanému programovému využití LLM, kde programy řídí a kontrolují generativní procesy LLM. Tyto programy se označují jako “Language Model Programs” (LM Programy). Pokročilé techniky vyvolání a agentic workflows spadají do rozsahu LM programů. Existují dvě společné vlastnosti LM programů: (1) LM programy obvykle zahrnují více LLM volání proložených s řízením toku pro dokončení komplexních úkolů a zlepšení celkové kvality. (2) LM programy přijímají strukturované vstupy a produkují strukturované výstupy, umožňující kompozici LM programů a integraci do stávajících softwarových systémů.
V tomto článku budeme podrobněji zkoumat rámec SGLang, prozkoumáme jeho architekturu, analyzujeme jeho výkon a porovnáme ho se stávajícími rámci. Takže pojďme začít.
Úvod do SGLang
Přes široké použití LM programů, stávající systémy pro vyjádření a provádění nich zůstávají neefektivní. SGLang identifikuje dvě hlavní výzvy spojené s efektivní utilizací LM programů:
- Programovací komplexita: Vývoj LM programů je únavný a obtížný kvůli nedeterministické povaze LLM. To zahrnuje rozsáhlou manipulaci řetězci, experimentální ladění vyvolání, křehkou analýzu výstupu, zpracování více vstupních modalit a implementaci paralelismu. Tato komplexita významně snižuje čitelnost dokonce i jednoduchých programů.
- Neefektivní provádění: Provádění LM programů je neefektivní kvůli redundanci výpočtu a využití paměti. Stávající systémy inference, optimalizované pro snížení latence a zlepšení propustnosti, postrádají přímou znalost pracovní zátěže, vedoucí k významným neefektivitám. Příkladem je opětovné použití KV cache, která se skládá z opakovaně použitelných mezitímních tensorů, které jsou nezbytné pro generativní inference. Stávající systémy postrádají efektivní mechanismy pro usnadnění opětovného použití KV cache napříč více LLM voláními, která sdílejí společný prefix, vedoucí k zbytečným výpočtům a plýtvání pamětí. Kromě toho je omezené dekódování pro strukturované výstupy, jako je JSON režim, suboptimální, protože stávající systémy dekódují pouze jeden token najednou.
Pro řešení těchto výzev SGLang zavádí strukturovaný generativní jazyk pro LLM. Základní myšlenka spočívá v systematickém využití multi-volání struktur v LM programech pro efektivní provádění. Jak je ukázáno na následujícím obrázku, SGLang se skládá ze dvou částí: frontendového jazyka a backendového runtime.

Frontend zjednodušuje programování LM programů a runtime urychluje jejich provádění. Tyto části mohou pracovat společně pro lepší výkon nebo fungovat nezávisle.
SGLang je doménově specifický jazyk vložený do Pythonu, poskytující primitivy pro generaci (například extend, gen, select) a řízení paralelismu (například fork, join). Je kompatibilní s Pythonovou kontrolou toku a knihovnami, umožňující uživatelům vyvíjet pokročilé workflows vyvolání snadno pomocí nativní Python syntaxe. SGLang zahrnuje interpret a kompilátor. Interpret spravuje stav vyvolání jako stream a předává primitive operace streamu pro asynchronní provádění, zajišťující správnou kontrolu nad synchronizací a intra-programovým paralelismem. Kromě toho lze programy SGLang sledovat a zkompilovat pro další optimalizace. Runtime SGLang navrhuje několik novými optimalizacemi pro urychlení provádění LM programů:
- RadixAttention: Tato technika umožňuje automatické opětovné použití KV cache napříč více generativními voláními. V stávajících systémech inference je KV cache požadavku odstraněna po zpracování, bránící opětovnému použití napříč více voláními a zpomalující provádění. SGLang udržuje LRU cache KV cache v radix stromu, spravující KV cache jako tradiční cache a využívající radix strom pro efektivní shodu, vložení a vyřazení. To umožňuje runtime zpracovat různé vzory opětovného použití efektivně.
- Komprimovaný konečný automat: Tato technika umožňuje rychlejší omezené dekódování pro strukturované výstupy. Stávající systémy následují omezení pouze pro následující token, umožňující dekódovat pouze jeden token najednou. Namísto toho SGLang analyzuje omezení a vytváří komprimovaný konečný automat pro jejich reprezentaci, komprimující multi-token cestu do jediného kroku, kdykoli je to možné, umožňující dekódování více tokenů najednou pro rychlejší rychlost.
- API spekulativní provádění: Pro API-only modely, jako je OpenAI’s GPT-4, SGLang zavádí API spekulativní provádění pro optimalizaci multi-volání programů.
Pomocí SGLang, různé LLM aplikace byly implementovány, včetně řízení agentů, logického uvažování, few-shot learning benchmarků, JSON dekódování, retrieval-augmented generativních potrubí, multi-turn chatu a multi-modality zpracování. Výkon byl testován na modelech, včetně Llama-7B/70B, Mistral-8x7B, LLaVA-v1.5-7B (obraz) a LLaVA-NeXT-34B (video) na NVIDIA A10G a A100 GPU. Experimentální výsledky ukazují, že SGLang dosahuje až 6,4× vyšší propustnosti napříč širokým rozsahem pracovních zátěží, modelů a hardwarových konfigurací, ve srovnání se stávajícími programovacími a inferenčními systémy, včetně Guidance, vLLM a LMQL.
SGLang: Programovací model a metodologie
Programovací model SGLang je uveden prostřednictvím běžícího příkladu, popisujícího jeho jazykové primitivy a režimy provádění, a naznačujícího runtime optimalizačních možností. Tento model zjednodušuje únavné operace v multi-volání workflows (například manipulaci řetězci, API volání, omezení specifikace, paralelismus) poskytováním flexibilních a komponovatelných primitiv. SGLang je doménově specifický jazyk vložený do Pythonu. Následující obrázek ukazuje program, který vyhodnocuje esej o obraze pomocí branch-solve-merge vyvolání metody.

Funkce multi_dimensional_judge bere tři argumenty: `s`, `path`, a `essay`. s spravuje stav vyvolání, path je cesta k obrazovému souboru a essay je text esej. Nové řetězce a SGLang primitivy mohou být připojeny ke stavu s pro provádění pomocí operátoru +=. Nejprve funkce přidá obraz a esej do vyvolání. Poté zkontroluje, zda je esej související s obrazem pomocí select, ukládající výsledek do s[“related”]. Pokud je související, vyvolání je rozvětveno do tří kopií pro paralelní vyhodnocení z různých dimenzí, využívající gen pro uložení výsledků do f[“judgment”]. Dále sloučí soudy, vygeneruje souhrn a přiřadí písmennou známku. Nakonec vrátí výsledky ve formátu JSON, následujícím schéma definovaném regulárním výrazem regex. SGLang značně zjednodušuje tento program, protože ekvivalentní program pomocí OpenAI API-like rozhraní by vyžadoval 2,1× více řádků kódu kvůli manuální manipulaci řetězci a paralelismu.
SGLang poskytuje primitivy pro kontrolu stavu vyvolání, generaci a paralelismu, které lze použít s Pythonovou syntaxí a knihovnami. Zde jsou primitivy:
gen: Volá model pro generaci a ukládá výsledky do proměnné se jménem specifikovaným v jeho prvním argumentu. Podporuje `regex` argument pro omezení výstupu na následování gramatiky definované regulárním výrazem (například JSON schéma).
- select: Volá model pro výběr nejvyšší pravděpodobnostní možnosti ze seznamu.
- += nebo extend: Připojuje řetězec k vyvolání.
- [proměnná_name]: Načte výsledky generace.
- fork: Vytvoří paralelní větve stavu vyvolání.
- join: Sloučí stav vyvolání.
- image a video: Přijímají obrazové a video vstupy.
Nejjednodušší způsob, jak provést program SGLang, je prostřednictvím interpretu, kde je vyvolání považováno za asynchronní stream. Primitivy, jako extend, gen a select, jsou předány streamu pro asynchronní provádění, zajišťující správnou kontrolu nad synchronizací a intra-programovým paralelismem. Kromě toho lze programy SGLang sledovat a zkompilovat pro další optimalizace. Runtime SGLang podporuje otevřené modely s vlastním SGLang Runtime (SRT), stejně jako API modely, jako je OpenAI a Anthropic modely.
Programovací systémy pro LLM lze klasifikovat jako vysoké úrovně (například LangChain, DSPy) a nízké úrovně (například LMQL, Guidance, SGLang). Vysoké úrovně systémy poskytují předdefinované nebo automaticky generované vyvolání, jako je DSPy’s prompt optimizer. Nízké úrovně systémy obvykle nemění vyvolání, ale umožňují přímou manipulaci s vyvoláním a primitivy. SGLang je nízkou úrovní systém, podobný LMQL a Guidance. Následující tabulka porovnává jejich funkce.

SGLang se zaměřuje více na runtime efektivitu a přichází se svým vlastním navrženým runtime, umožňujícím novými optimalizacemi. Vysoké úrovně jazyky (například DSPy) lze zkompilovat do nízké úrovně jazyků (například SGLang). Integrace SGLang jako backendu v DSPy pro lepší runtime efektivitu je demonstrována později.

Předchozí příklad ilustruje RadixAttention operace s LRU vyřazením zásad napříč devíti časovými body, ukazující dynamický vývoj radix stromu v reakci na různé požadavky. Tyto požadavky zahrnují dvě chatovací sezení, dávku few-shot learning dotazů a self-konzistence sampling. Každá stromová hrana nese štítek označující podřetězec nebo sekvenci tokenů. Uzly jsou barevně kódovány pro odraz různých stavů: zelená pro nově přidávané uzly, modrá pro cached uzly přístupné během časového bodu a červená pro uzly, které byly vyřazeny.
Krok 1: Radix strom je inicializován jako prázdný.
Krok 2: Server zpracovává příchozí uživatelskou zprávu “Hello” a odpovídá s LLM výstupem “Hi”. Systémové vyvolání “You are a helpful assistant”, uživatelská zpráva “Hello!” a LLM odpověď “Hi!” jsou konsolidovány do stromu jako jeden hrana spojená s novým uzlem.
Krok 3: Nové vyvolání přichází a server najde prefix vyvolání (tj. první kolo konverzace) v radix stromu a opětovně využije jeho KV cache. Nové kolo je připojeno ke stromu jako nový uzel.
Krok 4: Nové chatovací sezení začíná. Uzel z kroku 3 je rozdělen na dva uzly, aby umožnil dvě chatovací sezení sdílet systémové vyvolání.
Krok 5: Druhé chatovací sezení pokračuje. Nicméně, kvůli omezením paměti, musí být uzel z kroku 4 vyřazen. Nové kolo je připojeno po zbývajícím uzlu z kroku 4.
Krok 6: Server obdrží few-shot learning dotaz, zpracuje ho a vloží ho do stromu. Kořenový uzel je rozdělen, protože nový dotaz nesdílí žádný prefix s existujícími uzly.
Krok 7: Server obdrží dávku dalších few-shot learning dotazů. Tyto dotazy sdílejí stejnou sadu few-shot příkladů, takže uzel z kroku 6 je rozdělen, aby umožnil sdílení.
Krok 8: Server obdrží novou zprávu z prvního chatovacího sezení. Vyřazuje všechny uzly ze druhého chatovacího sezení, protože jsou nejméně nedávno používané.
Krok 9: Server obdrží požadavek na vygenerování více odpovědí pro otázky v uzlu z kroku 8, pravděpodobně pro self-konzistenci vyvolání. Pro uvolnění místa pro tyto požadavky jsou vyřazeny více uzly.
Tento příklad demonstruje, jak RadixAttention zpracovává dynamickou alokaci a vyřazení uzlů v reakci na různé typy požadavků, zajišťující efektivní opětovné použití KV cache a správu paměti.
SGLang: Evaluace a výsledky
Výsledky na otevřených modelech
Latence a propustnost výsledky jsou ukázány v následujících obrázcích. SGLang zlepšuje propustnost až 6,4× a snižuje latenci až 3,7×. Tyto zlepšení vyplývají z opětovného použití KV cache, využití paralelismu v rámci jednoho programu a rychlejšího omezeného dekódování.

Na těchto benchmarcích se dosahuje cache hit rate v rozmezí 50% až 99%. Obrázek 13 (Příloha) uvádí dosažené a optimální cache hit rate pro všechny z nich, ukazující, že SGLangův cache-aware scheduling se blíží 96% optimálnímu hit rate v průměru.

Výsledky na větších modelech s tensorovým paralelismem
Větší modely, Mixtral-8x7B a Llama-70B, byly testovány s tensorovým paralelismem na stejné sadě benchmarků a výsledky jsou uvedeny v následujícím obrázku. Zrychlení na větších modelech ukazuje trend podobný tomu, který byl pozorován na menších modelech, ukazující, že SGLangova optimalizace se dobře generalizuje na větší modely. Guidance a LMQL byly vynechány kvůli nedostatku efektivní implementace tensorového paralelismu.

Výsledky na multi-modálních modelech
SGLang má nativní podporu pro multi-modální modely s image a video primitivy. Optimalizace v tomto článku jsou kompatibilní s multi-modálními modely. Pro RadixAttention je hash vstupních obrazů vypočten a použit jako klíč v radix stromu, umožňující opětovné použití KV cache obrazových tokenů ze stejného obrazu. LLaVA-v1.5-7B (obraz) byl spuštěn na llava-bench-in-the-wild a LLaVA-NeXT-34B (video) na ActivityNet. Protože tyto modely nejsou dobře podporovány jinými baseline systémy, byla použita originální implementace modelů v Hugging Face Transformers jako baseline. Jak je ukázáno v následující tabulce, SGLang poskytuje propustnost až 6× vyšší na těchto benchmarcích. V llava-bench-in-the-wild byly zpracovány více otázek o stejném obraze a SGLang runtime opětovně využil KV cache v tomto případě.

Produkční nasazení
SGLang byl nasazen v Chatbot Arena pro službu otevřených modelů. Kvůli nízkému provozu pro některé modely slouží pouze jeden SGLang worker pro každý. Po jednom měsíci byla pozorována 52,4% RadixAttention cache hit rate pro LLaVA-Next-34B a 74,1% pro Vicuna-33B. Cache hity pocházely z běžných systémových zpráv, často opakovaně používaných příkladů obrazů a multi-turn chat historie. To snížilo latenci prvního tokenu v průměru o 1,7× pro Vicuna-33B.

Závěrečné myšlenky
V tomto článku jsme mluvili o SGLang, nově zavedeném systému, který se snaží vyřešit problém efektivního provádění komplexních programů jazykových modelů. SGLang se skládá z frontendového jazyka a runtime. Frontend zjednodušuje programování pomocí primitiv pro generaci a řízení paralelismu, zatímco runtime urychluje provádění prostřednictvím novými optimalizacemi, jako je RadixAttention pro opětovné použití KV cache a komprimované konečné automaty pro rychlejší dekódování strukturovaných výstupů. Experimenty prokázaly, že SGLang dosahuje až 6,4× vyšší propustnosti ve srovnání se stávajícími systémy inference na různých velkých jazykových a multimodálních modelech, řešících úkoly, jako je řízení agentů, logické uvažování, few-shot learning benchmarky, JSON dekódování, retrieval-augmented generativní potrubí a multi-turn chat.












