首页 智能家居

LLM 分词算法深度解析:BPE、WordPiece 和 Unigram 原理与实践

分类:智能家居
字数: (4102)
阅读: (1104)
内容摘要:LLM 分词算法深度解析:BPE、WordPiece 和 Unigram 原理与实践,

在自然语言处理 (NLP) 领域,特别是大型语言模型 (LLM) 的应用中,分词器扮演着至关重要的角色。它负责将原始文本切分成模型能够理解的最小语义单元——token。不同的分词算法直接影响着模型的词表大小、训练效率以及最终的性能。本文将深入探讨三种主流的 LLM 分词算法:BPE (Byte Pair Encoding)、WordPiece 和 Unigram,剖析其原理、优缺点以及实际应用中的一些坑。

BPE (Byte Pair Encoding) 分词算法详解

BPE 原理

BPE 是一种基于贪心策略的分词算法,其核心思想是通过迭代地合并出现频率最高的字节对 (byte pairs) 来构建词表。算法初始词表通常包含所有单个字符,然后逐步将出现频率最高的字符对合并成新的 token,并将其加入到词表中,直至词表大小达到预设的上限。

LLM 分词算法深度解析:BPE、WordPiece 和 Unigram 原理与实践

BPE 算法流程

  1. 初始化词表: 将所有单个字符加入词表。
  2. 统计字节对频率: 统计文本中所有字节对的出现频率。
  3. 合并最高频字节对: 将出现频率最高的字节对合并成新的 token,并将其加入词表。
  4. 更新文本: 将文本中所有出现的最高频字节对替换为新的 token。
  5. 重复步骤 2-4: 重复迭代,直至词表大小达到预设上限或没有可合并的字节对。

BPE 代码示例 (Python)

import re
from collections import Counter

def get_stats(vocab):
    pairs = Counter()
    for word, freq in vocab.items():
        symbols = word.split()
        for i in range(len(symbols)-1):
            pairs[symbols[i], symbols[i+1]] += freq # 统计字节对频率
    return pairs

def merge_vocab(pair, v_in):
    v_out = {}
    bigram = re.escape(' '.join(pair))
    p = re.compile(r'(?<!\S)' + bigram + r'(?!\S)')
    for word in v_in:
        w_out = p.sub(''.join(pair), word) # 将文本中所有出现的最高频字节对替换为新的 token
        v_out[w_out] = v_in[word]
    return v_out

