tokenizer介绍

在自然语言处理(NLP)领域,tokenizer 是一个重要的组件,它的主要作用是将文本字符串分割成更小的单位,这些单位通常被称为"标记"(tokens)。这些标记可以是单词、子词(subwords)、字符甚至是更复杂的结构。Tokenizer 的设计和实现对后续的 NLP 模型性能有着重要影响,因为它决定了模型如何理解和处理输入数据。

Tokenizer 的主要功能

  1. 分词(Tokenization):将连续的文本切分成独立的标记。例如,句子 "I love natural language processing" 可以被切分成 ["I", "love", "natural", "language", "processing"]。
  2. 规范化(Normalization):对文本进行标准化处理,比如转换为小写、去除标点符号等,以减少词汇的变异性。
  3. 特殊标记处理:添加一些特殊的标记,如开始标记(<s>)、结束标记(</s>)、未知词汇标记(<unk>)等,这些标记有助于模型更好地理解文本的结构和边界。

常见的 Tokenizer 类型

  1. 基于规则的 Tokenizer:使用预定义的规则或正则表达式来切分文本。例如,根据空格、标点符号等进行分词。
  2. 基于统计的 Tokenizer:利用统计方法来学习如何切分文本。例如,使用频率信息来决定哪些子词应该被合并为一个标记。
  3. 基于机器学习的 Tokenizer:训练一个模型来预测文本的最佳切分点。这种方法通常需要大量的标注数据。

应用场景

  • 机器翻译:将源语言文本切分成标记,然后由模型生成目标语言的翻译。
  • 情感分析:将评论或文本切分成标记,以便模型可以更好地理解其中的情感倾向。
  • 文本分类:将文档切分成标记,用于训练分类模型。
  • 命名实体识别:将文本切分成标记,以便模型可以识别出人名、地名等实体。

示例

假设我们有一个简单的句子:"Hello, how are you doing today?"

  • 基于规则的 Tokenizer 可能会将其切分成:["Hello", ",", "how", "are", "you", "doing", "today", "?"]
  • 基于统计的 Tokenizer 可能会根据频率信息将其切分成:["Hello", "how", "are", "you", "doing", "today", "?"]
  • 基于机器学习的 Tokenizer 可能会根据训练数据将其切分成:["Hello", "how", "are", "you", "doing", "today", "?"]

llama-tokenizer-jsWeb site created using create-react-apphttps://belladoreai.github.io/llama-tokenizer-js/example-demo/build/

主要介绍三种分词算法: BPE/wordpiece/unigram,以及分词工具sentencepiece

llama-tokenizer-js
https://belladoreai.github.io/llama-tokenizer-js/example-demo/build/

huggingface.co
https://huggingface.co/docs/transformers/v4.46.2/zh/main_classes/tokenizer

SentencePiece是什么

SentencePiece 是一个由 Google 开发的开源工具,旨在帮助构建高效的自然语言处理(NLP)模型。它是一个跨平台的库,可以在多种操作系统上运行,包括但不限于 Windows、Linux 和 macOS。SentencePiece 的主要功能是在不需要预先定义词汇表的情况下,自动从大规模文本数据中学习如何将文本切分为"子词单元"(subword units)。这种方法可以有效地处理未知词汇和低频词汇的问题,这对于提高自然语言处理模型的性能非常关键。

SentencePiece 的主要特点包括:

  • 无需预定义词汇表:传统的自然语言处理方法通常需要预先定义一个词汇表,这可能会导致遇到未登录词(即不在词汇表中的词)时的问题。SentencePiece 可以动态地学习词汇表,从而更好地处理这些未知词汇。
  • 子词单元:SentencePiece 使用一种称为"子词单元"的概念,即将单词分解为更小的单元。这种方式不仅可以有效地处理未知词汇,还能减少词汇表的大小,从而提高模型的效率。
  • 支持多种语言:无论是空白分隔的语言(如英语),还是非空白分隔的语言(如中文、日文),SentencePiece 都能够有效处理。
  • 灵活性:用户可以根据自己的需求调整分词策略,比如设置词块的最大长度、最小频率等参数。

应用场景

SentencePiece 被广泛应用于各种自然语言处理任务中,如机器翻译、情感分析、文本分类等。特别是对于那些需要处理大量文本数据的应用,SentencePiece 提供了一种高效且灵活的解决方案。此外,它也被用于构建大规模的语言模型,如 BERT、XLNet 等,以提高这些模型的泛化能力和处理未知词汇的能力。

BPE是什么

Byte Pair Encoding (BPE) 是一种用于自然语言处理的子词(subword)分割算法。BPE 通过迭代地合并最常见的字符对来生成词汇表,从而将单词拆分成更小的单元。这种方法特别适用于处理未知词汇和低频词汇,同时可以减少词汇表的大小,提高模型的效率和性能。

BPE 的工作原理

  1. 初始化:从原始文本中提取所有字符,并将每个单词视为一个字符序列。
  2. 统计频率:计算所有字符对(bigrams)的出现频率。
  3. 合并操作:选择频率最高的字符对,并将它们合并为一个新的子词单元。
  4. 更新:更新文本中的所有单词,将合并后的子词单元替换原来的字符对。
  5. 重复:重复上述步骤,直到达到预定的词汇表大小或没有更多的字符对可以合并。

