
Day 9 寫 vLLM 那天,Ornith 1.5 這個模型剛出爐,我在時事插播裡開了一張「完整實測排進第三週」的支票,今天來實現承諾吧。
先把它放進本系列這幾天建立的地端模型光譜。Day 14 測了兩個極端,密集模型 Qwen 3.8 27B 是「參數全上、頻寬付全額」的老實人,Qwen 3.8 Flash-Next 則是 125B 總參數卻推論時只啟用 6B 的極端稀疏派。Ornith 1.5 35B-A3B 站在中間偏稀疏的位置,35B 總參數、每 token 啟用 3B,BF16 權重檔案約 72 GB ,這台 GB10 單機放得下,具備原生 262K 上下文規格,該公司也同步供應官方版 NVFP4 權重。
Ornith 1.5 跟前兩個最大的不同在出身,這是一個明確就是「為 AI agent 而生」的模型,工具呼叫與多步任務是它擅長的部分,正好我們手上有一份現成的測試可讓它跑一遍看看。
今天主要針對 Ornith 1.5 的部署與速度、測驗題、長上下文、以及 AI agent 三部曲前的定位做實測。
部署走 vLLM,社群為 Spark 整理的 recipe 已經相當成熟(Day 9 提過),參數哲學跟本系列一路採用的一致,保守的 gpu-memory-utilization、fp8 KV、prefix caching 全開。
docker run -d --gpus all --ipc=host --shm-size 16g \
-p 127.0.0.1:8010:8000 \
-v /mnt/nas/AIModels/vllm:/models:ro \
vllm/vllm-openai:muse-glimmer \
--model /models/Ornith-1.5-35B-A3B \
--served-model-name ornith-bf16 \
--max-model-len 262144 \
--gpu-memory-utilization 0.85 \
--kv-cache-dtype fp8_e4m3 \
--enable-prefix-caching --trust-remote-code \
--enable-auto-tool-choice --tool-call-parser qwen3_xml \
--reasoning-parser qwen3 \
--port 8000
窗直接開原生 262144,這在地端 AI 給 AI 代理人跑的話是比較夠用的,要講清楚一件常被誤會的事,vLLM 的 KV 池是「權重之外剩下的」,把窗開大不會多吃記憶體,只要池子裝得下一條最長的序列就行。開 65536 跟開 262144 佔用完全一樣,差別只在你能不能真的送一份 121K 的文件進去,所以能夠開 262K 上下文的規格就值得開。
載入 319 秒(權重)、從啟動到 Starting vLLM server 共約 7 分 50 秒,權重 70.4 GB,decode 中系統記憶體峰值 120.7 GB(本機可用約 130.6 GB)。128GB 統一記憶體機種的優點在它身上再次展項,BF16 全精度直接跑,不必先遷就於量化的品質下降,NVFP4 版呢,則是留給速度需求出現時再上。當初留了退路的三個旗標實測都不必動用,fp8 KV 這個混合式模型吃得下,prefix caching 由 vLLM 自行處理,GDN 走 Triton/FLA 正規 kernel 而非 fallback。
速度用 Day 14 校正過的 MoE 公式算天花板,分母取每 token 實際讀取量。
| 配方 | 每 token 讀取 | 理論上限 | 實測 decode | 達成率 |
|---|---|---|---|---|
| BF16(檔案 71.9 GB) | 5.89 GB | 46.33 t/s | 29.92 t/s | 64.6% |
| NVFP4 官方(檔案 23.4 GB) | 2.255 GB | 121.08 t/s | 77.52 t/s | 64.0% |
每 token 讀取量照 Day 14 的張量表加總法逐項算出,safetensors 的檔頭本身就帶著每個張量的 dtype 與 shape,標準庫就能加總。
路由專家張量 64.42 GB,256 選 8,每 token 只讀 8/256 = 2.01 GB
共用專家 0.25 GB,每 token 全讀
其餘本體 2.61 GB,每 token 全讀(注意力、GDN、router、norm)
lm_head 1.02 GB,每 token 全讀
embed_tokens 1.02 GB,查表,每 token 只讀一列 4 KB
視覺塔 0.89 GB,純文字 decode 不讀
MTP 草稿層 1.69 GB,未開投機解碼,不讀
每 token 讀取 = 5.89 GB
這裡有兩個先前的粗估要修正。 BF16 我原本估「約 6 GB」,精確值 5.89 GB,估得不錯。NVFP4 我原本估「約 1.7 GB、上限 160 t/s」,精確值 2.255 GB、上限 121 t/s,差了三成。原因很具體,embed_tokens 與視覺塔在 NVFP4 檢查點裡沒有被量化,一個位元組都沒省,而 lm_head 與 NVFP4 的 block scale 也都要算進去。權重壓到 4 bit,不代表每一個參數軸都跟著壓。
這邊也說明一下視覺塔(Vision Tower)是做什麼的 ? 它是多模態 AI 或視覺語言模型中的視覺編碼器,工作是接收圖片並將其壓縮和轉譯成能與和文字對齊的中間特徵向量,這樣 AI 才能夠去推論計算出結果給你。
「排除視覺塔與 MTP」這個部分,由於它是帶視覺塔的多模態模型,也焊了一層 MTP,但純文字 decode 又沒開投機解碼時,這 2.6 GB 會躺著不動。天花板的分母只算這一次推論真的會掃過的位元組,檔案裡躺著不動的部分不計。
Day 14 學到 MoE 的達成率會低於密集模型(跳著讀專家小矩陣有存取效率成本),這兩列是驗證那個結論的新資料點,而且結果比預期乾淨。64.6% 與 64.0%,兩檔幾乎一樣。 我原本猜 NVFP4 的達成率會明顯更低,好用來展示「越壓縮存取效率傷越重」。猜錯了。 達成率跟壓縮程度無關,它來自 MoE 存取形態本身的成本。每層要從 256 個專家裡挑 8 個,跳著讀小矩陣,這個代價按比例支付成本,不隨著精度變化。故兩檔都低於 Day 14 密集模型的 77% 到 93% 區間,跟 Flash-Next 的 67% 是同一個等級。
prefill 部分,pp2048 3,166 t/s、pp8192 3,346 t/s(NVFP4 是 4,377 與 5,895)。社群跑分的參考值是 pp2048 超過 3,000 t/s、生成穩定在 31 t/s 附近,我這次的測試成績,測到 3,166 與 29.92,兩項都對得上。
Day 14 之後,這份測驗題已經整理成公開 repo(github.com/ivanusto/llm-zhtw-agent-exam),任何 OpenAI 相容端點都能考。Ornith 是第四位考生,而且是四位裡唯一一個掛著「agent 專用」招牌來的,成績究竟如何呢?
跑之前先踩到一個地雷得先說一下。
考卷前四項用 temperature=0,理由寫在 repo 的 README 裡,判準是二元通過制,要的是可重現。這個前提在 vLLM 上不成立。 同一題、同一個端點、同樣 temperature=0,連跑六次得到六種不同的輸出,長度從 238 到 336 字元。連續批次會改變批次組成,MoE 的路由與 kernel 的歸約順序跟著變,邊際 token 就翻面。

