Jared Palmer

Kev

基於 Qwen3.5 / Qwen3.8 的決策模型家族,四個尺寸從 0.8B 到 27B。一次前向傳播給出帶機率的型別化答案,介面與 TypeSafe 的 System One 相同。

核驗於 2026-10-05

小巧的、類 Jev 的決策模型,你可以自己訓練、自己執行。

CI Weights: Kev-0.8B · 4B · 9B · 27B Demo on Hugging Face Spaces Frozen eval suites License: Apache-2.0

Kev 是一族建立在 Qwen3.5 和 Qwen3.8 上的小型決策模型,基於 Jev’s Architecture Unmasked 裡描述的架構。你可以用預訓練權重,也可以自己訓練。API 與 TypeSafe 的 System One 一致,所以你可以把他們的 Python SDK 指向你自己的本地伺服器。

亮點

  • 一次請求裡同時問是非題(noul)、多選題(choice)和評分題(score)。這些問題共享文本,但彼此讀不到對方。
  • 預設輸出校準機率:每個 checkpoint 都帶一個擬合好的溫度。
  • 可直接替換 Jev:TypeSafe Python SDK 無需改動就能對 Kev 伺服器使用。
  • 四種規模,一起作為 Kev 1.0 發行:從能在筆記本上跑的 0.8B 到面向單張資料中心 GPU 的 27B。
  • 文件最長 65,536 tokens,支援 CUDA,也支援 Apple Silicon 上的 MLX。每張模型卡都說明在準確率下降之前文件能有多長。
  • 在你自己的標註樣本上微調。一個 coding-agent 技能在 Modal 上跑通整個閉環,從找出你的問題到服務結果。
  • 一條命令部署你自己的 HTTPS 端點。空閒時縮容到零。
  • 先在瀏覽器裡試: huggingface.co/spaces/jaredpalmer/kev。

模型

從 Kev-4B 開始。有更大的 GPU 就轉 Kev-9B,有 80 GB GPU 且想要最準確的 Kev 就轉 Kev-27B。當體積比準確率更重要時用 Kev-0.8B。

模型 基座(許可證) 可在:CUDA 上執行 可在:Mac (MLX) 上執行 已驗證上下文 留出資料集:指數 模型卡
Kev-0.8B Qwen3.5-0.8B-Base (Apache-2.0) L4,任何 4 GB GPU 任何 Apple Silicon Mac;實測到 65k tokens 8,192 23.3 詳情
Kev-4B Qwen3.5-4B-Base (Apache-2.0) L40S, H100 32 GB Mac;實測到 65k tokens 8,192 38.0 詳情
Kev-9B Qwen3.5-9B-Base (Apache-2.0) L40S, H100 32 GB 或更大的 Mac(預期,未實測) 8,192 41.0 詳情
Kev-27B Qwen3.8-27B,後訓練版 (Apache-2.0) B200, H200, H100 80 GB 96–128 GB Mac(預期,未實測) 65,536 52.3 詳情
Jev 託管 TypeSafe 的 API – – 54.0 –

「留出資料集」是社群 Decision Index 的隨機校正指數,在 breadth-v1 的測試劃分上打分:五個領域裡 14 個公開資料集,沒有任何 Kev 訓練過。「已驗證上下文」是以 tokens 計的最長文件,在該長度上,真實合同(CUAD)上的準確率與同一模型在 8k tokens 時的準確率相比保持在 3 個點以內(95 % 下界);每張模型卡都有按長度的測量。

模型 準確率:新來源 準確率:已訓練來源 Brier:新來源
Kev-0.8B 0.648 / 0.697 0.827 / 0.838 0.481 / 0.416
Kev-4B 0.817 / 0.838 0.873 / 0.865 0.269 / 0.242
Kev-9B 0.820 / 0.852 0.874 / 0.873 0.289 / 0.217
Kev-27B 0.851 / 0.889 0.865 / 0.866 0.225 / 0.156
Jev 0.857 / – 0.845 / – 0.211 / –

每個單元格是開發 / 測試。「新來源」是指 Kev 訓練時從未見過的資料集和政策規則。它是這裡最接近你自己問題的一類。「已訓練來源」是指 Kev 訓練所用資料集的留出樣本。我們用開發集選 checkpoint,每個已釋出模型只讀一次各自的測試集。Jev 只在這兩個套件的開發集上跑過。Brier 給整個機率分佈打分,而不只是最高答案;越低越好。

在新來源上,Kev-27B 與 Jev 相差一個點以內(0.851 對 0.857),Kev-4B 和 Kev-9B 在四個點以內。我們不知道 Jev 訓練用了什麼,所以這不是兩種架構的受控比較。What to Expect 說明 Kev 在哪些地方與 Jev 一樣好、哪些地方不是。

Kev-0.8B、4B 和 9B 從 Qwen 基座模型出發,共用一個訓練配方:在凍結基座上掛一個小介面卡。Kev-27B 從 Qwen 的後訓練釋出版出發,我們不知道它訓練用了什麼;它的每一個權重都經過微調,所以釋出出來的是 51 GB 完整權重,而不是介面卡。每張模型卡都有完整配方、全部結果,以及作為 Hub tag 保留的早期版本。

Kev 1.0

