跳到主要內容

【2026 最新】Adaptive KV Streaming 是什麼?AMD 16GB 長 Context 六步驗收(速度+繁中)

最後更新: ·
Adaptive KV Streaming 教學:AMD ROCm 長文的容量、速度與繁中驗收

你看到「16GB AMD 顯卡也能跑 262K 長文」,很容易立刻把 Context 拉滿。但 Adaptive KV Streaming 把資料搬到主記憶體之後,你還要付出多少等待?繁體中文是否因縮詞表,反而更快吃掉視窗?

這篇寫給已有本機模型環境、第一次接觸 ROCm 串流的讀者。先用白話搞懂原理,再照六步核對硬體、版本、繁中與速度。操作路線是 Linux 終端機,需要現成的 Git、CMake、Ninja、ROCm 工具鏈與可合法使用的 GGUF 模型;尚未準備好設備,也能先完成驗收考卷。

查核截至 2026 年 10 月 18 日。AlphaLab 這次環境是 Apple Silicon,未執行 AMD 推論;下文是依原始碼與官方文件整理的操作及驗收方法。速度圖保留作者的機器、版本與工作條件,沒有預填你的測試成績。

先說結論:把空間問題換成搬運問題

KV 串流=完整歷史留在 RAM+GPU 只保留工作頁+經 PCIe 持續搬運。RAM 是電腦主記憶體;VRAM 是顯卡上的顯存;PCIe 是兩者溝通的道路。工作桌變小,旁邊仍要有倉庫,道路也要能及時送貨。

  • 先問「裝得下」,再量「等得起」,最後驗「讀得準」。三項分開過關。
  • 作者公開測試集中在 RX 9070 XT;其他 AMD 型號先核對 ROCm 與編譯目標,再做小規模驗收。
  • ASCII-condensed 縮詞表保留 byte fallback;繁中能否原樣還原、會多花多少 tokens、答案是否合格,要各自檢查。

Adaptive KV Streaming 是什麼?先分清三種節省

模型權重像一套固定的百科全書;KV Cache(注意力機制保存的 key/value)像讀書時留下的索引筆記。量化把每份筆記存得更精簡;淘汰只保留部分筆記;串流則把歷史移到另一層記憶體,讓顯卡按需取用。這三個旋鈕會改變不同事情。

原始 CUDA 串流專案描述完整 KV 歷史留在 pinned RAM,也就是可供裝置傳輸使用的鎖頁記憶體;本篇討論的 achyudh ROCm 移植另加入 RDNA 4 核心與執行調校。它和Random Attention 的隨機淘汰解決容量的機制不同,驗收時應分別建立對照。

粗估時先分兩張帳:顯存=GPU 權重+常駐 KV 工作頁+計算/草稿緩衝;RAM=主記憶體端 KV+其他載入資料+程式與系統占用。傳統 full-attention 層的 KV 容量隨 tokens、層數、KV heads、head 維度與每元素位元組數增加;混合架構還要另算 recurrent state。需要算式可先讀本機 LLM 顯存規劃。

換句話說,降低 GPU 常駐頁面,可能替權重騰出空間,也可能增加搬運。把 RAM 容量直接加到顯存容量,會漏掉頻寬、暫存與計算排程這幾筆代價。Hugging Face 的 cache offloading 文件也把節省 GPU 記憶體與傳輸取捨放在一起說明;該實作與此 fork 的旗標則要分開看。

作者的速度圖,該怎麼讀?

以下數字來自 fork README 的原始測量:RX 9070 XT、PCIe 5.0 x16、ROCm 7.2.3、ASCII-condensed IQ4_XS、Q8_0 K/Q4_0 V,使用 SQLite C 原始碼、temperature 0、生成 128 tokens。作者標示測試 commit 為 bd063a49a;本文檢查的文件與操作版本則固定在 9e24be0,兩者有版本差異。

Adaptive KV Streaming 作者在不同 Context 深度的 decode 速度,262144 欄為 9.50 與 31.08 tokens 每秒
依作者 README 重繪,Context 欄保留其深度標籤;MTP 是多 token 預測。這是作者指定組合的測量,AlphaLab 未重跑。

