分词器对比

分词器对比2026:BPE/SentencePiece/Unigram

分词器:文本与模型之间的桥梁 LLM无法直接处理文本——它需要将文本切分为离散的token序列,每个token对应一个整数ID。分词器(Tokenizer)就是完成这一转换的组件。分词器的选择直接影响模型的词表大小、序列长度、多语言能力和推理效率。 2026年主流LLM使用的分词器虽然名称各异,但核心算法主要分为BPE、WordPiece和Unigram三大类。 BPE(Byte Pair Encoding) 算法原理 BPE最初是一种数据压缩算法,被Sennrich等人(2016)引入NLP作为子词分词方法。其训练过程是自底向上的——从字符开始,逐步合并最频繁的字符对: def train_bpe(texts, vocab_size=32000): """BPE训练算法""" # 1. 将文本拆分为字符序列 word_freqs = {} for text in texts: words = text.split() for word in words: chars = tuple(word) word_freqs[chars] = word_freqs.get(chars, 0) + 1 # 2. 初始化词表为所有字符 vocab = set() for word in word_freqs: for char in word: vocab.add(char) # 3. 迭代合并最频繁的字符对 merges = [] while len(vocab) < vocab_size: # 统计所有相邻字符对的出现频率 pair_freqs = {} for word, freq in word_freqs.items(): for i in range(len(word) - 1): pair = (word[i], word[i+1]) pair_freqs[pair] = pair_freqs.get(pair, 0) + freq if not pair_freqs: break # 选择频率最高的对 best_pair = max(pair_freqs, key=pair_freqs.get) new_token = best_pair[0] + best_pair[1] # 合并 merges.append(best_pair) vocab.add(new_token) # 更新词频 new_word_freqs = {} for word, freq in word_freqs.items(): new_word = merge_in_word(word, best_pair) new_word_freqs[new_word] = new_word_freqs.get(new_word, 0) + freq word_freqs = new_word_freqs return vocab, merges 编码过程 训练好的BPE分词器在编码新文本时,按训练时的合并顺序逐步合并: def bpe_encode(text, merges, special_tokens): """BPE编码""" tokens = [] for word in text.split(): # 先检查是否是特殊token if word in special_tokens: tokens.append(word) continue # 字符级开始 word_tokens = list(word) # 按合并顺序尝试合并 for (a, b) in merges: i = 0 while i < len(word_tokens) - 1: if word_tokens[i] == a and word_tokens[i+1] == b: word_tokens[i] = a + b del word_tokens[i+1] else: i += 1 tokens.extend(word_tokens) return tokens Byte-level BPE GPT-2引入的改进——在字节级别而非字符级别进行BPE。这使得词表可以处理任意UTF-8字符,彻底解决了未登录字符(OOV)问题: ...

2026-07-02 · 4 min · 734 words · 硅基 AGI 探索者
tokenizer principles and practice

分词器原理与工程实践:BPE vs SentencePiece vs Unigram

分词器:大模型的语言基础 分词器(Tokenizer)是大语言模型的第一个组件,决定了文本如何被切分为 Token。分词质量直接影响模型的词汇覆盖、多语言能力、编码效率乃至推理速度。本文深入解析 2026 年主流分词算法的原理与实践。 一、为什么分词很重要 1.1 分词的核心目标 高覆盖率:能处理任何输入文本,不出现 UNK(未知 Token) 高压缩率:用尽可能少的 Token 表示文本(降低推理成本) 语义一致性:语义相关的词切分为相似的 Token 序列 多语言支持:公平对待不同语言 可逆性:Token 序列可以无损还原为文本 1.2 分词对模型性能的影响 分词器直接影响: 训练效率:更少的 Token = 更短的序列 = 更快的训练 推理速度:输出 100 个 Token 比输出 200 个 Token 快一倍 多语言公平性:中文如果压缩率低于英文,同等参数下中文能力更弱 代码能力:代码中的缩进、特殊符号需要合理切分 实测数据:同一段中文文本,GPT-4 的分词器用 120 Token,而 Llama 2 用 280 Token——这意味着 Llama 2 处理中文的成本是 GPT-4 的 2.3 倍。 二、BPE(Byte Pair Encoding) 2.1 算法原理 BPE 从字符级别开始,迭代合并最高频的相邻 Token 对: 初始词表: a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, ... 训练语料统计: "low" : 5次 "lower" : 2次 "newest" : 6次 "widest" : 3次 第1轮: 合并 'e','s' → 'es' (出现9次) low, lower, n[es]t, wid[es]t 第2轮: 合并 'es','t' → 'est' (出现9次) low, lower, n[est], wid[est] 第3轮: 合并 'l','o' → 'lo' (出现7次) [lo]w, [lo]wer, n[est], wid[est] ... 直到词表大小达到目标 2.2 数学描述 给定训练语料 $\mathcal{D}$,初始词表为所有字符。每轮选择使以下目标最大化的合并对 $(a, b)$: ...

2026-06-28 · 4 min · 645 words · 硅基 AGI 探索者
tokenizer comparison

Tokenizer 全面对比:BPE vs WordPiece vs Unigram vs SentencePiece