上面四個模型一起作為 Kev 1.0 釋出。每個 Hub 倉庫都有一個 v1.0 tag,所以 --run jaredpalmer/kev-4b@v1.0 總是載入同一批權重,而 GitHub release kev-1.0 帶有 0.8B、4B 和 9B 的 checkpoint 及 SHA-256 校驗和。Kev-27B 的 51 GB 權重對 release 資產來說太大,只在 Hub 上。

模型 權重的 Hub revision 溫度 訓練所用 state 最長到
Kev-0.8B 9a45d25e 2.35 7,552 tokens
Kev-4B 139fdd94 2.41 7,552 tokens
Kev-9B b5d8c18e (v2) 2.19 7,552 tokens
Kev-27B 28be62e9 (v2, 完整權重) 1.32 32,768 tokens

Kev 1.0 沒有新訓練任何東西。它固定了下一代 Kev 將要對標的 checkpoint、模型卡、評測套件和服務程式碼。release notes 列出上個家族釋出以來的變化,以及已知哪些地方效果不好。

快速開始

在瀏覽器裡試

Hugging Face Space 執行 Kev-4B 和 Kev-0.8B,無需安裝任何東西。

在本地執行

你需要 Python 3.12 或 3.13 和 uv。倉庫的 .python-version 讓 uv sync 使用 3.13;torch 還沒有 3.14 的 wheel。

git clone https://github.com/jaredpalmer/kev.git && cd kev
uv sync --extra serve
uv run --extra serve python -m kev.serve --run jaredpalmer/kev-4b --port 8009

這會在你的機器上啟動 Kev-4B:有 GPU 就走 CUDA 或 ROCm,Apple Silicon 上走 MLX。首次執行會下載介面卡和基座模型。--run 也接受本地 checkpoint 目錄或像 jaredpalmer/kev-4b@qwen3 這樣的 Hub revision。

在另一個終端裡,給它發一張工單:

curl -s localhost:8009/v1/systemone -H 'content-type: application/json' -d '{
  "state": "Shoes arrived two weeks late and in the wrong size. Also I see two charges on my card.",
  "model": "kev-latest",
  "questions": {
    "department":  {"type": "choice", "instructions": "Which team should handle this?",
                    "criteria": {"returns": "Exchanges, refunds, wrong or damaged items",
                                 "shipping": "Delivery status, delays, lost packages",
                                 "billing": "Charges, invoices, payment problems"}},
    "escalate":    {"type": "noul",  "instructions": "Does this need urgent human attention?"},
    "frustration": {"type": "score", "instructions": "How frustrated is the customer?",
                    "criteria": ["Calm", "Frustrated", "Very angry"]}
  }}'

來自 Kev-4B 的示例響應,在 Apple M5 上以 bf16 執行:

{
  "model": "kev-latest",
  "answers": {
    "department":  { "type": "choice", "choice": "returns", "confidence": 0.21,
                     "probabilities": { "returns": 0.47, "shipping": 0.28, "billing": 0.25 } },
    "escalate":    { "type": "noul", "noul": 0.93 },
    "frustration": { "type": "score", "score": 1.44, "confidence": 0.34,
                     "legend": { "0": "Calm", "1": "Frustrated", "2": "Very angry" },
                     "probabilities": { "0": 0.00, "1": 0.56, "2": 0.44 } }
  },
  "usage": { "input_tokens": 101, "output_tokens": 161 },
  "latency_ms": 495
}

這張工單提到了退貨、延遲送達和賬單問題,部門機率也如實反映了這一點。這就是 Kev 返回機率而不是單個標籤的原因:你的程式碼可以把有把握的案例路由出去,把其餘的交給人工。

從 Python 使用

如果你已經在呼叫 Jev,把客戶端指向 Kev,其餘程式碼保持不變。TypeSafe SDK 包含在 uv sync --extra serve 裡:

from typesafe_sdk import Choice, Noul, Score, TypeSafeClient

client = TypeSafeClient(
    api_key="local",
    base_url="http://127.0.0.1:8009",
    model="kev-latest",
)
response = client.system_one(
    state="I was charged twice. Please fix this ASAP.",
    questions={
        "billing": Noul(instructions="Is this ticket about billing?"),
        "tone": Choice(
            instructions="What is the customer's tone?",
            criteria={"calm": None, "frustrated": None, "angry": None},
        ),
        "urgency": Score(
            instructions="How urgent is this ticket?",
            criteria=["can wait", "this week", "today"],
        ),
    },
)
print(response.nouls["billing"].noul)
print(response.choices["tone"].choice)
print(response.scores["urgency"].score)

在你自己的資料上微調

已釋出的模型是在公開資料集和生成的政策樣本上訓練的。如果你的問題看起來不一樣,比如你自己的路由類別、你自己的升級規則或另一種語言,一次短微調通常比任何 prompt 改動都更有效。它還會把溫度擬合到你的資料上,所以你據此設閾值的置信度是在你自己的標籤上測量的。

