大模型的分词

UNK

在自然语言处理(NLP)和大语言模型中,UNK 是 Unknown Token 的缩写,中文译为未知词元,是预训练语言模型在词汇表(Vocabulary) 中专门预留的一个特殊标记。

当模型处理文本时,遇到不在词汇表中的词 / 子词(即 OOV,Out-of-Vocabulary 词),就会将这个词替换为 [UNK],以此避免因未登录词导致的模型报错,保证文本序列处理的连续性。

为什么会出现 UNK?

词汇表大小有限:模型预训练时会构建一个固定大小的词汇表(比如 BERT-base 的词汇表约 30,000 个词),无法覆盖人类语言中所有的词(比如生僻词、专业术语、网络新词、拼写错误词)。

子词切分的兜底策略:现代模型(如 BERT、GPT)会用 WordPiece、Byte-Pair Encoding (BPE) 等子词切分算法,将未登录词切分为更小的子词。但如果切分后仍有子词不在词汇表中,就会用 [UNK] 替代。

典型场景示例

假设模型词汇表中只有 [我]、[喜欢]、[吃]、[苹果]、[UNK] 这些标记

输入句子"我喜欢吃车厘子":词汇表中没有"车厘子"词;子词切分后也无法拆分为已有子词;最终句子会被转换为:[我] [喜欢] [吃] [UNK]

UNK\] 本身没有语义信息,大量出现会降低模型理解和生成的精度 1. 扩大词汇表规模,纳入更多领域专属词汇 2. 优化子词切分算法(如改进 BPE),减少未登录词 3. 针对特定领域微调模型,补充领域词汇 4. 与其他特殊标记的区别 在大模型词汇表中,\[UNK\] 是和 \[PAD\](填充标记)、\[CLS\](分类标记)、\[SEP\](分隔标记)并列的特殊 token,各自分工不同: \[PAD\]:用于补齐不等长的文本序列 \[CLS\]:用于聚合句子语义,做分类任务 \[SEP\]:用于分隔两个句子(如问答任务的问题和上下文) \[UNK\]:专门处理未知词 ## 词嵌入,Word Embedding 大模型处理词嵌入(Word Embedding) 的核心逻辑: 将离散的文本符号(词 / 子词 / 字符)映射为连续的低维稠密向量,让模型能够通过向量运算捕捉语义关联。 该过程分为【基础嵌入层生成】和【上下文感知嵌入增强】两个核心阶段 不同架构的模型(如 BERT、GPT)会在此基础上做针对性优化 词嵌入的核心目标 自然语言是离散的符号系统(比如 "苹果" 是一个独立符号),而深度学习模型只能处理数值向量。 词嵌入的作用 将每个 token 转化为固定维度的向量(比如 768 维) 让语义相似的 token 对应的向量在空间中距离更近(比如 "苹果" 和 "香蕉" 的向量相似度 \> "苹果" 和 "电脑") 为后续的注意力机制、全连接层提供可计算的语义表示 ### 大模型处理词嵌入的完整流程 `/ˌtəʊkənaɪˈzeɪʃn/` #### 第一步:Token 化(Tokenization)------ 离散符号拆分 词嵌入前置步骤,模型先将原始文本拆分为最小处理单元(token),拆分后每个 token 会被映射为一个固定的整数 ID(来自模型词汇表) 常见策略有 3 种: 词级拆分:按空格 / 标点拆分(如英文 I love China → \[I, love, China\]),缺点是易产生大量 OOV(未登录词),已逐渐被淘汰 子词级拆分:主流方案(WordPiece、BPE、SentencePiece),将词拆分为子词(如 unhappiness → \[un, happy, ness\]),兼顾词汇覆盖度和语义完整性 字符级拆分:拆分为单个字符,适合小语种或低资源语言,但语义表达能力弱 低资源语言(Low-Resource Language) 是指在自然语言处理(NLP)和人工智能领域中,缺乏足够高质量数字化数据、工具和研究资源的语言 判断是否为低资源语言,核心不是语言的使用人口多少,而是支撑模型训练与应用的资源丰富度 #### 第二步:基础嵌入层(Embedding Layer)------ 离散→连续的映射 词嵌入的核心转换环节,模型通过一个可训练的嵌入矩阵,将 token 的整数 ID 转化为基础向量 核心原理:嵌入矩阵的维度为 \[词汇表大小, 嵌入维度\](如 BERT-base 是 \[30522, 768\]),每一行对应一个 token 的基础向量 (个人记录:这里的30522是行数,有这么多token;768是列数,表示任何一个token,会用768个数值的向量表示) 计算过程:对于输入 token 的 ID 序列 \[id1, id2, id3\],直接从嵌入矩阵中取出对应行,得到基础嵌入向量序列 \[e1, e2, e3

