Part 2:分词与词向量详解 - 文本如何变成数字
学习目标:理解"为什么大模型不直接处理汉字/字母",掌握主流分词算法的适用场景,学会诊断"模型不懂专业术语"的根本原因
一、为什么需要分词?—— 计算机只认识数字
1.1 核心问题:AI 看不懂文字
想象一下,你教一个孩子认字:
- 你指着"苹果"说:这是"píng guǒ"
- 孩子问:"那数字'529'是什么意思?"
大模型也一样困境:计算机只认识数字,不认识文字。
所以必须做转换:
"今天天气很好"
↓ 转换成数字
[5293, 1234, 5678, 9876] ← 每个词变成唯一ID
↓ 再转换成向量
[[0.2, 0.8, ...], [0.6, 0.1, ...], ...] ← 向量表示语义
1.2 分词粒度的选择:细、粗、平衡
问题:怎么把一句话切成"词"?
| 策略 | 怎么做 | 优点 | 缺点 | 例子 |
|---|---|---|---|---|
| 字级 | 每个汉字单独切分 | 简单,无生词(OOV) | 序列长,语义割裂 | "你好"→["你","好"] |
| 词级 | 按词典切分成完整词 | 语义完整,序列短 | 新词爆炸,"绝绝子"切不出 | "苹果手机"→["苹果手机"] |
| 子词级 | 高频词完整,低频拆分 | 平衡方案,主流 | 实现复杂 | "unhappy"→["un","happy"] |
实际选择:子词级是目前绝对主流(GPT用BPE,BERT用WordPiece)。
二、主流分词算法:拼乐高 vs 概率思维
2.1 BPE(字节对编码)- "拼乐高"思维
核心思想:从最小的"字符块"开始,不断合并最常出现的相邻组合。
三步走流程:
Step 1:从字符开始
初始状态:"h e l l o" → 每个字符独立
词表:{"h","e","l","o"}
Step 2:统计相邻词对频率
出现次数:
"h"+"e" = 5次
"e"+"l" = 3次
"l"+"l" = 10次 ← 最常出现!
"l"+"o" = 4次
Step 3:合并最常出现的"l"+"l"
新词表:{"h","e","l","o","ll"}
"hello" 变成 ["h","e","ll","o"]
继续迭代...直到词表达到目标大小(如5万)
直观理解:
- 高频组合(如"ing"、"tion")会合并成一个token
- 低频词会被拆开(如"xylophone"→["x","y","l","o","p","h","o","n","e"])
- 类似拼乐高:常用模块先拼好,不常用的保持散件
优点:
- ✅ 简单高效,实现容易
- ✅ GPT系列同款,生态成熟
- ✅ 自动适应数据,无需人工词典
2.2 WordPiece(词片算法)- "保常用词"思维
核心思想:优先保证常见词的完整性,低频词才拆分。
关键特点:
- 在词表中用
##表示"这是词的中间部分"- "playing" →
["play", "##ing"] - "replay" →
["re", "##play"]("play"被完整保留)
- "playing" →
概率模型:
- 不是简单合并,而是最大化整个序列的"联合概率"
- 相当于:在多个切分方案中,选"整体看起来最可能"的那个
与BPE的区别:
| 对比项 | BPE(拼乐高) | WordPiece(概率派) |
|---|---|---|
| 合并标准 | 频率最高 | 联合概率最大 |
| 后缀标记 | 无 | 用 ##标记中间部分 |
| 设计哲学 | 高频组合优先 | 常用词完整优先 |
| 代表模型 | GPT系列 | BERT系列 |
例子对比:
"tokenization"这个词:
BPE: ["token", "ization"] (按频率合并)
WordPiece: ["token", "##ization"] (保留"token"完整,加前缀)
2.3 Unigram(一元模型)- "最可能切分"思维
核心思想:假设每个token独立生成,在所有可能切分方案中,选"整体概率最高"的。
工作流程:
- 准备一个初始大词表(如所有字符+常见组合)
- 计算一个切分方案的概率:
P(词序列) = P(词1) × P(词2) × ... - 用Viterbi算法找最优切分
优点:
- ✅ 灵活:可以输出多个候选切分方案(第1候选/第2候选)
- ✅ 适合多语言:同一词表可处理不同语言混合
缺点:
- 训练复杂度高,不如BPE快
- 应用相对较少(SentencePiece框架支持)
2.4 四种算法对比总结
┌────────────────────────────────────────────┐
│ 主流分词算法对比雷达图 │
│ │
│ 实现难度: BPE ★☆☆ WordPiece ★★☆ │
│ Unigram ★★★ │
│ │
│ 速度: BPE ★★★ WordPiece ★★☆ │
│ Unigram ★★☆ │
│ │
│ 效果: BPE ★★☆ WordPiece ★★★ │
│ Unigram ★★★ │
│ │
│ 灵活性: BPE ★★☆ WordPiece ★★☆ │
│ Unigram ★★★ │
└────────────────────────────────────────────┘
★ = 评分(1-3星)
结论:BPE胜在简单快速,WordPiece效果更好,Unigram灵活但慢
三、中文分词:新词爆炸的挑战
3.1 中文的独特难题
不像英文有空格:
- 英文:"Hello world" → 天然两个词
- 中文:"你好世界" → 该切哪?
新词爆炸:
- 传统词典跟不上网络流行语
- "绝绝子"(2021)、"栓Q"(2022)、"显眼包"(2023)...
- 每年都有大量新词出现
专业术语:
- 医疗:"心肌梗死" vs "心肌"+"梗死"
- 法律:"善意取得" vs "善意"+"取得"
- 切分错误会导致语义完全改变
3.2 中文解决方案:混合策略
核心思路:字级保底 + 子词补充
典型实现(SentencePiece):
预处理:
1. 按字符切分(字级,保证100%覆盖率)
2. 用BPE/Unigram训练,合并高频字符组合
3. 出现过的词如"区块链"→完整保留
4. 新词如"Web3.0"→可能切为["Web","3",".","0"]
效果:
- 旧词完整:["区块链", "人工智能"] ✅
- 新词拆分:["Chat", "##GPT"] ✅
- 无生词:任何汉字都能切出 ✅
中英文混合例子:
"Weekend去coffee shop喝咖啡"
↓
["Weekend", "去", "coffee", "shop", "喝", "咖啡"]
- "Weekend"完整(英文词)
- "coffee"完整(高频借词)
- "shop"完整(高频借词)
- 汉字正常处理
3.3 实战技巧:中文场景选型
| 场景 | 推荐方案 | 理由 |
|---|---|---|
| 通用中文 | BPE + 字级保底 | 简单有效,覆盖全面 |
| 专业领域 | 领域数据重新训练词表 | 增加专业术语完整度 |
| 中英混合 | SentencePiece统一处理 | 支持多语言混合 |
| 资源受限 | 字级分词(最简单) | 无OOV,词表小(1-2万汉字) |
四、词表(Vocabulary)设计:大小权衡
4.1 词表大小怎么选?
核心权衡:覆盖率 vs 推理速度 vs 参数数量
| 词表大小 | 覆盖率 | 每个token的bits数 | 推理速度 | 适用场景 |
|---|---|---|---|---|
| 3万(小) | 85-90% | 15 bits | ⚡⚡⚡ 快 | 资源受限,英文为主 |
| 5-8万(中) | 95-98% | 16-17 bits | ⚡⚡ 中等 | 🎯 主流选择 |
| 10万+(大) | 99%+ | 17+ bits | ⚡ 慢 | 多语言,专业领域 |
实际案例:
- GPT-2: 5万token
- GPT-3/4: 约10万token(多语言支持)
- 中文模型(ChatGLM): 约15万token(中英混合)
4.2 生词(OOV)怎么办?
问题:词表外的字词(Out-Of-Vocabulary)如何处理?
方案1:直接归为UNK(不推荐❌)
"区块链技术" → 词表无"区块链" → ["<UNK>", "技术"]
↓
语义完全丢失!"<UNK>" meaningless
方案2:子词拆分(推荐✅)
"区块链技术" → ["区块链", "技术"] 如果"区块链"不在词表中
↓ 拆成字符
→ ["区", "块", "链", "技术"]
↓
保留了部分语义(虽然不如完整词)
为什么子词更好?
- 至少知道是哪些汉字组成
- 模型能从字符级别学习
- 避免
这种"black hole"
4.3 多语言扩展:共享 vs 独立
问题:同时支持中文、英文、日文...词表怎么设计?
方案A:共享词表
- 所有语言共用一个大词表(如15万)
- 优点:参数少,跨语言迁移好
- 缺点:小语种词被拆散
- 典型:mBERT(多语言BERT)
方案B:语言独立词表
- 中文1个词表(5万),英文1个词表(5万)
- 优点:每种语言都有完整覆盖率
- 缺点:参数多(总词表很大),跨语言困难
- 典型:XLM-R之前的方案
趋势:共享词表 + 子词 → 简单有效
五、Embedding(词向量):语义的几何表示
5.1 核心思想:意思相近的词,向量距离近
直观理解:
- "king"(国王)和"queen"(女王)在向量空间离得很近
- "apple"(苹果)和"orange"(橙子)离得很近
- "king" - "man" + "woman" ≈ "queen"(向量运算)
几何直觉:
向量空间(想象成300维的超级空间):
女王
↗
↗ 国王
↓
男人 女人
"国王"向量 - "男人"向量 + "女人"向量 = "女王"向量(近似)
关键点:
- 模型没学过"国王-男人+女人=女王"这个规则
- 它只是从海量文本中发现:国王和女王经常出现在类似上下文
- 所以它们的向量方向相似
- 向量运算恰好捕捉到了这种语义关系✨
5.2 Embedding训练:模型预训练时一起学
训练过程:
- 随机初始化每个词的embedding向量(如768维)
- 模型训练(预测下一个词)
- 每次梯度更新,embedding参数也更新
- 训练完成后,embedding自然学会了语义
不需要单独训练!这是大模型的 emergent ability(涌现能力)。
权重共享(Tying):
- 输入embedding矩阵 = 输出预测矩阵
- 优点:减少参数,提升效果(词在输入和输出用同一向量)
- 大部分Transformer模型使用
5.3 维度选择:多大才够?
类比:向量维度 = 描述一个词的"方面数"
| 维度 | 描述 | 例子 |
|---|---|---|
| 50维 | 粗粒度,只能区分大类别 | "动物""植物" |
| 300维 | 传统词向量(Word2Vec) | "猫""狗"都能区分 |
| 768维 | BERT-base / GPT-2 | 细分:"波斯猫""布偶猫" |
| 1024-2048维 | 大模型(GPT-3/4) | 极细粒度,甚至文化内涵 |
经验法则:
- 小模型(<1B参数):512-768维 ✅性价比
- 中模型(10B左右):1024-1536维
- 大模型(>50B):2048-4096维
注意:维度不是越高越好!
- 太高:参数爆炸,训练慢,可能过拟合
- 太低:表达力不足,语义混在一起
六、实战诊断:为什么模型"不懂"你的专业术语?
6.1 问题1:"模型总把'苹果手机'理解成水果"
现象:
用户问:"苹果手机最新款多少钱?"
模型答:"苹果营养价值很高,富含维生素C..."
原因诊断:
Step 1:查看分词结果
"苹果手机" → tokenize → ["苹果", "手机"]
↓
问题:模型看到"苹果"→水果,"手机"→电子产品
两个词独立,无法形成"苹果手机"这个整体概念
Step 2:看预训练词表
- 训练数据中"苹果手机"出现次数少(相比"苹果"水果)
- BPE算法:如果"苹果手机"未达到合并频率阈值 → 保持拆分
- Embedding向量:"苹果"向量偏向水果,"手机"向量偏向电子产品
- 二者线性组合 ≈ "水果+电子产品" → 语义错位
解决方案:
✅ 方案A:领域数据微调
- 收集1000条"手机领域"问答数据
- 微调模型:让"苹果手机"在上下文中指向电子产品
- 副效应:"华为手机""小米手机"也变聪明
✅ 方案B:词表扩展
- 在tokenizer词表中手动加入"苹果手机"
- 重新训练embedding(初始化为平均值或随机)
- 需要少量数据快速适配(100-1000条)
✅ 方案C:RAG增强
- 不依赖模型记忆,检索到"苹果手机"相关文档
- 在Prompt中明确给出:"根据资料,苹果手机是..."
- 立即可用,无需训练
6.2 问题2:"专业术语回答不准确"
现象:
医疗问答:
Q: "心肌梗死的临床表现?"
A: (笼统回答,缺少"胸痛持续超过20分钟"等关键细节)
原因:
- 专业术语在通用语料中出现频率低
- 词表可能拆分成字:"心肌"/"梗死" → 语义损失
- 或直接OOV → 变成
- Embedding未充分训练(没见过足够多的医学上下文)
解决方案:
✅ 方案A:领域词表重训练
步骤:
1. 收集10G医学文献(PubMed、医学教科书)
2. 在这些数据上训练新的BPE词表
3. 重点增加医学术语:["心肌梗死","心电图","冠状动脉"]
4. 加载预训练embedding,继续训练(或随机初始化)
5. 微调模型(LoRA即可)
✅ 方案B:Prompt工程 + RAG
Prompt:
"你是一名资深心内科医生。请基于以下医学文献回答问题:
[检索到的医学资料]
请问:心肌梗死的临床表现是什么?"
↓
效果:
- Role定位专业视角
- RAG提供准确资料
- 避免模型自由发挥
6.3 诊断流程图
问题:"模型不理解我的领域术语"
↓
Step 1: 检查分词结果
↓
词被完整保留? → Yes → 问题在embedding质量
↓ No ↓
词被拆分? Step 2: 检查embedding相似度
↓ ↓
拆分合理吗? "术语向量"离"相关概念"近吗?
↓ ↓
不合理 → 扩展词表 不远 → 需领域微调
很远 → 预训练数据不足
七、动手任务
任务1:用在线工具观察BPE分词过程
推荐工具:
- HuggingFace Tokenizer: https://huggingface.co/tokenizers
- 或本地运行:
pip install tokenizers
操作:
- 输入"unhappiness"
- 观察切分:
["un", "happiness"]还是["unhappy", "ness"]? - 换一个词"tokenization",看看英文BPE如何切分长单词
- 输入中文"区块链技术",看BPE vs WordPiece差异
任务2:可视化预训练词向量
工具:TensorFlow Projector (https://projector.tensorflow.org/)
操作:
- 加载BERT词向量模型
- 搜索"king"、"queen"、"man"、"woman"
- 观察它们在空间中的距离
- 验证:"king" - "man" + "woman" ≈ "queen"(用向量计算)
如果没有现成数据:
- 下载GloVe词向量(300维,40万词)
- 上传到Projector,体验语义聚类
任务3:为"医疗问答"设计词表扩展方案
场景:医疗问答系统,用户问专业病名,模型总切分成单字。
任务输出:
- 列出50个核心医学术语(如"心肌梗死""冠状动脉粥样硬化")
- 设计方案:
- 是重新训练词表?还是在现有词表添加?
- 如果添加,初始embedding用什么?(平均字向量?随机?)
- 预估效果:添加这些词后,期望精度提升多少?(定性判断)
✅ 学习检查点
完成Part 2后,您应该能:
-
解释为什么需要分词
- 计算机只认识数字,不认识文字
- 词到ID的映射过程
-
对比BPE与WordPiece核心差异
- BPE:频率合并(拼乐高)
- WordPiece:概率模型 +
##后缀 - 各自适用场景
-
诊断"模型不懂专业术语"问题
- 查看分词:是否被拆分或OOV?
- 检查embedding:语义方向对吗?
- 给出至少2种解决方案(词表扩展 vs 微调 vs RAG)
-
选择词表大小
- 根据场景(英文/中文/多语言)选择3万/8万/15万
- 理解大小对性能/质量的影响
-
理解Embedding本质
- 语义相近的词,向量距离近
- "国王-男人+女人≈女王"的几何意义
- 维度选择原则(更大表达力更强,但参数多)
📚 延伸阅读
- 分词算法原理:Sennrich et al. (2015) "Neural Machine Translation of Rare Words with Subword Units"(BPE原始论文)
- 中文分词实践:SentencePiece官方教程(支持BPE/Unigram)
- 词向量可视化:TensorFlow Projector(https://projector.tensorflow.org/)
- 多语言词表:Google Research论文"Multilingual Denoising Pre-training"
- HuggingFace实战:
AutoTokenizer.from_pretrained("bert-base-chinese")体验中文词表
Part 2 结束!
掌握分词与词向量后,您理解了文本如何变成模型能处理的数字,以及为什么模型会"误解"某些词。
下一部分 Part 3:Prompt Engineering(提示词工程) —— 学会写出让模型"秒懂"的高质量指令,不修改模型就能大幅提升效果。学习节奏:Part 2建议1.5周,重点理解三种分词算法的哲学差异,动手体验BPE分词过程。
系列文章规划:
- ✅ Part 1:Transformer原理大白话(已发布草稿)
- ✅ Part 2:分词与词向量详解(当前)
- 🔄 Part 3:提示词工程实战
- 🔄 Part 4:RAG检索增强生成
- 🔄 Part 5:Agent智能体架构
- 🔄 Part 6:MCP协议与Skills系统
- 🔄 Part 7:微调技术通俗解析
- 🔄 Part 8:推理优化与工程部署
- 🔄 Part 9:综合项目实战与职业发展
总字数预估:约5-8万字,系统学习大模型与智能体,从原理到实战全涵盖。
评论区