跳至主要內容
推論基礎設施

前綴快取與請求路由

路由推論請求時,平衡前綴重用、佇列負載、相容性與租戶隔離。

作者
Huang Tzu LinFounder
發布日期
閱讀時間
約 22 分鐘
更新於
目錄
  1. 01本篇在學習路線中的位置
  2. 02開始之前:先備知識與學習成果
  3. 03你將建置的成品
  4. 04第一層:單機自動前綴快取
  5. 精確前綴重用
  6. RadixAttention
  7. 單機快取能改善與無法改善的部分
  8. 05完整範例:五輪多輪對話
  9. 06第二層:分散式快取感知路由
  10. 07區分共用前綴的暖機節省與穩態效益
  11. 08鎖定偏斜路由測試軌跡
  12. 09路由模擬計算結果
  13. 10相容性與多租戶隔離鍵
  14. 11建立前綴重用與路由模擬器
  15. 12刻意破壞的案例
  16. 只測單一共用前綴的基準測試
  17. 不計代價只看快取親和性
  18. 未加鹽的多租戶共用快取
  19. 過期或相容性不符的路由索引
  20. 13動手實作
  21. 14可量測的完成標準
  22. 15提取練習
  23. 16解答
  24. 17本文不涵蓋的內容
  25. 18來源與延伸閱讀

在推論服務架構裡,有兩種位於不同層級的機制常被籠統地一起稱為「前綴感知(prefix-aware)」。單機前綴快取(local prefix caching)決定單一推論引擎執行個體能否直接重用記憶體池裡既有的 KV 區塊;分散式快取感知路由(distributed cache-aware routing)則決定要把新進請求派往哪一個模型副本或共用快取層。這兩層無法互相取代:如果目標引擎驗證相容性不過關,路由器再怎麼精準派送也變不出快取命中;反過來,如果 KV 區塊鎖在另一台無法存取的副本上,沒有跨節點傳輸或共享儲存層,單機引擎也無從重用。

本篇教學將拆開這兩個層級,逐步驗算五輪對話的前綴重用量,模擬快取親和性(cache affinity)與副本負載失衡之間的拉鋸,並實作快取相容性與多租戶隔離檢查。

互動實驗

平衡快取命中與排隊

持有快取的副本仍是較好的目的地嗎?

共用前綴 · 256 tokens新後綴 · 64
副本 A候選

3 排隊 · 64 新 tokens

66.4無單位分數 · 較低者優先
副本 B已選取

0 排隊 · 320 新 tokens

32無單位分數 · 較低者優先

只有快取相容時才能省去前綴運算;在此簡化分數下,過長的佇列可能抵消重用效益。

讀懂目前結果

副本 A 分數
3 × 20 + 64 × 0.1 = 66.4
副本 B 分數
0 × 20 + 320 × 0.1 = 32
選取副本
B

分數較低者勝出,同分選 A。這是無單位的規劃分數,不是毫秒。模型、token 或快取狀態不相容時須重算前綴;佇列長度可能抵銷重用效益。

簡化分數:每個排隊請求 20 單位,加每個新 token 0.1 單位;不是 TTFT 預測。

本篇如何銜接前後內容

本篇在學習路線中的位置

帶入前作:I-01:token 預算排程追蹤、I-02:KV 區塊容量計算表

本篇新增:相容快取路由模擬。請將假設、來源 ID 與失敗案例連同成果一併留存。

後續用途:I-03 將沿用這些成果。跨主題系列的先備順序請見完整閱讀路線。文章 ID 是固定標籤,編號不代表閱讀順序。

學習目標與實作準備

開始之前:先備知識與學習成果

請先完成 I-01 與 I-02,確認你已熟悉 token 預算排程、分頁 KV 區塊表、參照計數與快取驅逐(eviction)機制。

