人工知能
SGLang: 構造化言語モデルプログラムの効率的な実行
大規模言語モデル(LLM)は、複数の生成呼び出し、先進的なプロンプティング技術、制御フロー、構造化された入出力が必要な複雑なタスクにますます利用されています。ただし、これらのアプリケーションをプログラミングおよび実行するための効率的なシステムは不足しています。SGLangは、構造化言語モデルプログラムの効率的な実行を提供することでこの問題に対処することを目的としています。SGLangは、フロントエンド言語とランタイムで構成されます。フロントエンドは、生成と並列性制御のプリミティブを提供することでプログラミングを簡素化し、ランタイムは、RadixAttentionによるKVキャッシュの再利用や、構造化された出力の解码を高速化するための新しい最適化技術を通じて実行を加速します。実験結果は、SGLangが、さまざまな大規模言語モデルや多モーダルモデルで、最先端の推論システムと比較して、最大6.4倍のスループットを達成することを示しています。これらのタスクには、エージェント制御、論理的推論、少-shot学習ベンチマーク、JSON解码、検索強化生成パイプライン、多回チャットなどがあります。
LLMの機能の最近の進歩により、その有用性が拡大し、より幅広い一般的なタスクを処理できるようになり、自律エージェントとして機能することができます。これらのアプリケーションでは、LLMは、外部環境とのやり取りを含む、マルチラウンドの計画、推論、インタラクションに従事します。これは、ツールの使用、複数の入力モダリティ、そして、少-shot学習、自己一貫性、スケルトン・オブ・ソught、ツリー・オブ・ソughtなどのさまざまなプロンプティング技術を通じて促進されます。これらの新しいユースケースでは、複雑なタスクを完了するために、依存関係のあるLLM生成呼び出しが複数必要であることを示しています。
このシフトは、単純なチャットから、LLMのより洗練されたプログラミング使用に移行を示しています。ここで、プログラムはLLMの生成プロセスをスケジュールおよび制御します。これらのプログラムは、「言語モデルプログラム」(LMプログラム)と呼ばれます。先進的なプロンプティング技術やエージェントワークフローは、LMプログラムの範囲内にあります。LMプログラムには、2つの共通の特性があります。(1)LMプログラムは通常、複雑なタスクを完了し、全体の品質を向上させるために、制御フローを伴う複数のLLM呼び出しを含みます。(2)LMプログラムは、構造化された入力を受け取り、構造化された出力を生成します。これにより、LMプログラムを構成し、既存のソフトウェアシステムに統合することができます。
この記事では、SGLangフレームワークについて詳細に説明し、そのアーキテクチャを分析し、パフォーマンスを比較します。では、始めましょう。
SGLangの紹介
LMプログラムの広範な使用にもかかわらず、現在のシステムはそれらを表現および実行することが非効率的です。SGLangは、LMプログラムの効率的な使用に関連する2つの主要な課題を特定しています。
- プログラミングの複雑さ:LLMの非決定的な性質により、LMプログラムの開発は面倒で難しいです。これには、広範な文字列操作、プロンプトの実験的な調整、脆弱な出力解析、複数の入力モダリティの処理、並列性メカニズムの実装が含まれます。この複雑さにより、簡単なプログラムの可読性が大幅に低下します。
- 実行の非効率性:LMプログラムの実行は、冗長な計算とメモリ使用により非効率的です。待ち時間を削減し、スループットを向上させるために最適化された最先端の推論エンジンは、ワークロードに関する直接の知識が不足しているため、重大な非効率性が生じます。KVキャッシュの再利用は、生成的推論に不可欠な中間テンソルを含むキャッシュの再利用であり、共通のプレフィックスを共有する複数のLLM呼び出しに対して、現在のシステムでは効果的なメカニズムが不足しています。さらに、JSONモードなどの構造化された出力の制約付き解码は、既存のシステムが1回の解码で1トークンしか解码できないため、最適ではありません。
これらの課題に対処するために、SGLangはLLM用の構造化生成言語を導入します。基本的な考え方は、LMプログラムのマルチ呼び出し構造を効率的な実行のために体系的に活用することです。次の図に示すように、SGLangは2つの部分で構成されます。フロントエンド言語とバックエンドランタイムです。

