大模型是如何读懂人类语言的?它们的智慧从何而来?答案的起点是分词Tokenization:大模型处理文本的第一步。
分词不仅将句子拆解成可理解的“零件”,还为后续的词嵌入、训练和推理奠定了基础。本文将带你深入探索大模型的文本处理流程。
注:揭秘大模型的魔法属于连载文章,一步步带你打造一个大模型。
大模型的“魔法”起点
大模型无法直接处理字符串,需将文本拆为词元(Token,如单词、子词或字符),并转为数字表示。分词影响模型对语言的理解和生成。例如,“我爱学习”可能拆为["我", "爱", "学习"]或["我", "爱", "学", "习"],而英文“AI changes the world”可能拆为["AI", "changes", "the", "world"]。拆分方式决定语义捕捉的精度。
分词的重要性
语义分解:将复杂句子拆成最小语义单元。
统一输入:将不同语言、长度的文本转为固定格式。
生成基础:词元是模型生成文本的“积木”,支持句子重构。
多语言支持:统一处理中文、英文等语言。
文本处理的流程
01、文本分词:从句子到词元
什么是分词?
分词是将句子拆分成词元的过程,词元可以是单词、子词或字符。
例如:
中文:我爱学习
["我", "爱", "学习"] 或 ["我", "爱", "学", "习"]
英文:AI changes the world
["AI", "changes", "the", "world"] 或 ["AI", "change", "##s", "the", "world"]
字符级别:我爱学习 → ["我", "爱", "学", "习"];AI → ["A", "I"]
02、创建词元ID:从词元到数字
什么是词元ID?
词元ID是词元在词表中的唯一编号。词表是高频词元的集合,创建词元ID需统计词频并分配ID。例如,词表{"AI": 0, "changes": 1, "the": 2, "world": 3}将“AI changes the world”转为[0, 1, 2, 3]。
实现方式:统计词频,提取高频词元。构建词表,包含特殊词元(如[UNK])。映射ID。
03、特殊上下文词元:模型的“导航标”
什么是特殊词元?
特殊词元是添加的标记,帮助模型理解上下文,包括:
CLS(BERT):表示句子语义。
SEP(BERT):分隔句子或标记结束。
BOS/EOS(GPT):标记序列开始/结束。
PAD:填充统一长度。
UNK:表示未知词。
作用:提供结构信息。统一序列长度。处理异常输入.
04、词嵌入:赋予词元“语义灵魂”
什么是词嵌入?
词嵌入将词元ID映射为高维向量,捕捉语义关系。例如,“AI”和“technology”向量接近。
实现方式:静态嵌入:如Word2Vec。
动态嵌入:BERT、GPT在训练时学习。
工具:PyTorch的nn.Embedding.
从词元到句子:重构语言的“魔法”
什么是词元到句子?大模型从词元ID重构句子,是生成任务的核心。
例如,ID序列[0, 1, 2, 3]通过词表{"AI": 0, "changes": 1, "the": 2, "world": 3}还原为“AI changes the world”。
实现方式:用分词器的decode或词表逆映射将ID转为词元。拼接词元,移除特殊词元(如[PAD])。
示例代码
import numpy as np# 1. 自定义中文的“词表” vocabvocab = {'你': 0, '好': 1, ',': 2, '我': 3, '是': 4, '写': 5, '代码': 6, '的': 7,'中年人': 8, '!': 9, '专注': 10, 'AI': 11, '知识': 12, '分享': 13, '。': 14}# 2. 反向词表id_to_token = {v: k for k, v in vocab.items()}# 3. 简易分词函数def simple_bpe_tokenize(text):if text == "你好,我是写代码的中年人!专注AI知识分享。":return ['你', '好', ',', '我', '是', '写', '代码', '的', '中年人', '!', '专注', 'AI', '知识', '分享', '。']else:raise ValueError("这个例子目前只支持指定中文句子哟~")# 4. token → iddef tokens_to_ids(tokens):return [vocab[token] for token in tokens]# 5. id → 向量(随机生成,固定随机种子保证每次一致)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)# === 实际执行流程 ===sentence = "你好,我是写代码的中年人!专注AI知识分享。"# 分词tokens = simple_bpe_tokenize(sentence)print("Tokenized:", tokens)# 转换为 IDtoken_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', '知识', '分享', '。']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]知识 -> [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知识分享。
经过本章学习:从句子到分词,从分词到词元,从词元到向量,再从词元到句子,我们能基本了解大模型的运行流程,这里不做深入探讨,后边文章我们再一步步实现。
1024