1. 为什么 Tokenizer 如此重要 Tokenizer 是大语言模型与文本世界的接口。它决定了: 模型如何"看到"文本(粒度) 词表大小与序列长度的权衡 多语言、代码、特殊字符的覆盖能力 模型的最大知识单元(token = 模型的"字母") 一个不好的 tokenizer 会导致: 序列过长 → 计算浪费 未登录词过多 → 语义丢失 跨语言不均衡 → 多语言能力差 英文 "Hello World" 的不同分词: 字符级: H e l l o W o r l d → 11 tokens 词级: Hello World → 2 tokens (但词表爆炸) BPE: Hello World → 2 tokens (高频词保留) 字节级: Hello World → 2 tokens (256基础, 递归合并) 中文 "你好世界" 的不同分词: 字符级: 你 好 世 界 → 4 tokens BPE: 你 好 世 界 → 4 tokens (中文常见) 词级: 你好世界 → 1 token (理想但不可达) 2. BPE (Byte Pair Encoding) 2.1 算法原理 BPE 最初是一种数据压缩算法,被 Sennrich 等人 (2016) 引入 NLP。核心思想:从字符级开始,迭代合并最高频的相邻 token 对。 ...

2026-06-25 · 8 min · 1626 words · 硅基 AGI 探索者
tokenizer internals

Tokenizer 原理详解:BPE/WordPiece/Unigram/SentencePiece

1. 为什么 Tokenization 至关重要 LLM 不能直接处理文本,必须将文本切分为离散的 Token 序列,再将每个 Token 映射为向量。Tokenizer 直接影响: 词汇表大小:影响 Embedding 层参数量和 Softmax 计算量 序列长度:同一段文本,不同 Tokenizer 产生的 Token 数不同,影响上下文窗口利用率 多语言公平性:中文一个字 vs 英文一个 word,Tokenizer 决定了编码效率 OOV 问题:未知 Token 的处理能力 2. BPE (Byte Pair Encoding) 2.1 算法思想 BPE 最初是数据压缩算法,被 Sennrich 等人(2016)引入 NLP。核心思路:从一个字符级词汇表开始,反复合并出现频率最高的相邻 Token 对。 2.2 训练过程 输入语料: {"low": 5, "lower": 2, "newest": 6, "widest": 3} 步骤 1: 拆分为字符序列 l o w </w> : 5 l o w e r </w> : 2 n e w e s t </w> : 6 w i d e s t </w> : 3 步骤 2: 统计相邻 Token 对频率 (l, o): 7, (o, w): 7, (e, r): 2, (n, e): 6, ... 步骤 3: 合并最高频对 (l, o) → "lo" lo w </w> : 5 lo w e r </w> : 2 n e w e s t </w> : 6 w i d e s t </w> : 3 重复直到词汇表达到目标大小 2.3 编码过程 对新文本,按训练时的合并规则顺序应用: ...

2026-06-25 · 4 min · 707 words · 硅基 AGI 探索者
tokenization guide

分词原理与工程实践:BPE/SentencePiece/WordPiece

1. 为什么需要分词 1.1 分词的核心矛盾 自然语言是连续字符序列,模型需要离散输入单元。分词面临三重矛盾: 策略 词表大小 OOV 问题 序列长度 语义完整性 字符级 ~100 无 极长 差 词级 100K+ 严重 短 好 子词级 32K-128K 少 中 较好 子词分词是最佳折中:高频词保持完整,低频词拆为有意义的子词单元。 1.2 分词影响一切 分词不仅是预处理步骤,它直接决定: 模型能力边界:词表决定模型能处理的语言和字符 推理成本:相同文本,不同 Tokenizer 产生的 token 数不同 多语言公平性:中文分词效率直接影响中文任务成本 2. BPE(Byte Pair Encoding) 2.1 算法原理 BPE 最初是数据压缩算法,被 Sennrich 等人(2016)引入 NLP。核心思想:从字符级开始,迭代合并最高频的相邻字符对。 训练算法: 1. 将所有词拆为字符序列,词尾加 </w> "low" → ['l', 'o', 'w', '</w>'] 2. 统计相邻字符对频率 3. 合并最高频字符对为新 token 4. 重复步骤 2-3 直到达到目标词表大小 2.2 代码实现 from collections import Counter, defaultdict def train_bpe(corpus, vocab_size): """BPE 训练算法""" # 初始化:每个词拆为字符 word_freqs = Counter(corpus.split()) splits = {word: list(word) + ['</w>'] for word in word_freqs} merges = [] vocab = set(char for word in word_freqs for char in list(word) + ['</w>']) while len(vocab) < vocab_size: # 统计相邻对频率 pair_freqs = defaultdict(int) for word, freq in word_freqs.items(): split = splits[word] for i in range(len(split) - 1): pair_freqs[(split[i], split[i+1])] += freq if not pair_freqs: break # 合并最高频对 best_pair = max(pair_freqs, key=pair_freqs.get) merges.append(best_pair) new_token = best_pair[0] + best_pair[1] vocab.add(new_token) # 更新所有词的分词 for word in word_freqs: split = splits[word] i = 0 while i < len(split) - 1: if (split[i], split[i+1]) == best_pair: split = split[:i] + [new_token] + split[i+2:] else: i += 1 splits[word] = split return vocab, merges def bpe_encode(text, merges): """BPE 编码""" tokens = list(text) + ['</w>'] for pair in merges: i = 0 while i < len(tokens) - 1: if (tokens[i], tokens[i+1]) == pair: tokens = tokens[:i] + [tokens[i]+tokens[i+1]] + tokens[i+2:] else: i += 1 return tokens 2.3 BPE 的特点 确定性:相同训练数据 → 相同词表 贪婪合并:高频对优先,可能不是全局最优 可逆性:token 拼接即可还原原文 增量性:可以从已有词表继续训练 3. WordPiece 3.1 与 BPE 的区别 WordPiece(Google, 2012)用于 BERT,与 BPE 类似但有关键区别: ...

2026-06-24 · 4 min · 667 words · 硅基 AGI 探索者
鲁ICP备2026018361号