フロントエンドはLMプログラムのプログラミングを簡素化し、ランタイムは実行を加速します。これらの部分は、パフォーマンスを向上させるために共同で作業するか、独立して機能することができます。
SGLangは、Pythonに埋め込まれたドメイン固有の言語であり、生成(例:extend、gen、select)と並列性制御(例:fork、join)用のプリミティブを提供します。Pythonの制御フローとライブラリと互換性があるため、ネイティブのPython構文で先進的なプロンプティングワークフローを簡単に開発できます。SGLangには、インタープリターとコンパイラが含まれます。インタープリターは、プロンプト状態をストリームとして管理し、プリミティブ操作をストリームに提出して非同期実行を実行し、同期とプログラム内並列性の適切な制御を保証します。さらに、SGLangプログラムはトレースされ、コンパイルされてさらに最適化できます。SGLangのランタイムは、LMプログラムの実行を加速するためにいくつかの新しい最適化を提案します。
- RadixAttention:この技術により、KVキャッシュが複数の生成呼び出し間で自動的に再利用されます。既存の推論エンジンでは、リクエストのKVキャッシュが処理後に破棄され、複数の呼び出し間で再利用できず、実行が遅くなります。SGLangは、ルート木内のKVキャッシュのLRUキャッシュを維持し、ルート木を使用して効率的なマッチング、挿入、追い出しを実行します。これにより、ランタイムはさまざまな再利用パターンを効率的に処理できます。
- 圧縮された有限状態マシン:この技術により、構造化された出力の制約付き解码が高速化されます。既存のシステムは、次のトークンに対してのみ制約を従うため、1回の解码で1トークンしか解码できません。代わりに、SGLangは制約を分析し、それらを表すために圧縮された有限状態マシンを構築し、可能な場合はマルチトークンパスを1ステップのパスに圧縮し、複数のトークンを同時に解码して高速化します。
- API推測的実行:APIのみのモデル(例:OpenAIのGPT-4)に対して、SGLangはマルチ呼び出しプログラムを最適化するためにAPI推測的実行を導入します。
SGLangを使用して、エージェント制御、論理的推論、少-shot学習ベンチマーク、JSON解码、検索強化生成パイプライン、多回チャット、多モダリティ処理などのさまざまなLLMアプリケーションが実装されました。パフォーマンスは、Llama-7B/70B、Mistral-8x7B、LLaVA-v1.5-7B(画像)、LLaVA-NeXT-34B(ビデオ)などのモデルで、NVIDIA A10GおよびA100 GPUでテストされました。実験結果は、SGLangが、さまざまなワークロード、モデル、ハードウェア設定で、Guidance、vLLM、LMQLを含む既存のプログラミングおよび推論システムと比較して、最大6.4倍のスループットを達成することを示しています。
SGLang: プログラミングモデルと方法論
SGLangプログラミングモデルは、ランニングエクサンプルを介して導入され、言語プリミティブと実行モードについて説明し、ランタイム最適化の機会について概説します。このモデルは、マルチ呼び出しワークフロー(例:文字列操作、API呼び出し、制約の指定、並列性)で面倒な操作を簡素化することで、柔軟で構成可能なプリミティブを提供します。SGLangは、Pythonに埋め込まれたドメイン固有の言語です。次の図は、ブランチ・ソルブ・マージプロンプティング方法を使用して画像についてのエッセイを評価するプログラムを示しています。

関数multi_dimensional_judgeには3つの引数があります:`s`、`path`、`essay`。sはプロンプト状態を管理し、pathは画像ファイルパス、essayはエッセイのテキストです。新しい文字列とSGLangプリミティブは、実行のために+=演算子を使用して状態sに追加できます。まず、関数は画像とエッセイをプロンプトに追加します。次に、エッセイが画像に関連しているかどうかをselectを使用して確認し、結果をs[“related”]に保存します。関連している場合、プロンプトは3つのコピーに分岐して並列評価を行い、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コードは生成が完了するのを待たずに実行を続行できます。各プロンプトは、バックグラウンドスレッドのストリームエクスキューターによって管理され、プログラム内並列性が可能になります。生成結果の取得は、結果が準備できたときにブロックします。正しい同期を保証するためです。代わりに、SGLangプログラムは計算グラフとしてコンパイルされ、グラフエクスキューターで実行できます。これにより、さらに最適化できます。この論文では、デフォルトでインタープリターモードを使用し、コンパイルモードの結果については付録Dで説明します。SGLangは、独自のSGLangランタイム(SRT)を使用して、オープンウェイトモデルもサポートしています。また、OpenAIやAnthropicモデルなどのAPIモデルもサポートしています。
LLM用のプログラミングシステムは、高レベル(例:LangChain、DSPy)と低レベル(例:LMQL、Guidance、SGLang)に分類できます。高レベルシステムは、事前定義されたまたは自動生成されたプロンプト(例:DSPyのプロンプト最適化)を提供します。低レベルシステムは、通常、プロンプトを変更せずに、プロンプトとプリミティブの直接操作を許可します。SGLangは、LMQLやGuidanceと同様の低レベルシステムです。次の表は、それらの機能を比較しています。

