基于受限解码构建校准概率的决策模型
“系统一”决策模型旨在通过校准的概率对每个允许的答案进行推断和响应。虽然利用结构化输出可以限制生成内容以确保 JSON 格式的有效性,但模型在预填充输入后,仍需为生成的每一个代币(token)执行一次前向传播以产生有效响应。

在未采用推测解码等推理优化技术的情况下,生成最终输出可能需要多次传输。例如,在某些示例中,需要 11 次传输才能完成生成过程。
prompt (prefill) generated (predicted) being predicted通过单次前向传播即可快速做出选择。在该方法中,可能的输出被严格限制在预设选项 A、B、C、D、E 之中。通过对词汇表中其他项目进行掩码处理,模型仅能发射这些特定代币。随后,通过选取概率最高的输出代币,即可得到答案。
prompt (prefill) generated (predicted) being predicted由于输出空间被限定在一组固定选项中,模型无法选择集合之外的答案。然而,这并不保证输出结果的正确性。通常情况下,输出代币的概率被视为置信度分数,但在缺乏额外训练的情况下,这些分数往往反映的是模型对下一个代币生成的信心,而非答案真实正确的概率。
可以通过使用大型语言模型(LLM)并限制输出代币来模拟这一行为。以下示例使用了 Qwen/Qwen3-1.7B 模型:
import argparse
import json
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
model_name = "Qwen/Qwen3-1.7B"
options = ["A", "B", "C", "D", "E"]
parser = argparse.ArgumentParser()
parser.add_argument("--input", default="question.json")
args = parser.parse_args()
# load the tokenizer and the model
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(
model_name,
torch_dtype="auto",
device_map="auto"
)
# the token the model would emit for each option as the first assistant token
option_token_ids = [tokenizer.encode(opt, add_special_tokens=False)[0] for opt in options]
def format_prompt(item):
prompt = item["question"] + "\n"
for opt in options:
prompt += f"{opt}. {item[opt]}\n"
prompt += "Answer:"
messages = [
{"role": "user", "content": prompt}
]
return tokenizer.apply_chat_template(
messages,
tokenize=False,
add_generation_prompt=True,
enable_thinking=False
)
with open(args.input) as f:
item = json.load(f)
model_inputs = tokenizer(format_prompt(item), return_tensors="pt").to(model.device)
with torch.no_grad():
logits = model(**model_inputs).logits[0, -1]
# constrained decoding: only the option tokens are allowed
probs = torch.softmax(logits[option_token_ids].float(), dim=-1)
print(f"prediction: {options[probs.argmax().item()]}")
for opt, prob in zip(options, probs.tolist()):
print(f"{opt}: {prob:.4f} {item[opt]}")
针对一个简单问题进行测试,输出如下:
// input
{
"question": "What color is the sky?",
"A": "Red",
"B": "Blue",
"C": "Green",
"D": "Purple",
"E": "I don't know"
}
// output
prediction: B
A: 0.0000 Red
B: 0.9988 Blue
C: 0.0000 Green
D: 0.0000 Purple
E: 0.0012 I don't know
模型能够理解输入并做出与正确答案对应的预测。
为了评估模型的准确性,可在公开数据集上运行测试。针对 CommonsenseQA 的一个随机样本保留集进行的测试结果如下:
precision recall f1 support
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
accuracy: 725/1221 = 0.5938
macro f1: 0.5844
对于 1.7B 参数的模型而言,该表现尚可。通过对数据集进行快速微调,性能略有提升:
precision recall f1 support
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
accuracy: 762/1221 = 0.6241
macro f1: 0.6234
测试模型对一个模棱两可的问题揭示了校准问题:
// input
{
"question": "Where would you most likely find a bat?",
"A": "Cave",
"B": "Baseball game",
"C": "Attic",
"D": "Zoo",
"E": "Sporting goods store"
}
// output
prediction: A
A: 0.9978 Cave
B: 0.0004 Baseball game
C: 0.0017 Attic
D: 0.0000 Zoo
E: 0.0001 Sporting goods store
在此案例中,并无明确唯一的答案,但将输出概率视为伪“信心”得分时,显示模型对该答案存在极度的过度自信。
模型的信心与其实际准确率不匹配,表明模型未经过校准:
bin count confidence accuracy
(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] 26 0.3761 0.2692
(0.40, 0.50] 41 0.4538 0.2683
(0.50, 0.60] 70 0.5490 0.3286
(0.60, 0.70] 74 0.6476 0.3649
(0.70, 0.80] 77 0.7495 0.4286
(0.80, 0.90] 121 0.8555 0.4711
(0.90, 1.00] 809 0.9855 0.7009
数据显示,模型在 0.9 - 1.0 置信度区间内倾向于极度过度自信,尽管其声称拥有高信心,但只有 70% 的时间是正确的。当模型以 0.8 - 0.9 的信心做出预测时,准确率仅为 40%。这意味着该模型在预测中普遍存在过度自信现象。
为了使模型的输出得分反映其实际准确性,可以通过温度缩放(Temperature Scaling)进行校准。修改温度值可以平滑其输出概率分布曲线。
实验发现,将温度值设置为 3.797280788421631 可获得较好的效果:
bin count confidence accuracy
(0.00, 0.10] 0 0.0000 0.0000
(0.10, 0.20] 0 0.0000 0.0000
(0.20, 0.30] 82 0.2712 0.2317
(0.30, 0.40] 217 0.3507 0.3917
(0.40, 0.50] 199 0.4472 0.5126
(0.50, 0.60] 166 0.5475 0.5482
(0.60, 0.70] 139 0.6562 0.5827
(0.70, 0.80] 140 0.7492 0.7714
(0.80, 0.90] 169 0.8507 0.7988
(0.90, 1.00] 109 0.9333 0.9541
经过校准后,置信度与准确率的匹配程度显著提高。相关脚本已备份至 GitHub,可用于构建数据集、评估、微调和校准自定义模型。建议在更大型的模型上尝试此方法。