可以期待什麼:在一個示例支援工作負載上(三個問題、1,050 條生成記錄、H100 上 15 分鐘),微調把 Kev-4B 的準確率從 67.7% 提到 73.6%,並把 5% 誤差預算下可自動化的決策比例從 34% 提到 48%(詳情)。在真實資料上,對 5,219 條標註的消費金融投訴訓練一個 epoch,把 Kev-4B 在它從未見過的投訴上的準確率從 0.804 提到 0.904。這類增益是分佈內的:它們告訴你 Kev 學你的任務學得多好,而不是它在其他一切上表現如何。先確定你的資料集規模。只有 400 條記錄時,示例工作負載上的增益落在噪聲之內。

用 coding agent

npx skills add jaredpalmer/kev@kev-finetune

然後讓你的 agent「在我的支援工單上微調 Kev」。這個 kev-finetune 技能 會與你訪談,找出你的程式碼已經在向 Jev 或 TypeSafe 問的問題,轉換你已有的標籤,或用任意 LLM 生成足夠的標籤來測出增益,從已釋出的 checkpoint 出發在 Modal 上微調,在留出切片上擬合溫度,把結果與未改動的模型對比打分,部署一個端點,並在結束時拆掉一切。你不需要本地 GPU,也不需要克隆這個倉庫。一次 Kev-4B 訓練在 H100 上約 1 美元。

手工做

該技能的 README 是給人類看的同一套配方:六個簡短的標準庫指令碼和一個 Modal 應用。若要從本倉庫訓練,把你的樣本放進一個 JSONL 檔案,每行一個請求。它的形狀與 API 請求相同,只是每個問題上多一個 label:

{"state": {"subject": "Charged twice", "body": "I see two charges for order #4411. Please refund one."},
 "questions": {
   "team":     {"type": "choice", "instructions": "Which team should handle this ticket?",
                "criteria": {"billing": "Payments and refunds", "shipping": "Delivery problems", "access": "Login and account access"}, "label": "billing"},
   "angry":    {"type": "noul",   "instructions": "Is the customer angry?", "label": false},
   "priority": {"type": "score",  "instructions": "How urgent is this ticket?", "criteria": ["low", "normal", "high"], "label": 1}}}

對 choice,標籤是選項名;對 noul,是 true 或 false;對 score,是從 0 開始的檔位位置。留出檔案的 10–20% 用於評測。

然後用 --init_from 從已釋出的 checkpoint 出發:

uv run python -m kev.train --data train.jsonl --base Qwen/Qwen3.5-4B-Base --init_from jaredpalmer/kev-4b \
    --epochs 2 --lr 2e-5 --batch 1 --accum 8 --dtype bf16 --checkpointing 1 --device cuda --out runs/mine

uv run python -m kev.benchmark --run runs/mine --data heldout.jsonl --out runs/mine-eval
uv run --extra serve python -m kev.serve --run runs/mine --port 8009

--init_from 在訓練前從已釋出模型載入介面卡和指標頭,這樣你保留 Kev 已知的東西,並在其上疊加你的領域。改從基座模型出發會把它丟掉:在一個使用者對 836 個支援工具決策的測試中,從基座微調在 Kev 自己的評測集上得 0.33,而已釋出模型得 0.84;同樣的資料用 --init_from 在那裡保持 0.83,並在新領域上達到 0.88。使用比從零配方更小的學習率(2e-5 是個好起點),並讓 --base 與你出發的 checkpoint 匹配;trainer 在載入任何東西之前會檢查基座、revision、LoRA rank 和指標頭大小是否一致。

bf16 下的 --batch 1 --accum 8 能把 0.8B 模型放進 4 GB GPU。benchmark 會按問題型別報告準確率、Brier 分數和校準,所以你能看出微調幫到了你的哪些問題。你出發的 checkpoint 記在 runs/mine/training_config.json。在 Mac 上一次只跑一個訓練任務;同一塊 Apple GPU 上兩個任務會慢很多。

部署你自己的端點

要得到 HTTPS 端點而不是本地伺服器,你不需要這個倉庫,只需要一個 Modal 賬號:

pip install modal && modal setup
curl -LO https://raw.githubusercontent.com/jaredpalmer/kev/main/skills/kev-deploy/scripts/kev_serve.py
KEV_API_KEY=$(openssl rand -hex 24) modal deploy kev_serve.py

這會在 L40S 上服務 Kev-4B,地址是 https://<your-workspace>--kev-api.modal.run,API 與上面相同,前面加 Authorization: Bearer <key>。空閒時縮容到零,所以閒置的端點不花錢。空閒後的第一個請求要等約 35 秒讓容器啟動。KEV_MODEL=jaredpalmer/kev-9b 在其合適的 GPU 上服務另一個模型;Kev-27B 走 B200,回落到 H200 或 H100。如果你用 coding agent,npx skills add jaredpalmer/kev@kev-deploy 做同樣的事,並把 URL 接進你的程式碼。skills/kev-deploy 有 GPU 與成本表。

你用 kev-finetune 技能微調出來的模型,用自己的 Modal 應用以同樣方式部署(KEV_SERVE_SECRET=kev-serve-key KEV_SERVE_RUN=<run> modal deploy scripts/kev_modal.py;見 它的部署指南)。要把 Kev 託管在自己的機器上,改為在一臺 GPU 機器上跑 Run It Locally 裡的 kev.serve,加 --host 0.0.0.0,並把它放在你自己的代理之後;Serving Performance 說明該選哪塊 GPU。

What to Expect

