受限解码构建校准概率决策模型

受限解码可构建校准概率决策模型。通过掩码将输出锁定在预设选项,单次前向传播即可选出最高概率答案,避免多次传输。但原始置信度分数未必反映真实正确率,需额外处理以确保概率校准。

基于受限解码构建校准概率的决策模型

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

微调后准确率升至62.41%

在未采用推测解码等推理优化技术的情况下,生成最终输出可能需要多次传输。例如,在某些示例中,需要 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,可用于构建数据集、评估、微调和校准自定义模型。建议在更大型的模型上尝试此方法。

评论 0

0/500

评论需审核后展示,请文明发言

💬
还没有评论,来说两句

相关阅读