论文笔记--SentencePiece: A simple and language independent subword tokenizer and detokenizer for Neural Text Processing
1. 文章简介
- 标题:SentencePiece: A simple and language independent subword tokenizer and detokenizer for Neural Text Processing
- 作者:Taku Kudo, John Richardson
- 日期:2018
- 期刊:arxiv preprint
2. 文章概括
文章提出了一种子词分词方法,针对包括中文、日文、各种拉丁语等不同语言都可以进行通用的无监督学习。文章提出的分词方法SentencePiece
3 文章重点技术
3.1 SentencePiece的组成
SentencePiece包含4个组成部分
- Normalizer:将原始输入文本视作Unicode Char,然后默认通过Unicode NFKC对输入进行正则,也可以通过设置参数选择其它正则方式或者不采用正则
- Trainer:从上述正则之后的文本学习子词分词的模型。不同于现存的其它子词分割工具,SentencePiece不要求输入的文本为分词之后的文本,而是原始文本即可,从而可降低输入的门槛且进行lossless学习。
- Encoder/Tokenizer:Encoder内部会调用上述正则和训练,然后将原始文本分割成子词序列
- Decoder/Detokenizer:Decoder将分割的子词序列转化为正则后的文本。
3.2 Lossless Tokenization
已有的分词器针对以下场景往往需要手动添加规则:如将"Hello World.“分割成[Hello][World][.]之后,如果复原会在标点符号之前增加一个空格:“Hello World .”,这就造成了detokenization的不可逆性。针对中文、日文的句子,同一句话之间没有空格,detokenizer也很难对分割后的序列还原。为此文章将Decoder按照如下方式学习,使得Decoder为一个可逆的过程:
D
e
c
o
d
e
r
(
E
n
c
o
d
e
r
(
N
o
r
m
a
l
i
z
e
(
T
e
x
t
)
)
)
=
N
o
r
m
a
l
i
z
e
(
T
e
x
t
)
Decoder(Encoder(Normalize(Text))) = Normalize(Text)
Decoder(Encoder(Normalize(Text)))=Normalize(Text),文章称此为Lossless Tokenization。Lossless Tokenization会将输入视为Unicode字符(包含空格),然后先将句子分割成随机的子词序列,其中由”_“代替空格,如果单个单词被拆分,则非首字母的单词要以@@开头标记,如"world"如被分割则需标记为"wor"和”@@ld"。detokenization阶段我们只需通过detok = ''.join(tokens.replace('_', ' ‘))
还原至原始句子。
文章还提出了一些API的其它功能,这里笔者就不一一细述。
4.代码
文章的github里面附了一个超详细的官方介绍笔记本SentencePiece的python全部操作示例代码链接,感兴趣的读者可以去详细阅读。这里笔者附送一个中文/英文示例(很多网上找到的都跑不通,这里亲测有效)
!wget https://raw.githubusercontent.com/google/sentencepiece/master/data/botchan.txt
import sentencepiece as spm # 测过跑不通
由于上述链接失效,笔者自己在代码的文件夹下构建了一个同名的txt文件(测过其它名字会报错,应该是做了一些处理吧,由于源码是C++也没怎么看😫),然后在里面粘贴一些中文/英文文本即可。
import os
import sentencepiece as spm
# kwargs
spm.SentencePieceTrainer.train(
sentence_reader=open(os.path.join(os.getcwd(), 'botchan.txt'), 'r'),
model_prefix='my', vocab_size=900)
上述传参方法等价于下述指令字符执行代码
# 传入指令字符串
spm.SentencePieceTrainer.train(
'--input=botchan.txt --model_prefix=m --vocab_size=900')
笔者随便测试了几百行中文文本,如此小的样本分词效果竟然真得很可以!
5.文章亮点
文章提出了基于Lossless Tokenization的分词器SentencePiece,不同于其它现存的分词器,SentencePiece无需指定语言,一套系统通吃!而且操作简单,效果很好(我宣布SentencePiece即将成为笔者下一个project的工具!)。
6. 原文传送门
SentencePiece: A simple and language independent subword tokenizer and detokenizer for Neural Text Processing
SentencePiece的python全部操作示例代码链接