準確率。 在下圖 11 個新來源類別中的 9 個上,Kev-27B 與 Jev 相差三個點以內,或領先它。在路由、蘊含和科學問題這類分類形狀的來源上,Kev-4B 和 Kev-9B 也差不多接近。知識問題主要取決於基座模型:在 MMLU 上 Kev-9B 得 0.73,Kev-27B 以 0.90 追平 Jev,但在更難的 MMLU-Pro 上 Kev-27B 得 0.675,而 Jev 為 0.840。更小的模型在日精度日期算術上也落後。

Accuracy by source for Kev and Jev

置信度。 每個 checkpoint 都帶一個擬合好的溫度,所以其機率預設是校準的。按服務狀態,Kev-9B 對新來源問題有 2.4% 在錯誤答案上給出至少 0.9 的機率,而 Jev 是 3.7%。Jev 對自己的答案排序仍然更好:在 5% 誤差預算下,Kev-4B、9B 和 27B 能自動化 0.52–0.69 的新來源決策,Kev-0.8B 是 0.14,Jev 是 0.70。在依賴某個閾值之前,先在你自己的資料上檢查它。

速度。 Kev-4B 在 H100 上用 18.1 ms 模型時間回答關於一段新短文本的六個問題,在 L40S 上是 41.5 ms,一個容器在 H100 上每秒服務約 101 個請求。在 Apple M5 上,Kev-4B 五個問題要 721 ms,文本重複且來自快取時是 136 ms。Serving Performance 有每塊 GPU 和每個 batch size。

長度。 Kev-0.8B、4B 和 9B 主要在最多個 384 tokens 的 state 上訓練,其文件和技能微調裡有更長的(最多 7,552 tokens),Kev-27B 則訓練到 32,768。伺服器接受最長 65,536 tokens 的 state,每個問題再各加 8,192,遇到更長的會以 422 拒絕而不是截斷它。每個模型在超出其訓練長度後還能準確多遠,就是 Models 裡的「已驗證上下文」列。對 Kev-0.8B、4B 和 9B 那列是 8,192 tokens:在 16k 時真實合同上的測量已無法排除超過 3 個點的下降,在 32k 時三者都可測地不如 8k 準確。Kev-27B 保持到 65,536-token 上限。在最長 64k tokens 的真實合同(CUAD)上 Kev-27B 得 0.874,它在那種情況下比在短文本上更不可靠;它的模型卡有按長度的數字。

Playground

伺服器執行起來後,再開一個終端。你需要 Node 20.9+:

cd playground
npm install
npm run dev -- -p 3001

開啟 localhost:3001,載入一個預設,編輯文本和問題。按 ⌘↵ 執行。 「Packed vs separate」比較一次問所有問題與一次問一個。「Permute」用一個 Choice 問題跑六種選項順序。還有用於測試問題隔離和假分隔符 token 的預設。

Kev playground

還有一個國際象棋演示。棋盤是輸入,合法著法是 Choice 選項,一個 Score 問題給局面打分。你可以和 Kev 對弈,也可以讓它自己下。對局儲存在 localStorage 裡。

API

POST /v1/systemone

state 是要評估的文本。每個問題都有指令,在需要時還有一組可選的答案。

{
  "state": "…",                          // string | object | array — the content to evaluate
  "model": "kev-latest",
  "questions": {
    "<id>": {                            // you choose the id; the model never sees it
      "type": "noul" | "choice" | "score",
      "instructions": "…",               // string | object | array, optional
      "criteria": …                      // noul: {true?, false?}  choice: {option: description|null}  score: [level, …]
    }
  }
}
型別 判據 答案
noul true 和 false 的可選描述 noul:為是的機率
choice 1–255 個選項名,各帶一個描述或 null choice:最可能的選項;probabilities 和 confidence
score 1–255 個描述,從最低到最高有序 score:平均檔位索引,從 0 開始;legend、probabilities 和 confidence

對 K > 1 個選項的 Choice,置信度是 (p_max − 1/K) / (1 − 1/K)。單個選項的置信度為 1。Score 置信度是 max(0, 1 − E|level − mode| / D):mode 是最可能的檔位,D 是檔位上均勻分佈到其中點的平均距離(三個檔位時為 2/3),所以全部機率落在一個檔位時給出 1,均勻或更分散時給出 0。兩個公式都來自 TypeSafe 的參考介面卡(system-one-adapter 0.2.1)。兩個欄位都不是實測的準確率。

物件和陣列會被轉換成帶標籤的文本。使用者輸入裡類似分隔符的字串在 tokenize 之前會被轉義。無效請求返回 422,超過 65,536 tokens 的 state 也一樣:伺服器從不會靜默丟棄文件的一部分,錯誤會給出該 state 的 token 數和上限。usage.output_tokens 計的是序列化答案裡的 tokens,不是生成的 tokens。

方法 路徑 用途
GET /v1/models 模型卡(name、description、release_date)加上已載入 checkpoint 的詳情
POST /v1/systemone/permute 用不同選項順序跑一個 Choice 問題(n_perm 1 到 64,預設 6)
POST /v1/systemone/separate 每個問題各跑一次前向

