SGLang は1本の radix tree に FULL、SWA、Mamba という3種類の再利用ルールを詰め込んだ。命中はコンポーネント投票で決め、移行は HiCache の同名移行でこなし、淘汰はセッション感知で処理する。ツリーは1本だけ残し、ルールはコンポーネントに任せる。
たとえ話はここまで。実際には、木は各プレフィックス区間に座標を振る役割だけを担い、FULL、SWA、MAMBA はそれぞれコンポーネントとして自身の再利用境界を決め、最深で全員一致したノードを投票で確定する。
3種類の再利用ルールを1本の木にどう収めるか?
3種類の再利用境界は互いに異なるため、同じプレフィックスに押し込むのは無駄であり、ときには越境になる。SGLang の解決策は、木を1本だけ残し、ルールを木から切り離すことだ。
混合モデルは全注意 KV、スライディングウィンドウ KV、循環状態を同一リクエストに詰め込み、トークンプレフィックス(モデルが読み込む最小テキスト単位の列)を共有しても再利用境界は共有できない。全注意の KV はプレフィックス全体にわたって有効、スライディングウィンドウ(Sliding Window Attention, SWA)の KV は末尾の一定範囲のウィンドウ内でのみ有効、Mamba(固定サイズの状態で完全な KV の代わりに使う循環層アーキテクチャ、MAMBA)のような循環状態は正確なチェックポイントでのみ利用可能。従来の実装では組み合わせごとにキャッシュクラスを書き、HiCache のような直交機能をさらに重ねていた——キャッシュクラスが順列組み合わせで膨れ上がり、組合せ爆発を起こし、マッチ、挿入、ロック、淘汰のロジックも重複していた。
Unified Radix Cache はこの2つを分離する。トークンプレフィックスで組織化された1本の radix tree(基数木、radix tree)が各プレフィックス区間に唯一の座標を割り当て、FULL、SWA、MAMBA はそれぞれ TreeComponent としてぶら下がる。
たとえ話はここまで。実際の仕組みはこうだ。UnifiedTreeCore が各プレフィックス区間に座標を振り、FULL、SWA、MAMBA の各コンポーネントはその座標に対して自分がどこまで進めるかを投票する。FULL は経路全体を進み、SWA は末尾ウィンドウを進み、MAMBA は正確なチェックポイントだけを取る。マッチング時に UnifiedTreeCore は FULL 経路を辿り、アクセスした各ノードが境界候補となる。有効化された各コンポーネントが validator 投票を生成し、最深で全員通过的したノードだけが安全と見なされる。DeepSeek-V4 は FULL+SWA を採用し、Kimi-K3 の KDA(線形注意の変種で、固定サイズ状態で循環を行う)は FULL+MAMBA を通り、Inkling は3種類のコンポーネントを同一の木に載せている。
新しいモデルファミリーは既存のコンポーネント組み合わせをそのまま再利用できる。新しい再利用ルールを追加するときも、TreeComponent を1つ追加するだけで、新しい木を作る必要はない。
木は歩くだけ、ルールはコンポーネント投票に委ねる
境界を決めるのは誰か?木ではなく、ノードにぶら下がった3つのコンポーネントだ。FULL、SWA、MAMBA はそれぞれ自身の「再利用可能境界」を定義し、意見が割れたときは投票で決まる。新しいモデルはコンポーネント組み合わせを選ぶだけで、木を作り直す必要はない。
混合モデルが難しいのは、同じトークンプレフィックス下でも全注意・スライディングウィンドウ・循環状態がそれぞれ異なる「再利用可能境界」を持つことだ。組み合わせごとにキャッシュクラスを書き、HiCache を重ねると組合せ爆発になる。SGLang の Unified Radix Cache は、radix 木にプレフィックス座標の機能だけを担わせ、FULL、SWA、MAMBA がそれぞれ自身の境界を決め、ツリー全体を1本に保つ。
境界の見つけ方は投票制だ。UnifiedTreeCore は FULL 経路を辿り、アクセスした各ノードを境界候補として、すべての有効化済みコンポーネントのバリデータに投げ込む。スライディングウィンドウは末尾ウィンドウの連続性をチェックし、循環状態は正確なチェックポイントの有無を検査する。
いずれか1つでも否決すれば、別の候補に切り替えて再び歩く。すべてのコンポーネントが同意する最深的ノードが、再利用可能境界となる。1周し終えると、MatchResult が各コンポーネントの finalizer に渡されて仕上げを行う。例えば MAMBA のチェックポイントは共有コピーから該当リクエストの私有スロットへ書き写す必要がある。
投票の代償は、ノードが「半分空」になる可能性があることだ。SWA コンポーネントは古いスロットが淘汰された後、tombstone(墓標マーカー、該当位置が空であることを示す)のみを残し、radix ノード自体は動かない。MAMBA の私有コピーが完了しても、ノード上に空のスロットが残りうる。コンポーネントが再有効化されるか、ノードが無効化されない限り、empty スロットはクリアされない。
同一プレフィックス下で異なるコンポーネントのデータがずれて着座することがあっても、ツリーの位相は安定しており、コンポーネントが自分の分に戻れば作業を続行できる。
残りのライフサイクルはフックで繋ぐ。マッチング時は create_match_validator がノードの使用可否を決め、分割時は redistribute_on_node_split が KV を再配置し、挿入時は handle_node_insertion が重複を処理し、淘汰時は dispose_node がデバイス間の解放順序を決める。ツリーコアはサーブとポジショニングだけを担い、ルールの細部はコンポーネントに戻る。原典はこの抽象を「new model families can compose these capabilities without introducing another cache tree」と総括する。ただし前提は、再利用ルールが既存コンポーネントの射程内に収まることだ。
新モデルの組み込みは2ステップに圧縮される:既存の FULL / SWA / MAMBA 組み合わせから1つを選ぶか、TreeComponent を追加する。DeepSeek-V4 は FULL + MAMBA、Kimi-K3 は FULL + SWA、Inkling は FULL + SWA + MAMBA という具合に、同じプレフィックス座標で走らせる。新しいルール(例えば別の循環状態(モデルが長い上文を圧縮するための小型記憶ユニット)の変種)が現れたときのみ TreeComponent インターフェースに手を入れ、新たな木を増やすことはない。続く HiCache の階層移行や淘汰戦略も、同じ木の同じコンポーネントフック群に沿ってぶら下げればよく、キャッシュロジック一式を組み立て直す必要はない。
3種類の注意を1本の木で併用するとき、誰が采配を握るか?
3種類の再利用ルールはそれぞれ区間を分担する。FULL はプレフィックス全体にわたって有効、SWA(スライディングウィンドウ注意、末尾の一部のトークンのみをカバーする)は末尾ウィンドウのみを再利用でき、MAMBA(循環状態層、正確なチェックポイントでのみ有効)は正確なチェックポイントでのみ効く。SGLang は3種類のルールを同一の radix tree(基数木、トークン列でプレフィックスを索引化する木構造)にぶら下げ、再利用候補点をコンポーネント検証に1つずつ通し、否決した者は差し戻し、すべてのコンポーネントが同意した最寄りノードを最終的な境界として残す。
Figure 2 が描いているのもこのフローだ。UnifiedTreeCore は FULL 経路を n4 まで進むが、n3、n4 は少なくとも1つのコンポーネントに拒絶され、n2 が3つのコンポーネント同時に受容する再利用境界となる。再利用深度は投票結果であり、トラバーサル深度ではない。
Inkling のように3種類の注意機構を同時に混在させるフル複合モデルでも、追加の木実装は不要だ。
マッチング後にもう1ステップある。マッチング段階で各コンポーネントは候補境界を検証する validator を生成し、終了後に finalizer を走らせて結果を仕上げる。finalizer 段階で状態が複製されることがある。共有された MAMBA のチェックポイントが特定のリクエストにクレームされると、そのリクエストの私有スロットへコピーしてから書き換える必要がある。この「クレーム即私有」メカニズムにより、共有状態が並行書き込みで乱れることを防ぐ。
淘汰が人を識別し始める:アクティブなセッションを優先的に残す
異なる再利用ルールを同一の木に詰め込むのは第一歩にすぎない。木はさらに誰がオンラインで誰が去ったかも見分けられなければならない。次の試練は淘汰だ。
木の総容量には限りがある。
モデルとまだ対話中のセッションと、10分間動きのないセッションでは、キャッシュ価値が大きく異なる。前者の次ラウンドリクエストはこのプレフィックスを引き続き使う可能性が極めて高く、後者はいつでも丸ごと捨てられうる。
SGLang のやり方はセッション感知淘汰だ。キャッシュエントリとそれを生んだセッションを結びつけ、淘汰時にはアクティブセッションのエントリを優先的に残すが、硬直した固定はしない。原典はこうも明言している:
SWE-bench ワークロードにおいて、セッション感知版は通常の HiRadixCache + LRU と比較して TTFT(初トークン遅延)が 2.9% から 16.6% 低い。この2つの数字は何を意味するか?
TTFT は初トークン遅延で、低いほどユーザーがリクエスト送信後、最初の文字が返るまでの待ち時間が短いことを示す。LRU は最も古典的な「最も使われていないものを先に追い出す」淘汰アルゴリズムだ。セッション感知版は2種類の極端なワークロード双方でより低い遅延を実現しており、特定のリクエストパターンだけで勝っているわけではないことを示している。
効果は淘汰だけから来ているのではない。SGLang はさらに木のコアを Rust へ移行しており、プロトタイプはスライディングウィンドウベンチの第176〜200ラウンドで TTFT をさらに最大 42% 圧縮した。このテスト区間は極長対話の後段に対応し、木構造自体 overhead がボトルネックになり始めるポイントだ。
Python 実装では radix ノード(木の分岐点)にアクセスするたびにインタープリタコストがかかり、プレフィックスが長くノードが深くなるほど overhead が膨らむ。Rust 版ではこの部分を抑えた。
この3つを並べる:コンポーネントが再利用可能かを決め、HiCache がキャッシュをどの層に置くかを決め、セッション感知淘汰が誰を先に追い出すかを決め、Rust コアが大規模木のトラバーサルコストを決める。単独で TTFT 改善の功劳を背負えるものはない。
次フェーズで追う価値のあるシグナル:セッション感知淘汰が本番の長コンテキストワークロード下でも 16.6% のリードを維持できるか、そして Rust 木のコアが FULL+SWA+MAMBA の3コンポーネント全開時でもその 42% を保てるか。どちらかの数字が落ちれば、現在の「ソフト淘汰+言語越境移行」の組み合わせはまだ本番全面展開の段階にはないということだ。
1本の木がどう投票するかを見てから、採用を決める
手を動かす前にまず理解すべきこと:FULL、SWA、MAMBA の3コンポーネントがそれぞれ何を担当し、session-aware 淘汰と HiCache の3層移行がどう同一の木にぶら下がるか。下記5ステップで原典の情報を1つずつ確認する。
第1ステップは、原典が述べるコンポーネント組み合わせがモデルと一致するかを確認すること。原典は Unified Radix Cache を同一の token-keyed 木としており、FULL は常に有効、モデルが sliding window attention(直近の一定数のトークンのみを見る注意機構)を持てば SWA コンポーネントが加わり、Mamba 類循環層(履歴を固定サイズの状態に圧縮する層)を持てば MAMBA コンポーネントが加わる。手元のモデルと照らし合わせよ:SWA があるのか Mamba 層があるのかで、木に何個のコンポーネントがぶら下がるか決まる。コンポーネント組み合わせが噛み合わなければ、session-aware 淘汰と L3 外部層は機能しない。木の総容量には限りがある——コンポーネントごとに別の木を持てば容量は分割され、同一の木にぶら下げるからこそ全体のキャッシュ効率が保たれる。
第2ステップは、KV キャッシュ命中とコンポーネント投票の違いを理解すること。SGLang がエンドツーエンドで再利用しているのは KV cache(推論時に計算済みの中間結果を保存して再利用し、繰り返し計算を省く)であって、木自体ではない。同一の system prompt を共有する2本目のリクエストは、TTFT(リクエスト送信から最初のトークンが返るまでの時間)が明らかに下がる——これは KV 命中を証明するだけで、3種類のコンポーネントすべてが投票した証明にはならない。前者はキャッシュが効いたということで、後者はコンポーネント検証が通ったということで、別物だ。
第3ステップで、ようやくコンポーネント投票を理解できる。原典 Figure 2 の記述:FULL 経路は n4 まで進むが、n3、n4 の少なくとも1つでコンポーネント検証が失敗し、再利用境界は n2 で止まる。木の幹は最後まで進むが、再利用境界は最後までとは限らない。まずこの図の投票フローを理解し、その上で採用を語るべきだ。
第4ステップは HiCache の階層間移行を検証する。原典は、L3 外部層がマルチラウンドベンチで DeepSeek-V4-Flash の後段ヒット率を約 98%、Inkling-Small を約 96.8% に維持していると述べる。
HiCache はコンポーネントのキャリアを GPU L1、Host L2、外部 L3 のどこに置くかを制御する。コンポーネント名が変わらないということは同一性が移行可能ということであり、階層をまたいでも同一プレフィックスとして認識される。原典は読者が再現可能なマルチラウンドベンチスクリプトを提供していないため、この項目は公式がスクリプトとウェイトを公開するかどうかを追うしかなく、現時点で手を出せる再現経路はない。
第5ステップは session-aware 淘汰を観察する。原典は SWE-bench(モデルが実在のソフトウェア工学タスクを解けるかを測るテストセット)ワークロード下で、session-aware 構成が通常の HiRadixCache + LRU(最も使われていないものを先に追い出す淘汰戦略)と比較して TTFT が 2.9% から 16.6% 低いと述べる。この2つの数字は何を意味するか?セッション感知版は2種類の極端なワークロード双方でより低い遅延を実現しており、特定のリクエストパターンだけで勝っているわけではない。再現の入口は同じ SWE-bench のタスクフローを取得してログを取ること:session-aware のオン/オフで TTFT 分布を比較し、アクティブセッションのプレフィックスが優先的に残っているかを見る。この項目も原典は既成の再現スクリプトを提供しておらず、公式がリリースしだい上記の手法で走らせれば照合できる。
まだ起きていない2つのこと。原典は Rust 木のコアプロトタイプが、sliding window ベンチの第176〜200ラウンドで TTFT を最大 42% 削減したと述べる。これはエンジニアリングの進捗であり、今すぐ走らせられるものではない。
本記事は LMSYS Org Blog 原典(2026-08-11)に基づく。ベンダー発表の数値(ベンチスコア、削減率など)はすべて公式公表値であり、注記なき限り第三者による独立再検証はなされていない。