mcpField
H
huggingface-tokenizers

huggingface-tokenizers

github.com/kalarislabs开发7746 次安装4 天前更新
代码仓库

关于 huggingface-tokenizers

huggingface-tokenizers 是面向 NLP 开发者的快速分词库,适用于数据与模型处理流程。它支持训练自定义分词器、批量编码,以及将 Token 位置映射回原文。

主要功能

  1. 01训练自定义分词器
  2. 02加载预训练分词器
  3. 03批量编码与填充
  4. 04配置规范化和处理流程
  5. 05追踪 Token 原文偏移

适用场景

  1. 01处理大型文本语料
  2. 02为自定义数据集训练分词器
  3. 03将 NLP 预测映射到原文位置

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/kalarislabs/research-agent-skills --skill huggingface-tokenizers

安装后在 Claude Code 中输入/huggingface-tokenizers确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
tokenization-algorithms.md
training.md
integration.md
algorithms.md
pipeline.md

详细介绍

HuggingFace Tokenizers - NLP 快速分词

兼具 Rust 性能与 Python 易用性的快速、可用于生产环境的分词器。

何时使用 HuggingFace Tokenizers

在以下情况下使用 HuggingFace Tokenizers:

  • 需要极快的分词速度(每 GB 文本少于 20 秒)
  • 从头训练自定义分词器
  • 希望跟踪对齐关系(token → 原文位置)
  • 构建生产级 NLP 流水线
  • 需要高效地对大型语料库进行分词

性能:

  • 速度:在 CPU 上对 1GB 文本进行分词耗时少于 20 秒
  • 实现:基于 Rust 核心,并提供 Python/Node.js 绑定
  • 效率:比纯 Python 实现快 10-100 倍

可改用以下替代方案:

  • SentencePiece:与语言无关,T5/ALBERT 使用
  • tiktoken:OpenAI 为 GPT 模型开发的 BPE 分词器
  • transformers AutoTokenizer:仅用于加载预训练分词器(内部使用此库)

快速入门

安装
# Install tokenizers
pip install tokenizers

# With transformers integration
pip install tokenizers transformers
加载预训练分词器
from tokenizers import Tokenizer

# Load from HuggingFace Hub
tokenizer = Tokenizer.from_pretrained("bert-base-uncased")

# Encode text
output = tokenizer.encode("Hello, how are you?")
print(output.tokens)  # ['hello', ',', 'how', 'are', 'you', '?']
print(output.ids)     # [7592, 1010, 2129, 2024, 2017, 1029]

# Decode back
text = tokenizer.decode(output.ids)
print(text)  # "hello, how are you?"
训练自定义 BPE 分词器
from tokenizers import Tokenizer
from tokenizers.models import BPE
from tokenizers.trainers import BpeTrainer
from tokenizers.pre_tokenizers import Whitespace

# Initialize tokenizer with BPE model
tokenizer = Tokenizer(BPE(unk_token="[UNK]"))
tokenizer.pre_tokenizer = Whitespace()

# Configure trainer
trainer = BpeTrainer(
    vocab_size=30000,
    special_tokens=["[UNK]", "[CLS]", "[SEP]", "[PAD]", "[MASK]"],
    min_frequency=2
)

# Train on files
files = ["train.txt", "validation.txt"]
tokenizer.train(files, trainer)

# Save
tokenizer.save("my-tokenizer.json")

训练时间:100MB 语料库约需 1-2 分钟,1GB 约需 10-20 分钟

使用填充进行批量编码
# Enable padding
tokenizer.enable_padding(pad_id=3, pad_token="[PAD]")

# Encode batch
texts = ["Hello world", "This is a longer sentence"]
encodings = tokenizer.encode_batch(texts)

for encoding in encodings:
    print(encoding.ids)
# [101, 7592, 2088, 102, 3, 3, 3]
# [101, 2023, 2003, 1037, 2936, 6251, 102]

分词算法

详情、代码示例和参数表:references/tokenization-algorithms.md。适用此步骤时请阅读。

分词流水线

完整流水线:规范化 → 预分词 → 模型 → 后处理

规范化

清理并统一文本格式:

from tokenizers.normalizers import NFD, StripAccents, Lowercase, Sequence

tokenizer.normalizer = Sequence([
    NFD(),           # Unicode normalization (decompose)
    Lowercase(),     # Convert to lowercase
    StripAccents()   # Remove accents
])

