)
逐行读懂Clef源码State、图片与Schema如何打包进单次前向传播encode_record深度解读【免费下载链接】clef项目地址: https://ai.gitcode.com/hf_mirrors/Cloudflare/clefClef 是 Cloudflare 开源的 27B 多模态决策模型输入一段state状态JSON 或纯文本和一组类型化问题schema一次前向传播就返回所有问题每个合法选项的概率——没有自由文本生成也没有输出解析。这篇文章带你逐行读懂 Clef 的核心源码 joint_schema_model.py重点解读encode_recordState、图片与 Schema 是如何被打包进同一条 token 序列的。 先搞懂 Clef一次前向传播的决策模型传统大语言模型回答问题是写作文生成一段自由文本再靠正则或 JSON 解析把答案抠出来。Clef 换了个思路——把答案的取值范围直接写进输入让模型对每个选项打一个 logit问题类型含义选项来源noul是/否判断固定的true/falsechoice多选项分类criteria字典里的命名选项score有序打分criteria列表按 0、1、2… 编号三种类型的映射定义在 joint_schema_model.py 的QUESTION_TYPES中。模型输出后对每个问题做一次 softmax就得到了结构化答案见 README.md 的 Model 一节。 仓库地图从哪个文件开始读这个仓库的戏份高度集中读源码前先看这张表文件作用joint_schema_model.py全文核心record 编码、批处理、联合 schema 头、推理入口joint_head.safetensors joint_head_config.json小 Transformer 决策头的权重与超参width1024、layers4、routing_layers2model-00001-of-00012.safetensors 等 12 个分片 model.safetensors.index.jsonQwen3.8-27B 多模态主干含视觉编码器约 273.6 亿参数config.json主干模型架构配置qwen3_5hidden_size5120processor_config.json图片/视频处理器配置Qwen2VLImageProcessortokenizer.json、chat_template.jinja分词器与聊天模板一句话概括架构大主干负责读懂小头负责决策。下面进入主角encode_record。 逐行解读 encode_record打包的完整流程encode_record的签名很克制joint_schema_model.pydef encode_record( tokenizer, record, # 含 state、可选 images/videos、questions max_length16384, # 总 token 上限 max_state_tokensNone,# state 单独上限 processorNone, # 有图片/视频时必须提供 ) - EncodedRecord它的产物是一个EncodedRecordL69-L74一串input_ids、每个问题的位置坐标span以及媒体张量。整个函数分四步。第一步把 Schema 渲染成字段清单函数先固定写入标题SCHEMA FIELDS:然后遍历record[questions]为每个问题拼出一段带编号的文本L110-L148FIELD 1 ID: status TYPE: choice INSTRUCTION: What is the invoice status? ALLOWED OPTIONS: OPTION 1: {option_id: paid, description: Invoice is paid.} ... END FIELD两个细节值得注意空指令自动兜底instructions缺失时直接拿问题 ID 当指令L120-L123noul 类型自动补全question_optionsL46-L57会确保true/false两个选项永远存在可选地用criteria里的自定义描述覆盖默认语义。最关键的一步是边写边记坐标每写入一段文本就记下它在schema_ids中的起止下标——问题指令是question_span每个选项是option_spansL129-L137。这些 span 就是后面决策头从隐藏态里抽取证据的地址。第二步图片与视频在哪里进场如果 record 带了images或videos会走_encode_mediaL81-L100用占位符拼出媒体文本每张图一个 、每段视频一个 L28-L29交给视觉处理器processor得到pixel_values、image_grid_thw等张量键列表见MEDIA_BATCH_KEYSL30处理器会返回已展开占位符的 token 序列直接替换掉原始的占位文本。回到主流程媒体 token 被接在STATE:之后L158-L161并记下token_offset——批处理时mm_token_type_ids要用这个偏移把媒体标记填回正确位置collate_records。没有媒体时这一步直接返回空纯文本零开销。第三步State 进位与长度控制state通过renderL35-L43统一转成紧凑 JSON 字符串sort_keys保证同样的状态永远得到同样的 token利于缓存与复现。然后是两段安检L163-L170可选的max_state_tokens先截断 stateSchema 部分永远不截断——如果 prefix schema suffix 就已经超过max_length默认 16384直接抛ValueError。设计哲学很清楚宁可报错也不让模型看着残缺的选项清单瞎猜。第四步整体拼接与坐标平移最终的输入序列是一个四段式结构┌──────────────┬────────────┬─────────────┬──────────────────┬──────────────────────┐ │ prefix │ media │ state │ schema │ suffix │ │ system提示 │ tokens(可选) │ JSON 状态 │ FIELD 清单 │ JOINT SCHEMA │ │ STATE:\n │ │ │ │ DECISIONS: │ └──────────────┴────────────┴─────────────┴──────────────────┴──────────────────────┘拼接发生在 L188prefix state schema suffix。由于 schema 被放到了 state之后第一步记下的 span 还差一个平移量——schema_offset len(prefix) len(state)于是所有 span 统一加上偏移L171-L187得到指向最终input_ids的准确坐标。函数最后返回EncodedRecord空输入或空问题会直接报错L189-L190。⚙️ span 的用途决策头如何完成一次前向传播知道 span 被记录之后读者会问它在哪被使用答案是ClefModel.forwardL468-L491主干模型单次前向带use_cacheFalse取出全部last_hidden_state媒体张量经**media注入把隐藏态交给JointSchemaHeadL281-L459做决策。头部的流水线可以浓缩成一句话取均值 → 路由证据 → 联合打分对每个问题 span / 选项 span 内的隐藏态做平均池化得到问题向量和选项向量_mean_span、L359-L386额外取选项 token 的词表嵌入均值作为词汇向量L379-L383——即使主干没读懂至少选项字面本身是个锚点两层EvidenceRoutingLayerL242-L278让所有选项像 query 一样从整条序列中检索证据4 层 Transformer 解码器超参见 joint_head_config.json完成字段级联合推理所有问题的选项同时打分所以叫joint联合头最终 logit 词汇先验 sigmoid(门控)× 联合得分L453-L457。对比主干约 273.6 亿参数model.safetensors.index.json决策头只有 1024 宽、4 层——决策逻辑是轻量外挂主干只负责通用理解这也是 Clef 可以低成本后训练的原因。 快速上手5 行代码得到答案理解了打包流程后实际调用非常干净示例改编自 README.md 的 Usage 一节from joint_schema_model import encode_record, collate_records, load_release_model model, processor load_release_model(path, devicecuda) record { state: {invoice: {vendor: Acme, total: 1250.0, status: overdue}}, questions: { status: {type: choice, instructions: What is the invoice status?, criteria: {paid: Invoice is paid., overdue: Invoice is past due., draft: Not sent.}}, large: {type: noul, instructions: Is the total above 1000 USD?}, }, } encoded encode_record(processor.tokenizer, record, processorprocessor)之后collate_records补齐批处理张量、model(batch)一次前向对每题 logit 做 softmax 即得概率。更省事的方式是直接调用systemoneL546-L576它接收 Jev/SystemOne 风格请求体内部自动完成encode_record → collate → 前向 → 概率换算并返回带answers与usage的标准响应体。 要点回顾与常见疑问三个问题类型怎么选noul适合是否判断choice适合有限类别分类score适合有序严重度/优先级评分——三者的选项都会被完整写进 schema模型对每个选项各给一个 logit。Schema 太长怎么办会直接抛错而不是静默截断L166-L169。正确姿势是精简问题数量或用max_state_tokens压缩 state把预算让给 schema。图片能参与决策吗能。图片 token 紧跟在STATE:之后进入同一序列决策头的证据路由层会对整条序列含媒体区域做注意力检索所以看收据判断金额是否清晰这类多模态判断在一次前向里完成。关键路径速查打包逻辑encode_record批处理与媒体对齐collate_records决策头结构JointSchemaHead加载与推理入口load_release_model、systemone读懂了encode_record的四段式打包 span 记账你就掌握了 Clef 最核心的设计不是让模型复述答案而是让答案的候选项成为输入的一部分再由轻量决策头对它们联合打分——这正是单次前向传播出结构化决策的全部秘密。【免费下载链接】clef项目地址: https://ai.gitcode.com/hf_mirrors/Cloudflare/clef创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考