Bespoke-Nimble-9B 实战指南:基于 Qwen3.5-9B LoRA 的上下文接地候选评分模型(choices / boolean / rubric)
- 人工智能
- 大模型
- 微调
- LoRA
- 模型评测
- NLP
【免费下载链接】Bespoke-Nimble-9B
本文以 HuggingFace 镜像仓库hf_mirrors/bespokelabs/Bespoke-Nimble-9B中的 README.md 为主线,结合仓库内的 inference.py、schema_config.json、adapter_config.json 等源码与配置,系统讲解 Bespoke-Nimble-9B 的模型定位、安装加载、Schema 编写、候选评分原理与可靠性设计。读完本文,你将能够独立完成模型的下载安装、通过NimbleModel.score()完成布尔判断、选项分类与评分级(rubric)三类结构化预测,并理解其"直接对候选 token 打分、不做自由生成"的底层机制。
一、模型定位:不是生成式评分,而是候选 token 直接打分
Bespoke-Nimble-9B 是一个基于Qwen3.5-9B 基础模型的LoRA 适配器(adapter),专门用于"上下文接地"(context-grounded)的三种结构化输出任务:
- choices(选项分类):从给定候选中选出与上下文事实最匹配的一项;
- booleans(布尔判断):对某个命题给出 true / false;
- rubric score levels(评分等级):按等级描述(如 0、1、2、3)对结果打分。
它的核心工作方式与常见 LLM 应用不同:它直接对"允许出现的答案 token"计算得分(scores the allowed answer tokens directly),推理工作流不生成推理过程(reasoning),也不产出自由文本答案。也就是说,模型不是"写"出答案,而是从你给出的候选集合里"选"出最合适的一个,并以概率形式给出置信度。这一点在 README.md 中有明确说明,也是本模型适用场景(结构化分类、自动化评估、规则化决策)的设计前提。
版本信息方面,README 记录了一个重要更新(2026 年 9 月 24 日):本仓库发布的是最新 9B 检查点,具备8,192 token 上下文上限与单字段最多 255 个选项的能力,官方评估使用T=1.0;更早的检查点可通过revision="original-2676"获取,而 Bespoke-Nimble-9B-v2 保持不变。本仓库不重复存放基础模型权重,使用时需要自行获取 Qwen3.5-9B 基础检查点。
二、仓库构成与关键文件
本仓库只包含适配器本身(约165 MiB)及配套运行资产,不包含完整基础权重,典型文件及其作用如下:
| 文件 | 作用 |
|---|---|
| adapter_model.safetensors | LoRA 适配器权重 |
| adapter_config.json | PEFT LoRA 配置(rank、alpha、target_modules 等) |
| tokenizer.json / tokenizer_config.json | Qwen3.5 分词器 |
| chat_template.jinja | 聊天模板(prompt 渲染) |
| inference.py | 官方参考推理代码(NimbleModel) |
| serving_schema.py / candidate_schema.py / parallel_schema.py / extended_schema.py | 精确 prompt 构建与 schema 校验 |
| schema_config.json | 训练契约:任务类型、上下文上限、候选编码、数据审计等 |
| serving_config.json | 服务端候选编码(codebook)校验配置 |
| temperature_config.json | 温度配置与适配器 SHA-256 |
| provenance.json | 发布元数据(版本、基础模型、校验和) |
| requirements.txt | 固定依赖版本 |
| SHA256SUMS | 文件校验和清单 |
| LICENSE | Apache 2.0 许可证 |
从 adapter_config.json 可以看到本适配器的 LoRA 超参数:r=16、lora_alpha=32、lora_dropout=0.05、peft_type=LORA、task_type=CAUSAL_LM,目标模块覆盖了注意力(q_proj/k_proj/v_proj/o_proj)、线性注意力(in_proj_qkv/in_proj_z/in_proj_a/in_proj_b/out_proj)与 MLP(gate_proj/up_proj/down_proj)等投影层;基础模型固定为Qwen/Qwen3.5-9B,revision 为c202236235762e1c871ad0ccb60c8ee5ba337b9a。
三、环境要求与安装
3.1 硬件与软件前提
README 明确要求支持 BF16 的 CUDA GPU(官方原始运行环境为 PyTorch 2.8.0 + CUDA 12.8)。inference.py 在初始化时会强制检查torch.cuda.is_available()与torch.cuda.is_bf16_supported(),不满足条件直接抛出RuntimeError,因此在非 NVIDIA(或老架构不支持 BF16)的 GPU 上无法运行官方参考推理。
安装步骤分为两步:
hf download bespokelabs/Bespoke-Nimble-9B --local-dir nimble-model pip install -r nimble-model/requirements.txt- 第一条命令用
huggingface_hub的hf download将仓库下载到本地nimble-model目录; - 第二条命令安装固定依赖;如果仓库被设置为私有,需要配置一个具备读取权限的 Hugging Face token;
- 官方参考 helper 无需
trust_remote_code=True,但 README 建议导入前先自行审阅 helper 代码。
3.2 依赖版本
requirements.txt 中固定了以下核心版本,安装时可直接照搬:
transformers==5.17.0 peft==0.21.0 accelerate==1.15.0 sentencepiece==0.2.2 pillow==12.3.0 huggingface_hub>=0.34四、快速开始:加载模型并完成一次评分
将下载目录加入 Python 路径后导入NimbleModel(即 inference.py 中ParallelScorer的别名),传入模型目录即可完成加载。以下示例来自 README.md 并稍作展开:
import sys sys.path.insert(0, "nimble-model") from inference import NimbleModel model = NimbleModel("nimble-model") result = model.score( context="The store accepts returns within 30 days. This item was bought 12 days ago.", schema={ "eligible": { "type": "boolean", "description": "Is this item within the store return window?" } }, ) print(result["output"]) print(result["fields"]["eligible"]["probabilities"])返回结果result的结构为:
result["output"]:字典,每个字段名映射到该字段的预测值(如{"eligible": True});result["fields"][field_name]["probabilities"]:该字段各候选的概率分布;result["fields"][field_name]["logits"]:各候选的原始 logits;- 顶层还包含
temperature与temperature_fitted字段。
对布尔字段,结果中还会额外给出probability_true(见 inference.py 中kind == "noul"分支)。score()内部会逐字段独立处理,且完整保留训练时的 prompt 构造与概率计算方法,确保推理路径与评估路径一致。
五、Schema 字段类型详解
score(context, schema, score_fields=())中的schema是一个 JSON 对象:键为字段名,值为字段定义。支持两种字段类型:boolean与enum。
5.1 boolean 字段
如第四节示例,只需提供type与description。底层会把候选固定为[False, True](见 parallel_schema.py 的choices_for),无需手动指定 choices。
5.2 enum 字段(选项分类)
对于多选一场景,使用type="enum",并给出choices字符串列表、description,以及可选的choice_descriptions(用于给每个选项补充含义说明,辅助模型理解):
result = model.score( context="The report is 12 pages long and contains three charts.", schema={ "document_type": { "type": "enum", "description": "What kind of document is this?", "choices": ["report", "invoice", "email", "manual"], "choice_descriptions": { "report": "A structured summary of findings", "invoice": "A bill for goods or services", }, } }, )5.3 rubric score 字段(评分等级)
评分字段本质上是取整数值的 enum:用字符串形式的整数作为choices(如["0", "1", "2", "3"]),并为每个等级写描述,然后把该字段名传入score_fields:
result = model.score( context="The answer covers all key points but lacks examples.", schema={ "quality": { "type": "enum", "description": "Rate answer quality.", "choices": ["0", "1", "2", "3"], "choice_descriptions": { "0": "No relevant content", "1": "Partial, many gaps", "2": "Good, minor omissions", "3": "Complete and precise", }, } }, score_fields=["quality"], )此时返回值中除了prediction(选中等级对应的整数),还会给出expected_score(概率加权期望分数):sum(int(v) * p for v, p in zip(choices, probs))(见 inference.py)。从源码看,score_fields必须是 schema 中存在的字段,且要求为整数值 enum、各取值互不相同,否则会抛ValueError。
5.4 Schema 校验规则
无论是官方代码还是自定义调用,schema 都会经过 extended_schema.py(或 parallel_schema.py)中validate_schema的严格校验,核心规则包括:
- schema 必须是非空对象,字段名必须是非空字符串;
- 字段类型仅支持
enum与boolean; - 每个字段必须提供非空
description; enum的 choices 必须是 1~255 个非空字符串,且不允许重复;boolean的 choices 必须是[false, true]恰好各一次(默认即如此);choice_descriptions的键必须对应真实存在的选项名;- 字段定义中不允许出现除
type、choices、description、choice_descriptions之外的键。
这些校验保证了进入模型的 prompt 永远符合训练契约,避免格式漂移导致评分失真。
六、运行约束:255 个选项与 8,192 token 上限
本版本的两项关键上限在 schema_config.json 中固化:max_length: 8192、max_choices: 255。
- 单字段最多 255 个选项:超出会直接报错。当选项数 ≤ 26 时使用单字母编码(A~Z);超过 26 个时,extended_schema.py 会从分词器词表中挑选满足条件的 2~3 位大写纯字母 token(如
AA、AB…JT),并逐一验证其在"真实答案边界"上恰好编码为单个普通 token,这一编码方案在 schema_config.json 中登记为uppercase_single_token_v1。 - 超长 prompt 直接拒绝而非截断:extended_schema.py 与 parallel_schema.py 在构建 prompt 时若检测到最长序列超过
max_input_tokens,会抛出ValueError(错误信息明确写着 "Nothing was truncated"),保证上下文完整性。
此外,官方推理一次可以处理多个字段:prompt 构建使用__PARALLEL_FIELD_TARGET__标记,将共享的上下文与 schema 部分渲染一次,再为每个字段替换目标标记生成独立 prompt(见 extended_schema.py),score()内部逐字段执行前向并聚合结果。
七、底层原理:候选 token 直接评分
7.1 一次前向、只取最后位置
inference.py 的candidate_logits揭示了评分核心:模型前向时使用use_cache=False, logits_to_keep=1,只保留最后一个位置的 logits,然后通过gather取出各候选 token 对应的 logit,并用 mask 将不在候选项内的位置填充为-inf:
logits = model(input_ids=inputs["input_ids"], attention_mask=inputs["attention_mask"], use_cache=False, logits_to_keep=1).logits[:, -1, :].float() selected = logits.gather(1, inputs["candidate_ids"]) return selected.masked_fill(~inputs["candidate_mask"], -torch.inf)也就是说,模型从未"生成"过任何 token,它只负责评估:在给定上下文中,哪个候选 token 最应该出现在答案位置。
7.2 概率与温度
inference.py 的decision_result中,概率计算只有一步:
probs = softmax(candidate_logits / temperature)- 默认
temperature = 1.0(DEFAULT_TEMPERATURE); - 温度参数有严格校验:必须是正的有限数(bool 不被接受),否则抛
ValueError(见 inference.py); - 预测值取原始 logits 的 argmax,概率则来自温度缩放后的 softmax;
- 若在测试/评估场景提供
labels,还会额外计算correct、nll与brier等指标。
7.3 温度校准的重要提醒
README 特别强调:本检查点没有单独拟合过温度(temperature_fitted: false),评估默认就是 T=1.0,不要沿用旧版本模型拟合的 2.179 校准值。这一点在 temperature_config.json 与 provenance.json 中一致登记:"temperature": 1.0、"temperature_fitted": false、"method": "softmax(candidate_logits / temperature)",且note字段明确"先前版本的校准不适用"。因此在使用本版本时,请直接使用默认温度;如需自定义,务必先做自己的校准实验。
八、供应链与契约校验:防止"错误适配器"被加载
仓库在可靠性上有非常细致的设计:加载模型时会做多层一致性校验,任何不匹配都会抛出ValueError:
- 训练契约校验:
ParallelScorer.__init__读取 schema_config.json,校验task == "schema_candidate_classification_v2",并用 SHA-256 比对 parallel_schema.py、candidate_schema.py、extended_schema.py 等 prompt 源码哈希(对应prompt_source_sha256); - 服务 codebook 校验:
validate_serving_config读取 serving_config.json,比对max_choices、候选代码列表、候选 token id,以及各源文件的 SHA-256(见 inference.py); - 编码契约校验:用真实分词器在真实答案边界上重建完整 codebook,确认与训练契约一致(见 candidate_schema.py)。
这些校验的意义在于:prompt 构建代码若被修改、候选编码若与分词器不匹配、或适配器与 base 模型 revision 不匹配,都会在加载阶段被拦截,而不是在推理时悄悄产生错误结果。此外 provenance.json 记录了发布元数据:release: v3-12026、adapter_sha256、基础模型与 revision,并声明weights_unchanged_from_evaluated_checkpoint: true,即发布权重与官方评估所用权重完全一致。
九、训练契约速览(辅助参考)
schema_config.json 中的data_audit与超参记录提供了该检查点的训练背景(仅供理解模型来源,非性能声明):
- 数据规模:12,026 个训练行(8,468 个分组、5,370 个 family),324 个验证行;训练数据包含 13 个组件(如
decision-skills-local、safety-local、public-banking77、public-boolq、public-multinli等公开数据集); - 任务构成:训练集中 choice(选项分类)8,080 行、noul(布尔)2,412 行、score(评分)1,534 行;
- 超参数:
learning_rate: 5e-05、batch_size: 2、gradient_accumulation: 4、warmup_steps: 451、max_steps: 4512、线性调度、seed: 17、训练 GPU 为 NVIDIA H100 80GB; - 推理精度:
inference_precision: bf16_autocast,与官方推理路径一致。
十、常见问题与注意事项
- 没有 NVIDIA GPU / 不支持 BF16:官方参考推理会直接报错;Mac/MLX 与 Linux 平台的加载器请参考 Nimble 项目官方 quickstart(README 中提供了入口,本文不展开外部链接)。
- 想要旧检查点:加载时指定
revision="original-2676"可获取先前版本,但请注意其上下文上限、候选数与温度校准与本版本不同,不要混用。 - 温度参数:必须为正有限数;默认 T=1.0 是本版本的评估默认值,旧版 2.179 校准值不适用。
- 私有仓库认证:若模型仓库为私有,需要配置可读权限的 HF token。
- 超长输入:超过 8,192 token 的 prompt 会被拒绝而非截断,请在调用前自行控制上下文长度。
总的来说,Bespoke-Nimble-9B 提供了一条"结构化评分"的完整链路:从 README.md 给出的加载示例,到 inference.py 的候选 token 评分实现,再到 schema_config.json 与 serving_config.json 的契约校验,整个仓库都围绕"精确复现训练与评估路径"这一目标设计。对于需要稳定、可复现的布尔判断、选项分类与评分级结构化输出的工程场景,它是一个值得直接使用的参考实现。
- 人工智能
- 大模型
- 微调
- LoRA
- 模型评测
- NLP
【免费下载链接】Bespoke-Nimble-9B
相关推荐
Bespoke-Nimble-9B完全指南:Qwen3.5-9B的LoRA结构化分类适配器是什么?
Bespoke Nimble 9B完全指南:Qwen3.5 9B的LoRA结构化分类适配器是什么? Bespoke Nimble 9B 是一个基于 Qwen3.
人工智能大模型微调LoRA模型评测NLPopenpilot 怎么把车道居中和自适应巡航装进你的车
openpilot 怎么把车道居中和自适应巡航装进你的车 堵车蠕行时跟车跟到手酸,或者过弯时不敢松方向盘?openpilot 驾驶辅助把车道居中和自适应巡航搬进
自动驾驶人工智能深度学习计算机视觉Ryujinx 完整上手指南:5 步在电脑上免费跑起 Switch 游戏
Ryujinx 完整上手指南:5 步在电脑上免费跑起 Switch 游戏 先买了 Switch 游戏、主机却还在箱底吃灰?Ryujinx 是一款用 C 编写的开
硬件仿真图形学
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考