# Input: "Héllo WORLD"
# After normalization: "hello world"

常见规范化器:

  • NFD、NFC、NFKD、NFKC - Unicode 规范化形式
  • Lowercase() - 转换为小写
  • StripAccents() - 去除重音符号(é → e)
  • Strip() - 去除空白字符
  • Replace(pattern, content) - 正则表达式替换
预分词

将文本拆分为类似单词的单元:

from tokenizers.pre_tokenizers import Whitespace, Punctuation, Sequence, ByteLevel

# Split on whitespace and punctuation
tokenizer.pre_tokenizer = Sequence([
    Whitespace(),
    Punctuation()
])

# Input: "Hello, world!"
# After pre-tokenization: ["Hello", ",", "world", "!"]

常见预分词器:

  • Whitespace() - 按空格、制表符和换行符拆分
  • ByteLevel() - GPT-2 风格的字节级拆分
  • Punctuation() - 分离标点符号
  • Digits(individual_digits=True) - 将数字逐个拆分
  • Metaspace() - 将空格替换为 ▁(SentencePiece 风格)
后处理

为模型输入添加特殊 token:

from tokenizers.processors import TemplateProcessing

# BERT-style: [CLS] sentence [SEP]
tokenizer.post_processor = TemplateProcessing(
    single="[CLS] $A [SEP]",
    pair="[CLS] $A [SEP] $B [SEP]",
    special_tokens=[
        ("[CLS]", 1),
        ("[SEP]", 2),
    ],
)

常见模式:

# GPT-2: sentence <|endoftext|>
TemplateProcessing(
    single="$A <|endoftext|>",
    special_tokens=[("<|endoftext|>", 50256)]
)

# RoBERTa: <s> sentence </s>
TemplateProcessing(
    single="<s> $A </s>",
    pair="<s> $A </s> </s> $B </s>",
    special_tokens=[("<s>", 0), ("</s>", 2)]
)

对齐跟踪

跟踪 token 在原文中的位置:

output = tokenizer.encode("Hello, world!")

# Get token offsets
for token, offset in zip(output.tokens, output.offsets):
    start, end = offset
    print(f"{token:10} → [{start:2}, {end:2}): {text[start:end]!r}")

# Output:
# hello      → [ 0,  5): 'Hello'
# ,          → [ 5,  6): ','
# world      → [ 7, 12): 'world'
# !          → [12, 13): '!'

使用场景:

  • 命名实体识别(将预测结果映射回文本)
  • 问答(提取答案片段)
  • token 分类(将标签与原始位置对齐)

与 transformers 集成

使用 AutoTokenizer 加载
from transformers import AutoTokenizer

# AutoTokenizer automatically uses fast tokenizers
tokenizer = AutoTokenizer.from_pretrained("bert-base-uncased")

# Check if using fast tokenizer
print(tokenizer.is_fast)  # True

# Access underlying tokenizers.Tokenizer
fast_tokenizer = tokenizer.backend_tokenizer
print(type(fast_tokenizer))  # <class 'tokenizers.Tokenizer'>
将自定义分词器转换为 transformers 格式
from tokenizers import Tokenizer
from transformers import PreTrainedTokenizerFast

# Train custom tokenizer
tokenizer = Tokenizer(BPE())
# ... train tokenizer ...
tokenizer.save("my-tokenizer.json")

# Wrap for transformers
transformers_tokenizer = PreTrainedTokenizerFast(
    tokenizer_file="my-tokenizer.json",
    unk_token="[UNK]",
    pad_token="[PAD]",
    cls_token="[CLS]",
    sep_token="[SEP]",
    mask_token="[MASK]"
)

# Use like any transformers tokenizer
outputs = transformers_tokenizer(
    "Hello world",
    padding=True,
    truncation=True,
    max_length=512,
    return_tensors="pt"
)

常见模式

从迭代器训练(大型数据集)
from datasets import load_dataset

# Load dataset
dataset = load_dataset("wikitext", "wikitext-103-raw-v1", split="train")

# Create batch iterator
def batch_iterator(batch_size=1000):
    for i in range(0, len(dataset), batch_size):
        yield dataset[i:i + batch_size]["text"]

# Train tokenizer
tokenizer.train_from_iterator(
    batch_iterator(),
    trainer=trainer,
    length=len(dataset)  # For progress bar
)

性能:处理 1GB 数据约需 10-20 分钟

启用截断和填充
# Enable truncation
tokenizer.enable_truncation(max_length=512)

