AI2025-03-2330 分钟

词元和嵌入

深入解析分词器原理(BPE、字节级BPE)、静态词嵌入与上下文嵌入的本质区别、负例采样的作用,以及嵌入技术在推荐系统中的实际应用。

词元和嵌入

词元和嵌入

Q1. 大模型的分词器和传统的中文分词有什么区别?对于一个指定的词表,一句话是不是只有一种唯一的分词方式?

传统中文分词(如jieba)的目标是把句子切成有语义的词语,依赖词典和语言学规则,比如"中华人民共和国"要切成一个词。大模型的分词器(如BPE)完全不管语义,它是纯统计的,基于字符或字节的共现频率不断合并高频子序列,生成的token可能是完整的词、半个词、甚至单个字符。对于BPE来说,给定一个确定的词表和合并规则,一句话的分词方式是唯一确定的,因为BPE的合并过程是贪心的、确定性的——每一步都合并优先级最高的pair。但如果用的是Unigram(如SentencePiece的默认方法),理论上同一句话可能有多种分词方式,Unigram会选择概率最高的那种,或者通过采样得到多种分词结果用于正则化。

Q2. 为什么传统BM25检索对中文分词的质量很敏感,而大模型对分词器的选取不敏感?

BM25是基于精确词匹配的,分词直接决定了索引和查询的基本单元。如果"机器学习"被切成"机器"+"学习",那搜索"机器学习"就匹配不上了。分词粒度不对、切错位置,检索效果直接崩盘。大模型不一样,它靠的是上下文理解,不管你把"机器学习"切成什么样的子词组合,模型都能通过多层注意力把这些碎片的语义重新组合起来。分词器只是把文本转成模型能吃的输入格式,真正的语义理解是在后面几十层Transformer里完成的。所以大模型对分词器的选择没那么敏感,换一个分词器,只要重新训练或适配一下,效果差异不大。当然词表设计还是会影响效率——一个对中文友好的词表能用更少的token表达同样的内容,节省计算资源。

Q3. GPT-4、Llama等现代大模型采用的字节级BPE分词器相比传统的BPE分词器有什么优点?

传统BPE是在字符级别操作的,碰到词表外的字符(比如生僻字、emoji、特殊符号)就只能标记为[UNK],信息直接丢失了。字节级BPE把所有输入先转成UTF-8字节序列,基础词表就是256个字节值,任何文本都可以表示,永远不会出现未知token。这解决了一个很实际的问题:大模型要处理各种语言、代码、特殊符号,不可能穷举所有可能出现的字符。字节级BPE理论上可以覆盖任意输入。缺点是对非ASCII文本(比如中文)效率会低一些——一个中文字符需要3个UTF-8字节,如果词表里没有合并出足够多的中文子词,就会很碎。所以国内模型通常会在词表中加入大量中文常用子词来缓解这个问题。

Q4. 国内预训练的大模型与海外模型相比,是如何做到用相对更少的词元表达中文语料的?

核心就是在训练分词器时加入了大量中文语料,让BPE的统计合并能充分学习中文的高频子序列。比如Llama原版的词表主要从英文语料学出来,中文常见的"的"可能就是3个UTF-8字节对应3个token;而国内模型(如ChatGLM、Qwen、Baichuan)在训练BPE时喂入了充足的中文文本,使得"的"、"我们"、"人工智能"这些高频词组都能直接被合并成单个token。具体做法包括:扩大词表总量(比如从32K扩到64K甚至150K),其中大部分新增条目是中文专用的子词;有些模型还会先用字符级预分词把中文按字切开再做BPE,避免跨字边界的无意义合并。效果很明显,同样一段中文,国内模型可能只需要海外模型一半甚至更少的token数,直接降低了推理成本和延迟。

Q5. 大模型是如何区分聊天历史中用户说的话和AI说的话的?

通过特殊token来标记。每个模型都有自己的聊天模板(chat template),用特殊token把不同角色的发言分隔开。比如ChatGPT系列用<|im_start|>system、<|im_start|>user、<|im_start|>assistant这些标记;Llama用[INST]和[/INST]包裹用户消息。这些特殊token在词表中有专门的ID,模型在SFT阶段大量接触这种格式的数据,学会了看到user标记后面的内容就当作用户输入来理解,看到assistant标记就知道该自己回答了。本质上这就是一种格式约定——就像HTTP协议有header和body的分隔一样。在实际推理时,API层会自动按照模型的模板格式把多轮对话拼接成一个序列喂给模型。

Q6. 大模型做工具调用的时候,输出的工具调用参数是如何与文本回复区分开来的?

主流做法是用特殊token或者特定格式来标记工具调用。比如模型在SFT时学会了一套约定格式,当它决定调用工具时会输出类似<tool_call>{"name": "search", "arguments": {...}}</tool_call>这样的结构化内容。推理框架解析到这些特殊标记就知道这不是普通文本回复,而是需要执行工具调用。还有些模型(如GPT的function calling)在API层面就做了封装,模型的输出在logits层面就会被引导到工具调用的格式上去。另一种方案是限制采样(constrained decoding),一旦模型开始输出工具调用的起始标记,后续生成就被约束成必须符合JSON schema的合法结构。关键在于这不是模型"天然"会的能力,而是通过专门的训练数据教出来的行为模式。