SGLangは、ランタイム効率に重点を置き、独自の共同設計ランタイムを備えており、新しい最適化が可能です。高レベル言語(例:DSPy)は、低レベル言語(例:SGLang)にコンパイルできます。DSPyのバックエンドとしてSGLangを統合して、ランタイム効率を向上させることは、後で示されます。

上記の例は、9つの時間点でRadixAttention操作を示しています。ここでは、チャットセッション、少-shot学習のバッチ、自己一貫性サンプリングなどのさまざまなリクエストに応じて、ルート木の動的割り当てと追い出しがどのように行われるかを示しています。各ツリーのエッジには、サブ文字列またはトークンのシーケンスを表すラベルが付いています。ノードは、状態を反映して色分けされています。緑は新しく追加されたノード、青は時間点中にアクセスされたキャッシュされたノード、赤は追い出されたノードです。
ステップ1:ルート木は最初は空です。
ステップ2:サーバーは、ユーザーから「Hello」というメッセージを受信し、「Hi」というLLM出力を返します。システムプロンプト「You are a helpful assistant」、ユーザーメッセージ「Hello!」、LLMの返信「Hi!」は、ツリーに新しいノードに接続された単一のエッジとして統合されます。
ステップ3:新しいプロンプトが到着し、サーバーはプロンプトのプレフィックス(会話の最初のターン)をルート木で見つけ、KVキャッシュを再利用します。新しいターンはツリーに新しいノードとして追加されます。
ステップ4:新しいチャットセッションが開始されます。ステップ3のノードは、2つのチャットセッションがシステムプロンプトを共有できるように2つのノードに分割されます。
ステップ5:2番目のチャットセッションが続きます。ただし、メモリ制限のため、ステップ4のノードを追い出す必要があります。新しいターンは、ステップ4の残りのノードの後に追加されます。
ステップ6:サーバーは、少-shot学習のクエリを受信し、処理し、ツリーに挿入します。ルートノードは、新しいクエリが既存のノードとプレフィックスを共有しないため、分割されます。
ステップ7:サーバーは、さらに少-shot学習のクエリのバッチを受信します。これらのクエリは、同じセットの少-shot例を共有するため、ステップ6のノードが分割され、共有が可能になります。
ステップ8:サーバーは、最初のチャットセッションからの新しいメッセージを受信し、2番目のチャットセッションのすべてのノードを、最も最近使用されていないため、追い出します。
ステップ9:サーバーは、ステップ8のノードの質問に対してさらに回答をサンプリングするリクエストを受信します。可能であれば、自律性のあるプロンプティングのために。これらのリクエストにスペースを確保するために、複数のノードが追い出されます。
この例は、RadixAttentionが、チャットセッション、少-shot学習、自己一貫性サンプリングなどのさまざまなリクエストに応じて、ノードの動的割り当てと追い出しをどのように処理するかを示しています。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にデプロイされています。一部のモデルではトラフィックが低いため、各モデルには1つのSGLangワーカーしかありません。1ヶ月後、LLaVA-Next-34BのRadixAttentionキャッシュヒット率は52.4%、Vicuna-33Bのキャッシュヒット率は74.1%でした。キャッシュヒットは、共通のシステムメッセージ、頻繁に再利用される例の画像、多回チャットの履歴から来ました。これにより、Vicuna-33Bの最初のトークンの待ち時間が平均1.7倍短縮されました。

最終的な考え
この記事では、SGLangについて説明しました。SGLangは、構造化言語モデルプログラムの効率的な実行を提供することを目的とした新しいシステムです。SGLangは、フロントエンド言語とランタイムで構成され、フロントエンドはプログラミングを簡素化し、ランタイムはRadixAttentionや圧縮された有限状態マシンなどの新しい最適化技術を通じて実行を加速します。実験結果は、SGLangが、さまざまな大規模言語モデルや多モーダルモデルで、最先端の推論システムと比較して、最大6.4倍のスループットを達成することを示しています。これらのタスクには、エージェント制御、論理的推論、少-shot学習ベンチマーク、JSON解码、検索強化生成パイプライン、多回チャットなどがあります。