关键特点:基础嵌入是静态的(预训练阶段学习,微调阶段可更新),仅表示 token 的固有语义,不包含上下文信息(比如 "银行" 的基础向量,无法区分是 "金融银行" 还是 "河岸")

第三步:增强嵌入 ------ 注入位置与类型信息

基础嵌入只包含 token 本身的语义,而大模型需要捕捉位置信息和句子类型信息,因此会在基础嵌入上叠加两种特殊嵌入:

【位置嵌入(Position Embedding)】

告诉模型 token 在序列中的位置,解决 Transformer 对位置不敏感的问题

  • BERT:可训练的位置嵌入(每个位置对应一个向量,随模型训练更新)
  • GPT:正余弦位置嵌入(固定公式生成,无需训练)

【分段嵌入(Segment Embedding)】

区分不同句子(比如问答任务中的 "问题" 和 "上下文")

BERT 专用,输入两个句子时,第一个句子的 token 加 segment 0 向量,第二个句子的 token 加 segment 1 向量

最终基础表示:token_embedding + position_embedding + segment_embedding(三者维度相同,直接相加)

第四步:上下文感知嵌入 ------ 动态语义增强

大模型词嵌入的关键升级,通过 Transformer 的注意力机制,将基础表示转化为上下文相关的动态嵌入(也叫 Contextual Embedding)

核心逻辑:每个 token 的最终嵌入,不仅包含自身基础语义,还融合序列中其他所有 token 的语义信息(通过注意力权重加权求和)

示例:

我在银行取钱:"银行" 的上下文嵌入会偏向 "金融机构"

河边有个银行:"银行" 的上下文嵌入会偏向 "建筑物"

架构差异:

BERT(纯 Encoder):通过双向注意力生成双向上下文嵌入,每个 token 融合前后文信息;

GPT(纯 Decoder):通过单向注意力生成单向上下文嵌入,每个 token 仅融合前文信息;

T5(Encoder-Decoder):Encoder 生成双向上下文嵌入,Decoder 结合前文和 Encoder 输出,生成带对齐信息的嵌入。

第五步:嵌入的输出与应用

最终的上下文嵌入会作为后续任务的输入,不同任务的使用方式不同:

理解类任务(分类、NER):取 [CLS] token 的最终嵌入作为句子的全局语义表示

生成类任务(续写、翻译):将每个 token 的最终嵌入输入到语言模型头(LM Head),预测下一个 token

匹配类任务(语义相似度):计算两个句子嵌入的余弦相似度

大模型词嵌入的关键优化点

子词嵌入的优势:

相比传统词嵌入(如 Word2Vec),大模型的子词嵌入能处理 OOV 词(拆分为子词后,即使词不在词汇表,子词也大概率存在)

上下文嵌入的动态性:

传统词嵌入是静态的(一个词对应一个固定向量),大模型上下文嵌入是动态的,同一个词在不同语境下向量不同,更符合语言歧义性

嵌入层的训练策略:

预训练阶段,嵌入矩阵与模型其他参数一起训练

微调阶段,可选择冻结嵌入层(减少计算量)或继续更新(适配下游任务)

总结

大模型处理词嵌入的流程可以概括为:

文本 → Token 化 → 基础嵌入(token+位置+分段) → 注意力机制增强 → 上下文感知嵌入 → 下游任务输出

从 "静态基础嵌入" 到 "动态上下文嵌入" 的升级,是大模型词嵌入区别于传统词嵌入的核心标志

OOV

全称是 Out-of-Vocabulary,中文译为未登录词

在模型预定义的词汇表中没有收录的词或子词

Word2Vec - 静态词嵌入的经典

Word2Vec

Word2Vec 是静态词嵌入的经典实现,和大模型的上下文嵌入不同:

它的核心是 "一个词对应一个固定向量",不考虑上下文歧义(比如 "银行" 只有一个向量),但能体现基础的语义相似性

第一步:环境准备

pip install gensim numpy

第二步:

python 复制代码
from gensim.models import Word2Vec
from gensim.utils import simple_preprocess

# ===================== 1. 准备训练数据 =====================
# 原始文本(模拟小语料库,实际场景会用更大的文本集)
corpus = [
    "我 喜欢 吃 苹果",
    "我 喜欢 吃 香蕉",
    "我 不 喜欢 吃 橘子",
    "香蕉 和 苹果 都是 水果",
    "橘子 也是 一种 水果",
    "猫 喜欢 吃鱼",
    "狗 喜欢 啃 骨头"
]

# 数据预处理:将每个句子拆分为词列表(Word2Vec要求输入是"句子列表+每个句子是词列表")
# simple_preprocess 会自动分词、小写(中文需提前分词,这里已分好)
processed_corpus = [simple_preprocess(sentence, min_len=1) for sentence in corpus]
print("预处理后的数据:")
for sent in processed_corpus:
    print(sent)

# ===================== 2. 训练 Word2Vec 模型 =====================
# 核心参数说明:
# - vector_size:词向量维度(对应之前说的嵌入维度,这里设为10,简化计算)
# - window:上下文窗口大小(取每个词前后各2个词作为上下文)
# - min_count:忽略出现次数少于1的词(本例数据少,设为1)
# - sg:训练模式,0=CBOW(用上下文预测中心词),1=Skip-gram(用中心词预测上下文)
model = Word2Vec(
    sentences=processed_corpus,
    vector_size=10,
    window=2,
    min_count=1,
    sg=0  # 用CBOW模式,更适合小语料
)

# 保存/加载模型(可选)
# model.save("my_word2vec.model")
# model = Word2Vec.load("my_word2vec.model")

# ===================== 3. 验证 Word2Vec 核心功能 =====================
# 功能1:获取单个词的向量
print("\n===== 单个词的向量 =====")
apple_vec = model.wv["苹果"]
print("苹果的向量:", apple_vec)

# 功能2:找语义相似的词(核心能力)
print("\n===== 语义相似的词 =====")
# 找和"苹果"最相似的3个词
similar_to_apple = model.wv.most_similar("苹果", topn=3)
print("和苹果最相似的词:", similar_to_apple)

# 找和"喜欢"最相似的3个词
similar_to_like = model.wv.most_similar("喜欢", topn=3)
print("和喜欢最相似的词:", similar_to_like)

# 功能3:语义类比(经典的"国王-男人+女人=女王"逻辑)
print("\n===== 语义类比 =====")
# 尝试:苹果 - 水果 + 动物 = ?(预期接近猫/狗)
# 注:本例语料太小,结果可能不完美,但能体现逻辑
try:
    analogy = model.wv.most_similar(positive=["苹果", "动物"], negative=["水果"], topn=2)
    print("苹果 - 水果 + 动物 = ", analogy)
except KeyError as e:
    print(f"类比失败:缺少词 {e}")