讀完本篇後,你將能夠:

  1. 區分推論引擎內部的區塊查詢,以及跨副本之間的請求路由分派;

  2. 把先前模型生成的助理(assistant)token 一併納入多輪對話的可重用前綴計算;

  3. 解釋精確 token/區塊相容性條件與快取驅逐行為;

  4. 在偏斜的前綴請求軌跡上,比較輪詢(round-robin)、純親和(affinity-only)與混合(hybrid)三種路由策略;

  5. 說明為何「所有請求共用同一段短系統提示」測不出穩態路由優勢;以及

  6. 透過閘道器強制注入的快取鹽值(salt)或信任群組隔離,緩解前綴命中的時間側通道探測,但不宣稱所有時間側通道都會因此消失。

你將建置的成品

你會產出 prefix-routing-report.json,內容包含:

  • 五輪多輪對話的重用量計算(同時對照理想上限與 16-token 完整區塊結果);

  • 每一輪的新算(fresh)與重用(reused)prompt token 數;

  • 輪詢、純親和與混合路由三種策略的模擬結果;

  • 各副本的分派落差(assignment skew);以及

  • 加鹽與未加鹽的跨租戶快取鍵探測。

第一層:單機自動前綴快取

精確前綴重用

在因果注意力機制下,某個 token 的 K/V 狀態取決於產生它的那串精確前文 token 序列與位置。兩段展開後肉眼看起來一模一樣的提示,分詞結果仍可能不同;改動對話範本(chat template)、模型版本、轉接器(adapter,例如 LoRA)、位置參數、KV 資料型別或布局,或是多模態輸入,都可能讓原本留存的 KV 區塊不再相容。

vLLM 的自動前綴快取會把區塊內的 token ID、上一個區塊的雜湊值,以及 LoRA ID、多模態輸入雜湊、快取鹽值等額外鍵(extra keys)串成鏈式雜湊(chained hash),再重用完全吻合的完整區塊(vLLM 自動前綴快取文件)。vLLM V1 改為預設啟用自動前綴快取,舊版 V0 引擎則預設關閉(vLLM V1 alpha 發布說明)。現行版本的文件把這個開關寫成 --enable-prefix-caching/--disable-prefix-caching(vLLM 引擎參數文件);由於預設值與旗標寫法都曾隨版本改變,正式環境應鎖定引擎版本,並在設定中明確寫出這個開關。

RadixAttention

SGLang 的 RadixAttention 以基數樹(radix tree)留存 KV 狀態,比對跨請求最長的共用 token 前綴,並優先驅逐最久未使用的葉節點。SGLang 回報的最高 6.4× 吞吐量提升,是結構化語言模型程式工作負載上的整套系統結果,結合了 RadixAttention、壓縮有限狀態機解碼與前端平行化,並非單獨抽離 RadixAttention 的倍率(Zheng et al., NeurIPS 2024)。

單機快取能改善與無法改善的部分

前綴快取命中時,引擎可以直接跳過已吻合前綴的 prefill 運算。但等引擎算完後面未命中的後綴、進入自迴歸 decode 階段後,單機前綴快取並不會直接加快每一步吐出新 token 的速度,頂多只能藉由減輕 prefill 負載,間接降低排程干擾與排隊時間。因此,「輸入提示長且高度共用、輸出相對較短」的工作負載獲益最明顯。

完整範例:五輪多輪對話

假設旅行 Copilot 有一段五輪對話,提示長度依序增加如下:

輪次

輸入 token 數

該輪生成的助理 token 數

供下一輪重用的名義延伸前綴

1

400

100

約 500

2

700

100

約 800

3

1,000

150

約 1,150

4

1,400

100

約 1,500

5

1,700

不需要

-

假設每一輪經對話範本展開後的 token 序列,都嚴格接在「上一輪提示+上一輪助理回答」後面往後延伸,中間沒有任何範本改動、區塊驅逐或狀態不相容,那麼連上一輪模型自己生成的助理 token 也都能直接重用。把先前整段提示與回答全數計入,可算出理想上限:

plaintext
fresh prefill by turn = [400, 200, 200, 250, 200]
total fresh tokens    = 1,250

reused prefix by turn = [0, 500, 800, 1,150, 1,500]
total reused tokens   = 3,950

total input tokens    = 400 + 700 + 1,000 + 1,400 + 1,700
                      = 5,200

reuse fraction        = 3,950 / 5,200
                      = 75.96%

