程式碼同步更新在 Github
在深入了解大型語言模型(LLM)之前,我們首先需要澄清一個概念,這也是許多人初次接觸時可能產生的困惑:AI 和 LLM 到底有什麼區別?
AI (人工智慧) 是一個包含非常廣泛範疇的術語,它涉及到設計和開發會「思考」、「學習」以及「做決策」的系統。AI 技術已經滲透到各行各業,例如自動駕駛、圖像識別、推薦系統等等。可以說,凡是透過計算機模擬或執行人類智能任務的技術,都可以被稱為 AI。
LLM (大型語言模型),可以視為 AI 的一個子集或特化分支。LLM 是一種專門處理語言的 AI 模型,它的主要職責是「理解」和「生成」自然語言文本。
換句話說,AI 是一個大範疇,而 LLM 是專門針對語言處理任務的其中一種 AI 應用 。AI 涉及到了所有智能任務,而 LLM 則專注於文本理解與生成。
(圖片來源:【生成式AI導論 2024】第1講:生成式AI是什麼?)
大型語言模型 (Large Language Model, LLM) 是一種由大量文本文本訓練而成的人工智慧技術。簡單來說,它是一個經過訓練,能夠理解和生成自然語言 (如我們在講的英文、中文等) 文本的 AI 模型。這些模型大多採用了深度學習技術,例如「Transformer」架構來處理語言資訊。你可以想像 LLM 是一個超強大的語言助手,能「讀懂」人類的語言並進行有意義的回應。
你可以把大型語言模型當成一個很大的、有上萬個參數的函式 (function),該函式的功能就是「預測下一個字」。當輸入一個字串後,模型會根據你輸入的字串來做「文字接龍」。這種行為在專業術語中稱為「模型推論 (model inference)」,即將資料輸入模型並由模型預測結果的過程。在預測下一個字的過程中,模型實際上會為每一個可能的字計算出一個機率。這些機率代表了模型對每個字作為下一個字的信心程度。
ChatGPT 背後使用的 Transformer 架構是一種自迴歸模型 (autoregressive model),這種策略表示模型在生成文本時,會根據先前生成的字元或詞彙來預測下一個字。模型根據計算出的機率選擇最可能出現的字,並將這個新增的字串重新輸入模型中進行推論,直到模型輸出結束符號為止。
以下是一個簡單的例子,我給這個模型輸入「我喜歡」,它的輸出「吃蘋果」過程
模型本身其實看不懂中文字 (試想,有哪個數學式的輸入是數字以外的呢?),所以我們要先將輸入的字串轉化成詞元 (token),可以把它想成一個數字的代號。這個將輸入轉換成詞元的工具就叫做分詞器 (tokenizer)。以下是使用 transformer 套件,用 GPT2 來做文字接龍的例子。
安裝套件
pip install transformer -U
pip install torch
撰寫程式碼,這邊的 input_string
就是我們給模型的輸入
from transformers import GPT2LMHeadModel, GPT2Tokenizer
# 載入預訓練的 GPT-2 模型和分詞器
model_name = "gpt2"
model = GPT2LMHeadModel.from_pretrained(model_name) # 載入模型
tokenizer = GPT2Tokenizer.from_pretrained(model_name) # 載入分詞器
# 設定輸入的字串
input_string = "I love you, but"
# 將字串編碼為模型可以接受的格式,也就是 token
input_ids = tokenizer.encode(input_string, return_tensors='pt')
# 生成後續文本
output = model.generate(
input_ids, # 輸入的 token
max_length=100, # 生成文本的最大長度
num_return_sequences=1, # 生成幾個句子
no_repeat_ngram_size=2 # 避免重複的 n-gram,這邊的 n-gram 是指連續的 n 個詞
)
# 原始輸出
print("raw output:")
print(output)
# 解碼生成的 id 為字串
generated_text = tokenizer.decode(output[0], skip_special_tokens=True)
# 人看得懂的輸出
print("output:")
print(generated_text)
執行檔案並輸出結果
raw output:
tensor([[ 40, 1842, 345, 11, 475, 314, 1101, 407, 1016, 284,
1309, 345, 467, 13, 314, 836, 470, 765, 284, 766,
345, 4656, 13, 921, 821, 407, 616, 1545, 13, 198,
198, 1, 40, 1101, 7926, 11, 314, 1422, 470, 1612,
284, 5938, 345, 13, 887, 314, 760, 345, 821, 1016,
832, 257, 1256, 13, 632, 338, 407, 588, 314, 460,
655, 1309, 340, 467, 526, 198, 13, 764, 764, 198,
357, 464, 1306, 1110, 11, 262, 1306, 3329, 11, 290,
262, 1110, 706, 326, 11, 339, 373, 287, 262, 4436,
351, 257, 5445, 1232, 2014, 198, 11, 764, 22135, 198]])
output:
I love you, but I'm not going to let you go. I don't want to see you die. You're not my friend.
"I'm sorry, I didn't mean to hurt you. But I know you're going through a lot. It's not like I can just let it go."
...
(The next day, the next morning, and the day after that, he was in the hospital with a broken leg.)
,.."
上面的 raw output 就是模型輸出的結果,「tensor (張量)」是一種資料結構,有點像陣列,這個是人看不懂的所以還需要用分詞器再將它轉換成人看得懂的字。可以看到我的輸入是 “I love you, but”,模型則幫我些下去 “but I’m not going to let you go…”。
所以今天不論你看到什麼聊天機器人 (chatbot)、什麼智能體 (agent) 等一些好像很複雜的東西,先不要慌張,要記得他們的本質都是這個可以文字接龍的函式,沒有甚麼魔法。就好像晶片設計的底層也是基礎的邏輯閘。作為應用端初學者,我們可以不用理解複雜的數學,什麼線性代數、什麼詞向量詞嵌入,甚至不需要懂 Transformer 架構,但你一定要知道一件事:這些技術實際上都是文字接龍的延伸,只是我們用各種技巧讓它可以做到遠的不只文字街龍。
明天開始我們就要來使用 API 呼叫模型,用更簡單更抽象的方式來與模型對話吧!