MarkTechPost ★ 89 7 min

A Developer’s Guide to Laya: Zero-Shot Decisions and Calibration

Language ModelLarge Language ModelMachine LearningTutorials

🔗 https://www.marktechpost.com/2026/10/06/a-developers-guide-to-laya-zero-shot-decisions-and-calibration/

📌 實測開源決策引擎 Laya:零樣本準確率、校準與棄答門檻全解析

TL;DR:421M 參數、零輸出 token 的開源決策模型 Laya,在真實資料上零樣本準確率達 0.804,但校準與棄答門檻藏著不少坑。

🎣 一個模型如果連一個字都不產生,要怎麼回答問題?MarkTechPost 的這篇開發者教學,拿九月最多星星的開源機器學習專案之一 Laya,實際跑在有標準答案的資料上,結果發現:零樣本表現亮眼,但「模型講的信心」和「模型真的對不對」之間,有一段需要親手校準的落差。

🤔 Laya 是什麼:不產生文字的「System 1」決策引擎

Laya 是 Convai Innovations 開發的開源決策引擎,定位是非自迴歸(non-autoregressive)的「System 1」模型:一個 4.21 億參數的 encoder,輸入一段文字加上一組有型別的問題(choice 選項、score 分數、yes/no 是否題),單次前向傳播(forward pass)直接回傳每個選項的機率,全程零輸出 token。文中將它定位為 TypeSafe 的 Jev 的開源對照版本,賣點是速度與「校準過的機率」。

🧩 安裝、推理成本與型別化輸出

教學使用釋出版本 laya 0.3.27,載入英文 checkpoint。為了確保可重現性,作者固定了 checkpoint 版本(透過 laya.PINNED_REVISIONS),並在 CUDA 上關閉 Laya 預設的半精度 autocast,讓所有裝置都用 fp32 跑,使 GPU 結果能對齊 CPU 數字。

一次呼叫 predict 可以同時回答多個型別化問題(例如一張工單的部門分類、0 到 2 的緊急程度評分、是否流失風險的 yes/no),每個答案都附帶 answer_confidence(該答案的機率,後續校準與棄答判斷都用這個值)和 confidence(正規化熵的反向指標,尺度會隨選項數改變,容易與 answer_confidence 混淆)。

值得注意的是,作者印出 checkpoint 內建的溫度參數時就發現一個瑕疵:11 個以上選項的 choice 問題,溫度被設成 0.10,超出合理範圍,載入器會自動 clamp 到 0.5 並跳出警告,否則過低的溫度會讓模型對多選項問題「看起來」比實際更篤定。

另外,成本實測也給出一條設計準則:每個 yes/no 問題各自佔一列(row),16 個 yes/no 問題的成本約是 1 個的 8 倍;而一個 choice 問題無論選項多寡只佔一列,40 個選項的 choice 問題成本只比 3 個選項略高,遠低於 16 個 yes/no 問題。結論是:應該設計成「一個多選項的 choice 問題」,而不是「一堆 yes/no 問題」。

📊 CLINC150 銀行領域實測:零樣本 vs. 需標註資料的傳統分類器

作者用 CLINC150 意圖分類基準的銀行領域(15 個意圖,每類 100 筆訓練、20 筆驗證、30 筆測試)做 450 筆測試查詢的零樣本路由,並與 TF-IDF + 邏輯迴歸分類器做對照:

方法所需標註準確率
Laya 零樣本(含描述)00.804
Laya 零樣本(僅意圖名稱)00.878
TF-IDF + 邏輯迴歸每類 3 筆0.651
TF-IDF + 邏輯迴歸每類 10 筆0.848
TF-IDF + 邏輯迴歸每類 30 筆0.904

有趣的是,拿掉自訂的一行描述、只給 15 個意圖的「裸名稱」,準確率反而從 0.804 升到 0.878,耗時也減半(因為選項 token 變少);描述反而模糊了某些意圖之間的界線,例如 account_blocked 有十次被誤判為 freeze_account。另外,把選項順序反過來,雖然整體準確率幾乎不變,卻讓 4.2% 的個別答案改變,顯示存在「位置偏好」(position prior),提醒部署時的選項順序應該就是測試時用的順序。

💡 校準與棄答門檻:驗證集調好的參數,不保證測試集好用

15 個選項的 choice 問題落在那個被 clamp 成 0.5 的溫度桶裡。在 450 筆測試查詢上,92% 的答案宣稱信心 ≥ 0.9,其中 91.1% 真的答對,平均信心 0.974 遠高於實際準確率 0.878,期望校準誤差(ECE)高達 0.102。