3,950 是精確延伸假設下的理想上限,不是實測命中數。在區塊大小為 16 個 token、只比對完整區塊的分頁引擎裡,每一輪最後取樣出的 token 還沒有 KV 狀態;扣掉這 1 個 token 再向下取 16 的整數倍後,各輪可重用的完整區塊 token 數會降為 [0, 496, 784, 1136, 1488],合計 3,904 / 5,200(75.08%),每輪需新算的 prefill 則變成 [400, 204, 216, 264, 212](共 1,296 個 token)。副本能不能真的拿到這些命中,仍取決於區塊留存、token 是否精確吻合,以及路由放置。

第二層:分散式快取感知路由

當後端有多個模型副本時,路由器必須同時掌握前綴所在位置與各副本負載。這份資訊可能是:

  • 近似推測(approximate):由路由器根據近期派送紀錄,或字元層級、token 層級的前綴樹自行推估;

  • 事件驅動(event-driven):依推論引擎發布的 KV 快取事件(回報區塊的儲存與驅逐)更新;或

  • 共享儲存層(shared-tier):由多台工作節點都能存取的分散式 KV 儲存支撐。

Ray Serve 的 PrefixCacheAffinityRouter(目前為 alpha API)會在路由器端替派往各副本的提示維護字元層級的前綴樹,並以 imbalanced_threshold 防範熱點:設為有限值時,只要最長與最短副本佇列的差距超過門檻,路由器就改用 Power-of-Two-Choices 負載平衡;文件記載的預設值是無限大,因此永遠不會觸發這項備援(Ray 前綴感知路由文件)。Preble 與 DualMap 等研究排程器處理的正是這道取捨:把熱門前綴固定派往同一台副本會累積佇列,盲目平衡負載則會失去前綴重用(Srivatsa et al., ICLR 2025;Yuan et al., ICLR 2026)。

區分共用前綴的暖機節省與穩態效益

假設 50 筆請求全都共用同一段 200 個 token 的系統提示,後端有 5 台 KV 記憶體充裕的副本。輪詢(round-robin)會把前 5 筆請求分別送到 5 台不同副本,讓每台各暖機 1 次,其餘 45 筆都在各自副本命中。若把 50 筆全集中到同 1 台副本,只需暖機 1 次,可拿到 49 次命中而非 45 次:在按完整區塊取整前,暖機只省下 4 × 200 = 800 個 prefill token,代價是另外 4 台副本閒置,單台副本淪為熱點。5 台副本都暖機後,輪詢派送的後續每筆請求都會命中,也沒有負載偏斜;光是省下 token,並不足以證明延遲或容量有所改善。

因此,要驗證快取感知路由在穩態下是否有幫助,測試必須涵蓋多組偏斜前綴、受限的單副本快取容量、持續變長的多輪對話,或頻繁的快取驅逐,而不是只用一段每台副本都放得下的短系統提示。

鎖定偏斜路由測試軌跡

設定 3 台模型副本,每台最多只能以 LRU 留存 2 個前綴家族。四組前綴的長度如下:

前綴代號

Token 數

A

1,000

B

800

C

600

D

400

20 筆請求的抵達順序如下:

plaintext
A A B A C A B D A A C B A D A B C A B A

對照三種路由策略:

  • 輪詢(round-robin):依序輪流派往副本 0, 1, 2;

  • 純親和(affinity-only):只要有副本持有該前綴就一律派過去(若多台同時持有,挑累計分派數較少者;都未持有時,派給累計分派數最少的副本);以及

  • 混合(hybrid):只有在持有該前綴的副本當前累計分派數不超過「最閒副本+max_skew(設為 1)」時才走快取命中,否則改派給當下累計分派數最少的副本。

這個模型有三項簡化。快取容量以前綴筆數計算,而非位元組。累計分派數代替瞬間佇列深度,沒有模擬並行的 GPU 服務時間。最後,assignments[index] <= least + max_skew 在遞增之前檢查,因此不是嚴格的落差上限:剛完成一次分派時,落差可能達到 max_skew + 1(在這條軌跡上,混合策略中途的落差達到 2,最後為 1)。