# Enable padding
tokenizer.enable_padding(
    pad_id=tokenizer.token_to_id("[PAD]"),
    pad_token="[PAD]",
    length=512  # Fixed length, or None for batch max
)

# Encode with both
output = tokenizer.encode("This is a long sentence that will be truncated...")
print(len(output.ids))  # 512
多进程
from tokenizers import Tokenizer
from multiprocessing import Pool

# Load tokenizer
tokenizer = Tokenizer.from_file("tokenizer.json")

def encode_batch(texts):
    return tokenizer.encode_batch(texts)

# Process large corpus in parallel
with Pool(8) as pool:
    # Split corpus into chunks
    chunk_size = 1000
    chunks = [corpus[i:i+chunk_size] for i in range(0, len(corpus), chunk_size)]

    # Encode in parallel
    results = pool.map(encode_batch, chunks)

加速比:使用 8 个核心时可达 5-8 倍

性能基准测试

训练速度
语料库大小BPE(30k 词汇表)WordPiece(30k)Unigram(8k)
10 MB15 秒18 秒25 秒
100 MB1.5 分钟2 分钟4 分钟
1 GB15 分钟20 分钟40 分钟

硬件:16 核 CPU,在英文 Wikipedia 上测试

分词速度
实现方式1 GB 语料库吞吐量
纯 Python约 20 分钟约 50 MB/分钟
HF Tokenizers约 15 秒约 4 GB/分钟
加速比80 倍80 倍

测试:英文文本,平均句长为 20 个单词

内存用量
任务内存
加载分词器约 10 MB
训练 BPE(30k 词汇表)约 200 MB
编码 100 万个句子约 500 MB

支持的模型

可通过 from_pretrained() 使用的预训练分词器:

BERT 系列:

  • bert-base-uncased、bert-large-cased
  • distilbert-base-uncased
  • roberta-base、roberta-large

GPT 系列:

  • gpt2、gpt2-medium、gpt2-large
  • distilgpt2

T5 系列:

  • t5-small、t5-base、t5-large
  • google/flan-t5-xxl

其他:

  • facebook/bart-base、facebook/mbart-large-cc25
  • albert-base-v2、albert-xlarge-v2
  • xlm-roberta-base、xlm-roberta-large

浏览全部模型:https://huggingface.co/models?library=tokenizers

参考资料

资源

Agent 操作流程

  1. 检查环境。 检查 GPU 类型、内存和驱动/CUDA 版本(nvidia-smi)、框架版本,以及数据集的位置和大小。
  2. 明确输入。 根据数据或用户确认格式、标识符和参数。任何会改变结果的值都应询问确认,不要猜测。
  3. 先运行小规模版本。 执行冒烟测试:使用小型模型或数据子集,运行少量步骤,并确认损失下降且检查点成功保存。
  4. 根据上述说明和参考资料执行完整任务。
  5. 验证结果。 在留出数据上跟踪指标,与基线进行比较,并记录随机种子、配置和硬件信息。
  6. 报告。 说明运行内容(版本、命令、参数)、检查项目以及仍不确定之处。
如果出现这种情况请执行以下操作
CUDA 显存不足减小批次大小,启用梯度累积/检查点或混合精度,或者对模型进行分片。
损失为 NaN 或发散降低学习率,检查数据中是否有无效值,并启用梯度裁剪。
当前安装版本中缺少这些说明里提到的函数、标志或端点查阅已安装版本自身的文档(help()、--help、官方文档),调整用法并告知用户。切勿编造 API。
必需的输入、标识符或参数不明确询问用户,或在运行前明确说明所采用的假设。

诚信规则

  • 切勿捏造结果、参数、标识符、引文或统计数据。如果无法运行或验证某项内容,请如实说明。
  • 没有日志时,切勿声称取得了训练结果;启动大型任务前应估算计算成本。
  • 此处与特定版本相关的细节可能已过时:请根据已安装版本的官方文档进行确认。
  • 对于需要付费、占用共享 GPU 或云配额、涉及个人或患者数据,或无法撤销的操作,必须先征求同意。

相关技能

  • transformers:用于加载 Hub 模型、运行流水线推理、文本生成,以及在 NLP、视觉、音频等任务上使用 Trainer 微调的 Hugging Face Transformers……
  • sentencepiece:与语言无关的分词器,将文本视为原始 Unicode。

评论

支持 Markdown