Штучний інтелект
SGLang: Ефективна реалізація структурованих мовних моделей
Більші мовні моделі (LLM) все частіше використовуються для складних завдань, які вимагають декількох викликів генерації, просунутих технік промпту, контролю потоку та структурованих вхідних/вихідних даних. Однак ефективні системи для програмування та виконання цих застосунків відсутні. SGLang, нова система, спрямована на вирішення цієї проблеми, забезпечуючи ефективну реалізацію складних мовних моделей. SGLang складається з фронтенду мови та рантайму. Фронтенд спрощує програмування за допомогою примітивів для генерації та контролю паралелізму, тоді як рантайм прискорює виконання за допомогою нових оптимізацій, таких як RadixAttention для повторного використання кешу KV та стиснені скінченні автомати для швидшого декодування структурованих вихідних даних. Експерименти демонструють, що SGLang досягає до 6,4 разів вищої пропускної здатності порівняно з системами висновку останнього покоління на різних великих мовних та мульти-модальних моделях, які виконують завдання, такі як контроль агентів, логічне висновування, бенчмарки навчання з декількома зразками, декодування JSON, генерація з підтримкою пошукових запитів та багаторазовий чат.
Недавні досягнення в можливостях LLM розширили їхню корисність, дозволяючи їм обробляти ширший спектр загальних завдань та функціонувати як автономні агенти. У цих застосунках LLM займаються багаторазовим плануванням, висновуванням та взаємодією з зовнішнім середовищем. Це здійснюється за допомогою інструментів, декількох входних модальностей та різних технік промпту, таких як навчання з декількома зразками, самоузгодженість, скелет думки та дерево думки. Ці нові випадки використання вимагають декількох, часто залежних, викликів генерації LLM, вказуючи на тенденцію використання багаторазових структур для виконання складних завдань.
Цей перехід позначає переход від простого чату до більш складного програмного використання LLM, де програми планують та контролюють процеси генерації LLM. Ці програми називаються “Програмами мовної моделі” (LM Програми). Розширені техніки промпту та робочі процеси агентів входять до складу LM програм. Є дві спільні властивості LM програм: (1) LM програми зазвичай включають декілька викликів LLM, перемішаних з контролем потоку для виконання складних завдань та підвищення загальної якості. (2) LM програми приймають структуровані вхідні дані та видають структуровані вихідні дані, дозволяючи складати LM програми та інтегрувати їх у існуючі програмні системи.
У цій статті ми глибше розглянемо.framework SGLang, дослідимо його архітектуру, проаналізуємо його продуктивність та порівняємо його з системами останнього покоління. Тому почнімо.
Введення в SGLang
Незважаючи на широке використання LM програм, поточні системи для їх вираження та виконання залишаються неефективними. SGLang визначає дві основні проблеми, пов’язані з ефективним використанням LM програм:
- Складність програмування: Розробка LM програм є трудомісткою та складною через недетерміновану природу LLM. Це включає обширну маніпуляцію рядками, експериментальне налаштування промпту, крихку обробку вихідних даних, обробку декількох входних модальностей та реалізацію механізмів паралелізму. Ця складність суттєво знижує читабельність навіть простих програм.
- Неефективність виконання: Виконання LM програм є неефективним через повторну обчислення та використання пам’яті. Системи висновку останнього покоління, оптимізовані для зниження затримки та підвищення пропускної здатності, не мають прямого знання про робочий процес, що призводить до суттєвих неефективностей. Видатним прикладом є повторне використання кешу KV, який складається з повторно використовуваних проміжних тензорів, необхідних для генерації висновку. Поточні системи не мають ефективних механізмів для забезпечення повторного використання кешу KV між декількома викликами LLM, які мають спільний префікс, що призводить до зайвих обчислень та марнування пам’яті. Крім того, обмежене декодування для структурованих вихідних даних, таких як режим JSON, є субоптимальним, оскільки існуючі системи декодують лише один токен за раз.
Для вирішення цих проблем SGLang вводить структуровану мову генерації для LLM. Основна ідея полягає в систематичному використанні багаторазової структури в LM програмах для ефективного виконання. Як показано на наступному малюнку, SGLang складається з двох частин: фронтенду мови та рантайму.