Q7. 参考章节中用播放列表数据训练歌曲嵌入的案例,设计一个使用嵌入技术解决电子商务产品推荐的系统

核心思路跟歌曲嵌入一样:利用用户行为序列中的共现关系来学习商品的嵌入表示。具体方案:1)数据构建——把用户的浏览/购买序列类比为"播放列表",按session切分,每个session中浏览过的商品构成一个序列;2)嵌入训练——用Word2Vec的思路(或者Prod2Vec),把商品ID视为"词",用session中的商品共现关系来训练,经常一起被浏览/购买的商品在嵌入空间中会靠近;3)推荐——给定用户最近交互的商品,在嵌入空间中做最近邻检索,找到向量距离最近的商品作为推荐。可以进一步优化:加入商品的文本描述(标题、类目)用BERT提取语义嵌入,和行为嵌入拼接或融合;对不同行为赋予不同权重(购买比浏览权重大);定期增量更新嵌入以反映新商品和新趋势。冷启动的新商品可以先用文本嵌入兜底,有了足够多的行为数据后再切换到行为嵌入。

Q8. word2vec的训练过程中,负例的作用是什么?

如果Word2Vec只拿正例训练(共现的词对),模型会走一条捷径——把所有词的嵌入向量都映射到差不多的位置上,因为这样所有词对的相似度都很高,损失函数自然就最小了。这就是所谓的"坍缩"问题。负例采样(negative sampling)的作用就是阻止这种坍缩:对于每个正例(目标词和上下文词),随机采样几个不在上下文窗口中的词作为负例,训练时要求正例的相似度高、负例的相似度低。这迫使模型学会区分什么词该靠近、什么词该远离,从而在嵌入空间中形成有意义的结构。负例的采样策略也有讲究,通常按词频的3/4次方采样,避免高频词被过度采样为负例。

Q9. 传统的静态词嵌入(如word2vec)与大模型产生的与上下文相关的嵌入相比,有什么区别?

静态嵌入给每个词一个固定的向量,不管这个词出现在什么句子里,向量都是一样的。"苹果"在"吃苹果"和"苹果公司"中是同一个向量。上下文嵌入(如BERT、GPT产生的)则是动态的,同一个词在不同句子中有不同的向量表示,因为它经过了多层attention和前馈网络,已经融合了整个句子的上下文信息。这是本质上的差别:静态嵌入只编码了词的"平均"语义,上下文嵌入编码了词在具体语境下的精确含义。不过静态嵌入也有它的好处:计算极快(查表就行)、存储小、适合大规模检索的初筛。上下文嵌入效果好但计算成本明显更高,需要过一遍整个模型。在很多工程场景中,两者是互补的而非替代关系。

Q10. 与上下文相关的嵌入是如何解决一词多义问题的,如技术语境下,英文token可能表示词元、代币、令牌,而中文"推理"可能表示reasoning或inference?

自注意力机制是关键。当模型处理一个多义词时,注意力头会去看这个词周围的所有其他词,根据上下文动态调整这个词的表示。比如"token"出现在"tokenizer splits text into tokens"中,注意力会关注到"tokenizer""splits""text"这些词,把"token"的表示推向"词元"的语义方向;而在"cryptocurrency token"中,注意力捕获到"cryptocurrency",就会把表示推向"代币"方向。多层Transformer的堆叠让这个过程逐层细化——底层可能只捕获局部语法关系,高层逐渐整合全局语义。所以同一个词经过模型处理后,在不同上下文中的向量可能差异很大。这不是通过显式的词义消歧模块实现的,而是注意力机制的自然结果——上下文信息被"注入"到了每个位置的表示中。

Q11. 在word2vec等词嵌入空间中,存在king-man + woman ≈ queen的现象,这是为什么?大模型的词元嵌入空间是否也有类似的属性?

这个现象说明Word2Vec学到的嵌入空间具有线性结构——语义关系被编码为向量偏移。king→queen和man→woman的偏移方向(大致代表"性别转换")近似相同,所以做减法加法就能类比。原因在于训练数据中这些词在相似的语法模式中出现("king ruled""queen ruled""man worked""woman worked"),Word2Vec捕获了这种分布规律性。大模型底层的token embedding矩阵理论上也有类似属性,但实际上不那么明显。原因是大模型的embedding只是一个初始表示,真正的语义理解分布在几十层Transformer中。如果你拿大模型某一层的隐状态做类比实验,可以找到一些线性关系,但远比Word2Vec复杂——大模型的语义空间是高度非线性的,很多关系被编码在了更深层的参数中,不一定体现在简单的向量加减上。

RELATED

AI2025-04-01

为分类任务微调表示模型

深入讲解为分类任务微调表示模型的完整流程:分类头设计、全量微调 vs LoRA 的选择、小样本场景下的 SetFit 方案,以及过拟合防范与模型评估。

Read next25 分钟
AI2025-03-31

构建文本嵌入模型

从 Sentence-BERT 到对比学习(SimCSE),再到 Matryoshka 嵌入和 MTEB 基准评估——系统讲解如何构建和优化高质量文本嵌入模型。

Read next25 分钟