# 功能4:计算两个词的相似度
print("\n===== 词相似度计算 =====")
sim_apple_banana = model.wv.similarity("苹果", "香蕉")
sim_apple_dog = model.wv.similarity("苹果", "狗")
print("苹果 vs 香蕉 的相似度:", sim_apple_banana)
print("苹果 vs 狗 的相似度:", sim_apple_dog)

第三步:运行结果解释(示例)

plaintext 复制代码
预处理后的数据:
['我', '喜欢', '吃', '苹果']
['我', '喜欢', '吃', '香蕉']
['我', '不', '喜欢', '吃', '橘子']
['香蕉', '和', '苹果', '都是', '水果']
['橘子', '也是', '一种', '水果']
['猫', '喜欢', '吃鱼']
['狗', '喜欢', '啃', '骨头']

===== 单个词的向量 =====
苹果的向量: [0.012, -0.034, 0.056, ...] (共10个数值)

===== 语义相似的词 =====
和苹果最相似的词: [('香蕉', 0.92), ('橘子', 0.88), ('水果', 0.85)]
和喜欢最相似的词: [('吃', 0.90), ('我', 0.87), ('猫', 0.75)]

===== 语义类比 =====
苹果 - 水果 + 动物 = [('猫', 0.78), ('狗', 0.76)]

===== 词相似度计算 =====
苹果 vs 香蕉 的相似度: 0.92
苹果 vs 狗 的相似度: 0.21

苹果和香蕉的相似度远高于苹果和狗,说明 Word2Vec 捕捉到了 "苹果 / 香蕉都是水果" 的语义关联

"喜欢" 和 "吃" 相似度高,因为语料中二者频繁共现,符合 Word2Vec "共现即相关" 的核心逻辑

和大模型嵌入的区别

Word2Vec 的向量是静态的:"喜欢" 在所有语境下都是同一个向量

大模型(如 BERT)的向量是动态的:"喜欢" 在 "我喜欢吃苹果" 和 "猫喜欢吃鱼" 中向量不同

总结

Word2Vec 核心是通过词的共现关系训练静态词向量,一个词对应一个固定向量

核心功能包括获取词向量、找相似词、语义类比,能体现基础的语义关联

早期词嵌入的经典方案,相比大模型的上下文嵌入,缺少对语境歧义的处理能力

共现即相关,出现在相似上下文中的词往往具有相似的含义

BPE分词

BPE 的全称是 Byte-Pair Encoding

中文译为字节对编码,是一种子词切分算法,也是大语言模型(如 GPT、BERT)中主流的 Tokenization 策略之一

核心目标是在词汇表大小和语义完整性之间做平衡,将单词拆分为更小的子词单元:

既解决了传统词级分词的 OOV(未登录词)问题,又避免了字符级分词的语义碎片化

BPE 的核心原理

BPE 的本质是从训练语料中,迭代合并出现频率最高的字符 / 子词对,最终生成一个包含 "字符、子词、完整词" 的混合词汇表

整个过程分为 训练阶段(构建词汇表) 和 推理阶段(切分新词) 两步

训练阶段:构建子词词汇表

假设训练语料只有 3 个单词:low, lower, newest

步骤 1:初始化

将所有单词拆分为单个字符,并在词尾添加特殊标记 (表示词的结束,区分前缀和完整词):

plaintext 复制代码
low → l o w </w>
lower → l o w e r </w>
newest → n e w e s t </w>

统计所有字符的出现频率:

l:2, o:2, w:2, :3, e:2, r:1, n:1, s:1, t:1

步骤 2:迭代合并高频字符对

设定目标词汇表大小(比如从 9 扩充到 12),每次找出出现次数最多的相邻字符对并合并:

第 1 轮:统计所有相邻对的频率,w 出现 2 次

重新统计:

语料拆分后的相邻对:

l-o(2), o-w(2), w-(1, low), w-e(1, lower), e-r(1), r-(1), n-e(1), e-w(1), w-e(1), e-s(1), s-t(1), t-(1)

最高频对是 l-o(2 次),合并为 lo,词汇表新增 lo

第 2 轮:基于新的拆分,继续找高频对,比如 o-w(2 次),合并为 ow,词汇表新增 ow

第 3 轮:继续合并,比如 e-s(1 次,若没有更高频),直到词汇表达到目标大小

步骤 3:生成最终词汇表

最终词汇表包含原始字符、合并后的子词、完整词,例如:l, o, w, , lo, ow, lower, ...

  1. 推理阶段:切分新词(OOV 词)
    当遇到词汇表中没有的新词时,BPE 会用贪心策略从左到右切分:
    从词的开头开始,匹配词汇表中最长的子词
    切分后剩余部分重复此过程,直到整个词切分完毕
    词尾添加

示例:假设新词是 newer,词汇表中有 ne, ew, er, e, w 等子词

切分过程:newer → ne w e r → 若词汇表有 new,则切分为 new e r

BPE 的核心优势

解决 OOV 问题

即使遇到未见过的词,也能拆分为已有的子词,避免 [UNK] 标记的滥用。比如 unhappiness 可拆分为 un + happy + ness

平衡词汇表大小

相比词级分词(词汇表动辄几十万),BPE 词汇表更小,降低模型嵌入层参数量;相比字符级分词,子词更具语义(ing tion 有意义的后缀)

跨语言友好

不需要针对不同语言设计复杂的分词规则(如中文的 jieba 分词),直接基于字符迭代合并,适合低资源语言

BPE 的变体与应用

原始 BPE 是字符级的,后来衍生出多个变体,被不同模型采用:

WordPiece:BERT 采用的变体,合并策略不是 "频率最高",而是 "合并后能最大程度提升训练数据的似然概率",更适合双向模型

SentencePiece:将空格也视为一个字符,实现无监督分词,不需要提前做分词预处理,适合多语言模型

BPE 与传统分词的区别

分词方式 核心逻辑 优点 缺点

词级分词 按空格 / 词典拆分单词 语义完整 词汇表大,OOV 多

字符级分词 拆分为单个字符 无 OOV,词汇表小 语义碎片化,模型学习难度大

BPE 子词分词 迭代合并高频字符对 平衡词汇表与 OOV,语义完整 训练过程稍复杂

相关推荐
阿里-于怀2 小时前
Nacos 安全护栏:MCP、Agent、配置全维防护,重塑 AI Registry 安全边界
安全·ai·nacos·agent
一个天蝎座 白勺 程序猿4 小时前
Apache IoTDB(13):数据处理的双刃剑——FILL空值填充与LIMIT/SLIMIT分页查询实战指南
数据库·sql·ai·apache·时序数据库·iotdb
m0_603888714 小时前
UR-Bench A Benchmark for Multi-Hop Reasoning over Ultra-High-Resolution Images
ai·论文速览
CoderJia程序员甲5 小时前
GitHub 热榜项目 - 日榜(2026-01-18)
人工智能·ai·大模型·github·ai教程
海绵宝宝de派小星5 小时前
什么是人工智能?AI、机器学习、深度学习的关系
人工智能·深度学习·机器学习·ai
张3蜂16 小时前
Label Studio 详解:一站式数据标注平台全面介绍
ai
北龙云海19 小时前
从宕机到智变:2025数据中心进化启示录,数智运维如何定义未来
运维·ai·数据中心·智算·数智运维·数据中心规划
xcLeigh21 小时前
AI的提示词专栏:Prompt 与 Python Pandas 的结合使用指南
人工智能·python·ai·prompt·提示词
砚边数影21 小时前
AI开发依赖引入:DL4J / Java-ML 框架 Maven 坐标配置
java·数据库·人工智能·深度学习·机器学习·ai·maven