Фронтенд спрощує програмування LM програм, а рантайм прискорює їхнє виконання. Ці частини можуть працювати разом для кращої продуктивності або функціонувати незалежно.
SGLang є мовою зі спеціальним призначенням, вбудованою в Python, яка забезпечує примітиви для генерації (наприклад, extend, gen, select) та контролю паралелізму (наприклад, fork, join). Він сумісний з контролем потоку Python та бібліотеками, що дозволяє користувачам легко розробляти просунуті робочі процеси промпту за допомогою рідної синтаксики Python. SGLang включає інтерпретатор та компілятор. Інтерпретатор керує станом промпту як потоком та підсилає примітивні операції до потоку для асинхронного виконання, забезпечуючи належний контроль над синхронізацією та внутрішньопрограмним паралелізмом. Крім того, програми SGLang можна відстежувати та компілювати для подальших оптимізацій. Рантайм SGLang пропонує декілька нових оптимізацій для прискорення виконання LM програм:
- RadixAttention: Ця техніка дозволяє автоматичне повторне використання кешу KV між декількома викликами генерації. У існуючих системах висновку кеш KV запиту викидається після обробки, що запобігає повторному використанню між декількома викликами та сповільнює виконання. SGLang підтримує кеш LRU кешу KV у радіальному дереві, керуючи кешем KV як традиційним кешем та використовуючи радіальне дерево для ефективного збігу, вставки та видалення. Це дозволяє рантайму ефективно обробляти різні моделі повторного використання.
- Compressed Finite State Machine: Ця техніка дозволяє швидше обмежене декодування для структурованих вихідних даних. Існуючі системи слідують обмеженням лише для наступного токену, що дозволяє їм декодувати лише один токен за раз. Натомість SGLang аналізує обмеження та створює стиснене скінченне автоматичне державне машину для їх представлення, стискаючи багаторазовий шлях у один крок, коли це можливо, що дозволяє декодувати декілька токенів одночасно для підвищення швидкості.
- API Speculative Execution: Для моделей API, таких як OpenAI’s GPT-4, SGLang вводить спекулятивне виконання API для оптимізації багаторазових програм.
За допомогою SGLang були реалізовані різні застосунки LLM, включаючи контроль агентів, логічне висновування, бенчмарки навчання з декількома зразками, декодування JSON, генерацію з підтримкою пошукових запитів, багаторазовий чат та обробку мульти-модальності. Продуктивність була протестована на моделях, включаючи Llama-7B/70B, Mistral-8x7B, LLaVA-v1.5-7B (зображення) та LLaVA-NeXT-34B (відео) на процесорах NVIDIA A10G та A100. Експериментальні результати показують, що SGLang досягає до 6,4 разів вищої пропускної здатності на широкому спектрі робочих процесів, моделей та апаратних конфігурацій, порівняно з існуючими системами програмування та висновку, включаючи Guidance, vLLM та LMQL.
SGLang: Модель програмування та методологія
Модель програмування SGLang вводиться через приклад, який описує її мовні примітиви та режими виконання, та викладає можливості оптимізації рантайму. Ця модель спрощує трудомісткі операції у багаторазових робочих процесах (наприклад, маніпуляцію рядками, виклики API, специфікацію обмежень, паралелізм) за допомогою гнучких та складних примітивів. SGLang є мовою зі спеціальним призначенням, вбудованою в Python.