所以這一輪 Ornith 兩檔的前四項都跑四輪,報中位數與全距。
| Ornith BF16(四輪) | Ornith NVFP4(四輪) | |
|---|---|---|
| 繁中十題 | 20, 20, 20, 20 | 19, 19, 20, 19 |
| 簡體字洩漏 | 0, 0, 0, 0 | 1, 1, 0, 2 |
NVFP4 掉的那一分在四輪裡出現三次,可以排除抽樣運氣。 這也是這份考卷第一次分出高下,前三位考生全部滿分。
要確認差異是不是因為量化,我比對了兩份檢查點除權重以外的所有檔案,chat template、tokenizer、generation_config 全部逐位元相同。同一個模型、同一份提示詞、同一套測量方式,當權重從 BF16 壓到 NVFP4,繁中就開始漏簡體字。這重現了 Day 12 與 Day 14 那條「量化對繁中的傷害大於英文」的規律,而且這次量到的是正確率,比 PPL 更直接。
| Ornith BF16 | Ornith NVFP4 | Flash-Next IQ4_XS | pplx 後訓練 | 27B 原版 FP8 | |
|---|---|---|---|---|---|
| 繁中十題 | 20 / 20 | 19 / 20 | 20 / 20 | 20 / 20 | 20 / 20 |
| 簡體字洩漏 | 0 | 1 | 0 | 0 | 0 |
| 工具呼叫十輪 | 10 / 10 | 10 / 10 | 10 / 10 | 10 / 10 | 10 / 10 |
| 多步 agent 三題 | 3 / 3 | 3 / 3 | 3 / 3 | 3 / 3 | 3 / 3 |
| JSON 緊湊度(多行 / 50,越少越好) | 24 / 50 | 40 / 50 | 24 / 50 | 0 / 50 | 0 / 50 |
| 平均輸出長度 | 60 字元 | 63 | 59 | 51 | 51 |
前四項是這份測試的基本,沒有通過的話,繁體中文環境就會不好用,而真正的鑑別題是 JSON 緊湊度。
Ornith 沒有逼近 0。 24/50,跟 Flash-Next 打成平手,輸給兩個 27B 的掛零。這個明著為 agent 而生的模型,在「不多話」這件事被 27B 模型打敗。Day 14 的結論在這裡又被佐證一次,agentic 能力與 agentic 禮儀是兩件事。
而且量化讓它更糟,NVFP4 從 24/50 升到 40/50。同一個模型,壓到 4 bit 之後繁中與格式紀律一起退。 這是今天最實用的一個紀錄,如果你要拿它跑 agent 迴圈,NVFP4 那兩倍的速度有代價,而代價出在每一輪要多付的 token 數,所以最前面我才說如果要常駐,這台機器上可以用 BF16 版的,如果你有雙機,效率也可以改善。
這一列我做了 Day 14 沒做的事,五欄全部用同一組取樣(temp 0.7 / top_p 0.80)、各跑 5×10 = 50 輪。理由是 Day 14 自己記下的缺陷,當時只有 Flash-Next 那一欄留了取樣設定。
補跑之後,Day 14 那一列有兩欄重現不出來。
| Day 14 記錄 | 本輪 50 輪 | |
|---|---|---|
| pplx 後訓練 | 0 / 10 | 0 / 50 ✅ |
| 原版 27B FP8 | 7 / 10 | 0 / 50 ❌ |
| Flash-Next | 8 / 10 | 24 / 50(48%) ❌ |
原版 27B 那一欄我另外排除了兩個變因,思考模式開與關都是 0/10,取樣拉到 temp 1.0 / top_p 1.0 也只到 1/10。沒有任何一組設定能重現那個 7。
還有一件事值得記,十輪對這一題根本不夠。實測每十輪的散布,Ornith BF16 是 2 到 7、NVFP4 是 6 到 10。十輪分得開 0 與 5,分不開 5 與 7。 所以這一列改成 50 輪並記錄全距。
受影響的是 Day 14 第五關的結論。 當時我把 0 對 7 的差距歸給「後訓練買到的格式紀律」。現在兩個 27B 都是 0/50,這個紀律屬於 27B 這一家的基底,與後訓練無關。後訓練值不值得做是另一個問題,但我當初拿來支持它的那個證據已經不成立。
Day 14 提供的經驗是測試腳本比模型更需要被檢查,今天的經驗,多了這件事,沒有記錄取樣設定的成績,等於沒有測試到。
Day 14 發現有模型思考時用簡體、答案切回繁體,Ornith 這方面行為乾淨。掛 --reasoning-parser qwen3 之後思考內容落在 reasoning 欄位(注意欄位名與 model card 寫的 reasoning_content 不同),不會汙染 content。考卷腳本送的 enable_thinking: false 它也吃得下,不像 Flash-Next 要在伺服器層級另外關。
KV 的用量,可以從 vLLM 啟動日誌反推。
| 配方 | KV 池 | 可容納 token | 每 token 成本 |
|---|---|---|---|
| BF16 | 36.3 GB | 3,358,223 | 10.56 KB |
| NVFP4 | 82.1 GB | 7,598,204 | 10.56 KB |
(兩檔的每 token 成本一樣,池子大小卻差一倍多,原因很單純,NVFP4 的權重小了 48 GB,同一個 0.85 的分配邏輯下,省下來的空間全數進了 KV 池。)
翻 config 可發現是對得上的,40 層裡只有 10 層是完整注意力(full_attention_interval: 4),其餘 30 層是 GDN 線性注意力,而且 KV head 只有 2 個。
10 層完整注意力 × 2(K 與 V)× 2 個 KV head × 256 dim × 1 byte(FP8 KV)= 10.0 KB
實測每個 token 10.56 KB,差額是 30 層 GDN 的固定狀態與 vLLM 的層對齊 padding。
放進 Day 11 開始累積的那張跨模型成本表,這是目前最便宜的一個,難怪很多人拿它當代理人覺得好用。
| 模型 | 每 token KV | 注意力設計 |
|---|---|---|
| Qwen3.8-27B | 34.5 KB(fp8) | 64 層裡 16 層完整、head_dim 256、4 KV head |
| Qwen3.8-Flash-Next | 33 KB(f16) | 12 層完整 24 KB + QSA 索引快取 9 KB |
| Ornith 1.5 35B-A3B | 10.56 KB(fp8) | 40 層裡 10 層完整、2 KV head |
它的長窗成本只有另外兩個的三分之一。 這就是為什麼它敢開 262K 而且滿窗還有 12.81 倍的平行處理餘裕,36.3 GB 的 KV 裝得下 335 萬個 token。
深度實測,同一份長文四檔。
| 提示長度 | TTFT | prefill | 後續 decode |
|---|---|---|---|
| 7,874 | 2.73 s | 2,889 t/s | 30.01 t/s |
| 33,119 | 12.87 s | 2,573 t/s | 28.76 t/s |
| 64,889 | 28.39 s | 2,286 t/s | 27.89 t/s |
| 121,405 | 63.65 s | 1,908 t/s | 26.18 t/s |
社群跑分說它長上下文堆到 32K 深度時生成僅小幅下滑,我們把深度拉到 121K。
decode 從 8K 到 121K 只掉 12.8%,對照 27B 的 15.5% 與 Flash-Next 的 54.4%。prefill 掉 34.0%,對照 27B 的 35.9% 與 Flash-Next 的 63.1%。