路由模擬計算結果

執行下方模擬器可得到:

路由策略

重用前綴 token 數

各副本分派數

最終分派落差

Round-robin

10,000

[7, 7, 6]

1

Affinity-only

13,800

[10, 5, 5]

5

Hybrid

12,000

[7, 7, 6]

1

純親和策略在這條軌跡上達到可能的最大重用量(13,800 個 token:除了每個前綴的第一筆,其餘請求全部命中),代價是把 10 筆 A 請求,也就是一半的流量,全送到副本 0([10, 5, 5])。混合策略比輪詢多重用 2,000 個前綴 token,負載分布則與輪詢同為 [7, 7, 6]。這些都是模擬器輸出;若要把省下的 prefill token 換算成 TTFT 或有效吞吐量(goodput)的改善,必須讓路由器搭配真實的佇列與服務時間壓測。

相容性與多租戶隔離鍵

健全的前綴快取鍵(cache key)會綁定所有可能改變 KV 張量數值或存取權限的輸入。至少要評估:

plaintext
(model_revision,
 tokenizer_and_chat_template_revision,
 adapter_or_LoRA_id,
 attention_and_position_configuration,
 KV_dtype_and_layout,
 multimodal_input_identity,
 tenant_or_trust_group_salt,
 token_prefix)

若讓不同租戶共用未加鹽的前綴區塊雜湊,就會打開時間側通道(timing side channel):攻擊者可以送出猜測的前綴文字,光看回傳的 TTFT 有沒有突然變快,就能推知其他租戶剛才是否送過相同內容。在請求中帶入每個租戶各自的 cache_salt,會把隔離用的秘密鹽值混入第一個區塊的雜湊計算,確保只有帶相同鹽值的請求才能命中該批快取(vLLM 資安指南)。實務上應由經過身分驗證的閘道器,依使用者或信任群組注入高熵的秘密鹽值,不要信任呼叫者自行提供的標頭或可預測的租戶 ID。在這個威脅模型下,加鹽能隔離前綴雜湊查詢;但鹽值一旦外洩就無法提供保護,也無法杜絕其他時間側通道。

多模態推論還多出一道快取身分邊界。vLLM 資安指南指出,呼叫者自行傳入的媒體 uuid 會取代原始媒體位元組雜湊,成為處理器快取、編碼器快取與前綴快取中的快取身分;一旦 UUID 碰撞,伺服器就可能重用從別人媒體算出的結果(vLLM 多模態媒體 UUID 資安說明,查閱日期 2026-11-02)。經過身分驗證的閘道器應指派不可預測、限定於信任群組的媒體識別碼,拒絕不可信的 UUID 覆寫,並以「兩份不同媒體宣稱同一個 UUID」的情境實測。同一份指南也說明,cache_salt 這類選項只能降低特定的跨租戶風險,並不構成隔離邊界;租戶邊界不允許共用快取時,應部署獨立的執行個體。下方的純文字程式只驗證前綴鍵加鹽,不涵蓋多模態快取。

建立前綴重用與路由模擬器

將以下程式存為 simulate_prefix_routing.py,並執行 python simulate_prefix_routing.py > prefix-routing-report.json。程式中的隔離斷言只驗證快取鍵集合的成員關係,不是網路層的時間量測:

python
import json
import secrets
from collections import OrderedDict

turn_inputs = [400, 700, 1000, 1400, 1700]
prior_outputs = [0, 100, 100, 150, 100]
reused = [0]
fresh = [turn_inputs[0]]
for index in range(1, len(turn_inputs)):
    reusable = turn_inputs[index - 1] + prior_outputs[index]
    reused.append(reusable)
    fresh.append(turn_inputs[index] - reusable)

