Штучний інтелект
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 у radix дереві, керуючи кешем KV як традиційний кеш та використовуючи radix дерево для ефективного збігання, вставки та видалення. Це дозволяє часу виконання ефективно обробляти різні шаблони повторного використання.
- Стиснутий Скінченний Автомат: Ця техніка дозволяє швидше обмежене декодування для структурованих виходів. Існуючі системи слідують обмеженням лише для наступного токену, що дозволяє їм декодувати лише один токен за раз. Натомість SGLang аналізує обмеження та будує стиснутий скінченний автомат для їхнього представлення, стискаючи багаторівневий шлях у один крок, коли це можливо, що дозволяє декодувати декілька токенів одночасно для швидшої швидкості.
- API Спекулятивне Виконання: Для моделей 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 GPU. Експериментальні результати показують, що SGLang досягає до 6,4 разів вищої пропускної здатності на широкому спектрі робочих процесів, моделей та конфігурацій апаратного забезпечення, порівняно з існуючими системами програмування та висновку, включаючи Guidance, vLLM та LMQL.
SGLang: Модель Програмування та Методологія
Модель програмування SGLang вводиться через приклад, що описує його мовні примітиви та режими виконання, та викладає можливості оптимізації часу виконання. Ця модель спрощує трудомісткі операції в багаторівневих робочих процесах (наприклад, маніпуляцію рядками, виклики API, специфікацію обмежень, паралелізм) за допомогою гнучких та складних примітивів. SGLang є мовою спеціального призначення, вбудованою в Python. Наступна фігура показує програму, яка оцінює есе про зображення за допомогою методу branch-solve-merge.

Функція 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: Додає рядок до промпту.
- [ім’я_змінної]: Отримує результати генерації.
- 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 на дев’яти точках часу, демонструючи динамічну еволюцію radix дерева у відповідь на різні запити. Ці запити включають два сеанси чату, партію запитів навчання з декількома зразками та вибірковий самоузгодженість. Кожний край дерева містить мітку, що позначає підстроку або послідовність токенів. Вузли кольорові, щоб відображати різні стани: зелений для нових вузлів, синій для кешованих вузлів, доступних під час точки часу, та червоний для вузлів, які були видалені.
Крок 1: Радix дерево спочатку порожнє.
Крок 2: Сервер обробляє надіслане користувачем повідомлення “Привіт” та відповідає виходом LLM “Привіт”. Системний промпт “Ви є корисним помічником”, повідомлення користувача “Привіт!” та відповідь LLM “Привіт!” об’єднуються у дерево як один край, пов’язаний з новим вузлом.
Крок 3: Надходить новий промпт, та сервер знаходить префікс промпту (тобто перший хід розмови) у radix дереві та повторно використовує його кеш 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 хеш вхідних зображень обчислюється та використовується як ключ у radix дереві, що дозволяє повторно використовувати кеш 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, трубопроводи генерації з підтримкою пошукових систем та багатотурні чати.












