TL;DR: 用 Qwen3.5-9B(Q4_K)在單張 16GB AMD GPU 上跑本地 LLM-as-a-Verifier,每次 code comparison 約 0.5–2 秒,cache hit rate 66%,正確程式碼穩定給 1.0 分,有 bug 的給 0.0–0.14 分。16GB 跑 9B 模型綽綽有餘,還有空間跑其他服務。
這篇是實測續篇,前兩篇分別講了架構設計和 Docker 封裝。前兩篇講的是「做什麼」跟「怎麼做」,這篇來量「到底多快」。
1. 測試環境
在一台 homelab Linux(CachyOS)上跑的:
| 項目 | 內容 |
|---|---|
| GPU | AMD 16GB(15.9 GiB)via ROCm |
| 模型 | Qwen3.5-9B(8.95B 參數,Q4_K ~5.7GB GGUF) |
| 後端 | llama.cpp(llama-server,ROCm HIP build) |
| Verifier | Docker container(llm-verifier),port 8010 |
| 模型 VRAM | ~10.2 GB(模型本身 + 動態 KV cache) |
| GPU 使用率 | 78% |
| 系統 RAM | 62 GB;使用 27 GB(swap 用了 9.3 GB) |
| Context window | 131,072 tokens |
| MIN_SCORE | 0.8 |
後端跑在另一台機器上,走 local Gigabit 網路連線。
2. Verifier 在幹嘛
docker-llm-as-a-verifier 包裝了 LLM-as-a-Verifier 這個研究套件,讀取 token-level log probability 來算連續分數,不是簡單的 yes/no 判斷。
Container 開了 7 個 HTTP endpoint:
| Endpoint | Method | 用途 |
|---|---|---|
/health |
GET | 健康檢查 |
/v1/compare |
POST | 兩組答案比對評分 |
/v1/select |
POST | Best-of-N 選最佳 |
/v1/track |
POST | Agent 軌跡分數追蹤 |
/v1/directed |
POST | 導向式 (A→B) 偏好比較 |
/v1/score-pairs |
POST | 批次 pairwise 評分 |
/v1/usage |
GET | 累計 token 統計 |
每個 /v1/compare 實際做 3 次 LLM inference:先評 A,再評 B,最後比較兩者分數給 verdict。
3. 實測數據
3.1 Latency
從 verifier 自己的 log timestamp 撈的:
| 操作 | 後端呼叫數 | 總時間 | 每次平均 |
|---|---|---|---|
| Compare(一般) | 3 | ~1,000 ms | ~330 ms |
| Compare(命中 cache) | 3 | ~800 ms | ~270 ms |
| Select(N=3, pivots=2) | 6 | ~1,200 ms | ~200 ms |
| 單次 inference | 1 | 200–800 ms | 200–800 ms |
Cache hit rate 66.4% — 80 次 request 裡 22,417 個 prompt tokens 被 cache 住(總共 33,768)。verifier 的 fine_grained_reward 模組會把評分結果 cache 到 disk(verifier-cache Docker volume),同樣的 code snippet 重複比對時直接跳過 LLM。
3.2 評分品質
| 候選程式 | 分數 | 結果 |
|---|---|---|
| 正確的程式碼 | 0.97–1.0 | ACCEPTED |
| 明顯的 bug | 0.0–0.02 | REJECTED |
| 微妙的 bug | 0.02–0.14 | REJECTED |
MIN_SCORE=0.8 設下去,即使最接近正確的 buggy code(0.14)還是被正確擋掉。正反案例的分數落差很乾淨,沒有模糊地帶。
3.3 Token 用量
80 次 verifier request 的累計數字:
| 項目 | 數值 |
|---|---|
| Prompt tokens 總計 | 33,768 |
| — 其中 cache hit | 22,417(66.4%) |
| Completion tokens 總計 | 47,538 |
| 總 token 數 | 81,306 |
| Reasoning tokens | 0(Qwen 不是 R1) |
| 後端請求數 | 80 |
Reasoning tokens 是 0,確認 Qwen3.5-9B 是 dense model,不是 reasoning/R1 系列。Verifier 直接用模型的 log-probability 輸出,不走 chain-of-thought。
3.4 VRAM & GPU 使用率
| 項目 | 數值 |
|---|---|
| VRAM 總容量 | 15.9 GiB |
| VRAM 使用量 | 10.2 GiB(64%) |
| GPU 使用率 | 78% |
| Context window | 131,072 tokens |
9B 模型 Q4_K 量化後只佔 ~5.7 GB,還有 ~5.7 GB 給 KV cache 和其他服務。131K context window 是 llama.cpp 的預設值,verifier 實際 prompt 小很多(~400–800 tokens)。
4. 真正的架構長這樣
實際跑起來的 pipeline 比第一篇架構圖簡單:
Agent(OpenCode)
│ 送出修改提案
▼
guardrail-mcp
│ commit_token → validate → consume
│ apply_patch(cargo check / tsc syntax 驗證)
│ softguard(HTTP → verifier)
▼
llm-verifier(Docker :8010)
│ POST /v1/directed(比對舊程式 vs 新程式)
▼
llama.cpp(ROCm)
│ Qwen3.5-9B Q4_K inference
guardrail-mcp 提供的工具:
- commit_token:2PC 生命週期(create → validate → consume → revoke),SHA-256 綁定 proposal,30 分鐘 TTL,綁定 git revision
- apply_patch:套用 patch 前先用 compiler 驗證(cargo check / tsc),通過才寫入
- inspect_context:Tree-sitter 結構化萃取,讓 patch 更精準
- softguard:HTTP verifier 呼叫器,可設定 endpoint、timeout、API key
關鍵設計:LLM verifier 是 soft guard,負責抓 syntax 檢查抓不到的語意 bug。cargo check / tsc 這種便宜的確定性檢查先做第一關,通過的才送 LLM 做語意審查。
5. 已知限制
這些數字是單次 session 的 benchmark,不是正式的 evaluation suite:
- 沒有併發測試:80 個 request 是循序跑的,不是同時。真實 TPS 會更低。
- 沒有雲端 baseline:OpenRouter free route 還沒測,本地 ROCm vs 雲端 API 的比較還欠著。
- 沒有 VL 數據:多模態 vision endpoint(9B VL)還在開發中,這些數字只適用 text-only 的 code comparison path。
- 沒有 Track 1 short-circuit 率:第一篇提到的 AST 結構檢查是 aspirational 的。目前 guardrail-mcp 用 syntax validation(cargo check / tsc)當確定性閘門,不是專屬的 AST structural checker。
- 沒有精確成本:0.5–2s per comparison 在 78% GPU 使用率下,大概不到 1 塊台幣的電費,但這是粗估,不是實測。
6. 結論
一張不到 15,000 台幣的 16GB AMD GPU,就能跑本地 LLM-as-a-Verifier 做 code review 的 guardrail:
- Qwen3.5-9B Q4_K 塞得進去還有空間(10.2 GB / 15.9 GB)
- Compare latency:~0.5–2s,interactive guardrail 夠用
- Cache hit rate:66%,重複比對幾乎免費
- 評分品質:正確(1.0)跟錯誤(0.0–0.14)分得很開
不需要雲端 API key,沒有月費,沒有資料外洩問題。
下一步是 benchmark OpenRouter free route 做雲端 baseline,以及量併發 throughput。但即使沒有對照組,本機路徑已經夠日常使用了。
Repository:
- Verifier Docker 封裝:github.com/cawa0505/docker-llm-as-a-verifier
- 2PC guard gate:github.com/cawa0505/guardrail-mcp
- 架構總覽:Poor Man's LLM-as-a-Verifier
留言
張貼留言
回應不用錢,請多多益善!懶得寫字按個讚也是相當感謝!