作者用 300 筆驗證集紀錄呼叫 agent.fit_temperatures,擬合出該選項桶的溫度 1.258,ECE 降到 0.059,準確率不變(因為溫度調整不會改變哪個選項勝出)。但這裡有個陷阱:一次擬合會把整張溫度表全部覆寫,包括把沒有資料的 score 與 yes/no 溫度重設回 1.0,因此作者選擇只替換自己量測過的那個桶,其餘沿用原廠設定。

棄答門檻(abstention threshold)也有類似的落差:用 fit_abstention_thresholds 針對 5% 誤差目標,在驗證集上找到信心門檻 0.602,驗證集上確實維持 95.7% 保留率、4.5% 誤差;但套到測試集,保留率降到 92.2%、誤差卻升到 9.2%,幾乎是目標的兩倍(2% 目標的實際誤差更到 5.3%)。原因是 Laya 在驗證集上的正確率是 92.7%,測試集卻只有 87.8%,說明誤差預算一旦用某一批資料擬合,只在「長得很像」的流量上才成立,門檻需要保留餘裕並定期用真實流量重新擬合。

對於分布外(out-of-scope)流量,作者加入 150 筆 OOS 查詢與 150 筆其他領域查詢,銀行領域查詢平均信心 0.912,其他則約 0.25,5% 門檻可攔下 89.3% 的跨領域查詢與 93.3% 的 OOS 查詢(代價是誤棄 7.8% 的真實銀行查詢)。另一個不需要標註資料的替代方案,是直接加一個「不是銀行請求」的第 16 個選項,可攔下 80.0% 與 90.0% 的異常流量,但會讓 2.0% 的正常銀行查詢被誤導、銀行領域準確率從 0.878 降到 0.864,因為新選項改變了每個意圖的評分基準。

⚠️ 限制:校準與門檻都不是「調一次就一勞永逸」

整篇實測下來最值得留意的限制是:溫度擬合會覆寫整張表、必須手動挑著還原;棄答的誤差預算在驗證集與測試集之間有明顯落差,代表上線後需要用真實流量定期重新擬合;而且門檻是按「選項數量」分桶存在,兩個選項與十五個選項不能共用同一個數字。

🎯 實務啟示

把 Laya 這類零樣本決策模型放進 production router 之前,至少要做三件事:用自己的標註資料實測零樣本準確率(不要照單全收 README 的宣稱)、針對實際會用到的選項數量分別做溫度與棄答門檻校準、並且替分布外流量準備額外的「不適用」選項或監控機制,而不是假設校準過的信心分數可以直接拿來當作上線的誤差保證。

🔗 來源

#Laya #ZeroShotLearning #ModelCalibration #IntentClassification #OpenSourceAI #MachineLearning #AIEngineering #CLINC150 #DecisionEngine #MLOps

原始資料 MarkTechPost · 收集於 2026-10-07
來源原標題
A Developer’s Guide to Laya: Zero-Shot Decisions and Calibration
作者
Sana Hassan
原始標籤
Artificial Intelligence · Editors Pick · Language Model · Large Language Model · Machine Learning · Staff · Tech News · Technology · Tutorials
原始連結
https://www.marktechpost.com/2026/10/06/a-developers-guide-to-laya-zero-shot-decisions-and-calibration/

摘要原文