Функція multi_dimensional_judge приймає три аргументи: `s`, `path` та `essay`. s керує станом промпту, path — шлях до зображення, а essay — текст есе. Нові рядки та примітиви SGLang можна додати до стану s для виконання за допомогою оператора +=. Спочатку функція додає зображення та есе до промпту. Потім вона перевіряє, чи пов’язане есе з зображенням, використовуючи select, та зберігає результат у s[“related”]. Якщо пов’язане, промпт розділяється на три копії для паралельної оцінки з різних вимірів, використовуючи gen для збереження результатів у f[“judgment”]. Далі вона об’єднує судження, генерує підсумок та призначає буквену оцінку. Нарешті, вона повертає результати у форматі JSON, згідно зі схемою, визначеною регулярним виразом regex. SGLang суттєво спрощує цю програму, оскільки еквівалентна програма, використовуючи інтерфейс, подібний до OpenAI API, займе 2,1 рази більше рядків коду через ручну маніпуляцію рядками та контроль паралелізму.
SGLang забезпечує примітиви для контролю стану промпту, генерації та паралелізму, які можна використовувати з синтаксисом Python та бібліотеками. Ось ці примітиви:
gen: Викликає модель для генерації та зберігає результати у змінній з ім’ям, вказаним у першому аргументі. Він підтримує аргумент regex для обмеження виводу згідно з граматикою, визначеною регулярним виразом (наприклад, схемою JSON).
- select: Викликає модель для вибору найбільш імовірного варіанту з списку.
- += або extend: Додає рядок до промпту.
- [variable_name]: Відкриває результати генерації.
- fork: Створює паралельні копії стану промпту.
- join: Об’єднує стан промпту.
- image та video: Приймають вхідні дані зображення та відео.
Найпростіший спосіб виконання програми SGLang — через інтерпретатор, де промпт обробляється як асинхронний потік. Примітиви, такі як extend, gen та select, підсилаються до потоку для асинхронного виконання. Ці неблокуючі виклики дозволяють коду Python продовжувати виконання без очікування завершення генерації, подібно до запуску ядер CUDA асинхронно. Кожен промпт керується виконавцем потоку у фонових потоках, що дозволяє здійснювати внутрішньопрограмний паралелізм. Відкриття результатів генерації буде блокуватися до тих пір, поки вони не будуть готові, забезпечуючи правильну синхронізацію. Альтернативно, програми SGLang можна скомпілювати як обчислювальні графи та виконувати з виконавцем графа, що дозволяє здійснювати подальші оптимізації. Ця стаття використовує режим інтерпретатора за замовчуванням та обговорює результати компілятора у додатку D. SGLang підтримує відкриті моделі з власним рантаймом SGLang (SRT), а також моделі API, такі як OpenAI та Anthropic.
Системи програмування для LLM можна класифікувати як високорівневі (наприклад, LangChain, DSPy) та низькорівневі (наприклад, LMQL, Guidance, SGLang). Високорівневі системи забезпечують попередньо визначені або автоматично згенеровані промпти, такі як оптимізатор промпту DSPy. Низькорівневі системи зазвичай не змінюють промпти, але дозволяють прямий контроль над промптами та примітивами. SGLang є низькорівневою системою, подібною до LMQL та Guidance. Наступна таблиця порівнює їхні функції.

SGLang зосереджується на ефективності рантайму та поставляється з власним ко-дизайнованим рантаймом, що дозволяє здійснювати нові оптимізації. Високорівневі мови (наприклад, DSPy) можна скомпілювати у низькорівневі мови (наприклад, SGLang). Інтеграція SGLang як бекенду в DSPy для кращої ефективності рантайму демонструється пізніше.

Вищезгаданий приклад ілюструє операції RadixAttention з політикою видалення LRU через дев’ять точок часу, демонструючи динамічну алокацію та видалення вузлів у відповідь на різні запити, забезпечуючи ефективне повторне використання кешу KV та керування пам’яттю.
Крок 1: Радіальне дерево спочатку порожнє.
Крок 2: Сервер обробляє вхідне повідомлення користувача “Привіт” та відповідає виводом LLM “Привіт!”. Системний промпт “Ви є корисним помічником”, повідомлення користувача “Привіт!” та відповідь LLM “Привіт!” консолідуються у дерево як один край, пов’язаний з новим вузлом.
Крок 3: Надходить новий промпт, та сервер знаходить префікс промпту (тобто перший поворот розмови) у радіальному дереві та повторно використовує його кеш KV. Новий поворот додається до дерева як новий вузол.
Крок 4: Починається нова сесія чату. Вузол з кроку 3 розділяється на два вузли, щоб дозволити двом сесіям чату спільно використовувати системний промпт.
Крок 5: Друга сесія чату продовжується. Однак через обмеження пам’яті вузол з кроку 4 повинен бути видалений. Новий поворот додається після залишеного вузла з кроку 4.
Крок 6: Сервер приймає запит на навчання з декількома зразками, обробляє його та вставляє у дерево. Кореневий вузол розділяється, оскільки новий запит не має спільного префіксу з існуючими вузлами.
Крок 7: Сервер приймає пакет додаткових запитів на навчання з декількома зразками. Ці запити мають спільний набір прикладів навчання з декількома зразками, тому вузол з кроку 6 розділяється для забезпечення спільного використання.
Крок 8: Сервер приймає нове повідомлення від першої сесії чату. Він видалить усі вузли другої сесії чату, оскільки вони є найменш недавно використаними.
Крок 9: Сервер приймає запит на вибірку додаткових відповідей для питань у вузлі з кроку 8, ймовірно, для промпту самоузгодженості. Для розміщення цих запитів видаляються декілька вузлів.
Цей приклад демонструє, як RadixAttention обробляє динамічну алокацію та видалення вузлів у відповідь на різні запити, забезпечуючи ефективне повторне використання кешу KV та керування пам’яттю.
SGLang: Оцінка та результати
Результати на відкритих моделях
Результати затримки та пропускної здатності показані на наступному малюнку. SGLang підвищує пропускну здатність до 6,4 разів та знижує затримку до 3,7 разів. Ці покращення є результатом повторного використання кешу KV, використання паралелізму всередині однієї програми та швидшого обмеженого декодування.