block_size = 16
block_reused = [0] + [((turn_inputs[i-1] + prior_outputs[i] - 1) // block_size) * block_size
                      for i in range(1, len(turn_inputs))]
if any(r > n for r, n in zip(reused, turn_inputs)):
    raise ValueError("not an extending conversation")

prefix_lengths = {"A": 1000, "B": 800, "C": 600, "D": 400}
requests = list("AABACABDAACBADABCABA")

def simulate(policy, max_skew=1, cache_capacity=2):
    if cache_capacity < 1 or max_skew < 0:
        raise ValueError("invalid policy configuration")
    caches = [OrderedDict() for _ in range(3)]
    assignments = [0, 0, 0]
    reused_tokens = 0
    evictions = 0
    round_robin = 0

    for prefix in requests:
        hits = [index for index, cache in enumerate(caches) if prefix in cache]
        if policy == "round_robin":
            target = round_robin % len(caches)
            round_robin += 1
        elif policy == "affinity_only":
            target = min(hits, key=lambda index: assignments[index]) if hits else assignments.index(min(assignments))
        elif policy == "hybrid":
            least = min(assignments)
            eligible = [index for index in hits if assignments[index] <= least + max_skew]
            target = min(eligible, key=lambda index: assignments[index]) if eligible else assignments.index(least)
        else:
            raise ValueError(policy)

        cache = caches[target]
        if prefix in cache:
            reused_tokens += prefix_lengths[prefix]
            cache.move_to_end(prefix)
        else:
            cache[prefix] = True
            if len(cache) > cache_capacity:
                cache.popitem(last=False)
                evictions += 1
        assignments[target] += 1

    return {
        "reused_prefix_tokens": reused_tokens,
        "evictions": evictions,
        "assignments": assignments,
        "max_assignment_skew": max(assignments) - min(assignments),
    }

# Trusted runtime selects secrets; callers cannot supply another tenant's salt.
salts = {"tenant-a": secrets.token_hex(32), "tenant-b": secrets.token_hex(32)}
def key(tenant, prefix, model="model-v1", adapter="adapter-v1", salted=True):
    return (model, adapter, salts[tenant] if salted else "", prefix)
unsalted_cache = {key("tenant-a", "A", salted=False)}
salted_cache = {key("tenant-a", "A")}
tenant_b_probe_unsalted = key("tenant-b", "A", salted=False) in unsalted_cache
tenant_b_probe_salted = key("tenant-b", "A") in salted_cache
assert key("tenant-a", "A") in salted_cache
assert key("tenant-a", "A", model="model-v2") not in salted_cache
assert key("tenant-a", "A", adapter="adapter-v2") not in salted_cache

artifact = {
    "conversation": {
        "input_tokens": turn_inputs,
        "full_block_reused_by_turn": block_reused,
        "full_block_reused_total": sum(block_reused),
        "full_block_fresh_total": sum(turn_inputs) - sum(block_reused),
        "reused_tokens_by_turn": reused,
        "fresh_tokens_by_turn": fresh,
        "total_reused_tokens": sum(reused),
        "total_input_tokens": sum(turn_inputs),
        "reuse_fraction": sum(reused) / sum(turn_inputs),
    },
    "routing": {
        "round_robin": simulate("round_robin"),
        "affinity_only": simulate("affinity_only"),
        "hybrid": simulate("hybrid"),
    },
    "isolation": {
        "cross_tenant_hit_without_salt": tenant_b_probe_unsalted,
        "cross_tenant_hit_with_distinct_salts": tenant_b_probe_salted,
    },
}
print(json.dumps(artifact, indent=2))

預期檢查結果:

plaintext
total_reused_tokens = 3950
total_input_tokens = 5200
reuse_fraction ≈ 0.7596
round_robin reused = 10000, skew = 1
affinity_only reused = 13800, skew = 5
hybrid reused = 12000, skew = 1
cross_tenant_hit_without_salt = true
cross_tenant_hit_with_distinct_salts = false

刻意破壞的案例

只測單一共用前綴的基準測試

如果壓測只用一段共用系統提示、KV 記憶體充裕且負載很輕,測到的主要是冷啟動暖機。它能呈現有限的暖機優勢,但每台副本都留住這些區塊後,命中率就會趨於一致,因此無法證明穩態路由優勢或 SLO 改善,也看不出快取驅逐與熱點控制的表現。

不計代價只看快取親和性

純親和模擬把 20 筆請求中的 10 筆送給副本 0。在真實的並行流量下,即使命中率看起來很漂亮,在過載熱門副本前排隊的時間仍可能抵銷快取命中省下的 prefill 時間。正式環境的路由評分應在省下的 prefill token 與即時的 prefill/decode 佇列深度、KV 記憶體壓力、TTFT SLO 餘裕之間權衡。

未加鹽的多租戶共用快取

若跨租戶時把 salted 設為 False,cross_tenant_hit_without_salt 就會是 true;在真實引擎中,這個共用的快取鍵會讓呼叫者能從過快的 TTFT 判斷猜測的前綴是否已被快取。改用各自獨立、由閘道器管理的鹽值後,跨租戶探測結果就會變成 false。

過期或相容性不符的路由索引

路由器掌握的前綴資訊可能落後於副本的 LRU 驅逐,也可能漏掉模型版本、轉接器、tokenizer 或 KV 資料型別與布局的差異,因此路由提示只是盡力而為(best-effort)的最佳化訊號;目標引擎在重用 KV 狀態之前,仍須完整驗證區塊相容性。

動手實作

  1. 執行基準版模擬器並檢視 prefix-routing-report.json。

  2. 將每台副本的 cache_capacity 從 2 個前綴家族調降為 1 個。

  3. 將 max_skew 依序改為 0、1 與 2 對照變化。

  4. 新增一組長度 1,200 個 token 的熱門前綴 E,並在請求序列尾端接上一波連續 8 筆 E 的突發流量。

  5. 針對每種策略回報重用 token 數、分派落差、驅逐次數,以及自訂的簡易排隊懲罰分數。

  6. 執行程式內建的 model 與 adapter 失效斷言檢查,並以文件說明正式環境的快取鍵還必須如何綁定 tokenizer/對話範本版本、位置/遮罩設定、KV 布局與多模態媒體識別碼;這些後端檢查不在這個純文字模擬器的範圍內。

  7. 新增兩個已驗證的信任群組,各自使用閘道器指派的不同鹽值;在快取鍵模型中確認同群組會命中、跨群組不會命中,並另外規劃一項端對端測試,涵蓋閘道器的標頭剝除與時間探測。

可量測的完成標準

本篇教學實作須滿足以下所有條件才算通過:

  • 單機引擎前綴查詢與分散式快取感知路由分開分析;

  • 五輪對話計算明確區分 3,950 個理想可重用 token,以及在「16-token 區塊+結尾取樣 token 未產生 KV」假設下的 3,904 個完整區塊快取 token;

  • 先前輪次由模型生成的助理 token 有納入後續輪次的可重用前綴;

  • 單一共用前綴分析有將 800 個 token 的暖機節省與穩態/延遲結論明確切開;

  • 基準路由模擬能重現 10,000、13,800 與 12,000 個重用 token;

  • 混合路由在基準軌跡下的最大分派落差(max_assignment_skew)為 1;

  • 快取鍵設計完整列出模型、tokenizer/範本、轉接器、位置/遮罩設定、KV 布局、多模態媒體識別碼與租戶鹽值,並註明隨附程式只測試模型、轉接器、前綴與租戶鹽值欄位,其餘輸入須由後端驗證;

  • 未加鹽的跨租戶探測明確呈現碰撞風險(true);以及

  • 不同的鹽值能讓跨租戶探測不命中(false)。

提取練習

  1. 單機前綴快取(local prefix caching)與分散式快取感知路由(distributed cache-aware routing)有何不同?

  2. 為什麼五輪對話範例在第 2 輪能重用約 500 個 token,而不只是第 1 輪輸入的 400 個 token?

  3. 當所有請求都共用同一段短系統提示時,為什麼輪詢(round-robin)在穩態下能追平親和路由?

  4. 相較於純親和路由,混合路由(hybrid routing)做了什麼取捨?

  5. 為什麼路由器預期會命中的請求,送到推論引擎後卻可能變成未命中(miss)?

  6. 為每個租戶加上快取鹽值(cache salting)能防範什麼風險?又有哪些風險不在它的保護範圍內?

解答

  1. 單機前綴快取負責在單一推論引擎的記憶體池內計算雜湊、驗證相容性並重用 KV 區塊;分散式快取感知路由則負責決定哪一個副本或快取域應該接收這筆請求。

  2. 只要第 2 輪完整接在第 1 輪對話後面,第 1 輪的 400 個提示 token 加上模型生成的 100 個助理 token,就構成第 2 輪延伸的前綴。以 16-token 完整區塊計算,且最後取樣的 token 還沒有 KV 時,這 500 個 token 中有 496 個可以重用。

  3. 前 5 筆請求會讓 5 台副本各自暖機一次;只要快取空間足夠,此後每台副本都能留住這段短前綴,後續請求都在原副本命中,也不會讓負載集中在單一副本。

  4. 當持有快取的副本在分派數上領先超過 max_skew 時,混合路由會放棄該次前綴命中、改派給較閒的副本,避免熱門前綴壓垮單一副本。

  5. 目標副本可能在請求抵達前就已依 LRU 驅逐該區塊,路由器的近似前綴樹可能與實際分詞結果不一致,或者轉接器、範本版本等相容性中繼資料不相符。

  6. 由閘道器為各信任群組強制注入高熵鹽值後,在這個威脅模型下,加鹽能阻止租戶比對到其他租戶快取的前綴區塊,也就無法透過 TTFT 刺探。可預測或外洩的鹽值、多模態媒體 UUID 的覆寫碰撞,以及其他時間側通道,則需要另外的防護。

本文不涵蓋的內容

I-03 將結合快取親和位置與網路拓撲,決定分離式 prefill 與 decode 工作節點的配對;I-07 會把快取命中率、佇列等待與尾端延遲 SLO 整合成完整的正式環境壓測基準。至於商業 API 提供的提示快取(prompt caching),包括計費方式與保留行為,則屬於供應商另訂的產品合約,不屬於引擎內部機制。


來源與延伸閱讀

  • Zheng, L., Yin, L., Xie, Z., et al. "SGLang: Efficient Execution of Structured Language Model Programs." NeurIPS, 2024。RadixAttention 與結構化語言模型程式整體系統評估的第一手論文。arxiv.org/abs/2312.07104

  • vLLM Project. "Automatic Prefix Caching." 現行文件,查閱日期 2026-11-02。鏈式區塊雜湊、相容性規則與 V1 自動前綴快取設計的官方說明。docs.vllm.ai

  • Srivatsa, V., He, Z., Abhyankar, R., et al. "Preble: Efficient Distributed Prompt Scheduling for LLM Serving." ICLR, 2025。在分散式提示排程中兼顧前綴重用與副本負載的第一手論文。arxiv.org/abs/2407.00023

  • Yuan, Y., Zuo, P., Wang, B., et al. "DualMap: Enabling Both Cache Affinity and Load Balancing for Distributed LLM Serving." ICLR, 2026。在 TTFT SLO 約束下以雙雜湊兼顧快取親和與熱點負載平衡的第一手論文。arxiv.org/abs/2602.06502

  • Ray Serve. "Prefix-Aware Routing." 現行 alpha 文件,查閱日期 2026-11-02。PrefixCacheAffinityRouter 近似前綴路由行為與 imbalanced_threshold 門檻語意的官方說明。docs.ray.io

  • vLLM Project. "Security: Prefix Cache Timing Side-Channel Mitigation." 現行文件,查閱日期 2026-11-02。cache_salt 與多租戶信任群組隔離的官方資安指南。docs.vllm.ai

閱讀順序

完整閱讀路線

章節 22 / 25

你在這裡88%
  1. 01
  2. 02
  3. 03
  4. 04
  5. 05
  6. 06
  7. 07
  8. 08
  9. 09
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25

查看先備知識、分支路線與共用實作 →

分享這篇文章
XLinkedIn

Huang Tzu Lin

富宇資訊科技創辦人。撰寫 AI 系統設計、證據與工程取捨的文章。

透過 RSS 訂閱

使用慣用的 RSS 閱讀器追蹤最新的 AI 系統實作教學。

開啟 RSS Feed

支援任何 RSS 閱讀器,新文章將自動送達。

回到頂端