Python 使用示例代码

下面是一个使用 sentencepiece 库实现 BPE 的示例代码。sentencepiece 是一个广泛使用的库,支持 BPE 和其他分词方法。

安装 sentencepiece

首先,你需要安装 sentencepiece 库。可以使用以下命令进行安装:

bash 复制代码
pip install sentencepiece
python 复制代码
import sentencepiece as spm

# 准备训练数据
with open('train.txt', 'w', encoding='utf-8') as f:
    f.write("Hello, how are you doing today?\n")
    f.write("I am fine, thank you.\n")
    f.write("Natural language processing is fascinating.\n")

# 训练 BPE 模型
spm.SentencePieceTrainer.train(input='train.txt', model_prefix='bpe', vocab_size=1000)

# 加载训练好的模型
sp = spm.SentencePieceProcessor(model_file='bpe.model')

# 测试分词
text = "Hello, how are you doing today?"
encoded = sp.encode(text, out_type=str)
print(f"Encoded: {encoded}")

decoded = sp.decode(encoded)
print(f"Decoded: {decoded}")

代码解释

  1. 准备训练数据 :创建一个包含训练文本的文件 train.txt
  2. 训练 BPE 模型 :使用 SentencePieceTrainer.train 方法训练 BPE 模型。input 参数指定训练数据文件,model_prefix 参数指定输出模型文件的前缀,vocab_size 参数指定词汇表的大小。
  3. 加载训练好的模型 :使用 SentencePieceProcessor 加载训练好的 BPE 模型。
  4. 测试分词:对一段文本进行编码(分词)和解码(还原)。

输出结果

bash 复制代码
Encoded: ['▁Hello', ',', '▁how', '▁are', '▁you', '▁doing', '▁today', '?']
Decoded: Hello, how are you doing today?

注意事项

  • 词汇表大小vocab_size 参数决定了最终词汇表的大小。较大的词汇表可以更好地捕捉文本中的细节,但也会增加模型的复杂度。
  • 模型文件 :训练完成后,会生成两个文件:bpe.modelbpe.vocab。前者是模型文件,后者是词汇表文件

WordPiece是什么

WordPiece 是另一种常用的子词(subword)分割算法,与 Byte Pair Encoding (BPE) 类似,但有一些不同之处。WordPiece 也是通过迭代地合并常见的字符对来生成词汇表,但它在选择合并字符对时使用了概率模型,确保生成的词汇表在训练数据上的覆盖率最大化。

WordPiece 的工作原理

  1. 初始化:从原始文本中提取所有字符,并将每个单词视为一个字符序列。
  2. 统计频率:计算所有字符对(bigrams)的出现频率。
  3. 合并操作:选择使词汇表在训练数据上的覆盖率最大的字符对,并将它们合并为一个新的子词单元。
  4. 更新:更新文本中的所有单词,将合并后的子词单元替换原来的字符对。
  5. 重复:重复上述步骤,直到达到预定的词汇表大小或没有更多的字符对可以合并。

Python 使用示例代码

下面是一个使用 transformers 库实现 WordPiece 的示例代码。transformers 是 Hugging Face 开发的一个广泛使用的库,支持多种预训练模型及其分词器。

安装 transformers

首先,你需要安装 transformers 库。可以使用以下命令进行安装:

bash 复制代码
pip install transformers
python 复制代码
from transformers import BertTokenizer

# 初始化 BERT 的 WordPiece 分词器
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')

# 测试分词
text = "Hello, how are you doing today?"
tokens = tokenizer.tokenize(text)
print(f"Tokens: {tokens}")

# 编码为模型输入
input_ids = tokenizer.encode(text, add_special_tokens=True)
print(f"Input IDs: {input_ids}")

# 解码回原始文本
decoded_text = tokenizer.decode(input_ids)
print(f"Decoded Text: {decoded_text}")

代码解释

  1. 初始化 WordPiece 分词器 :使用 BertTokenizer.from_pretrained 方法加载预训练的 BERT 模型的 WordPiece 分词器。这里使用的是 bert-base-uncased,这是一个不区分大小写的 BERT 模型。
  2. 测试分词:对一段文本进行分词,得到子词单元的列表。
  3. 编码为模型输入 :将文本编码为模型可以接受的输入格式,add_special_tokens=True 表示添加特殊的标记,如 [CLS][SEP]
  4. 解码回原始文本:将编码后的输入解码回原始文本。

输出结果

bash 复制代码
Tokens: ['hello', ',', 'how', 'are', 'you', 'doing', 'today', '?']
Input IDs: [101, 3793, 1010, 2088, 2003, 2117, 2644, 1029, 102]
Decoded Text: [CLS] hello, how are you doing today? [SEP]