На цих бенчмарках рівень влучності кешу варіюється від 50% до 99%. Фігура 13 (Додаток) перераховує досягнуті та оптимальні рівні влучності кешу для всіх з них, показуючи, що підхід до планування, залежного від кешу, SGLang наближається до 96% оптимального рівня влучності кешу в середньому.

Результати на більших моделях з паралелізмом тензорів
Більші моделі, Mixtral-8x7B та Llama-70B, були протестовані з паралелізмом тензорів на тому ж наборі бенчмарків, та результати зазначені на наступному малюнку. Прискорення на більших моделях показує тенденцію, подібну до тієї, що спостерігається на менших моделях, вказуючи на те, що оптимізації SGLang добре узагальнюються на більші моделі. Guidance та LMQL були опущені через відсутність ефективних реалізацій паралелізму тензорів.

Результати на мульти-модальних моделях
SGLang має вбудовану підтримку мульти-модальних моделей з примітивами зображення та відео. Оптимізації в цій статті сумісні з мульти-модальними моделями. Для RadixAttention хеш вхідних зображень обчислюється та використовується як ключ у радіальному дереві, що дозволяє повторно використовувати кеш KV токенів зображень з того самого зображення. LLaVA-v1.5-7B (зображення) була запущена на llava-bench-in-the-wild, а LLaVA-NeXT-34B (відео) — на ActivityNet. Оскільки ці моделі не підтримуються іншими системами базових порівнянь, оригінальна реалізація авторів моделей у Hugging Face Transformers була використана як базова система. Як показано на наступній таблиці, SGLang забезпечує пропускну здатність до 6 разів вищу на цих бенчмарках. У llava-bench-in-the-wild оброблювались декілька запитів про одне зображення, та рантайм SGLang повторно використовував кеш KV у цьому випадку.

Розгортання у виробництві
SGLang було розгорнуто у Chatbot Arena для обслуговування відкритих моделей. Через низький трафік для деяких моделей лише один робітник SGLang обслуговує кожну модель. Через місяць було спостережено рівень влучності кешу RadixAttention у 52,4% для LLaVA-Next-34B та 74,1% для Vicuna-33B. Влучності кешу походили від спільних системних повідомлень, часто повторно використовуваних прикладів зображень та багаторазових історій чату. Це знизило затримку першого токену в середньому на 1,7 рази для Vicuna-33B.

Заключні думки
У цій статті ми говорили про SGLang, нову систему, спрямовану на забезпечення ефективної реалізації складних мовних моделей. SGLang складається з фронтенду мови та рантайму. Фронтенд спрощує програмування за допомогою примітивів для генерації та контролю паралелізму, тоді як рантайм прискорює виконання за допомогою нових оптимізацій, таких як RadixAttention для повторного використання кешу KV та стиснені скінченні автомати для швидшого декодування структурованих вихідних даних. Експерименти демонструють, що SGLang досягає до 6,4 разів вищої пропускної здатності порівняно з системами висновку останнього покоління на різних великих мовних та мульти-модальних моделях, які виконують завдання, такі як контроль агентів, логічне висновування, бенчмарки навчання з декількома зразками, декодування JSON, генерацію з підтримкою пошукових запитів та багаторазовий чат.












