大模型是如何讀懂人類語言的?它們的智慧從何而來?答案的起點(diǎn)是分詞Tokenization:大模型處理文本的第一步。
分詞不僅將句子拆解成可理解的“零件”,還為后續(xù)的詞嵌入、訓(xùn)練和推理奠定了基礎(chǔ)。本文將帶你深入探索大模型的文本處理流程。
注:揭秘大模型的魔法屬于連載文章,一步步帶你打造一個(gè)大模型。
大模型的“魔法”起點(diǎn)
大模型無法直接處理字符串,需將文本拆為詞元(Token,如單詞、子詞或字符),并轉(zhuǎn)為數(shù)字表示。分詞影響模型對(duì)語言的理解和生成。例如,“我愛學(xué)習(xí)”可能拆為["我", "愛", "學(xué)習(xí)"]或["我", "愛", "學(xué)", "習(xí)"],而英文“AI changes the world”可能拆為["AI", "changes", "the", "world"]。拆分方式?jīng)Q定語義捕捉的精度。
分詞的重要性
語義分解:將復(fù)雜句子拆成最小語義單元。
統(tǒng)一輸入:將不同語言、長度的文本轉(zhuǎn)為固定格式。
生成基礎(chǔ):詞元是模型生成文本的“積木”,支持句子重構(gòu)。
多語言支持:統(tǒng)一處理中文、英文等語言。
文本處理的流程
01、文本分詞:從句子到詞元
什么是分詞?
分詞是將句子拆分成詞元的過程,詞元可以是單詞、子詞或字符。
例如:
中文:我愛學(xué)習(xí)
["我", "愛", "學(xué)習(xí)"] 或 ["我", "愛", "學(xué)", "習(xí)"]
英文:AI changes the world
["AI", "changes", "the", "world"] 或 ["AI", "change", "##s", "the", "world"]
字符級(jí)別:我愛學(xué)習(xí) → ["我", "愛", "學(xué)", "習(xí)"];AI → ["A", "I"]
02、創(chuàng)建詞元ID:從詞元到數(shù)字
什么是詞元ID?
詞元ID是詞元在詞表中的唯一編號(hào)。詞表是高頻詞元的集合,創(chuàng)建詞元ID需統(tǒng)計(jì)詞頻并分配ID。例如,詞表{"AI": 0, "changes": 1, "the": 2, "world": 3}將“AI changes the world”轉(zhuǎn)為[0, 1, 2, 3]。
實(shí)現(xiàn)方式:統(tǒng)計(jì)詞頻,提取高頻詞元。構(gòu)建詞表,包含特殊詞元(如[UNK])。映射ID。
03、特殊上下文詞元:模型的“導(dǎo)航標(biāo)”
什么是特殊詞元?
特殊詞元是添加的標(biāo)記,幫助模型理解上下文,包括:
CLS(BERT):表示句子語義。
SEP(BERT):分隔句子或標(biāo)記結(jié)束。
BOS/EOS(GPT):標(biāo)記序列開始/結(jié)束。
PAD:填充統(tǒng)一長度。
UNK:表示未知詞。
作用:提供結(jié)構(gòu)信息。統(tǒng)一序列長度。處理異常輸入.
04、詞嵌入:賦予詞元“語義靈魂”
什么是詞嵌入?
詞嵌入將詞元ID映射為高維向量,捕捉語義關(guān)系。例如,“AI”和“technology”向量接近。
實(shí)現(xiàn)方式:靜態(tài)嵌入:如Word2Vec。
動(dòng)態(tài)嵌入:BERT、GPT在訓(xùn)練時(shí)學(xué)習(xí)。
工具:PyTorch的nn.Embedding.
從詞元到句子:重構(gòu)語言的“魔法”
什么是詞元到句子?大模型從詞元ID重構(gòu)句子,是生成任務(wù)的核心。
例如,ID序列[0, 1, 2, 3]通過詞表{"AI": 0, "changes": 1, "the": 2, "world": 3}還原為“AI changes the world”。
實(shí)現(xiàn)方式:用分詞器的decode或詞表逆映射將ID轉(zhuǎn)為詞元。拼接詞元,移除特殊詞元(如[PAD])。
示例代碼
import?numpy?as?np
# 1. 自定義中文的“詞表” vocab
vocab = {
? ??'你':?0,?'好':?1,?',':?2,?'我':?3,?'是':?4,?'寫':?5,?'代碼':?6,?'的':?7,
? ??'中年人':?8,?'!':?9,?'專注':?10,?'AI':?11,?'知識(shí)':?12,?'分享':?13,?'。':?14
}
# 2. 反向詞表
id_to_token = {v: k?for?k, v?in?vocab.items()}
# 3. 簡(jiǎn)易分詞函數(shù)
def?simple_bpe_tokenize(text):
? ??if?text ==?"你好,我是寫代碼的中年人!專注AI知識(shí)分享。":
? ? ? ??return?['你',?'好',?',',?'我',?'是',?'寫',?'代碼',?'的',?'中年人',?'!',?'專注',?'AI',?'知識(shí)',?'分享',?'。']
? ??else:
? ? ? ??raise?ValueError("這個(gè)例子目前只支持指定中文句子喲~")
# 4. token → id
def?tokens_to_ids(tokens):
? ??return?[vocab[token]?for?token?in?tokens]
# 5. id → 向量(隨機(jī)生成,固定隨機(jī)種子保證每次一致)
def?id_to_vector(token_id, dim=4):
? ? np.random.seed(token_id)
? ??return?np.round(np.random.rand(dim),?3)
# 6. id → 還原文本
def?ids_to_text(token_ids):
? ? tokens = [id_to_token[i]?for?i?in?token_ids]
? ??return?''.join(tokens)
# === 實(shí)際執(zhí)行流程 ===
sentence =?"你好,我是寫代碼的中年人!專注AI知識(shí)分享。"
# 分詞
tokens = simple_bpe_tokenize(sentence)
print("Tokenized:", tokens)
# 轉(zhuǎn)換為 ID
token_ids = tokens_to_ids(tokens)
print("Token IDs:", token_ids)
# 模擬向量表示
vectors = [id_to_vector(i)?for?i?in?token_ids]
print("Token Vectors:")
for?i, vec?in?zip(tokens, vectors):
? ??print(f" ?{i}?->?{vec}")
# 模擬還原文本
reconstructed = ids_to_text(token_ids)
print("Reconstructed Sentence:", reconstructed)
# 輸出
Tokenized: ['你',?'好',?',',?'我',?'是',?'寫',?'代碼',?'的',?'中年人',?'!',?'專注',?'AI',?'知識(shí)',?'分享',?'。']
Token IDs: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
Token Vectors:
? 你 -> [0.549 0.715 0.603 0.545]
? 好 -> [0.417 0.72 ?0. ? ?0.302]
? , -> [0.436 0.026 0.55 ?0.435]
? 我 -> [0.551 0.708 0.291 0.511]
? 是 -> [0.967 0.547 0.973 0.715]
? 寫 -> [0.222 0.871 0.207 0.919]
? 代碼 -> [0.893 0.332 0.821 0.042]
? 的 -> [0.076 0.78 ?0.438 0.723]
? 中年人 -> [0.873 0.969 0.869 0.531]
? ! -> [0.01 ?0.502 0.496 0.134]
? 專注 -> [0.771 0.021 0.634 0.749]
? AI -> [0.18 ?0.019 0.463 0.725]
? 知識(shí) -> [0.154 0.74 ?0.263 0.534]
? 分享 -> [0.778 0.238 0.824 0.966]
? 。 -> [0.514 0.773 0.87 ?0.008]
Reconstructed Sentence: 你好,我是寫代碼的中年人!專注AI知識(shí)分享。
經(jīng)過本章學(xué)習(xí):從句子到分詞,從分詞到詞元,從詞元到向量,再從詞元到句子,我們能基本了解大模型的運(yùn)行流程,這里不做深入探討,后邊文章我們?cè)僖徊讲綄?shí)現(xiàn)。