這張圖最有用的訊息是:深度改變,等待也會改變。短 Context 的輸出速度應和最深一格分開讀;MTP 欄也不是單純串流開關的效果。fork 同時改了核心、記憶體路徑與草稿處理,主線對 fork 的差距會包含多項改動。原始測試設定可供核對,但不據此推定繁中任務品質。

Adaptive KV Streaming 六步上手與驗收

①「先認卡」:ROCm 支援與 fork 通過,是兩張收據

你有 16GB,是否就能貼作者指令?先跑 rocminfo 與 hipcc --version,保存作業系統、核心、驅動、GPU 型號和 gfx 目標。AMD GPU 規格表列出 RX 9070 XT 為 gfx1201、RX 9060 XT 為 gfx1200、RX 7900 GRE 為 gfx1100。作者編譯範例鎖定 gfx1201,因此另外兩張卡應視為待驗配置。

再到 AMD 當前相容性矩陣選出自己的卡、系統與版本。作者測量用 7.2.3;要重跑該條件,就核對那個版本的支援組合。用更新工具鏈則記成新配置,不把「較新」當成測試結果相同的證明。README 建議至少 32GB RAM;這是作者配方門檻,完整系統峰值仍需實際記錄。

②「鎖版本」:先知道自己跑的是哪一份程式

準備獨立工作資料夾,下載程式碼後固定 commit。以下只取得原始碼;沒有下載模型,也沒有替系統安裝 ROCm。

git clone https://github.com/achyudh/llama.cpp aks-rocm
cd aks-rocm
git checkout 9e24be0e52bb64bc2773b0193a15328966fbe2fe
git rev-parse HEAD

RX 9070 XT、已有相容 ROCm 工具鏈的讀者,可依下列已核對的 Linux 編譯範例建立。保留完整輸出;其他 gfx 卡先改成自己辨識出的 target,再將編譯、短輸入和長輸入各當一關。

cmake -B build-rocm -G Ninja \
  -DCMAKE_C_COMPILER=hipcc -DCMAKE_CXX_COMPILER=hipcc \
  -DGGML_HIP=ON -DAMDGPU_TARGETS=gfx1201 \
  -DGGML_HIP_NO_VMM=ON -DGGML_BACKEND_DL=OFF \
  -DGGML_CUDA_FA_QUANTS="q4_0-q4_0,q8_0-q8_0,f16-f16,bf16-bf16,q8_0-q4_0"
cmake --build build-rocm --config Release -j2
./build-rocm/bin/llama-server --help

這裡把編譯並行數設成 2,方便先控制主機負載;可依已有資源調整。旗標名中的 CUDA 出現在這份 HIP 範例裡,不要自行刪成另一套。接著記下 GGUF 的來源 revision、完整檔名、sha256sum MODEL.gguf,以及 batch、context、模板、KV 與草稿設定。不同縮詞表檔案的大小和底本不同,應分組保存。

③「先讀繁中」:往返成功與理解正確,分開驗

縮詞表作者的 模型卡說明保留 256 個 byte-fallback tokens,非 ASCII 文字可退回位元組表示,代價是更多 tokens。因此不能把「刪去非 ASCII 詞表列」直接寫成繁中無法輸入;也不能把往返成功當成長文理解合格。

先用同一份短測資:臺灣與台灣不同;髮型、發票;金額 NT$1,234.50;代碼 AZ-709。。把全文送到 /tokenize,設定 add_special:false、parse_special:false;再把回傳的 tokens 原封不動送到 /detokenize。將回來的 content 逐字比對原文,同時保存 tokens 數。API 欄位可查 該版 server 文件。

先依下一步啟動 server,再回到本節;保持它運行,在另一個終端機貼上這段 Python 3。它只呼叫本機 tokenizer,不會生成模型回答;成功時會列出 token 數及往返比對結果。

python3 - <<'PYROUND'
import json
from urllib.request import Request, urlopen

def post(path, data):
    req = Request("http://127.0.0.1:8080" + path,
        data=json.dumps(data, ensure_ascii=False).encode("utf-8"),
        headers={"Content-Type": "application/json"})
    with urlopen(req, timeout=30) as response:
        return json.load(response)

text = "臺灣與台灣不同;髮型、發票;金額 NT$1,234.50;代碼 AZ-709。"
tokens = post("/tokenize", {"content": text,
    "add_special": False, "parse_special": False})["tokens"]
