96 lines
5.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 1. Tokenizing
## Tokenizing
**Tokenizing** 是将数据(如文本)分解为更小、可管理的部分,称为 _tokens_ 的过程。每个 token 都会被分配一个唯一的数字标识符ID。这是为机器学习模型处理文本做准备的基本步骤尤其是在自然语言处理NLP中。
> [!TIP]
> 这个初始阶段的目标非常简单:**以某种有意义的方式将输入划分为 tokensids**。
### **How Tokenizing Works**
1. **Splitting the Text:**
- **Basic Tokenizer:** 一个简单的 tokenizer 可能会将文本分割成单个单词和标点符号,去除空格。
- _Example:_\
文本: `"Hello, world!"`\
Tokens: `["Hello", ",", "world", "!"]`
2. **Creating a Vocabulary:**
- 为了将 tokens 转换为数字 ID创建一个 **vocabulary**。这个 vocabulary 列出了所有唯一的 tokens单词和符号并为每个 token 分配一个特定的 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]`\
_(假设 `[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"` 是频繁的子词。
2. **WordPiece:**
- **Used By:** 像 BERT 这样的模型。
- **Purpose:** 类似于 BPE它将单词分解为子词单元以处理未知单词并减少 vocabulary 大小。
- **How It Works:**
- 从单个字符的基础 vocabulary 开始。
- 迭代地添加最频繁的子词,以最大化训练数据的可能性。
- 使用概率模型决定合并哪些子词。
- **Benefits:**
- 在拥有可管理的 vocabulary 大小和有效表示单词之间取得平衡。
- 高效处理稀有和复合单词。
- _Example:_\
`"unhappiness"` 可能被 tokenized 为 `["un", "happiness"]``["un", "happy", "ness"]`,具体取决于 vocabulary。
3. **Unigram Language Model:**
- **Used By:** 像 SentencePiece 这样的模型。
- **Purpose:** 使用概率模型确定最可能的子词 tokens 集合。
- **How It Works:**
- 从一组潜在的 tokens 开始。
- 迭代地移除那些对模型的训练数据概率改善最小的 tokens。
- 最终确定一个 vocabulary其中每个单词由最可能的子词单元表示。
- **Benefits:**
- 灵活且可以更自然地建模语言。
- 通常会导致更高效和紧凑的 tokenizations。
- _Example:_\
`"internationalization"` 可能被 tokenized 为更小的、有意义的子词,如 `["international", "ization"]`
## Code Example
让我们通过来自 [https://github.com/rasbt/LLMs-from-scratch/blob/main/ch02/01_main-chapter-code/ch02.ipynb](https://github.com/rasbt/LLMs-from-scratch/blob/main/ch02/01_main-chapter-code/ch02.ipynb) 的代码示例更好地理解这一点:
```python
# 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]
```
## 参考
- [https://www.manning.com/books/build-a-large-language-model-from-scratch](https://www.manning.com/books/build-a-large-language-model-from-scratch)