建立自己的决策模型
"系统一"决策模型是通过校准的概率或每个允许的答案进行推断和响应的模型。考虑到你的日常语言模型,要从中获得类型化的输出(JSON),可以使用结构化输出以限制输出为保证有效的 JSON。当模型在一次传递中填充输入时,仍需对每个标记执行一次传递以生成有效响应。在这个例子中,生成最终输出需要 11 次传递。(我们不考虑投机解码和其他推理优化技术。)提示(预填充)生成(预测)正被预测,比如 Jev 的决策模型,假设我们可以快速从固定选项中选择,并且可以通过一次传递做到这一点。在这个例子中,我们将可能输出的集合限制为选项 A、B、C、D、E。通过屏蔽词汇表中的其他项目,模型只能发出这些标记。通过选择概率最高的输出,我们得到了答案。提示(预填充)生成(预测)正被预测。由于输出仅限于固定选项集合,模型不能选择这些选项以外的内容。然而,这并不能保证输出将是正确的。在这种情况下,通常将输出标记概率视为置信分数,但如果没有额外的训练,这些分数很可能反映的是模型对下一个标记的置信度,而不是响应是正确答案的真实概率。建立你自己的模型。我们可以通过使用 LLM 限制输出标记来模拟这一行为。这里我使用 Qwen/Qwen3-1.7B。导入 argparse 导入 json 导入 torch 从 transformers 导入 AutoModelForCausalLM、AutoTokenizer。模型名称 = "Qwen/Qwen3-1.7B" 选项 = ["A", "B", "C", "D", "E"] 解析器 = argparse.ArgumentParser() 解析器.add_argument("--input", default="question.json") args = 解析器.parse_args() # 加载分词器和模型 分词器 = AutoTokenizer.from_pretrained(模型名称) 模型 = AutoModelForCausalLM.from_pretrained(模型名称、torch_dtype="auto"、device_map="auto") # 模型将为每个选项发出的标记作为第一个助手标记 option_token_ids = [分词器.encode(opt, add_special_tokens=False)[0] for opt in 选项] def format_prompt(item): prompt = item["question"] + "\n" for opt in 选项: prompt += f"{opt}. {item[opt]}\n" prompt += "答案:" 消息 = [{"role": "user", "content": prompt}] return 分词器.apply_chat_template(消息,tokenize=False,add_generation_prompt=True,enable_thinking=False) with open(args.input) as f: item = json.load(f) model_inputs = 分词器(format_prompt(item),return_tensors="pt").to(模型.device) with torch.no_grad(): logits = 模型(**model_inputs).logits[0, -1] # 受限解码:仅允许选项标记 probs = torch.softmax(logits[option_token_ids].float(), dim=-1) print(f"预测:{选项[probs.argmax().item()]}") for opt, prob in zip(选项, probs.tolist()): print(f"{opt}: {prob:.4f} {item[opt]}") 用一个简单的问题运行它以进行测试的结果是以下输出 // 输入 { "question": "天空是什么颜色?", "A": "红色", "B": "蓝色", "C": "绿色", "D": "紫色", "E": "我不知道" } // 输出 预测:B A: 0.0000 红色 B: 0.9988 蓝色 C: 0.0000 绿色 D: 0.0000 紫色 E: 0.0012 我不知道。模型能够理解我们的输入并作出与正确答案合理对应的预测。我们可以通过在公共数据集上运行它来测试模型的准确性。我在 CommonsenseQA 的随机抽样中进行测试 Precision Recall F1 支持 A 0.5733 0.7197 0.6382 239 B 0.5506 0.7686 0.6416 255 C 0.5372 0.6598 0.5922 241 D 0.7206 0.3904 0.5065 251 E 0.7519 0.4255 0.5435 235 准确率:725/1221 = 0.5938 macro f1:0.5844 对于一个 1.7B 的模型来说还不错,快速在数据集上进行微调给出了稍微更好的性能 Precision Recall F1 支持 A 0.6475 0.6611 0.6542 239 B 0.6113 0.6784 0.6431 255 C 0.6234 0.5975 0.6102 241 D 0.6700 0.5418 0.5991 251 E 0.5808 0.6426 0.6101 235 准确率:762/1221 = 0.6241 macro f1:0.6234 校准你的模型 针对一个非常模糊的问题测试模型展示了一个有趣的问题。 // 输入 { "question": "你最可能在哪里找到蝙蝠?", "A": "洞", "B": "棒球比赛", "C": "阁楼", "D": "动物园", "E": "运动用品商店" } // 输出 预测:A A: 0.9978 洞 B: 0.0004 棒球比赛 C: 0.0017 阁楼 D: 0.0000 动物园 E: 0.0001 运动用品商店 这里应该没有明确的答案,但是把输出概率当作一种伪 "置信" 分数,显示出模型对这个答案过于自信。如果我们在早些时候进行的评估中将置信度分数范围进行分组,我们可以看到模型的置信度与其准确性不匹配。这意味着模型没有经过校准。 组区间 计数 置信度 准确性 (0.00, 0.10] 0 0.0000 0.0000 (0.10, 0.20] 0 0.0000 0.0000 (0.20, 0.30] 3 0.2834 0.0000 (0.30, 0.40]
本站免费、广告极少。如果觉得有帮助,可以请我们喝杯咖啡 —— 任何金额都对持续运营有实际帮助。
☕请我喝杯咖啡