vocab = {'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}
num_merges = 10

for i in range(num_merges):
    pairs = get_stats(vocab)
    if not pairs:
        break
    best = max(pairs, key=pairs.get) # 找到出现频率最高的字节对
    vocab = merge_vocab(best, vocab)
    print(f'Iteration {i+1}: Merged {best} -> {vocab}')

BPE 优缺点

  • 优点: 简单有效,能够处理未登录词 (unknown words) 问题,通过子词 (subword) 的组合来表示新的词汇。
  • 缺点: 基于贪心策略,可能无法得到最优的词表;对于不同的语料,需要重新训练 BPE 模型。

WordPiece 分词算法详解

WordPiece 原理

WordPiece 算法与 BPE 算法类似,也是一种基于迭代的子词分词算法。但与 BPE 不同的是,WordPiece 算法并非简单地合并出现频率最高的字节对,而是每次选择合并后能够最大程度地增加语言模型概率的字节对。具体来说,WordPiece 算法会计算每个字节对的“得分”,得分越高,说明合并该字节对对语言模型带来的提升越大。

LLM 分词算法深度解析:BPE、WordPiece 和 Unigram 原理与实践

WordPiece 算法流程

  1. 初始化词表: 将所有单个字符加入词表。
  2. 训练语言模型: 使用当前词表训练一个语言模型。
  3. 计算字节对得分: 对于每个字节对,计算合并该字节对后,语言模型概率的提升值,作为该字节对的得分。
  4. 合并最高得分字节对: 将得分最高的字节对合并成新的 token,并将其加入词表。
  5. 更新文本: 将文本中所有出现的最高得分字节对替换为新的 token。
  6. 重复步骤 2-5: 重复迭代,直至词表大小达到预设上限或没有可合并的字节对。

WordPiece 代码示例 (伪代码)

由于 WordPiece 涉及语言模型的训练,完整代码实现较为复杂,这里提供一个伪代码示例,展示其核心思想。

LLM 分词算法深度解析:BPE、WordPiece 和 Unigram 原理与实践
def calculate_score(pair, model):
    # 计算合并 pair 前的语言模型概率
    prob_before = model.get_prob()
    # 合并 pair
    model.merge(pair)
    # 计算合并 pair 后的语言模型概率
    prob_after = model.get_prob()
    # 计算得分
    score = prob_after - prob_before
    return score

# ... (其余代码与 BPE 类似,只需将频率统计替换为得分计算) ...

WordPiece 优缺点

  • 优点: 相较于 BPE,WordPiece 考虑了合并字节对对语言模型的实际影响,通常能够得到更好的词表。
  • 缺点: 需要训练语言模型,计算复杂度较高。

Unigram 分词算法详解

Unigram 原理

Unigram 算法与 BPE 和 WordPiece 算法不同,它是一种基于概率模型的子词分词算法。Unigram 算法的初始词表通常包含所有单个字符以及一些常见的词汇,然后通过迭代地删除词表中对语言模型贡献最小的 token 来优化词表。

LLM 分词算法深度解析:BPE、WordPiece 和 Unigram 原理与实践

Unigram 算法流程

  1. 初始化词表: 将所有单个字符以及一些常见的词汇加入词表。
  2. 训练语言模型: 使用当前词表训练一个 Unigram 语言模型。
  3. 计算 token 损失: 对于词表中的每个 token,计算将其从词表中删除后,语言模型损失的增加值,作为该 token 的损失。
  4. 删除最低损失 token: 删除词表中损失最小的若干个 token。
  5. 重复步骤 2-4: 重复迭代,直至词表大小达到预设下限或没有可删除的 token。

Unigram 代码示例 (伪代码)

def calculate_loss(token, model):
    # 计算删除 token 前的语言模型损失
    loss_before = model.get_loss()
    # 从词表中删除 token
    model.remove(token)
    # 计算删除 token 后的语言模型损失
    loss_after = model.get_loss()
    # 计算损失增加值
    loss = loss_after - loss_before
    return loss

# ... (其余代码与 BPE 类似,只需将频率统计替换为损失计算) ...

Unigram 优缺点

  • 优点: 基于概率模型,能够更好地反映词汇的语义信息;支持多种分词结果,可以根据不同的需求选择不同的分词方案。
  • 缺点: 需要训练 Unigram 语言模型,计算复杂度较高;词表压缩过程中,某些重要的 token 可能被误删。

LLM 分词算法的实际应用与避坑

在实际应用中,选择合适的分词算法需要综合考虑多种因素,包括语料的特点、模型的规模、计算资源以及性能要求等。例如,对于资源有限的场景,BPE 算法可能是一个不错的选择;而对于追求更高性能的场景,WordPiece 或 Unigram 算法可能更适合。

在模型上线后,为了提高服务的稳定性,需要考虑对服务进行限流,可以使用 Nginx 进行反向代理,并配置 limit_req 指令限制单个 IP 的请求速率,避免突发流量导致服务崩溃。同时,需要对 Nginx 进行性能优化,例如调整 worker_processesworker_connections 参数,以充分利用服务器的 CPU 和内存资源。如果服务部署在宝塔面板上,可以通过宝塔面板提供的监控功能,实时监控服务器的 CPU、内存、磁盘 IO 等指标,及时发现并解决性能瓶颈。

另外,需要注意以下几点:

  • 词表大小的选择: 词表大小直接影响模型的性能,过小的词表可能导致信息损失,过大的词表可能增加模型的计算复杂度。通常需要根据具体的任务和语料进行调整。
  • 特殊 token 的处理: 需要对特殊 token(例如 [CLS][SEP][MASK])进行特殊处理,避免影响模型的训练和推理。
  • 未登录词的处理: 对于未登录词,需要使用合适的处理策略,例如使用 BPE 或 WordPiece 算法进行子词切分,或者使用预训练的词向量进行表示。

总结

LLM 分词器是大型语言模型的基础,理解其原理和应用对于构建高性能的 NLP 应用至关重要。本文深入探讨了三种主流的 LLM 分词算法:BPE、WordPiece 和 Unigram,并分享了一些实际应用中的经验和技巧。希望本文能够帮助读者更好地理解和应用 LLM 分词技术。

LLM 分词算法深度解析:BPE、WordPiece 和 Unigram 原理与实践

转载请注明出处: 代码一只喵

本文的链接地址: http://m.acea4.store/article/83039.html

本文最后 发布于2026-04-27 21:03:32,已经过了0天没有更新,若内容或图片 失效,请留言反馈

()
您可能对以下文章感兴趣
评论
  • 非酋本酋 3 小时前
    楼主讲的 Nginx 限流那部分很实用,最近正好在做这块,学习了。
  • 橘子汽水 4 天前
    楼主讲的 Nginx 限流那部分很实用,最近正好在做这块,学习了。
  • 咖啡不加糖 9 小时前
    讲得很详细,不过感觉 WordPiece 那部分代码示例如果能更完整一些就更好了。
  • 绿豆汤 3 天前
    分词算法是 NLP 的基础,这篇文章梳理得很清晰,点赞!