restored = post("/detokenize", {"tokens": tokens})["content"]
print({"tokens": len(tokens), "roundtrip_equal": restored == text})
assert restored == text, repr(restored)
PYROUND

完整詞表與 ASCII-condensed 各跑一次。固定相同文字比較 token 成本與答案;做速度測試時,另以相同 token 深度比較執行階段。兩張考卷都保留,才看得出縮詞表是否讓你的文件更早塞滿視窗。若原文已無法往返,就先停在 tokenizer 排錯;完整詞表裝不下時,降低 Context 或改較小模型,再量共同能跑的範圍。

④「短跑起步」:先關草稿,再打開串流

把模型環境變數換成你已有且完成指紋核對的絕對路徑。以下從 8,192 容量、單一請求開始,僅綁定本機地址;450/2,100 MiB 是作者的兩階段工作頁配方,不是所有卡的最佳值。

export MODEL_GGUF=/absolute/path/to/your-model.gguf
export ROCR_VISIBLE_DEVICES=0
export GPU_MAX_HW_QUEUES=2
export DEBUG_HIP_FORCE_ASYNC_QUEUE=1
export DEBUG_HIP_FORCE_GRAPH_QUEUES=1
./build-rocm/bin/llama-server \
  -m "$MODEL_GGUF" --host 127.0.0.1 --port 8080 \
  -c 8192 -np 1 -dev ROCm0 -fa on -fit off \
  -ctk q8_0 -ctv q4_0 -ctkd q8_0 -ctvd q4_0 \
  --kv-stream --kv-resident-mib 450 \
  --kv-resident-mib-decode 2100 --spec-type none \
  -b 2048 -ub 512

啟動後讀 log,確認實際裝置、GPU 載入層數、context、cache 類型及配置成功,別只看程序還活著。參數實作把這條串流路徑標為 experimental,要求 Flash Attention 與 Q8_0 K/Q4_0 V;--kv-resident-mib-decode 也依賴 --kv-stream。MiB 表示工作頁預算,整個進程的顯存還有權重與其他緩衝。

⑤「拆開開關」:先找串流,再看 MTP

同一個 fork 建四組,每換一組都停止舊 server、重啟並保存命令。固定權重、輸入、KV 精度、batch、輸出上限與並行數:

  • S0:移除三個串流旗標(含其數值),保留 --spec-type none,作為同版無串流基線。
  • S1:使用上面的串流命令,草稿仍關閉。S0 對 S1 才較接近隔離這版串流路徑的效果。
  • S2:只把 --spec-type none 換成 --spec-type draft-mtp --spec-draft-sampling probabilistic,另記草稿相關預設值。
  • S3:再改成 --spec-type draft-mtp,ngram-mod,另固定 --spec-ngram-mod-n-max 16 --spec-ngram-mod-n-min 12 --spec-ngram-mod-n-match 24;這是另一組混合加速,獨立報告。

MTP(Multi-Token Prediction,多 token 預測)像助手先擬候選,再交主模型核對;接受情況會影響收益。若主線也要加入比較,作者表列主線 commit 為 23f7aabc1,保留它的編譯與啟動設定。S0 已經含 fork 的核心改動,不能把主線對 S1 的全部差距都算成串流功勞。某組 OOM 就記失敗邊界,其他組的品質仍另行判分。

⑥「真的塞入」:量長度、時間與取證能力

先在短容量跑通,再逐級增加實際輸入。可從約 4K、16K、64K、128K tokens 起步;每級先以該模型 tokenizer 計數,調整 server 容量,並留出模板及輸出空間。接近上限時仍保留餘裕,例如 262,144 容量先用不超過 261,120 的輸入預算,並重新核對實際提交格式。

品質題先用 /apply-template 的 messages 套用模型對話模板,取得 prompt,再計數並送出;固定模板 revision。送到 /completion 時固定 temperature:0、n_predict:128、cache_prompt:false,保留完整 JSON。檢查 tokens_evaluated、truncated 與 timings;長度被截斷或未完成就註記失敗。原始文字長度、配置容量與真正評估的 token 數,應有各自的欄位。

每次另記五項:prefill tokens/s 與耗時;客戶端送出到第一個有內容輸出的 TTFT;decode tokens/s 與實際輸出數;整體 E2E 牆鐘時間;RAM/VRAM 峰值與是否發生交換。串流 API 的 ping 或空事件不算第一個 token,stream:true 的回傳串流也和 KV 記憶體串流是兩個開關。

