You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Llama-2-7b-chat-hf生成Token概率显示100%异常问题排查

Llama-2生成Token概率异常问题的分析与修正

问题背景

用户希望查看Llama-2-7b-chat-hf针对提示语Could you give me 3 cities located in Europe ?生成每个token的真实概率,以评估模型置信度,编写了如下代码:

from transformers import LlamaForCausalLM, LlamaTokenizer, AutoModelForCausalLM, AutoTokenizer
import torch
import numpy as np

device = "cuda:0" if torch.cuda.is_available() else "cpu"

model=LlamaForCausalLM.from_pretrained("Llama-2-7b-chat-hf").to(device)
tokenizer= LlamaTokenizer.from_pretrained("Llama-2-7b-chat-hf")

prompt = "Could you give me 3 cities located in Europe ?"

inputs = tokenizer([prompt], return_tensors="pt").to(device)

outputs=model.generate(**inputs,return_dict_in_generate=True, output_scores=True,max_new_tokens=75)

transition_scores = model.compute_transition_scores(outputs.sequences, outputs.scores, normalize_logits=True)

input_length = 1 if model.config.is_encoder_decoder else inputs.input_ids.shape[1]
generated_tokens = outputs.sequences[:,input_length:]

for tok, score in zip(generated_tokens[0], transition_scores[0]):
        # | token | token string | logits | probability
            print(f"| {tok:5d} | {tokenizer.decode(tok):8s} | {score.numpy(force=True):.4f} | {np.exp(score.numpy(force=True)):.2%}")

运行后输出多数token的选中概率为100%,显然不符合逻辑(Llama-2词表含32000个token,合理概率不应为100%),因此判断代码存在问题,请求定位错误。

问题分析

认同该判断,代码核心错误在于compute_transition_scores的参数设置:

  • 错误根源:当normalize_logits=True时,函数会返回归一化后的对数概率——即当前生成token的对数概率,减去所有token对数概率的logsumexp值。对于模型选出的概率最高的token,这个归一化后的值会趋近于0,指数化后就显示为100%,但这并非该token在原始概率分布中的真实占比,而是相对归一化的结果。

修正方案

将normalize_logits设为False,即可获取模型输出的原始对数概率,指数化后得到该token在整个词表中的真实概率占比。修正后的代码如下:

from transformers import LlamaForCausalLM, LlamaTokenizer
import torch
import numpy as np

device = "cuda:0" if torch.cuda.is_available() else "cpu"

model = LlamaForCausalLM.from_pretrained("Llama-2-7b-chat-hf").to(device)
tokenizer = LlamaTokenizer.from_pretrained("Llama-2-7b-chat-hf")

prompt = "Could you give me 3 cities located in Europe ?"

inputs = tokenizer([prompt], return_tensors="pt").to(device)

# 生成时保留输出分数
outputs = model.generate(**inputs, return_dict_in_generate=True, output_scores=True, max_new_tokens=75)

# 关闭归一化,获取原始对数概率
transition_scores = model.compute_transition_scores(outputs.sequences, outputs.scores, normalize_logits=False)

input_length = inputs.input_ids.shape[1]
generated_tokens = outputs.sequences[:, input_length:]

# 打印格式化结果
print("| token | token string | logits | probability")
for tok, score in zip(generated_tokens[0], transition_scores[0]):
    prob = np.exp(score.numpy(force=True))
    print(f"| {tok:5d} | {tokenizer.decode(tok):8s} | {score.numpy(force=True):.4f} | {prob:.2%}")

另一种直接从outputs.scores计算真实概率的方式:

# 遍历每个生成步骤的分数
for i, score_logits in enumerate(outputs.scores):
    # 对logits做softmax得到全词表概率分布
    full_probs = torch.softmax(score_logits, dim=-1)
    # 获取当前生成的token及其概率
    generated_tok = generated_tokens[0][i]
    tok_prob = full_probs[0, generated_tok].item()
    tok_str = tokenizer.decode(generated_tok)
    # 计算对数概率并打印
    log_prob = torch.log(full_probs[0, generated_tok]).item()
    print(f"| {generated_tok:5d} | {tok_str:8s} | {log_prob:.4f} | {tok_prob:.2%}")

修正效果:修正后输出的概率为该token在整个32000词表中的真实占比,不会出现100%的异常值,能准确反映模型生成该token的置信度。

内容的提问来源于stack exchange,提问作者Zerokerim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 00:37:07