LLM 溫度是一個參數,它控制著 LLM 預測的下一個單詞的概率分布。它通過改變下一個單詞被選中的可能性,為 LLM 的輸出增加了一些隨機性或多樣性。溫度可以影響 LLM 的輸出,使其更確定 (可預測) 或更隨機 (隨機),這樣的參數被用來模擬或模仿人類語言產生的內在變化。
1. LLM Temperature 的簡要回顧
在生產環境中,較低的溫度值 (<1) 可以導致更確定或可預測的 LLM 輸出,稱為使 LLM 更 “可預測”。溫度為 1 默認為在訓練中學到的 LLM 固有的單詞分布,反映了Softmax未改變的輸出。較高的溫度值 (> 1) 可以導致更隨機或隨機和多變的 LLM 輸出,被稱為使 LLM 更 “創造性”。然而,“創造性” 這個詞可能用詞不當,因為產生更多不同的輸出并不一定等同于創造性。
當溫度值設置為 0 時,大多數系統會觸發對下一個單詞預測的貪婪采樣,這只是以詞匯表中概率最高的單詞進行采樣。在某些情況下,如果溫度值太高 (> 2) 或太低 (= 0) ,這可能會引發退化行為,如 LLM 幻覺。LLM 中的幻覺指的是看似合理但事實上不正確的輸出,或者是不連貫和無意義的文本。這個術語在隱喻上類似于一個人如何感知那些并不真實存在的東西。
值得注意的是,溫度值在 0 到 2 之間并不能消除幻覺;相反,它們在輸出中引入了隨機性和多樣性,這可能會根據上下文增加或減少幻覺。為了減輕幻覺,可以采用檢索增強生成 (RAG)、思維鏈 (CoT) 等策略來提高 LLM 生成文本的準確性和連貫性。
2. Softmax激活函數 與 LLM的溫度
Softmax激活函數是一種數學變換,將原始分數的向量轉換為概率分布。為此,它對每個值進行指數運算,并對所有指數運算值的和進行規范化,以便它們的和等于 1。它最初應用于 1868 年左右的物理學和統計學,被稱為玻爾茲曼分布或吉布斯分布。術語 “softmax” 是由 John s. Bridle 在 1989 年創造的。
在自然語言處理 (NLP) 中,Softmax激活函數通常應用于 LLM 生成的 logits,從而對可能的下一個令牌產生概率分布。該分布表示每個標記成為序列中下一個字或子字的可能性。
溫度 (t) 參數是對調節輸入的Softmax激活函數的一個簡單修改:
“溫度” 這個術語是從物理學領域借來的。它來源于它與波茲曼分布的關系,后者描述了能量狀態如何隨溫度變化。早在 1985 年,Ackley 及其同事就在機器學習中使用了術語 “溫度”。
2.1 無溫度的softmax 變換
例如,給定一個數字列表,計算它們的 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])
2.2 隨溫度變化的 Softmax 變換
給定一個來自 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,概率分布從更加集中 (或 “尖峰”) 轉變為更加分散 (或 “平坦”) ,這意味著在較低溫度下概率較低的單詞被選中的幾率更高。使用貪婪抽樣,總是選擇概率最高的單詞,模型一致地選擇排名最高的單詞。
3. LLM 的Temperature 應用
考察溫度參數如何影響大模型的輸出,我們將使用GPT-2, 這個由 OpenAI 開發的開源文本生成模型,可以通過Hugging Face 獲得。GPT-2 具有以下特點:
- 1.24 億個參數: 這些是模型中可學習的權重,幫助模型根據輸入數據進行預測。
- 50,257 詞匯量: 模型的詞匯量由一組符號 (使用字節對編碼的單詞或子詞) 組成,gpt-2 被訓練來識別和生成這些符號。
- 768 維向量嵌入大小: 這是指用于編碼每個令牌的稠密向量表示的大小。
- 12 個注意力頭: 這些是用于每個Transformer層的并行注意力機制,用于捕捉輸入序列關系的不同方面。
- 12 層: 該模型有 12 個轉換層,允許它處理和理解數據中更復雜的模式。
我們將探索如何將 LLM 用于兩種類型的任務:
單個的下一個單詞生成: 根據給定輸入的上下文預測下一個單詞。連續的下一個單詞生成: 生成一個單詞序列,根據先前生成的單詞預測每個新單詞。
3.1 模型構建
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])
3.2 單個的下一個單詞的生成
在單個的下一個詞生成中,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.1Input : The cat slept on theOutput: The cat slept on the floor
LLM Temperature: 0.5Input : The cat slept on theOutput: The cat slept on the bed
LLM Temperature: 1.0Input : The cat slept on theOutput: The cat slept on the back
LLM Temperature: 5.0Input : The cat slept on theOutput: The cat slept on the bathroom
LLM Temperature: 10.0Input : The cat slept on theOutput: The cat slept on the corner
LLM Temperature: 100.0Input : The cat slept on theOutput: The cat slept on the inside
隨著溫度從 0.1 到 100.0 升高,概率分布從更加集中 (或 “尖峰”) 變得更加分散 (或 “平坦”) ,這意味著在較低溫度下出現概率較低的單詞被選中的幾率更高。
3.3 連續的下一個單詞的生成
在連續的下一個單詞生成中,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.0Parameters:
Input text: “The cat slept on the”Temperature: 10.0Max 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 的溫度下,輸出變得越來越不連貫,人類讀者越來越難以理解。
這突出了溫度參數是如何通過改變模型詞匯表中可能的下一個單詞的概率分布來影響連續生成單詞的。
4. 小結
LLM 中的溫度參數控制生成文本的隨機性。較低的值導致更具確定性和一致性的輸出,而較高的值增加多樣性,但可能降低一致性。除了基本應用之外,業界也在探索基于輸入上下文的動態溫度調節,針對多任務學習等特定任務進行優化,控制連貫性和文本長度,以及影響情緒的基調。
隨著技術的發展,可以期待看到增強的模型靈活性,允許跨不同應用程序的更上下文敏感、自適應和創造性的輸出。