用一份自編的假庫存文件當完整例子:開頭寫「AZ-709 對應 青岑店」,中段寫「青岑店盤點量 17」,末段寫「損耗 3,問可出貨量並引用兩段原文」。標準答案是 14,同時要找對代碼與盤點證據。換成缺少損耗資料的版本,答案應指出資料不足。把關鍵段落輪流放前、中、後,加入相似代碼干擾,不靠模型常識猜答案。

每個可跑的深度先各做三次,冷啟動與暖機紀錄分開,保留逐題輸出及所有失敗。三次只是探索穩定性;要採用到日常工作,再擴大自己的文件題組。這套流程可接到本機 LLM 評測紀錄與AI Evals 驗收設計。

最常見的三個誤判,怎麼退一步?

  • 模型尚未載入就 OOM:核對權重、裝置分工與剩餘顯存,再縮短 context/調小工作量;保留失敗 log,勿直接開更多草稿加速。
  • 能生成,卻等太久:先看 prefill、TTFT、PCIe 與 RAM 交換紀錄;若需求只用短片段,可用較短輸入或檢索切片比較。
  • 繁中 token 大增或取證掉分:改完整詞表在共同深度重跑。降低容量是可檢查的選擇;沿用英文短碼速度當繁中成績,會把問題藏起來。

Adaptive KV Streaming 常見問題 FAQ

1. 每張 16GB AMD 卡都適用嗎?

先驗相容性。本文作者測量鎖定 RX 9070 XT;ROCm 的卡別與系統支援,加上 fork 的編譯、短跑及深跑,各自需要核對。

2. RAM 多一點,就會和大顯存同速嗎?

速度要另外量。頁面仍要經過傳輸與排程,實際深度、道路頻寬及模型工作會改變等待。

3. ASCII-condensed 代表繁中一定壞掉?

先檢查。作者保留 byte fallback,但更多 tokens 與任務品質是另外兩關,往返成功後仍要做取證題。

4. 80+ tokens/s 可以當 262K 的速度嗎?

應讀對深度欄。作者最深一格與短文列有不同數字,也要分清 MTP 是否開啟;不能只抄最高值。

5. 看到 262144 配置就算長文測完?

要看實際輸入。保存 tokenizer 計數、server 評估數、截斷狀態與輸出,才能確認做了哪段工作。

6. MTP 可以和串流一起打開嗎?

該版 README 提供合併配方。先跑 S1,再做 S2/S3,比較記憶體、等待和合格答案,才知道自己工作是否受益。

7. 沒有 AMD 卡,今天能做什麼?

先完成考卷與版本清單。準備無私密資料的繁中文件、正解、失敗條件與紀錄欄位;硬體成績等有設備再填。

8. 什麼時候值得留下這套配方?

三關同時過。你需要的深度可反覆完成、等待符合工作需求、繁中與取證都通過;把那個深度記為自己的可用範圍。

給新手的三個重點

  • 把權重、KV、RAM 與傳輸分開算。
  • 把同版串流、MTP 與不同詞表分開比較。
  • 保留實際深度、時間與答案證據,讓容量標籤對回可交付的工作。

接著閱讀

左右滑動查看更多推薦

下一步:先替自己的繁中短文做一張收據

今天先完成「模型指紋、原文字串、往返結果、token 數」四欄,再決定是否往長 Context 走。有相容硬體時,從 S0/S1 的短跑開始,把等待與取證答案一起留下。桌面變小、倉庫仍在、搬運有成本;能把這三件事說清楚,才知道長文容量是否真的幫上忙。

想繼續把本機模型接進可驗收的工作流,可從 AlphaLab AI 專區選下一個概念,或在 AlphaLab 線上課程繼續練習。

ALPHALAB 社群

有問題?來 Telegram 聊

和 Terry、編輯、其他網友一起討論這篇文章。提問、分享觀點,回覆更即時。

加入 Telegram 討論

📩 訂閱 AlphaLab 電子報

每週最多三封:一封 Weekly 週報與最多兩封關鍵 Alpha Signal。

我們不會 spam,隨時可退訂。已訂閱?管理主題偏好(會寄登入連結到你的信箱)