关于HuggingFace SentencePiece分词器无损性及未知token编码的技术问询
SentencePiece分词器无损性相关问题解答
背景
我使用HuggingFace实现的SentencePieceBPETokenizer和SentencePieceUnigramTokenizer类,在无Unicode字符的数据集上训练分词器后,尝试对含Unicode字符的字符串编码时发现,这些未见过的Unicode字符会被编码为<unk>。但SentencePiece本身应该具备无损可逆特性,理论上无需<unk>就能像ByteLevelBPETokenizer一样解码回原字符串。
问题1:这是SentencePiece的普遍现象,其无损性的说法并不成立?
SentencePiece的无损性是建立在启用字节fallback机制的前提下的。默认配置下,不管是原生版本还是HuggingFace实现,若训练时未开启该机制,遇到训练数据中没有的Unicode字符,都会输出<unk>。这不是无损性不成立,而是没有启用对应的 fallback 策略——原生SentencePiece支持将未识别的字符分解为UTF-8字节序列编码,只要开启这个功能,就能保证编码解码完全可逆,不会出现<unk>。
问题2:这仅存在于HuggingFace实现而非Google原生版本?
不是。原生SentencePiece默认同样会对未见过的字符输出<unk>,但它提供了--byte_fallback命令行参数来启用字节级fallback,开启后就能避免<unk>,实现无损编码。HuggingFace的实现只是默认没有开启这个选项,该问题并非HuggingFace独有。
问题3:有无办法让HuggingFace实现像ByteLevelBPETokenizer一样完全无损?
有两种可行方案:
- 训练时开启字节fallback:在训练
SentencePieceBPETokenizer或SentencePieceUnigramTokenizer时,添加byte_fallback=True参数,训练后的分词器会自动将未见过的字符分解为UTF-8字节编码,不会生成<unk>。示例代码:
from tokenizers import SentencePieceBPETokenizer tokenizer = SentencePieceBPETokenizer() tokenizer.train( files=["your_dataset.txt"], vocab_size=32000, byte_fallback=True # 启用字节fallback的关键参数 )
- 加载已训练分词器时配置:如果是已训练好的分词器,可以在加载时通过修改配置开启字节fallback,不过更稳妥的方式是重新训练时添加上述参数。
内容的提问来源于stack exchange,提问作者Shital Shah
相关产品推荐
相关产品推荐