一個請求可以帶任意數量的問題。伺服器按一個 token 預算一批地跑它們(每次前向一行最多 16,384 tokens,該次前向中每個問題把快取的文件計一次),所以記憶體不隨問題數增長,答案也不依賴如何切分。每個響應都帶一個 x-typesafe-request-id 頭。伺服器繫結到 127.0.0.1(--host 0.0.0.0 接受其他機器),預設開放;設定 KEV_API_KEY 要求 /v1/* 上帶 Authorization: Bearer <key>,因為 TypeSafe 客戶端總是會發它。

變數 作用
KEV_TEMPERATURE=1.0 返回原始機率而不是校準後的機率
KEV_DATE_FACTS=1 追加 state 中任意兩個日期之間的天數(見 Benchmarks)
KEV_TRUNCATE_STATES=1 讀取更長 state 的前 65,536 tokens 而不是拒絕它;此時每個響應都帶 truncated 和 usage.state_tokens / state_tokens_used
KEV_DTYPE=fp32 服務評測所用的確切 fp32 路徑(GPU 上預設是 bf16)
KEV_API_KEY 要求 bearer key

How It Works

每個 checkpoint 都是一個 rank-16 LoRA 介面卡加一個在 Qwen 基座模型上的小指標頭。在純注意力基座(Qwen3)上,state 和問題進入一條 token 序列:

<state> …state…
<q> instructions <opt> option 1 </opt> <opt> option 2 </opt> … <decide>
<q> instructions <opt> option 1 </opt> <opt> option 2 </opt> … <decide>

注意力掩碼讓一個 token 能讀到 state 和它自己的問題,但讀不到其他問題或未來的 token。每個問題的 position ID 緊接在 state 之後重新開始。這讓模型把 state 處理一次,並各自獨立地回答每個問題。

Qwen3.5 和 Qwen3.8 把注意力層與 Gated DeltaNet 層混合,後者是迴圈的、忽略注意力掩碼。對這類模型(也就是當前每一個 Kev),每個問題各跑一行:state 後接該問題,position 與上面相同。各行相互獨立,所以隔離是精確的,伺服器和 DecisionModel.probs() 把 state 計算一次,併為每一行復用它。forward()(kev.benchmark 打分、每個已釋出數字都來自它)保留普通行,每個問題把 state 跑一次;兩者在 fp32 舍入範圍內一致。在純注意力模型上,上述行與掩碼給出完全相同的機率(tests/test_model.py)。

Kev-27B 在 Qwen/Qwen3.8-27B 上用同樣的設計,有兩處不同。它的基座是 Qwen 的後訓練釋出版而不是 -Base checkpoint,我們不知道它後訓練用了什麼。並且每個主幹權重都被訓練,而不只是介面卡,且以 bf16 儲存,所以 checkpoint 就是整個模型:51 GB 的 bf16 權重加指標頭。它只以 bf16 服務(含服務緩衝常駐約 66 GB),這也是它需要 80 GB 卡的原因。在 Apple Silicon 上 MLX 後端按原樣載入這些權重,不做合併(見 Serving Performance);我們預計它裝得進 96–128 GB 的 Mac,但尚未測量。它在 H200 上服務時的機率與評測路徑保持在 0.022 以內(runs/serving-27b-r23)。

指標頭把每個選項 </opt> 的隱狀態與問題的 <decide> 隱狀態打分。softmax 把分數轉成機率。因為 <decide> 在最後,它能注意到完整的選項列表。

訓練在正確答案上使用交叉熵。介面卡和指標頭一起訓練;基座其餘權重保持不變(Kev-27B 把它們全都訓練)。訓練樣本和 API 請求使用相同的文本格式。沒有使用任何 Jev 輸出做訓練。

一起問和分開問產生機率相差在 4e-6 以內(fp32 測試)。這不意味著選項順序無關緊要:一個問題內的選項仍可能相互影響。見模型程式碼和一致性測試。

Training

已釋出的模型共用一個基礎訓練集 decision-v7:來自十個公開資料集的 10,000 條樣本、896 條生成的政策樣本,以及 1,680 條來自 60 個生成規則結構的樣本。Kev-0.8B、4B 和 9B 在其上訓練兩個 epoch,LoRA rank 16 加交叉熵。學習率對 0.8B 是 1e-4,對 4B 和 9B 是 5e-5。在這些混合基座上,介面卡覆蓋注意力、MLP 和 DeltaNet 投影;kev.train 從模型配置裡挑出正確的目標。

Kev-0.8B、4B 和 9B 隨後從各自已釋出的 checkpoint 做簡短的後續微調,走的就是你會用於自己資料的同一條 --init_from 路徑:宣告天數計數或被去掉決定證據的生成案例(三者都有),然後是真實文件和生成的技能資料(三者都有;Kev-9B 自 v2、2026-09-30 起)。Kev-27B 的訓練方式不同。基座的每個權重都在 8 張 H200 上對一個 145,840 條記錄的語料微調一個 epoch(--full_ft 1,學習率 2e-6):Kev 自己的資料、文件、技能與開發者工具套件、公開資料集、授權任務家族,以及生成的長文件、工具路由、agent 日誌和護欄記錄,state 最多 32,768 tokens。結果隨後與更早的介面卡訓練的 Kev-27B 按 0.85 對 0.15 平均。模型卡列出每個階段及其資料與成本。

# sanity run, ~1 minute
uv run python -m kev.train --n_per_source 40 --accum 4 --out runs/smoke

# the first stage of Kev-0.8B (~20 min on one H100; the Mac path works but is slow for Qwen3.5 bases)
uv run python -m kev.train --suite evals/v7/decision-v7 --base Qwen/Qwen3.5-0.8B-Base --base_revision dc7cdfe2ee4154fa7e30f5b51ca41bfa40174e68 \
    --epochs 2 --lr 1e-4 --batch 8 --dtype bf16 --p_none_pair 0.25 --device cuda --out runs/kev-0.8b

# the first stage of Kev-4B (one H100 via Modal, ~1 h; see below). Swap in Qwen/Qwen3-4B-Base for the previous generation.
uv run python -m kev.train --suite evals/v7/decision-v7 --base Qwen/Qwen3.5-4B-Base --base_revision 1001bb4d826a52d1f399e183466143f4da7b741b \
    --epochs 2 --lr 5e-5 --batch 4 --accum 2 --dtype bf16 --checkpointing 1 --p_none_pair 0.25 --device cuda --out runs/kev-4b

用 uv run python -m kev.train --help 看所有訓練選項。已釋出的模型不使用可選的 --perm_kl 或 --ord_w 損失。PLAN.md 記錄了什麼試過、什麼有幫助、什麼沒有。

每次試驗各拿一張 H100。你斷開連線後研究仍在跑,完成後可以把結果下載下來:

uv run modal token new                                    # once; opens the browser
KEV_GPU=T4 uv run modal run modal_app.py::smoke           # end-to-end check, ~1 minute of GPU

uv run modal deploy modal_app.py                          # once; studies run on the deployed app and survive disconnects
uv run modal run modal_app.py::study \
    --suite evals/v7/decision-v7 --plan experiments/v7-final.json \
    --name my-study --transfer evals/v4/transfer-v4 --budget 30 --timeout 7200
uv run modal run modal_app.py::pull --name my-study       # results -> runs/my-study, ranked

Study plans 列出訓練設定。每次試驗都儲存設定、程式碼 hash、資料集 hash 和結果。用開發結果選模型,而不是鎖定的測試。選定最終候選後,你可以讀一次它的測試結果:

uv run modal run modal_app.py::locked_test --trial my-study/00-trial-0 --name my-candidate   # one read, ever

Benchmarks

evals/ 下的評測資料是凍結的:資料集版本和檔案校驗和記錄在每個 manifest 裡。大檔案從 Hub 映象下載,並對照這些 hash 校驗。上面各表中的每個模型都在相同的條目上打分。本 README 和模型卡里的數字在 CI 中對照它們來源的已提交報告校驗(docs/claims.json、uv run python scripts/verify_claims.py)。

套件 它測什麼
decision-v7 來自十個訓練資料集、生成的政策和規則結構的留出樣本(「已訓練來源」)
transfer-v4 來自 Kev 從未訓練過的資料集以及政策與規則型別的 764 條記錄:QNLI、SciQ、PAWS、MMLU、Emotion、TweetEval、留出政策和規則(「新來源」)
transfer-v9 transfer-v4 加上 10 路 MMLU-Pro、埋在無關文本里的記錄,以及去掉了決定證據的「不可知」記錄
uv run python -m kev.benchmark --run jaredpalmer/kev-4b --suite evals/v4/transfer-v4 --out runs/my-eval      # new sources
uv run python -m kev.benchmark --run jaredpalmer/kev-4b --suite evals/v9/transfer-v9 --out runs/my-eval-v9   # + MMLU-Pro, buried states, unknowable items
uv run python -m kev.benchmark --run jaredpalmer/kev-4b --suite evals/v7/decision-v7 --out runs/my-eval-id   # trained sources
uv run python -m kev.benchmark --remote http://127.0.0.1:8009 --suite evals/v4/transfer-v4 --out runs/my-remote   # any System One endpoint, Jev included

這些命令使用開發資料。測試資料需要 --allow-test。benchmark 報告準確率、Brier 分數、校準誤差、5% 誤差預算下可自動化的決策比例、選項順序變化和問題隔離。在不可知記錄上,它報告模型仍以至少 0.9 置信度作答的頻率(Kev-9B 0%,Jev 9%)。已釋出的準確率數字使用 fp32 評測,而不是 bf16 服務路徑。kev.jev 通過 Vercel AI Gateway 對 Jev 跑同樣的問題,kev.compare 用配對 bootstrap 置信區間比較兩次已儲存的執行。

校準。 每個 checkpoint 存一個溫度,指標頭在模型載入時施加它。Kev-4B (2.41) 和 Kev-0.8B (2.35) 在各自的分佈內開發集上擬合;Kev-27B (1.32) 和 Kev-9B (2.19) 在它們從未訓練過的留出資料集上擬合。對兩個較小模型在這些留出資料集上的一次重擬合經過測試,兩個都沒保留:它沒有改善 Kev-4B,還讓 Kev-0.8B 在其文件和技能套件上校準變差(模型卡有數字)。溫度從不改變哪個答案勝出。在新來源上,它把 Kev-9B 的校準誤差從 0.103 降到 0.041,把它的自信錯誤(機率 ≥ 0.9 的錯誤答案)從 8.2% 降到 2.4%,低於 Jev 的 3.7%。上面的準確率數字兩種情況下都一樣;Brier 數字是原始機率的。scripts/calibrate_checkpoint.py 還會報告一個折外估計,所以樣本內擬合可以對照它沒見過的記錄檢查。

日期。 Kev 無法可靠地做日期減法,但它能用給定的天數計數。KEV_DATE_FACTS=1 為 state 中每一對日期追加一句話(「June 26, 2026 is 8 days before July 4, 2026」)。在截止日期政策問題上,這把 Kev-9B 從 0.80 提到 0.90(Jev 0.93)。沒有任何表使用它。

別人的測試集。 evals/external/ 裝著來自其他專案的測試集,轉成本格式,並附上它們已釋出的即時 Jev 結果。有些是在更早版本的 Kev 權重上打分的,Kev 那一列的名稱標明瞭這點。三個被移除,因為它們無法作為關卡,模型卡保留它們各自發布時所依據的數字:scienthoon 在 2026-09-27 的合成支援工單(模板化文本;它三個問題中有一個依賴文本未陳述的規則),以及 2026-09-30 的 WANLI(wanli-v1、wanli-v2:四分之一的配對是 WANLI 兩位標註者標註不同的,gold 取其中之一)和 TypeSafe 的公開評測(typesafe-v1:gold 是兩個閉源前沿模型的平均答案,在 89 個問題上它無法區分 checkpoint)。

套件 它是什麼 Jev Kev
SemIf 144 個手寫決策 0.965 0.917(Kev-9B 在 v7-base)

SemIf 的標籤站得住,但它接近飽和:每個 Kev-27B checkpoint 都答對 144 箇中的 130 個,所以它是一個健全性檢查,不是給模型排名的方法。

Serving Performance

按模型選 GPU:

模型 GPU ($/h) 6 個問題,短文本 5 個問題,2,200-token 文本 請求/s,64 客戶端
Kev-0.8B L4 (0.80) 22.7 / 16.1 ms 108.6 / 32.3 ms 62.8
Kev-4B L40S (1.95) 41.5 / 27.7 ms 145.2 / 43.0 ms 51.4
Kev-4B H100 (3.95) 18.1 / 12.9 ms 89.4 / 22.5 ms 100.8
Kev-9B L40S (1.95) 66.4 / 42.7 ms 235.6 / 57.5 ms 32.7
Kev-9B H100 (3.95) 24.0 / 16.6 ms 88.5 / 26.4 ms 79.5
Kev-27B B200 (6.25) 46.5 / 32.2 ms 178.0 / 52.1 ms 44.2
Kev-27B H200 (4.54) 67.2 / 50.0 ms 274.8 / 73.8 ms 28.6
Kev-27B H100 (3.95) 75.0 / 52.0 ms 277.5 / 79.3 ms 28.9

時間是每個請求的模型時間(API 返回的 latency_ms),20 次的中位數,分別為新文本 / 同一文本再來一次。伺服器快取文本,所以對已經發過的文件多問問題只為問題付費。每秒請求數是針對 64 個併發客戶端、各自發送關於一段新短文本的六個問題;伺服器把它們批處理。Kev-27B 的 B200 和 H100 行是在其上一版本上測的,相同架構以 bf16 服務(runs/fused-27b-*);H200 行是當前 checkpoint(runs/serving-27b-r23)。網路時間另算:經同一區域的 Modal web 端點,每個往返約 65 ms。

對 Kev-0.8B 來說 L4 足夠,但對 Kev-4B 太慢。A100 在這裡比 L40S 慢且更貴。Kev-9B 需要約 17 GB GPU 視訊記憶體,Kev-27B 需要 51 GB 權重(含批處理緩衝約 66 GB);負載下 Kev-27B 受算力限制,B200、H200 或 H100 每個請求成本差不多。在 CUDA 上,為 Qwen3.5 模型安裝 flash-linear-attention(kev_serve.py 和 Modal 映象已經這麼做)。

在 Apple Silicon 上,uv sync --extra serve 會安裝 MLX,伺服器自動使用它。在 M5(32 GB)上對一段約 270-token 文本問五個問題:

模型 新文本 同一文本再來一次
Kev-0.8B 149 ms 28 ms
Kev-4B 721 ms 136 ms

長文件以每次 1,024 tokens 讀入快取,所以記憶體貼近權重。對一份 65,000-token 文件,Kev-0.8B 首次要 21.2 s,之後 202 ms,峰值 3.8 GB,Kev-4B 是 84.5 s 和 716 ms,峰值 13.0 GB(runs/mlx-long-states;模型卡有每個長度)。Kev-9B 尚未用這種方式測量。

介面卡 checkpoint 在載入時被折進基座,會短暫持有第二份權重。像 Kev-27B 這樣的完整權重 checkpoint 按儲存的樣子載入,不合並任何東西,所以載入只需要權重。我們在寫出的完整 bf16 權重 Kev-4B 上驗證了這一點:8.4 GB 權重載入峰值 8.4 GB,而介面卡路徑是 15.9 GB。兩者的答案在持有相同 bf16 值後完全一致,並在 60 個問題上與 fp32 路徑保持在 0.015 以內(runs/mlx-full-4b)。Kev-27B 的權重是 51 GB。按同樣的測量它需要約 51 GB 加工作記憶體,所以 64 GB Mac 是邊界,96–128 GB Mac 應該能裝。我們還沒在那麼大的 Mac 上跑過它。Kev-27B 的第一個版本(一個介面卡)確實在一臺 128 GB M5 Max 上這樣跑過,與已釋出的準確率一致(感謝 Sean Connelly,#175)。

伺服器在 GPU 和 Mac 上以 bf16 執行。它的機率與已釋出評測所用的 fp32 路徑相差至多約 0.03(GPU)和 0.05(Mac),最高答案大約每 300 個問題改變一個。設 KEV_DTYPE=fp32 走確切路徑。/v1/models 報告所用的後端和精度。uv run modal run modal_app.py::serving --run jaredpalmer/kev-4b --gpu L40S --name <name> 在你自己的賬號上測表中的一行(上面各行:runs/serve-*、runs/grouping-4b-h100、runs/fused-27b-*、runs/serving-27b-r23)。

Limitations

  • 校準只有一個溫度。它無法重排置信度順序,所以在 5% 誤差預算下你能自動化的新來源決策比例(Kev-4B、9B 和 27B 為 0.52–0.69)仍低於 Jev 的 0.70。在依賴某個機率閾值之前,先在你自己的資料上測試它。
  • 知識問題由基座模型決定。MMLU 上 Kev-9B 是 0.73,對 Jev 的 0.90,MMLU-Pro 是 0.59 對 0.84。
  • 微調可能讓基座模型在個別任務上變差。日期算術是最清楚的一例(issue #8);在陳述的天數計數上訓練加 KEV_DATE_FACTS=1 能恢復它。
  • 改動選項順序可能改變答案。問題隔離並不能阻止這一點。
  • Kev-0.8B、4B 和 9B 主要訓練時最多 384 個 state token,state 加一個問題最多 1,024 tokens(其文件和技能微調到最多 7,552 tokens 的 state),Kev-27B 訓練到最多 32,768 tokens。服務允許 65,536-token 的 state;每個模型的已驗證上下文長度在 Models 裡。
  • 在 Mac 上,答案要幾百毫秒,不是幾十毫秒。Kev-27B 需要一張 80 GB GPU。在 Mac 上它需要約 51 GB 加工作記憶體;我們預計 96–128 GB Mac 裝得下,但尚未測量。
  • Kev-27B 從一個訓練資料不為我們所知的後訓練模型出發。

Development

uv run --extra serve python -m pytest tests/test_unit.py tests/test_research.py tests/test_generators.py tests/test_conventions.py \
    tests/test_documents_tools.py tests/test_hard_v1.py tests/test_devtools_v1.py tests/test_breadth_v1.py tests/test_rounds.py tests/test_skill_scripts.py -q   # no weights, no server; what CI runs
KEV_BASE_URL=http://127.0.0.1:8009 uv run --extra serve python -m pytest tests/test_api.py -q   # against a running server
cd playground && npm run lint && npx next typegen && npx tsc --noEmit -p .

API 測試對你的本地伺服器跑 TypeSafe 的示例請求和官方 SDK。PLAN.md 是研究計劃:我們學到了什麼、每個實驗遵循的規則,以及每輪一行。完整日誌(每個實驗、執行前設定的判據、以及結果如何)在 git tag research-archive-2026-09-24。

Previous generation (Qwen3) and the prototype

第一個 Kev 家族使用 Qwen3 基座,資料和設定相同。那些權重仍然釋出,能在 Mac 上用普通 PyTorch 跑,但不再繼續開發。

模型 基座 準確率:已訓練來源 準確率:新來源 Brier:新來源 模型卡
Kev-0.6B (Qwen3) — jaredpalmer/kev-0.6b Qwen3-0.6B-Base 0.801 / 0.808 0.620 / 0.642 0.536 / 0.483 詳情
Kev-4B (Qwen3) — jaredpalmer/kev-4b@qwen3 Qwen3-4B-Base 0.854 / 0.856 0.790 / 0.806 0.328 / 0.294 詳情
Kev-8B (Qwen3) — jaredpalmer/kev-8b Qwen3-8B-Base 0.863 / 0.870 0.796 / 0.780 0.337 / 0.327 詳情

最初的 Kev-0.5B 使用 Qwen2.5-0.5B,作為參考保留;見它的模型卡。

Troubleshooting
  • 如果訓練時 MPS 視訊記憶體不足,檢查你是否只跑了一個任務。不要啟用 output_hidden_states,也不要用 peft 的 trainable_token_indices 新增 tokens;兩者在這裡都造成過記憶體問題。
  • 如果 playground 能載入但按鈕不工作,使用 localhost:3001。Next.js 會檢查開發主機名。其他主機需要在 playground/next.config.ts 的 allowedDevOrigins 里加一條。
  • 如果資料集載入報告 Dataset scripts are no longer supported,改用 legacy-datasets/banking77。本倉庫已經在用它。

Authors

用 Devin 構建。感謝 Archer Hume 的架構文章、TypeSafe 的 API 設計,以及 Qwen 的基座模型。

相關工作:Hydragen、DeFT、FIRST。

License

Apache-2.0。Qwen3、Qwen3.5 和 Qwen3.8 基座模型也是 Apache-2.0。訓練資料集各有自己的許可證;見模型卡。