注意事项

  • 预训练模型transformers 库提供了多种预训练模型,每种模型都有对应的分词器。你可以根据需要选择不同的模型,如 bert-base-cased(区分大小写)或 roberta-base
  • 特殊标记add_special_tokens=True 参数会在编码时添加 [CLS][SEP] 等特殊标记,这些标记在 BERT 等模型中用于表示句子的开始和结束。
  • 词汇表大小:预训练模型的词汇表大小通常是固定的,但你可以通过训练自己的分词器来定制词汇表大小。

unigram是什么

Unigram Language Model 是一种基于单个词(或子词)的概率模型,常用于自然语言处理中的分词任务。与 Byte Pair Encoding (BPE) 和 WordPiece 不同,Unigram 模型通过优化词汇表中每个子词的频率分布来生成子词单元。Unigram 模型的目标是使生成的子词单元在训练数据上的概率最大化。

Unigram 的工作原理

  1. 初始化:从原始文本中提取所有字符,并将每个单词视为一个字符序列。
  2. 初始化词汇表:将所有字符作为初始词汇表。
  3. 优化过程:通过迭代地调整词汇表中的子词单元,使生成的子词单元在训练数据上的概率最大化。
  4. 更新:在每次迭代中,重新计算每个子词单元的概率,并根据这些概率调整词汇表。
  5. 终止条件:当达到预定的词汇表大小或收敛条件时,停止迭代。

Python 使用示例代码

下面是一个使用 sentencepiece 库实现 Unigram 分词的示例代码。sentencepiece 是一个广泛使用的库,支持多种分词方法,包括 Unigram。

安装 sentencepiece

首先,你需要安装 sentencepiece 库。可以使用以下命令进行安装:

bash 复制代码
pip install sentencepiece
python 复制代码
import sentencepiece as spm

# 准备训练数据
with open('train.txt', 'w', encoding='utf-8') as f:
    f.write("Hello, how are you doing today?\n")
    f.write("I am fine, thank you.\n")
    f.write("Natural language processing is fascinating.\n")

# 训练 Unigram 模型
spm.SentencePieceTrainer.train(
    input='train.txt',
    model_prefix='unigram',
    vocab_size=1000,
    model_type='unigram'
)

# 加载训练好的模型
sp = spm.SentencePieceProcessor(model_file='unigram.model')

# 测试分词
text = "Hello, how are you doing today?"
encoded = sp.encode(text, out_type=str)
print(f"Encoded: {encoded}")

decoded = sp.decode(encoded)
print(f"Decoded: {decoded}")

代码解释

  1. 准备训练数据 :创建一个包含训练文本的文件 train.txt
  2. 训练 Unigram 模型 :使用 SentencePieceTrainer.train 方法训练 Unigram 模型。input 参数指定训练数据文件,model_prefix 参数指定输出模型文件的前缀,vocab_size 参数指定词汇表的大小,model_type 参数指定使用 Unigram 模型。
  3. 加载训练好的模型 :使用 SentencePieceProcessor 加载训练好的 Unigram 模型。
  4. 测试分词:对一段文本进行编码(分词)和解码(还原)。

输出结果

bash 复制代码
Encoded: ['▁Hello', ',', '▁how', '▁are', '▁you', '▁doing', '▁today', '?']
Decoded: Hello, how are you doing today?

注意事项

  • 词汇表大小vocab_size 参数决定了最终词汇表的大小。较大的词汇表可以更好地捕捉文本中的细节,但也会增加模型的复杂度。
  • 模型文件 :训练完成后,会生成两个文件:unigram.modelunigram.vocab。前者是模型文件,后者是词汇表文件。
  • 模型类型model_type 参数可以设置为 unigrambpechar,分别对应 Unigram、BPE 和字符级别的分词方法。
相关推荐
zaim115 小时前
计算机的错误计算(一百八十七)
人工智能·ai·大模型·llm·错误·正弦/sin·误差/error
张拭心17 小时前
Google 提供的 Android 端上大模型组件:MediaPipe LLM 介绍
android·人工智能·llm
带电的小王17 小时前
whisper.cpp: Android端测试 -- Android端手机部署音频大模型
android·智能手机·llm·whisper·音频大模型·whisper.cpp
三月七(爱看动漫的程序员)21 小时前
LEAST-TO-MOST PROMPTING ENABLES COMPLEX REASONING IN LARGE LANGUAGE MODELS---正文
人工智能·gpt·学习·机器学习·语言模型·自然语言处理·llama
带电的小王1 天前
whisper.cpp: PC端测试 -- 电脑端部署音频大模型
llm·whisper·音视频·音频大模型
码狂☆1 天前
源码编译llama.cpp for android
android·人工智能·llama
Ambition_LAO1 天前
LLaMA-Factory QuickStart 流程详解
llm·llama
宇梵文书C2 天前
在CFFF云平台使用llama-factory部署及微调Qwen2.5-7B-Instruct
llm·llama·cfff
zaim12 天前
计算机的错误计算(一百八十六)
人工智能·python·ai·大模型·llm·误差·decimal
带电的小王2 天前
llama.cpp:PC端测试 MobileVLM -- 电脑端部署图生文大模型
llm·llama.cpp·vlm·mobilevlm·图生文