多代理並發性能數據對比

在 RTX 3090 上運行 Qwen3.8-27B Q4_K_M 模型時,OpenJet 同時服務四個代理的總吞吐量為每秒 256 至 288 token。相比之下,使用 llama-server 並行處理四個請求的總吞吐量僅為每秒 72 至 80 token。

單一代理獨立運行時,OpenJet 的速度為每秒 117 token;當擴展至四個代理時,每個代理的速度降至每秒 64 至 72 token(短提示詞)或 52 至 55 token(23K 上下文)。這意味著雖然單代理速度下降,但整體系統吞吐量大幅提升。

在實際編碼場景中,由於代理需要暫停以執行工具與測試,四個真實編碼代理的總吞吐量約為每秒 150 至 200 token。此外,當一個代理正在處理 20K 提示詞時,另一個代理仍能維持每秒 9.5 token 的生成速度,而 llama-server 在此情境下僅剩每秒 0.6 token。

透過批次化權重讀取突破記憶體頻寬限制

GPU 生成 token 的速度受限於記憶體頻寬,因為每個解碼步驟都需要從 VRAM 讀取全部 16.7 GB 的模型權重。在 RTX 3090 上,僅讀取權重就需要約 18 毫秒,而後續的計算量相對較小。

OpenJet 引擎並非依序執行代理任務,而是將每個活躍代理的工作堆疊成一個批次。例如四個代理時,每步處理 12 行數據(每個代理的下一個 token 加上其多 token 預測草稿)。

這種方法讓權重僅需讀取一次即可同時計算所有代理的輸出,利用 Tensor Core 在晶片上直接進行矩陣乘法。因此,四個代理的成本約等於單次權重讀取,而非四次,這是每個代理速度未降至理論線性衰減值(約每秒 30 token)的主要原因。

動態資源管理與上下文優化技術

為避免新提示詞處理時阻塞其他代理,引擎將新提示詞的區塊分散到每個解碼步驟中與其他代理的數據一同處理。這確保了其他代理能持續生成內容,且最終結果與單獨處理該提示詞完全一致。

系統採用共享的 132K token KV Cache 池(q8_0 格式),並採用分頁機制。這允許某個代理使用大部分緩存空間,而其他代理僅佔用少量空間,避免了固定分割(如 4 x 32K)造成的資源浪費。

對於多個代理共用的系統提示詞與工具列表(1024 token 以上),引擎僅處理並儲存一次。此外,對話請求會回到已持有該對話的插槽,僅處理新增的 token,進一步減少重複計算。

準確性驗證與使用限制

由於算術運算順序不同,OpenJet 的輸出並非與 llama.cpp 位元級一致。然而,相對於 llama.cpp 自身的下一個 token 分佈,其 KL 散度差異處於 llama.cpp 批次處理與逐 token 處理之間的範圍內。

目前該引擎僅支援 Q4_K_M 量化格式,混合量化版本仍僅服務單一對話。系統最多支援八個代理,且忽略存在懲罰(presence penalty)與重複懲罰(repetition penalty)。

使用者可透過 Python 腳本啟動伺服器並監控即時狀態,包括每個代理的生成速度、上下文使用量及 GPU 統計數據。開發者計畫未來加入 TurboQuant 支援,以在單張顯卡上將最大上下文窗口擴展至 256K。