名称: sentencepiece 描述: 语言无关的分词器,将文本视为原始Unicode。支持BPE和Unigram算法。快速(每秒50,000个句子),轻量级(6MB内存),确定性词汇。被T5、ALBERT、XLNet、mBART使用。无需预分词即可在原始文本上训练。当需要多语言支持、CJK语言(中文、日文、韩文)或可复现分词时使用。 版本: 1.0.0 作者: Orchestra Research 许可证: MIT 标签: [分词, SentencePiece, 语言无关, BPE, Unigram, 多语言, CJK语言, Unicode, 确定性, Google] 依赖项: [sentencepiece, transformers]
SentencePiece - 语言无关分词
无监督分词器,无需语言特定预处理即可处理原始文本。
何时使用SentencePiece
使用SentencePiece时:
- 构建多语言模型(无语言特定规则)
- 处理CJK语言(中文、日文、韩文)
- 需要可复现分词(确定性词汇)
- 希望在原始文本上训练(无需预分词)
- 需要轻量级部署(6MB内存,每秒50,000个句子)
性能:
- 速度: 每秒50,000个句子
- 内存: 约6MB用于加载模型
- 语言: 全部(语言无关)
使用替代方案:
- HuggingFace Tokenizers: 训练更快,更灵活
- tiktoken: OpenAI模型(GPT-3.5/4)
- BERT WordPiece: 以英语为中心的任务
快速开始
安装
# Python
pip install sentencepiece
# C++(需要CMake)
git clone https://github.com/google/sentencepiece.git
cd sentencepiece
mkdir build && cd build
cmake .. && make -j $(nproc)
sudo make install
训练模型
# 命令行(BPE,词汇量8000)
spm_train --input=data.txt --model_prefix=m --vocab_size=8000 --model_type=bpe
# Python API
import sentencepiece as spm
spm.SentencePieceTrainer.train(
input='data.txt',
model_prefix='m',
vocab_size=8000,
model_type='bpe'
)
训练时间: 约1-2分钟用于100MB语料库
编码和解码
import sentencepiece as spm
# 加载模型
sp = spm.SentencePieceProcessor(model_file='m.model')
# 编码为片段
pieces = sp.encode('This is a test', out_type=str)
print(pieces) # ['▁This', '▁is', '▁a', '▁test']
# 编码为ID
ids = sp.encode('This is a test', out_type=int)
print(ids) # [284, 47, 11, 1243]
# 解码
text = sp.decode(ids)
print(text) # "This is a test"
语言无关设计
空格作为符号(▁)
text = "Hello world"
pieces = sp.encode(text, out_type=str)
print(pieces) # ['▁Hello', '▁world']
# 解码保留空格
decoded = sp.decode_pieces(pieces)
print(decoded) # "Hello world"
关键原则: 将文本视为原始Unicode,空格 = ▁(元符号)
分词算法
BPE(字节对编码)
spm.SentencePieceTrainer.train(
input='data.txt',
model_prefix='bpe_model',
vocab_size=16000,
model_type='bpe'
)
被使用于: mBART
Unigram(默认)
spm.SentencePieceTrainer.train(
input='data.txt',
model_prefix='unigram_model',
vocab_size=8000,
model_type='unigram'
)
被使用于: T5, ALBERT, XLNet
训练配置
基本参数
spm.SentencePieceTrainer.train(
input='corpus.txt',
model_prefix='m',
vocab_size=32000,
model_type='unigram',
character_coverage=0.9995, # CJK用1.0
user_defined_symbols=['[SEP]', '[CLS]'],
unk_piece='<unk>',
num_threads=16
)
字符覆盖
| 语言类型 | 覆盖 | 理由 |
|---|---|---|
| 英语 | 0.9995 | 最常见字符 |
| CJK(中文) | 1.0 | 需要所有字符 |
| 多语言 | 0.9995 | 平衡 |
编码选项
子词正则化
# 采样不同分词
for _ in range(3):
pieces = sp.encode('tokenization', out_type=str, enable_sampling=True, alpha=0.1)
print(pieces)
# 输出(每次不同):
# ['▁token', 'ization']
# ['▁tok', 'en', 'ization']
使用案例: 数据增强以提高鲁棒性。
常见模式
T5风格训练
spm.SentencePieceTrainer.train(
input='c4_corpus.txt',
model_prefix='t5',
vocab_size=32000,
model_type='unigram',
user_defined_symbols=[f'<extra_id_{i}>' for i in range(100)],
unk_id=2,
eos_id=1,
pad_id=0
)
与transformers集成
from transformers import T5Tokenizer
# T5内部使用SentencePiece
tokenizer = T5Tokenizer.from_pretrained('t5-base')
inputs = tokenizer('translate English to French: Hello', return_tensors='pt')
性能基准
训练速度
| 语料库 | BPE(16k) | Unigram(8k) |
|---|---|---|
| 100 MB | 1-2 分钟 | 3-4 分钟 |
| 1 GB | 10-15 分钟 | 30-40 分钟 |
分词速度
- SentencePiece: 每秒50,000个句子
- HF Tokenizers: 每秒200,000个句子(快4倍)
支持模型
T5系列: t5-base, t5-large(32k词汇,Unigram)
ALBERT: albert-base-v2(30k词汇,Unigram)
XLNet: xlnet-base-cased(32k词汇,Unigram)
mBART: facebook/mbart-large-50(250k词汇,BPE)
参考资料
资源
- GitHub: https://github.com/google/sentencepiece ⭐ 10,000+
- 论文: https://arxiv.org/abs/1808.06226 (EMNLP 2018)
- 版本: 0.2.0+