三個模型三種注意力設計,這一節的重點就是這張衰減對照。Ornith 兩件事都贏,絕對值全程領先,衰減也比 27B 平。30 層線性加 10 層完整這個 3:1 比例,跟 27B 的 48:16 比例相同,多拿到的是更少的 KV head 與更少的完整層總數。Qwen 3.8 Flash-Next 的 QSA 稀疏路線在這台機器、這個實作上,衰減是三者裡最陡的。
必須揭露一個混淆項,Flash-Next 走 llama.cpp 加 IQ4_XS,另外兩個走 vLLM。引擎與量化都不同,衰減比例仍然可比(各自跟自己的 8K 比),但是絕對值不能直接對。
埋針測試的三個位置照前例,在 121,472 token 的文件裡開頭(VIOLET-7734)、中段(The 19th of November)、尾端(A double espresso with exactly two sugar cubes)三比三全中。同樣的保留仍然適用,單針測試通不過代表有問題,通過了不代表沒問題。
接下來的文章還會有 agent 三部曲(框架總覽、DeepSeek Harness 實戰、herdr 指揮中心),三部曲需要一個地端主力模型。
| 候選 | 優勢 | 顧慮 |
|---|---|---|
| Ornith 35B-A3B | agent 出身、decode 29.92 t/s、KV 只要 10.56 KB/token、長上下文衰減最平、BF16 放得下 | JSON 緊湊度 24/50,禮儀不如兩個 27B。BF16 吃掉約 121 GB,同時跑別的服務很緊 |
| 27B(pplx 混合) | JSON 緊湊度 0/50 滿分、出廠配草稿模型 | decode 靠投機解碼撐、繁中思考混簡體 |
| Flash-Next | 官方 agentic 基準最強 | 吃掉四分之三記憶體、JSON 緊湊度 24/50、引擎支援未合併、長上下文衰減 54% |
| gpt-oss-120b | 生態最成熟、MoE decode 快 | 未考 |
我的試鏡標準很務實。agent 迴圈一天打幾百輪工具呼叫,decode 速度、JSON 守規矩程度、以及跑著 agent 還能留多少記憶體給別的服務,三項都及格才配當常駐主力。
今天測完,我的答案是 Ornith BF16 當主力,但要接受它的話比較多。我自己用 Hermes Agents 來搭配它使用時,它真的回話頻率比其他模型要多,會想把它多話的部分限制調。
上面的測試表格成績中,三項裡它贏兩項半。decode 29.92 對 27B(未開投機解碼)的 10.66,將近三倍,KV 成本是三分之一(在 agent 迴圈裡,這個成績代表的是更長的對話歷史),長上下文衰減最平。
要公平的話可以在補充一下,pplx 那個開起 DFlash2 投機解碼後有 25 t/s 上下的實力,屆時差距會縮到兩成,投機解碼在我自己堆疊上的復現留給後面的篇章。
上面提到輸掉的格式紀律呢,這部分有解,AI agent 框架本來就會做 schema 驗證與重試,多行 JSON 一樣 parse 得動,只是多付的成本是 token。反過來說,NVFP4 那一款模型我就不會拿來跑 AI agent,兩倍速度換來繁中掉分加 80% 多行輸出,在一天幾百輪的迴圈裡,這個會划不來。

