Jev-like Python 包裝器,使用 token logprobs 進行 LLM 和視覺模型操作
TL;DR – 包裝器的功能與重要性
作者建立了一個最小的 Python 包裝器,可將 Jev 風格的請求(狀態、問題、可選的影像附件)發送到任何 Chat Completion 端點,要求模型輸出 一個 token(代表所選選項的字母),並讀取所有候選 token 的 log-probabilities。此技術將生成式 LLM 轉化為低成本、低延遲的分類器,適用於純文字與視覺增強模型。
核心概念 – 使用 log-probs 將生成轉為分類
- 提示格式 – 包裝器會建立一個提示,列出狀態、問題與以
[A]、[B]… 標記的選項,最後加上指令 「僅以最佳選項的字母作答。」 範例:狀態: 檢查此網路攝影機畫面。僅根據可見內容判斷。 問題:可見有人嗎? 選項: [A] true [B] false 僅以最佳選項的字母作答。 - API 參數 – 請求包含:
將{ "max_completion_tokens": 1, "logprobs": true, "top_logprobs": 20, "temperature": 0 }max_completion_tokens設為 1 可強制模型輸出單一 token,使回應極小且延遲低。 - log-prob 提取 – API 回傳前 N 個 token 候選及其 log-probabilities。包裝器透過將每個選項字母對應至 token,將這些 log-prob 轉換為選項上的歸一化機率分佈。
- 結果解讀 – 對於二元問題(
noul類型),包裝器回傳true的機率。對於多選題,回傳最可能的選項與完整機率表。對於序數評分,則計算期望值。
擴展 Jev 至視覺 – attachments 欄位
- 原始 Jev 規格僅支援文字/JSON 的
state。作者新增了attachments陣列,可包含檔案路徑或 base64 編碼的資料 URL。 - 當請求發送到 OpenAI 端點時,每張影像會以
type: "input_image"元素加入;對於 llama.cpp 則以type: "image_url"加入。 - 範例使用 OpenCV 捕捉即時網路攝影機畫面,將其編碼為 JPEG,包裝成資料 URL,並在每次請求前放入
attachments。
端到端 Python 範例(約 150 行)
該腳本在迴圈中執行三個步驟:
- 擷取
/dev/video0的畫面幀。 - 編碼 畫面為 base64 JPEG,並設定
data["attachments"]。 - 提交 請求至所選後端(本地的 llama.cpp 伺服器或 OpenAI),使用背景執行緒。
- 列印 包含最新答案與測量 FPS 的表格。
關鍵函數:
score(data, url, model)– 為每個問題建立提示,發送請求,歸一化 log-probs,並回傳結構化答案字典。main– 解析 CLI 參數(url與model),啟動網路攝影機,並協調非同步評分。
此腳本刻意自包含;唯一外部相依是 opencv-python 用於網路攝影機存取。其他所有函式庫皆為 Python 標準程式庫的一部分。
作者報告的效能數字
| 後端 | 模型 | 硬體 | FPS(幀/秒) |
|---|---|---|---|
| llama.cpp(本地) | Gemma‑4‑12B‑QAT(GGUF) | RTX 3090 | ≈ 1 fps(每幀三題) |
| OpenAI | gpt‑6‑luna | 雲端 | ≈ 0.2 fps |
作者指出,OpenAI 執行較慢的部分原因在於每幀會為每個問題建立 新的 HTTP 連線,此處可優化。
本地 llama.cpp 伺服器設定說明
# 1. 下載 7 GB 的 Gemma‑4‑12B 模型及其多模態投影器(約 175 MB)
mkdir -p ~/models/gemma-4-12b/
cd ~/models/gemma-4-12b/
curl -fL -C - -o gemma-4-12b-it-qat-q4_0.gguf \
https://huggingface.co/google/gemma-4-12B-it-qat-q4_0-gguf/resolve/main/gemma-4-12b-it-qat-q4_0.gguf
curl -fL -C - -o mmproj-gemma-4-12b-it-qat-q4_0.gguf \
https://huggingface.co/google/gemma-4-12B-it-qat-q4_0-gguf/resolve/main/mmproj-gemma-4-12b-it-qat-q4_0.gguf
# 2. 安裝 CUDA‑86 的 llama.cpp 二進位檔
curl -fL -o llama.zst \
https://huggingface.co/buckets/ggml-org/install.sh/resolve/b11160/x86_64/linux/cuda/86/llama-app.zst
mkdir -p ~/bin/
zstd -d llama.zst -o ~/bin/llama
chmod +x ~/bin/llama
# 3. 在 8060 端口啟動伺服器
~/bin/llama serve --models-dir ~/models/ --port 8060
伺服器啟動後,執行包裝器:
uv run webcam.py http://localhost:8060/v1 gemma-4-12b
# 或使用 OpenAI(需先設定 OPENAI_API_KEY)
uv run webcam.py https://api.openai.com/v1 gpt-6-luna
社群反應(選取 HN 評論)
@TeMPOraL – 「這就是我們如何實現星際迷航風格的環境感知:從多模態情境中推斷意圖並自動行動。」 評論強調了此包裝器在即時意圖偵測上的廣闊願景,超越簡單分類。
@prathje – 「這只是基於語法的解碼,並以 JSON 回應?如果是這樣,Jev 本質上只是在那之上加了一層快取。」 作者的實作確實依賴於決定性提示與 token 級 logits,這類似於語法約束解碼,但增加了輕量級快取策略以處理重複的狀態前綴。
@frabcus – 「以 RLHF 訓練的普通 LLM 可能在網路早期就做出決定,因此 Jev 風格的 log-prob 包裝器可能比專為校準決策訓練的模型準確度較低。」 此點指出潛在限制:一般模型的機率校準可能不適合下游決策。
@arcticbull – 「這就像 Jev,但成本與速度差了好幾個數量級。」 評論反映了通用 LLM 的彈性與專用視覺分類器效率之間的權衡。
@CROON_tv – 「我希望看到尾部延遲的數字;在我們的即時語音端點中,Jev 比使用相同提示的普通 LLM 更快且更不猶豫。」 延遲是互動應用的關鍵指標,而包裝器的單 token 方法有助於維持低尾部延遲。
@czl_my – 「我建立了一個可與任何 OpenAI 兼容端點搭配使用的 Jev 包裝器:https://github.com/zhulinchng/jevper。」 外部實作顯示此概念正逐漸受到關注。
局限與開放問題
- 機率校準 – 普通模型的原始 log-probs 可能未良好校準,特別是對稀有 token。使用者可能需要溫度縮放或事後校準。
- 遺失 token 處理 – 包裝器將任何未出現在 top-N 列表中的選項視為機率為零,但若遺失機率超過 1e‑6 則會拋出錯誤。此安全檢查可防止靜默的錯誤排序。
- 可擴展性 – 每個問題發送獨立請求(範例中每幀三題)會增加網路開銷。將多個問題合併至單一提示可提升吞吐量。
- 視覺模型選擇 – 雖然 Gemma‑4‑12B 可用,但專用多模態模型(如 CLIP、Florence)可能達到更高的 FPS 與更好的視覺準確度。
結論
所發布的包裝器展示了一種實用、語言模型無關的方法,可利用 token 級 log-probabilities,將任何 Chat Completion API(包括視覺增強後端)轉化為快速、決定性的分類器。其簡單性(僅一個 Python 函數)與支援影像附件的能力,使其成為即時多模態決策系統的有用元件,儘管仍需注意機率校準與每問題請求開銷的常見限制。