In this tutorial, we work with Laya , the open-source decision engine from Convai Innovations that became one of the most-starred machine-learning repositories of September 2026. Laya is a non-autoregressive System 1 model: instead of generating text, a 421-million-parameter encoder reads a piece of text and a set of typed questions, a choice between labels, a score on a scale, or a yes/no, and returns a probability for every option in a single forward pass with zero output tokens. Its pitch is speed and calibrated probabilities, the open answer to TypeSafe’s Jev. Rather than repeat the README’s examples, we put those promises to work on real labelled data with known answers, the banking domain of the CLINC150 intent dataset, and measure what a production router actually gets: zero-shot accuracy against a trained classifier, how much the wording and order of the options matter, how honest the shipped probabilities are, what fitting a temperature on validation data fixes and what it quietly breaks, an abstention gate fitted to an error budget, out-of-scope traffic, a yes/no question that temperature cannot repair, and typed outputs from a pydantic schema. We install the released package, laya 0.3.27, and load the English checkpoint. Two choices here keep the run reproducible. By default laya.load follows the Hugging Face main branch, so we pin the revision the library’s own authors reviewed, which it exposes as laya.PINNED_REVISIONS. And on CUDA Laya autocasts to half precision, so we switch that off to keep every device in fp32 and let a GPU run reproduce the CPU numbers shown here. Printing the checkpoint’s shipped temperatures turns up the first finding before any prediction: the entry for choice questions with eleven or more options is 0.10, outside the valid range, so the loader clamps it to 0.5 and warns. A temperature below one sharpens probabilities, so every answer to a question with that many options will look twice as certain as the raw model is. One call to predict answers three typed questions about a support ticket in a single forward pass: the department as a choice, the urgency as a score from 0 to 2, and the churn risk as a yes/no. The result carries a probability for every option and two confidence fields that are easy to confuse. answer_confidence is the probability of the reported answer, and it is the quantity that calibration, the abstention gate and every metric later in this tutorial use. confidence is one minus the normalized entropy, whose scale depends on how many options a question has. The usage block shows zero output tokens, because Laya scores the options it is given and never generates text. Before building on Laya, we measure the cost of a forward pass on a single message. Each question becomes its own row, paired with the message, so sixteen yes/no questions take about eight times as long as one. All the options of a choice question share one row and its head budget, so a forty-option choice costs barely twice a three-option one and a quarter of what sixteen yes/no questions do on our CPU. That gives a design rule that shapes everything after it: ask one choice question with many options rather than many yes/no questions. For real labeled data, we use CLINC150, a public intent-classification benchmark of 150 intents across ten domains plus a set of out-of-scope queries, read straight from the Hugging Face Hub as a parquet file. We take its banking domain, fifteen intents with 100 training, 20 validation, and 30 test queries each, and ask Laya to route the 450 test queries zero-shot, giving it each intent’s name and a one-line description of the kind a developer would write. It reaches 0.804 accuracy with no labeled examples. For scale, a TF-IDF and logistic-regression classifier reaches 0.651 with three labeled queries per intent, 0.848 with ten, and 0.904 with thirty. Next we change only the wording of the options. Giving Laya the fifteen bare intent names, without our descriptions, lifts accuracy from 0.804 to 0.878 and halves the time, because the options take less than half the tokens. The descriptions blurred intents the names keep apart: account_blocked was routed to freeze_account ten times, and interest rate questions to balance. Reversing the order of the bare names changes 4.2 percent of individual answers even though overall accuracy barely moves, a sign of a position prior, so the option order you deploy should be the order you tested. Only labeled data could tell us either thing; from here on we route on the bare names. We then ask how honest the probabilities are. A fifteen-option question falls into the checkpoint’s choice:11+ temperature bucket, the one clamped to 0.5. The reliability table on the 450 test queries shows the result: 92 percent of answers claim a confidence of at least 0.9, but 91.1 percent of those are right, and the mean confidence of 0.974 sits well above the accuracy of 0.878, an expected calibration error of 0.102. Laya’s training objective uses proper scoring rules, which is what the model card means by calibrated. Still, calibration is a property of a question on a distribution, and you have to measure it on your own labels. Laya’s calibration module turns labeled examples into records of raw logits and targets, and fits a temperature to them. We build 300 records from the validation split and call agent.fit_temperatures, which fits a choice temperature of 1.258 and installs it, then prints the full temperature table next to what shipped. The fit replaced the entire map: every per-option-count entry is gone, because a bucket needs 2,000 records to keep its own temperature, and the score and yes/no temperatures were reset to 1.0 because there were no records of those types. One fit on a choice question silently changed how every yes/no question in the agent is calibrated. So we restore the shipped values and install only the bucket we measured. On the test set, calibration error falls from 0.102 to 0.059 with accuracy unchanged, since temperature never changes which option wins, and save_calibration writes the result to a JSON file that laya.load can read back. laya.fit_abstention_thresholds takes the same validation records and, for each option-count bucket, returns the loosest confidence cut that keeps the validation error within a target. For a 5 percent target, it picks 0.602, which keeps 95.7 percent of the validation queries at 4.5 percent error, and Laya applies the same cut itself when it is passed to predict_batch as min_confidence, marking 35 of the 450 test answers as abstained. On the test set, though, that gate keeps 92.2 percent of the queries at 9.2 percent error, nearly twice the budget, and the 2 percent target realizes 5.3 percent. The data explains it: Laya is right on 92.7 percent of the validation queries but only 87.8 percent of the test queries, so an error budget fitted on one sample holds only for traffic that looks like it. The ranking itself is sound, with the most confident half of the test answers 97.8 percent correct, but an error target needs margin and periodic re-fitting on real traffic. The thresholds stay per option-count bucket because one number doesn’t transfer between a two-way and a fifteen-way question. Production traffic includes requests the router was never built for, so we add 150 out-of-scope CLINC queries and 150 queries from other CLINC domains. The calibrated confidence separates them sharply: banking queries average 0.912, the others about 0.25, and the 5 percent gate stops 89.3 percent of other-domain queries and 93.3 percent of out-of-scope ones while abstaining on 7.8 percent of banking queries. The alternative needs no labeled data: a sixteenth option, not a banking request, catches 80.0 and 90.0 percent of them, at the cost of routing 2.0 percent of banking queries away and lowering banking accuracy from 0.878 to 0.864, because the new option changes what every intent is scored against.

由 claude-code/sonnet 自動生成