1. Tokenizing

Tokenizing

Tokenizing 是将数据(如文本)分解为更小、可管理的部分,称为 tokens 的过程。每个 token 然后被分配一个唯一的数字标识符(ID)。这是为机器学习模型处理文本做准备的基本步骤,特别是在自然语言处理(NLP)中。

这个初始阶段的目标非常简单:以某种合理的方式将输入划分为 tokens(ids)

How Tokenizing Works

  1. Splitting the Text:

  • Basic Tokenizer: 一个简单的 tokenizer 可能会将文本拆分为单个单词和标点符号,去除空格。

  • Example: 文本:"Hello, world!" Tokens: ["Hello", ",", "world", "!"]

  1. Creating a Vocabulary:

  • 为了将 tokens 转换为数字 ID,创建一个 vocabulary。这个 vocabulary 列出了所有唯一的 tokens(单词和符号),并为每个分配一个特定的 ID。

  • Special Tokens: 这些是添加到 vocabulary 中以处理各种场景的特殊符号:

  • [BOS](序列开始):表示文本的开始。

  • [EOS](序列结束):表示文本的结束。

  • [PAD](填充):用于使批次中的所有序列具有相同的长度。

  • [UNK](未知):表示不在 vocabulary 中的 tokens。

  • Example: 如果 "Hello" 被分配 ID 64","455"world"78"!"467,那么: "Hello, world!"[64, 455, 78, 467]

  • Handling Unknown Words: 如果像 "Bye" 这样的单词不在 vocabulary 中,它将被替换为 [UNK]"Bye, world!"["[UNK]", ",", "world", "!"][987, 455, 78, 467] &#xNAN;(假设 [UNK] 的 ID 是 987)

Advanced Tokenizing Methods

虽然基本的 tokenizer 对于简单文本效果很好,但它有局限性,特别是在处理大型 vocabulary 和新词或稀有词时。高级 tokenizing 方法通过将文本分解为更小的子单元或优化 tokenization 过程来解决这些问题。

  1. Byte Pair Encoding (BPE):

  • Purpose: 通过将稀有或未知单词分解为频繁出现的字节对,减少 vocabulary 的大小并处理稀有或未知单词。

  • How It Works:

  • 从单个字符作为 tokens 开始。

  • 迭代地将最频繁的 token 对合并为一个单一的 token。

  • 继续直到没有更多频繁的对可以合并。

  • Benefits:

  • 消除了对 [UNK] token 的需求,因为所有单词都可以通过组合现有的子词 tokens 来表示。

  • 更高效和灵活的 vocabulary。

  • Example: "playing" 可能被 tokenized 为 ["play", "ing"] 如果 "play""ing" 是频繁的子词。

  1. WordPiece:

  • Used By: 像 BERT 这样的模型。

  • Purpose: 类似于 BPE,它将单词分解为子词单元,以处理未知单词并减少 vocabulary 大小。

  • How It Works:

  • 从单个字符的基础 vocabulary 开始。

  • 迭代地添加最频繁的子词,以最大化训练数据的可能性。

  • 使用概率模型决定合并哪些子词。

  • Benefits:

  • 在拥有可管理的 vocabulary 大小和有效表示单词之间取得平衡。

  • 高效处理稀有和复合单词。

  • Example: "unhappiness" 可能被 tokenized 为 ["un", "happiness"]["un", "happy", "ness"],具体取决于 vocabulary。

  1. Unigram Language Model:

  • Used By: 像 SentencePiece 这样的模型。

  • Purpose: 使用概率模型确定最可能的子词 token 集合。

  • How It Works:

  • 从一组潜在的 tokens 开始。

  • 迭代地移除那些对模型的训练数据概率提升最小的 tokens。

  • 最终确定一个 vocabulary,其中每个单词由最可能的子词单元表示。

  • Benefits:

  • 灵活且可以更自然地建模语言。

  • 通常会导致更高效和紧凑的 tokenization。

  • Example: "internationalization" 可能被 tokenized 为更小的、有意义的子词,如 ["international", "ization"]

Code Example

让我们通过来自 https://github.com/rasbt/LLMs-from-scratch/blob/main/ch02/01_main-chapter-code/ch02.ipynb 的代码示例更好地理解这一点:

# Download a text to pre-train the model
import urllib.request
url = ("https://raw.githubusercontent.com/rasbt/LLMs-from-scratch/main/ch02/01_main-chapter-code/the-verdict.txt")
file_path = "the-verdict.txt"
urllib.request.urlretrieve(url, file_path)

with open("the-verdict.txt", "r", encoding="utf-8") as f:
raw_text = f.read()

# Tokenize the code using GPT2 tokenizer version
import tiktoken
token_ids = tiktoken.get_encoding("gpt2").encode(txt, allowed_special={"[EOS]"}) # Allow the user of the tag "[EOS]"

# Print first 50 tokens
print(token_ids[:50])
#[40, 367, 2885, 1464, 1807, 3619, 402, 271, 10899, 2138, 257, 7026, 15632, 438, 2016, 257, 922, 5891, 1576, 438, 568, 340, 373, 645, 1049, 5975, 284, 502, 284, 3285, 326, 11, 287, 262, 6001, 286, 465, 13476, 11, 339, 550, 5710, 465, 12036, 11, 6405, 257, 5527, 27075, 11]

参考文献

Last updated