記憶體一直都是 AI 模型的最重要問題,BF16 峰值 120.7 GB,開著就別想同時跑別的東西。這跟 Flash-Next 的顧慮是同樣的,只是程度輕一些。
順帶埋一個伏筆,這個模型我其實跑過雙機叢集(Day 9 文章中,為了騰記憶體停掉的那組就是它),兩台 Spark 走 100GbE 直連合跑的完整故事,留給之後文章的雙機合體篇。今天這篇的數字全部是單機,之後可以再對照。
模型實測週告一段落,手上已經累積四個模型、三種注意力設計、五級量化的完整資料。明天 Day 16 把這一切收斂成方法論,包括模型選型的判斷框架,以及 地端模型的其他眉角,依任務挑模型,排行榜只當參考,並包括哪些模型該住本機 SSD、哪些可以住 NAS 的儲存分配原則。
我們 Day 16 見。
本篇所有數字為本機實測,DGX Spark GB10、標示 128GB 統一記憶體、273 GB/s 規格頻寬。本篇容量單位統一為十進位 GB(1 GB 為 10 的 9 次方位元組),vLLM 與 nvidia-smi 日誌的原始輸出為 GiB,已按 1.0737 換算,機器標示的 128GB 實為 128 GiB,換算 137.4 GB,扣除系統保留後本機可用約 130.6 GB。KV 每 token 成本為池子位元組直除 token 數,與 Day 14 同基準以保可比。速度用 bench-decode.py(分母取伺服器回報的 usage.completion_tokens,提示詞帶奈秒前綴打掉 prefix cache),長上下文用 bench-longctx.py(四檔深度用伺服器自己的 /tokenize 收斂到目標的 2% 以內,後續 decode 排除 prefill 視窗),兩支都與 Day 14 逐行相同以保可比性。每 token 讀取量由 active-bytes-st.py 讀 safetensors 檔頭逐張量加總,分桶總和與檔案實際大小的誤差 0.0003%(BF16)與 0.055%(NVFP4)。考卷用這份公開 repo 的 exam.py 與 json-compact.py 執行。所有結果由 collect.py 從各工具的輸出彙整進 results/raw.json。
Day 1|為什麼 2026 年是地端 AI 部署元年:系列規劃與硬體總覽
Day 2|DGX Spark GB10 深度解析:128GB 統一記憶體到底解決了什麼問題
Day 3|網路與儲存規劃:10GbE 骨幹、雙 Spark 直連與 NFS 集中模型庫
Day 4|開箱之後:DGX OS 初始環境建置與 CUDA、Docker 生態確認
Day 5|NFS 模型庫實戰:下載工具、權限設計與版本管理
Day 6|llama.cpp、vLLM、TensorRT-LLM 、Ollama、DS4 與 Unsloth 的定位與取捨
Day 7|第一個模型上線:gpt-oss-120b 從模型庫到 API 的完整流程
Day 8|llama.cpp 實測:先定量尺與 SOP
Day 9|vLLM 實測:官方容器、同時處理吞吐曲線,與剛出爐的新模型 Ornith 1.5
Day 10|TensorRT-LLM 實測:我花了一個下午,跟它的預設值搏感情
Day 11|地端 AI 三大推論引擎綜合評測,同場加映神秘嘉賓
Day 12|量化格式解析:「4-bit」兩個字,古今多少事 ? 都付笑談中
Day 13|Perplexity 把整套 Agent 搬上 DGX Spark:地端元年的官方背書
Day 14|Qwen3.8-27B 與 Flash-Next 加碼實測:地端模型世代對決與落地評估
Day 15|Ornith 1.5 實測:為 AI agent 而生的 35B-A3B
Day 16|模型選型方法論:五個問題幫你跳脫排行榜迷失,找到適合自己任務用的 AI 模型