LLM 温度是一个参数,它控制着 LLM 预测的下一个单词的概率分布。它通过改变下一个单词被选中的可能性,为 LLM 的输出增加了一些随机性或多样性。温度可以影响 LLM 的输出,使其更确定 (可预测) 或更随机 (随机),这样的参数被用来模拟或模仿人类语言产生的内在变化。
在生产环境中,较低的温度值 (<1) 可以导致更确定或可预测的 LLM 输出,称为使 LLM 更 “可预测”。温度为 1 默认为在训练中学到的 LLM 固有的单词分布,反映了Softmax未改变的输出。较高的温度值 (> 1) 可以导致更随机或随机和多变的 LLM 输出,被称为使 LLM 更 “创造性”。然而,“创造性” 这个词可能用词不当,因为产生更多不同的输出并不一定等同于创造性。
当温度值设置为 0 时,大多数系统会触发对下一个单词预测的贪婪采样,这只是以词汇表中概率最高的单词进行采样。在某些情况下,如果温度值太高 (> 2) 或太低 (= 0) ,这可能会引发退化行为,如 LLM 幻觉。LLM 中的幻觉指的是看似合理但事实上不正确的输出,或者是不连贯和无意义的文本。这个术语在隐喻上类似于一个人如何感知那些并不真实存在的东西。
值得注意的是,温度值在 0 到 2 之间并不能消除幻觉;相反,它们在输出中引入了随机性和多样性,这可能会根据上下文增加或减少幻觉。为了减轻幻觉,可以采用检索增强生成 (RAG)、思维链 (CoT) 等策略来提高 LLM 生成文本的准确性和连贯性。
Softmax激活函数是一种数学变换,将原始分数的向量转换为概率分布。为此,它对每个值进行指数运算,并对所有指数运算值的和进行规范化,以便它们的和等于 1。它最初应用于 1868 年左右的物理学和统计学,被称为玻尔兹曼分布或吉布斯分布。术语 “softmax” 是由 John s. Bridle 在 1989 年创造的。
在自然语言处理 (NLP) 中,Softmax激活函数通常应用于 LLM 生成的 logits,从而对可能的下一个令牌产生概率分布。该分布表示每个标记成为序列中下一个字或子字的可能性。
温度 (t) 参数是对调节输入的Softmax激活函数的一个简单修改:
“温度” 这个术语是从物理学领域借来的。它来源于它与波兹曼分布的关系,后者描述了能量状态如何随温度变化。早在 1985 年,Ackley 及其同事就在机器学习中使用了术语 “温度”。
例如,给定一个数字列表,计算它们的 softmax 概率。 list=[2.0,4.0,3.0]
#Calculating Softmax
import torch
import torch.nn.functional as F
#1) Using Our Function
#Define a softmax function
def my_softmax(input_vector):
e = np.exp(input_vector)
return e / e.sum()
list_in = [2.0, 4.0, 3.0]
output = my_softmax(list_in)
print(f"\nThe softmax probabilities are: \n {output}")
#2) Using PyTorch Function
#Convert list to torch tensor
list_in_torch = torch.tensor(list_in)
output = F.softmax(list_in_torch, dim=0)
print(f"\nThe softmax probabilities (using Pytorch) are: \n {output}")
输出结果如下:
The softmax probabilities are:
[0.09003057 0.66524096 0.24472847]
The softmax probabilities (using Pytorch) are:
tensor([0.0900, 0.6652, 0.2447])
给定一个来自 LLM 的 logit 输出列表,找到最可能的单词及其概率。假设 LLM 只知道 5 个单词 (LLM 词汇通常包含数千个单词),计算温度为 1.0 和 100.0 的概率。
index=[0,1,2,3,4]
words=[ceiling,floor,mat,car,grass]
logits=[−49.82,−46.40,−45.25,−47.30,−48.32]
Temperature: 1.0
python 代码如下:
# Assume for simplicity:
# * The model only knows the 5 words listed below (it has a vocabulary of 5).
import pandas as pd
import seaborn as sns
#Example model output
model_output_vals = {"word_index":[i for i in range(5)],
"words":["ceiling", "floor", "mat", "car", "grass"],
"logits":[-49.82, -46.40, -45.25, -47.30, -48.32]}
temp = 1.0
#Convert the data to a DataFrame
model_output = pd.DataFrame(model_output_vals)
#Define a softmax function with temperature
def my_softmax(input_vector, Temp=1.0):
e = np.exp(np.divide(input_vector,Temp))
return e / e.sum()
#Calculate the probabilities
probs = my_softmax(model_output["logits"], Temp=temp)
model_output["softmax_prob"] = probs
#Select the most probable word
most_prob = np.argmax(probs)
print(f"\nThe index of the most probable word is: {most_prob}")
#Pull out the most probable word
print(f"\nThe most probable word is: { model_output['words'][most_prob] }" \
f" (Prob: {model_output['softmax_prob'][most_prob]:.5f})")
#Style our table
cm = sns.light_palette("orange", as_cmap=True)
s1 = model_output
s1 = s1.style.background_gradient(subset=["logits"],cmap=cm)
cm = sns.light_palette("green", as_cmap=True)
s1.background_gradient(subset=["softmax_prob"],cmap=cm)
输出结果如下:
The index of the most probable word is: 2
The most probable word is: mat (Prob: 0.66571)
从 softmax 概率中我们看到最可能的单词是: mat,概率约为0.666
如果 Temperature: 100.0,那么
# Example Softmax Calculation
# Assume for simplicity:
# * The model only knows the 5 words listed below (it has a vocabulary of 5).
import pandas as pd
import seaborn as sns
#Example model output
model_output_vals = {"word_index":[i for i in range(5)],
"words":["ceiling", "floor", "mat", "car", "grass"],
"logits":[-49.82, -46.40, -45.25, -47.30, -48.32]}
temp = 100.0
#Convert the data to a DataFrame
model_output = pd.DataFrame(model_output_vals)
#Define a softmax function with temperature
def my_softmax(input_vector, Temp=1.0):
e = np.exp(np.divide(input_vector,Temp))
return e / e.sum()
#Calculate the probabilities
probs = my_softmax(model_output["logits"], Temp=temp)
model_output["softmax_prob"] = probs
#Select the most probable word
most_prob = np.argmax(probs)
print(f"\nThe index of the most probable word is: {most_prob}")
#Pull out the most probable word
print(f"\nThe most probable word is: { model_output['words'][most_prob] }" \
f" (Prob: {model_output['softmax_prob'][most_prob]:.5f})")
#Style our table
cm = sns.light_palette("orange", as_cmap=True)
s1 = model_output
s1 = s1.style.background_gradient(subset=["logits"],cmap=cm)
cm = sns.light_palette("green", as_cmap=True)
s1.background_gradient(subset=["softmax_prob"],cmap=cm)
输出结果为:
The index of the most probable word is: 2
The most probable word is: mat (Prob: 0.20436)
从 softmax 概率中,我们看到最可能的单词是: mat,概率为: 0.204
随着温度从 1.0 升高到 100.0,概率分布从更加集中 (或 “尖峰”) 转变为更加分散 (或 “平坦”) ,这意味着在较低温度下概率较低的单词被选中的几率更高。使用贪婪抽样,总是选择概率最高的单词,模型一致地选择排名最高的单词。
考察温度参数如何影响大模型的输出,我们将使用GPT-2, 这个由 OpenAI 开发的开源文本生成模型,可以通过Hugging Face 获得。GPT-2 具有以下特点:
我们将探索如何将 LLM 用于两种类型的任务:
单个的下一个单词生成: 根据给定输入的上下文预测下一个单词。 连续的下一个单词生成: 生成一个单词序列,根据先前生成的单词预测每个新单词。
from transformers import AutoModelForCausaLLM, AutoTokenizer
model_to_load = "openai-community/gpt2"
model_to_load_task = "text-generation"
# Load the model's pretrained tokenizer
tokenizer = AutoTokenizer.from_pretrained(model_to_load)
# Load the pretrained model
model = AutoModelForCausaLLM.from_pretrained(
model_to_load,
device_map = device, #CPU or GPU
torch_dtype = "auto",
trust_remote_code = True
)
To pass inputs to the model we can run the following:
# Input sentence
prompt = "The cat sat on the"
temperature = 0.5
# Tokenize/encode input prompt
input_ids = tokenizer.encode(prompt, return_tensors="pt")
# Generate the output with adjusted temperature
outputs = model.generate(input_ids,
max_new_tokens=1, #Just want one word generated
temperature=temperature, #Set temp
output_scores=True, #Output model word scores
output_logits=True, #Outout logits
return_dict_in_generate=True,
do_sample=True, #Perform sampling for next word
pad_token_id=tokenizer.eos_token_id)
# Get the generated token ID/next word
generated_token_id = outputs.sequences[0][-1].item()
# Decode the generated token ID to a word
generated_word = tokenizer.decode([generated_token_id])
在单个的下一个词生成中,gpt-2 被给定一个初始输入序列 (例如一个部分句子) 并预测最有可能的下一个词。该模型根据序列中前面的单词提供的上下文进行预测。一旦下一个单词被预测,它就会被输出,这个过程就停止了,意思是一次只生成一个单词. 根据模型的学习关联,基于最高概率选择单词,并且除非使用新的输入重复该过程,否则不会发生进一步的预测。
输入: The cat slept on the ______.
prompt = "The cat slept on the"
temps = [0.1, 0.5, 1., 5., 10., 100.]
for ii in temps:
word_out = next_word_prediction(prompt, temp=ii)
print(f"LLM Temperature: {ii} \n {prompt} {word_out}")
这里我们将相同的输入句子以不同的温度值传递给 LLM,然后查看模型词汇表中选择单词的概率分布。
LLM Temperature: 0.1 Input : The cat slept on the Output: The cat slept on the floor
LLM Temperature: 0.5 Input : The cat slept on the Output: The cat slept on the bed
LLM Temperature: 1.0 Input : The cat slept on the Output: The cat slept on the back
LLM Temperature: 5.0 Input : The cat slept on the Output: The cat slept on the bathroom
LLM Temperature: 10.0 Input : The cat slept on the Output: The cat slept on the corner
LLM Temperature: 100.0 Input : The cat slept on the Output: The cat slept on the inside
随着温度从 0.1 到 100.0 升高,概率分布从更加集中 (或 “尖峰”) 变得更加分散 (或 “平坦”) ,这意味着在较低温度下出现概率较低的单词被选中的几率更高。
在连续的下一个单词生成中,gpt-2 给出一个初始输入句子,并以自回归的方式预测下一个最可能的单词。该模型使用它建立的上下文,根据它已经预测的前一个单词生成每个单词。在预测下一个单词之后,它被添加到句子中,更新后的序列被传递回模型以进行下一次迭代。这个过程一直持续到满足以下两个条件之一: 模型生成序列结束标记 (例如 < eos> 或 \n) ,或者达到最大迭代次数 (或标记)。
我们将向 LLM 传递上述相同的句子,以查看它在如下所示的若干次迭代中将输出什么。
Input sentence: The cat slept on the ______
1: The cat slept on the floor ______
2: The cat slept on the floor next ______
3: The cat slept on the floor next to ______
4: The cat slept on the floor next to the ______
5: The cat slept on the floor next to the window ______
6: The cat slept on the floor next to the window . ______
7: The cat slept on the floor next to the window . < EOS >
我们将把提示词传递给 LLM,并将其预测的输出 (word _ out) 附加到提示词后面,然后继续迭代,直到达到最大迭代次数 (max _ gen _ iteration) 或者预测句子结束标记 ( 或 \n)。
prompt = "The cat slept on the"
temp = 0.5
max_gen_iteration = 20
for ii in range(max_gen_iteration):
word_out, probs_out = next_word_prediction(prompt, temp=temp)
print(prompt + word_out)
prompt += word_out
这里我们将相同的输入句子以不同的温度值传递给 LLM,然后查看模型词汇表中选择单词的概率分布。
Temp: 10.0 Parameters:
Input text: “The cat slept on the” Temperature: 10.0 Max iterations: 20
prompt = "The cat slept on the"
temp = 10.0
max_iter = 20
gen_next_word_loop(prompt, temp = temp, max_iter = max_iter)
当比较 0.5 和 10.0 两种温度下的输出时,我们观察到在 0.5 的温度下生成的文本更连贯,而在 10.0 的温度下,输出变得越来越不连贯,人类读者越来越难以理解。
这突出了温度参数是如何通过改变模型词汇表中可能的下一个单词的概率分布来影响连续生成单词的。
LLM 中的温度参数控制生成文本的随机性。较低的值导致更具确定性和一致性的输出,而较高的值增加多样性,但可能降低一致性。除了基本应用之外,业界也在探索基于输入上下文的动态温度调节,针对多任务学习等特定任务进行优化,控制连贯性和文本长度,以及影响情绪的基调。
随着技术的发展,可以期待看到增强的模型灵活性,允许跨不同应用程序的更上下文敏感、自适应和创造性的输出。
如果进一步了解大模型应用的开发, 推荐两本书——
【参考资料与关联阅读】