ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

38毫秒:Cloudflare 开源的 Clef 决策模型,本地 6GB 就能跑

38毫秒:Cloudflare 开源的 Clef 决策模型,本地 6GB 就能跑 让大模型做判断题它总想给你写小作文。Cloudflare 开源的 Clef 干脆不生成文字一次前向传播直接返回每个选项的概率。本文用 Clef-Flash Q4_K_M 量化版在本地跑了一遍还写了个 .NET 控制台来测它。1. 引言做 Agent 或者工作流开发时有一类需求出现频率极高让模型看一眼当前状态然后做个判断这条工单该分给哪个组这张发票是不是逾期了严重程度算几级这些事用普通大模型做总有点别扭。你想要的是一个答案它给你的是一段话。于是你要写提示词约束格式、让它输出 JSON、再写代码解析祈祷它别在 JSON 外面包一层好的我来分析一下。更要命的是你无法从一段文本里可靠地读出它有多确定。最近这个痛点催生了一个新物种决策模型decision model。Typesafe AI 的 Jev 提出了 System One 模型的概念。不做长链推理只做快速、结构化的直觉判断直接输出代码能消费的类型化结果。这个赛道最近相当热闹9 月底 StartLux原点星辉开源了 StartLux-Decision一口气放出 0.8B 到 27B 五档版本上海 AI 实验室也发布了 Intern-Decision。紧接着 Cloudflare 带着Clef入场Apache 2.0 协议开源目前在 Jev Decision Index 基准上排名第一。更关键的是配套生态的跟进速度llama.cpp 官方在三天内把 SystemOne 接口/v1/systemone做进了 llama-server。这套原本要调云端 API 的决策能力现在一条命令就能在本地跑还兼容 Jev 的客户端协议。这篇文章主要做三件事讲清楚 Clef 到底是什么、和传统 LLM 路线差在哪然后用 llama.cpp 在本地跑起来最后用一个 .NET 控制台程序实际测一测。2. Clef 是什么一个不会聊天的模型Clef 是 Cloudflare 首个自研并开源的决策模型系列一共两个模型基座定位ClefQwen3.8-27B LoRA高精度版Clef-flashQwen3.5-9B LoRA低延迟版中位延迟 38.8ms名字取得挺讲究clef谱号是五线谱开头定义整段音符音高的符号决策模型则是定义上下文的域以及随后的行动CF 又恰好是 Cloudflare 的缩写。它的工作方式和聊天模型完全不同。你给它两样东西一个状态state可以是文本、JSON甚至图片和视频和一组类型化问题typed questions。它一次前向传播返回每个问题每个选项的概率。没有自由文本生成也没有输出解析这回事。问题只有三种类型这就是从 Jev 沿袭下来的三种原语类型问的是什么返回choice从命名选项里选一个各选项概率 置信度score按有序等级打分如不紧急/本周/今天各等级概率 期望分数 置信度noul是非判断true/false为真的概率0~1看一个官方示例就明白了。给它一段客服场景描述同时问三个问题responsesystemone(model,processor,{model:clef,state:Our checkout started returning errors and orders are blocked.,questions:{department:{type:choice,criteria:{billing:Payments or invoices,technical:Bugs or outages},},urgency:{type:score,criteria:[Can wait,This week,Today]},outage:{type:noul,instructions:Is a service down?},},})返回的是按问题 ID 组织的结构化答案department 大概率是 technicalurgency 偏向 Todayoutage 为真的概率接近 1。代码拿到结果可以直接分支、排序、路由。这正是它和让 LLM 输出 JSON的本质区别概率是模型算出来的不是从文本里解析出来的。Jev 的中文 cookbookdatawhalechina.github.io/jev-cookbook里有一个设计哲学我很认同问题要原子化组合逻辑放在代码里。不要问给这个创业项目打分而是分别问市场规模、技术可行性、差异化然后用你自己的公式组合。优先级变了改代码里的一个系数就行不用重写提示词。而且每个问题相互独立评估增加问题不会造成上下文腐化也几乎不增加延迟。还有一个生态层面的好消息这套/v1/systemone接口已经不是云端 API 的专属。llama.cpp 官方在 10 月 2 日合并了 PR #29818llama-server 原生提供 SystemOne 端点首批支持 laya、openjev、kev 等五个决策模型次日又通过 PR #29831 加入了 Clef。也就是说任何按 Jev 协议写的客户端现在都可以零改动地指向一台本地 llama-server这对数据不出内网的场景意义重大。3. 它为什么快把决策从自回归生成里拆了出来普通 LLM 做一次分类走的是完整的老流程逐 token 生成文本你再从文本里抠答案。这是自回归的慢而且结果本质上是一段很像答案的话。Clef 的做法是另一条路。Cloudflare 冻结了 Qwen 基座只训练两部分一个 rank-256 的 LoRA 适配器和一个联合 schema 打分头joint schema head。推理时只做 prefill不打字。打分头直接读取骨干网络的最终隐藏状态通过两阶段注意力机制先把与每个选项相关的证据从状态里路由出来再对所有问题的所有选项做联合跨字段打分。每个合法选项输出一个 logit按问题做 softmax 就是概率。一句话总结它把生成一段结构化文本再解析换成了直接从内部表示导出结构化答案。决策步骤是非自回归的没有中间文本所以快得离谱。后训练也有讲究对合法 schema 输出用 label-smoothed cross-entropy配合 Brier loss 优化概率校准再加上 Cloudflare 自研的 RLCD面向校准决策的强化学习对相邻的有序选项给部分分数、奖励整条记录完全正确的输出同时施加 reference penalty 防止分布漂移。最终效果就是输出被约束成纯概率而且概率本身是校准过的代码可以放心拿置信度做门控。Cloudflare 自己已经在用了。威胁情报团队用 Clef 给域名分类结合浏览器渲染抓取网页后Clef 用2.2 秒完成整个流程并输出多个类别的概率比如 95% 时尚网站、85% 电商、不到 1% 钓鱼而最快的通用模型 gpt-oss-120b 走同样流程要4.7 秒还只返回两个分类结果。延迟和结果丰富度都是约两倍的差距。4. 跑分Decision Index 第一名是什么水平Clef 的评测跑的是 Decision Index 0.2.1 套件对手是 Jev、DiffusionGemma Jev、Kev 9B 和 Laya。完整表格有四十多项挑一些有代表性的分数为百分比加粗为该基准最佳基准ClefClef-flashJevKev 9BBFCL 函数调用准确率98.598.895.894.5API-Bank准确率91.993.188.256.3BANKING77 意图分类macro-F194.290.979.784.8CLINC150OOSmacro-F197.466.889.379.0家电模拟器准确率83.097.752.325.0ContractNLI 合同推理macro-F181.484.371.757.8ForecastBenchBrier越低越好13.910.617.417.6中位延迟ms越低越好209.338.8524.151.4p95 延迟ms越低越好238.6122.4536.0187.9几个值得注意的点Clef 系列在绝大多数决策类基准上领先Jev 只在少数知识推理类项目GPQA、BBH、MMLU-Pro上占优那些本来就更像考试不像决策。Clef-flash 在家电模拟器上拿到 97.7%是全场最高比自家大哥还高了 15 个百分点说明小模型在设备控制这类边界清晰的任务上完全够用。延迟差距是数量级的Clef-flash 中位 38.8ms只有 Jev 的 7%。把决策模型放进 Agent 的热路径这个差距直接决定架构可不可行。Typesafe 官方的端到端工作流评测发票处理、客服、安全事件、Agent 链路观测里四项中 Clef 系列赢下三项剩下一项与 Jev 基本持平。这个成绩是在API 与 Jev 完全兼容的前提下拿到的意味着现有 Jev 集成可以近乎零成本切换。和 Jev 相比Clef 还多两张牌带视觉编码器可以直接输入图片和视频做分类Jev 目前仅支持文本上下文窗口 64k是 Jev 32k 的两倍。4.1 开源决策模型现在有哪些选择决策模型开源圈半个月内一下子热闹起来把三家放在一起看更清楚Clef / Clef-flashStartLux-DecisionIntern-Decision发布方CloudflareStartLux原点星辉上海 AI 实验室规格27B、9B 两档0.8B / 2B / 4B / 9B / 27B 五档4B 等权重协议Apache 2.0可商用CC BY-NC 4.0仅非商业见其仓库GGUF官方 ggml-org 转换含打分头 bartowski 社区量化仅骨干官方直接提供 Q8_0 / Q4_K_M / BF16见其仓库视觉输入支持图片/视频未提及未提及接口兼容 Jev / SystemOne兼容 /v1/systemone—有两点值得展开。一是协议StartLux-Decision 的权重是 CC BY-NC 4.0研究和非商业用途没问题商用要单独授权Clef 直接 Apache 2.0对企业落地来说省心得多。二是跑分口径StartLux 官方公众号公布的 Decision Index 成绩是 63.88自测对照 9 月 28 日榜单快照高于 Jev 1.13 的 57.91Clef 的第一则来自 Cloudflare 用同一套件的内部评测。两家口径、快照时间不同严格说不能直接比大小。但结论方向一致开源决策模型已经整体越过了 Jev 这条线而且分数还在快速刷新。对开发者来说与其纠结谁是榜一不如按协议、规格和部署成本挑一个上手试。5. 本地跑起来llama.cpp 三天内原生支持了 Clef模型在 Hugging Face 上完全开源而第 2 节提到的 llama.cpp 原生支持让本地部署变得极其简单joint schema 打分头直接进了 llama.cpp 的计算图官方预量化 GGUF 同步放出llama-server-hfggml-org/Clef-Flash-GGUF# 9B提供 BF16 / Q8_0 / Q4_K_M6.49GBllama-server-hfggml-org/Clef-GGUF# 27B-hf方式会从 Hugging Face 拉模型。国内网络不方便的话官方在 ModelScope 上也放了同一份文件下载后用-m指定本地路径即可# 从 ModelScope 下载 Clef-Flash-Q4_K_M.gguf 后llama-server-m./Clef-Flash-Q4_K_M.gguf--port8000-b4096-ub4096从官方 GGUF 的元数据里还能读到两个有意思的信息一是clef.context_length 262144原生 256K 上下文二是元数据里同时存在ssm.*和full_attention_interval 4这些键Qwen3.5 基座是线性注意力与全注意力交替的混合架构这也解释了为什么 PR 里说这个模型明显更复杂需要新增llama_batch_extAPI 来标记问题段和选项段。决策头本身的配置也在元数据里2 个路由块、4 个决策块、16 个头。用最新版 llama.cpp 加载 Clef 后有几个和普通模型不同的行为server 只提供/v1/systemone一个端点聊天接口不再可用它变成一台专职决策服务器。整个 promptstate 所有问题和选项在一次 batch 内算完必须放得下--ubatch-size。长 state 记得调大比如-ub 4096。视觉输入暂未支持要等 PR #29622 合并且单 batch 单序列。5.1 一个容易踩的坑bartowski 的 GGUF 跑不了 /v1/systemone我手头先下载的是 bartowski 的量化版Q4_K_M5.84GB这个发布的比较早下载量也多但用最新 llama.cpp 启动后调/v1/systemone直接返回 501 “This model is not a decision model”。排查后确认了原因服务器是根据 GGUF 元数据{arch}.decision.type判断决策模型的而 bartowski 的文件是在 Clef 支持合并之前转换的。把两个文件的头部元数据拉出来对比差异一目了然bartowski 版ggml-org 官方版general.architectureqwen35clefdecision 元数据无clef.decision.type clef张量数量427仅骨干网络587多出 160 个打分头张量这不是启动参数能补救的--override-kv之类的参数可以改元数据但变不出文件里不存在的 160 个打分头张量。要么换 ggml-org 的官方转换版要么用最新 convert 脚本自己从 HF 权重转。不过 bartowski 版也不是白下载它可以把 clef-flash 当普通生成式模型跑正好给我提供了一个对照实验。同一个模型生成 JSON 再解析和打分头直接出概率两种玩法到底差多少。从对话测试截图来看生成的结果是否可靠暂且不论这个直接 5s 才出结果的体验还是糟糕的。6. .NET 控制台实测两种玩法对比测试场景统一为工单分流一段 502 故障描述问三个问题该由哪个团队处理choice、紧急程度score、是否为服务中断noul。客户端是零第三方依赖的 .NET 文件级程序只用HttpClient和System.Text.Json。6.1 玩法一生成模式模拟bartowski GGUF chat completions先用 bartowski 版走 OpenAI 兼容接口靠提示词让模型输出 JSONusingSystem.Text;usingSystem.Text.Json.Nodes;varhttpnewHttpClient{BaseAddressnewUri(http://localhost:8000)};// 决策任务状态 类型化问题用提示词模拟 schemavarstate我们的结账接口从一小时前开始对全部用户返回 502订单全部卡住。;varprompt$$$ 你是一个决策模型。针对下面的状态回答问题只输出 JSON不要输出任何其他文字。 状态{{{state}}}问题1.department:该由哪个团队处理选项 billing支付或发票问题,technical故障或缺陷,sales商务咨询2.urgency:紧急程度评分选项0可以等,1本周处理,2今天处理3.outage:是否为服务中断true/false输出格式字符串值必须加英文双引号只使用英文标点{department:...,urgency:0,outage:false,confidence:{department:0.0,urgency:0.0,outage:0.0}};varrequestnewJsonObject{[messages]newJsonArray(newJsonObject{[role]user,[content]prompt}),[temperature]0.0,[max_tokens]512,// llama.cpp 扩展约束输出必须是合法 JSONGBNF 语法层面保证不依赖模型自觉[response_format]newJsonObject{[type]json_object},};// 手动序列化/解析不走反射文件级程序默认禁用反射序列化usingvarrespawaithttp.PostAsync(/v1/chat/completions,newStringContent(request.ToJsonString(),Encoding.UTF8,application/json));resp.EnsureSuccessStatusCode();varbodyJsonNode.Parse(awaitresp.Content.ReadAsStringAsync())!;varcontentbody[choices]![0]![message]![content]!.GetValuestring();// 剥离 think 思考段截取第一个 { 到最后一个 } 之间的 JSONvartextcontent;varthinkEndtext.IndexOf(/think,StringComparison.Ordinal);if(thinkEnd0)texttext[(thinkEnd8)..];vardecisionJsonNode.Parse(text[text.IndexOf({)..(text.LastIndexOf(})1)])!;Console.WriteLine($团队:{decision[department]});Console.WriteLine($紧急度:{decision[urgency]});Console.WriteLine($服务中断:{decision[outage]});这段代码能跑起来也是解决了几个坑的最主要的还是模型输出格式坑。第一版靠提示词约束 JSON模型返回了不带引号的值和中文逗号根本解析不了。加上 llama.cpp 支持的response_format: {type: json_object}后输出合法性由 GBNF 语法在采样层面保证这是本地部署相比单纯提示词工程最实用的一张牌。另外 Qwen 系的思考段think.../think也要剥掉再解析。格式问题解决了但实测答案本身翻了车团队: technical ← 对了 紧急度: 0可以等 ← 全站 502 一小时还可以等 服务中断: false ← 同上 置信度: 全部 0.0 ← 照抄提示词模板里的示例值格式对了判断错了。这不能全怪模型clef-flash 的决策能力在打分头里而 bartowski 版只有骨干网络相当于让一个被拿掉决策器官的模型用聊天的方式假装做决策。这个反面教材恰好说明了决策模型存在的意义判断的可靠性不该建立在模型今天愿不愿意好好说话上。6.2 玩法二原生决策接口ggml-org GGUF /v1/systemone换上ggml-org/Clef-Flash-GGUF后请求变得极其干净没有提示词工程没有输出解析就是 state questionsusingSystem.Text;usingSystem.Text.Json.Nodes;varhttpnewHttpClient{BaseAddressnewUri(http://localhost:8000)};varrequestnewJsonObject{[state]我们的结账接口从一小时前开始对全部用户返回 502订单全部卡住。,[questions]newJsonObject{[department]newJsonObject{[type]choice,[instructions]该由哪个团队处理,[criteria]newJsonObject{[billing]支付或发票问题,[technical]故障或缺陷,[sales]商务咨询,},},[urgency]newJsonObject{[type]score,[instructions]紧急程度如何,[criteria]newJsonArray(可以等,本周处理,今天处理),},[outage]newJsonObject{[type]noul,[instructions]是否为服务中断,},},};usingvarrespawaithttp.PostAsync(/v1/systemone,newStringContent(request.ToJsonString(),Encoding.UTF8,application/json));varrawawaitresp.Content.ReadAsStringAsync();if(!resp.IsSuccessStatusCode){Console.WriteLine($HTTP{(int)resp.StatusCode}:{raw});return;}varanswersJsonNode.Parse(raw)![answers]!;foreach(var(id,node)inanswers.AsObject()){switch(node![type]!.GetValuestring()){casechoice:Console.WriteLine(${id}{node[choice]}(confidence{node[confidence]}));break;casescore:Console.WriteLine(${id}{node[score]}(confidence{node[confidence]}));break;casenoul:Console.WriteLine(${id} P(true) {node[noul]});break;}}实测结果RTX 4070 Ti SUPERQ4_K_M 全量 GPU offload328 个输入 token、三个问题一次回答department [choice] technical (confidence 0.88, 概率 billing 0.07 / sales 0.01 / technical 0.92) urgency [score] 1.59 (confidence 0.38, 概率 可以等 0.16 / 本周处理 0.10 / 今天处理 0.75) outage [noul] P(true) 0.90 usage: input_tokens 328, output_tokens 0和玩法一的翻车结果放在一起看差距一目了然同一个 state生成模式判可以等、非服务中断、置信度照抄 0.0真打分头给出 technical 0.92、outage 0.90、“今天处理” 0.75三题全部符合直觉。这里有两个细节值得注意score 返回 1.59 而不是整数它是按概率加权的期望级别可以落在两级之间比硬分类的信息量更大。output_tokens恒为 0没有任何文本被生成这就是不吐一个字的字面含义。choice 和 score 的 confidence 是打分头算出来的可以直接拿来做置信度门控低于阈值转人工或转大模型而不是玩法一里模型自报的数字。官方也诚实地提醒概率按模型文件里存好的温度缩放在你的数据上不一定校准过门控阈值要结合业务数据自己标定。6.3 延迟实测与调参说明在 RTX 4070 Ti SUPER 上连续请求单次耗时稳定在64~92ms328 个输入 token、三个问题一次回答服务启动后的首次请求约 500ms是 GPU 计算图编译的一次性开销。这个数字和官方宣传 clef-flash 的 38.8msCloudflare 生产环境H200 级硬件已经在同一量级消费级显卡跑出两位毫秒决策模型很轻这件事是实打实的。因为启动脚本我是直接复制本地通用大模型然后改的模型地址所以做了参数调整的测试。有意思的是这个实验结论怎么调都差不多。--flash-attn开不开耗时没有可感知的差别-b 4096 -ub 4096加上去也一样。把启动参数全部砍掉输出概率逐位一致、显存占用相同8.1GB新版 llama.cpp 的--fit默认开启会自动按显存调整未指定的参数。原因不复杂决策请求的耗时几乎全是 prompt 前向传播prefill纯算力瓶颈而模型权重和计算图是固定的-ngl、-c、-t、-ctk、-fa这些参数碰到一次前向就出结果的负载全都没有发挥空间。真正影响速度的只有两件事prompt 的 token 数问题和选项描述越短越快基本线性和GPU 算力。想再快要么缩短 prompt要么换更小的决策模型比如 4B 档。参数对速度无感但有一个参数对能不能跑至关重要-ubClef 要求整个 prompt 在一个物理 batch 里算完而-ub默认只有 512。实测 980 个 token 的 prompt 直接返回 HTTP 500 “input is too large to process. increase the physical batch size”。所以推荐启动命令是llama-server-mClef-Flash-Q4_K_M.gguf--port8000-b4096-ub4096-b逻辑 batch默认 2048要不小于-ub所以两者一起给。如果你的 state 可能更长比如丢给它一整篇日志按需再加大。7. 结语Clef 让我感兴趣的不是又一个开源模型而是它代表的分工思路把判断和表达拆开。聊天模型负责思考和表达决策模型负责在关键节点快速给出带概率的结构化答案代码在两者之间做编排。Agent 工作流里大量该走哪条路的瞬间其实根本不需要一段散文。对个人开发者来说眼下最实际的用法就是本地跑ggml-org/Clef-Flash-GGUF的 Q4_K_MApache 2.0一条/v1/systemone请求就是一次带概率的决策当分类器、路由器、意图识别器用成本只有电费。
返回列表