BPE莽囤、WordPiece和SentencePiece

1. 背景與基礎(chǔ)

在使用GPT BERT模型輸入詞語常常會(huì)先進(jìn)行tokenize 咙鞍,tokenize具體目標(biāo)與粒度是什么呢房官?tokenize也有許多類別及優(yōu)缺點(diǎn),這篇文章總結(jié)一下各個(gè)方法及實(shí)際案例续滋。

tokenize的目標(biāo)是把輸入的文本流翰守,切分成一個(gè)個(gè)子串,每個(gè)子串相對(duì)有完整的語義疲酌,便于學(xué)習(xí)embedding表達(dá)和后續(xù)模型的使用蜡峰。

tokenize有三種粒度:word/subword/char

  • word/詞,詞朗恳,是最自然的語言單元湿颅。對(duì)于英文等自然語言來說,存在著天然的分隔符粥诫,如空格或一些標(biāo)點(diǎn)符號(hào)等油航,對(duì)詞的切分相對(duì)容易。但是對(duì)于一些東亞文字包括中文來說臀脏,就需要某種分詞算法才行劝堪。順便說一下,Tokenizers庫(kù)中揉稚,基于規(guī)則切分部分秒啦,采用了spaCy和Moses兩個(gè)庫(kù)。如果基于詞來做詞匯表搀玖,由于長(zhǎng)尾現(xiàn)象的存在余境,這個(gè)詞匯表可能會(huì)超大。像Transformer XL庫(kù)就用到了一個(gè)26.7萬個(gè)單詞的詞匯表灌诅。這需要極大的embedding matrix才能存得下芳来。embedding matrix是用于查找取用token的embedding vector的。這對(duì)于內(nèi)存或者顯存都是極大的挑戰(zhàn)猜拾。常規(guī)的詞匯表即舌,一般大小不超過5萬

  • char/字符挎袜,即最基本的字符顽聂,如英語中的'a','b','c'或中文中的'你'肥惭,'我','他'等紊搪。而一般來講蜜葱,字符的數(shù)量是少量有限的。這樣做的問題是耀石,由于字符數(shù)量太小牵囤,我們?cè)跒槊總€(gè)字符學(xué)習(xí)嵌入向量的時(shí)候,每個(gè)向量就容納了太多的語義在內(nèi)滞伟,學(xué)習(xí)起來非常困難揭鳞。

  • subword/子詞級(jí),它介于字符和單詞之間梆奈。比如說'Transformers'可能會(huì)被分成'Transform'和'ers'兩個(gè)部分汹桦。這個(gè)方案平衡了詞匯量和語義獨(dú)立性,是相對(duì)較優(yōu)的方案鉴裹。它的處理原則是,常用詞應(yīng)該保持原狀钥弯,生僻詞應(yīng)該拆分成子詞以共享token壓縮空間径荔。

2. 常用tokenize算法

最常用的三種tokenize算法:BPE(Byte-Pair Encoding),WordPiece和SentencePiece


2.1 Byte-Pair Encoding (BPE) / Byte-level BPE

2.1.1 BPE

BPE脆霎,即字節(jié)對(duì)編碼总处。其核心思想在于將最常出現(xiàn)的子詞對(duì)合并,直到詞匯表達(dá)到預(yù)定的大小時(shí)停止睛蛛。

  • 首先鹦马,它依賴于一種預(yù)分詞器pretokenizer來完成初步的切分。pretokenizer可以是簡(jiǎn)單基于空格的忆肾,也可以是基于規(guī)則的荸频;

  • 分詞之后,統(tǒng)計(jì)每個(gè)詞出現(xiàn)的頻次客冈,供后續(xù)計(jì)算使用旭从。例如,我們統(tǒng)計(jì)到了5個(gè)詞的詞頻

("hug", 10), ("pug", 5), ("pun", 12), ("bun", 4), ("hugs", 5)

  • 建立基礎(chǔ)詞匯表场仲,包括所有的字符和悦,即:

["b", "g", "h", "n", "p", "s", "u"]

  • 根據(jù)規(guī)則,我們分別考察2-gram渠缕,3-gram的基本字符組合鸽素,把高頻的ngram組合依次加入到詞匯表中,直到詞匯表達(dá)到預(yù)定大小停止亦鳞。比如馍忽,我們計(jì)算出ug/un/hug三種組合出現(xiàn)頻次分別為20棒坏,16和15,加入到詞匯表中舵匾。
  • 最終詞匯表的大小= 基礎(chǔ)字符詞匯表大小 + 合并串的數(shù)量俊抵,比如像GPT,它的詞匯表大小 40478 = 478(基礎(chǔ)字符) + 40000(merges)坐梯。添加完后徽诲,我們?cè)~匯表變成:

["b", "g", "h", "n", "p", "s", "u", "ug", "un", "hug"]

實(shí)際使用中,如果遇到未知字符用<unk>代表吵血。

2.1.2 Byte-level BPE

BPE的一個(gè)問題是谎替,如果遇到了unicode芝囤,基本字符集可能會(huì)很大护锤。一種處理方法是我們以一個(gè)字節(jié)為一種“字符”,不管實(shí)際字符集用了幾個(gè)字節(jié)來表示一個(gè)字符措伐。這樣的話侦另,基礎(chǔ)字符集的大小就鎖定在了256秩命。

例如,像GPT-2的詞匯表大小為50257 = 256 + <EOS> + 50000 mergers褒傅,<EOS>是句子結(jié)尾的特殊標(biāo)記弃锐。

2.2 WordPiece

WordPiece,從名字好理解殿托,它是一種子詞粒度的tokenize算法subword tokenization algorithm霹菊,很多著名的Transformers模型,比如BERT/DistilBERT/Electra都使用了它支竹。

它的原理非常接近BPE旋廷,不同之處在于它做合并時(shí),并不是直接找最高頻的組合礼搁,而是找能夠最大化訓(xùn)練數(shù)據(jù)似然的merge饶碘。即它每次合并的兩個(gè)字符串A和B,應(yīng)該具有最大的\frac{P(AB)}{P(A)P(B)}值馒吴。合并AB之后熊镣,所有原來切成A+B兩個(gè)tokens的就只保留AB一個(gè)token,整個(gè)訓(xùn)練集上最大似然變化量與\frac{P(AB)}{P(A)P(B)}成正比募书。

2.3 Unigram

與BPE或者WordPiece不同绪囱,Unigram的算法思想是從一個(gè)巨大的詞匯表出發(fā),再逐漸刪除trim down其中的詞匯莹捡,直到size滿足預(yù)定義鬼吵。

初始的詞匯表可以采用所有預(yù)分詞器分出來的詞,再加上所有高頻的子串篮赢。
每次從詞匯表中刪除詞匯的原則是使預(yù)定義的損失最小齿椅。訓(xùn)練時(shí)琉挖,計(jì)算loss的公式為:
Loss = - \sum^{N}_{i=1}log \left( \sum_{x \in S(x_i)} p(x) \right )
假設(shè)訓(xùn)練文檔中的所有詞分別為 x_1;x_2,...,x_N,而每個(gè)詞tokenize的方法是一個(gè)集合S(x_i)涣脚。
當(dāng)一個(gè)詞匯表確定時(shí)示辈,每個(gè)詞tokenize的方法集合S(x_i)就是確定的,而每種方法對(duì)應(yīng)著一個(gè)概率p(x)遣蚀。
如果從詞匯表中刪除部分詞矾麻,則某些詞的tokenize的種類集合就會(huì)變少,log(*)中的求和項(xiàng)就會(huì)減少芭梯,從而增加整體loss险耀。

Unigram算法每次會(huì)從詞匯表中挑出使得loss增長(zhǎng)最小的10%~20%的詞匯來刪除。
一般Unigram算法會(huì)與SentencePiece算法連用玖喘。

2.4 SentencePiece

SentencePiece甩牺,顧名思義,它是把一個(gè)句子看作一個(gè)整體累奈,再拆成片段贬派,而沒有保留天然的詞語的概念。一般地澎媒,它把空格space也當(dāng)作一種特殊字符來處理赠群,再用BPE或者Unigram算法來構(gòu)造詞匯表

比如旱幼,XLNetTokenizer就采用了_來代替空格,解碼的時(shí)候會(huì)再用空格替換回來突委。

目前柏卤,Tokenizers庫(kù)中,所有使用了SentencePiece的都是與Unigram算法聯(lián)合使用的匀油,比如ALBERT缘缚、XLNet、Marian和T5.

3. 切分實(shí)例與代碼分析

3.1 BertTokenizer/ WordPiece

先試一個(gè)BertTokenizer敌蚜,它基于WordPiece算法桥滨,base版本的詞匯表大小為21128

from transformers import BertTokenizer
tokenizer = BertTokenizer.from_pretrained('bert-base-chinese')
tokens = t.encode(...).tokens

切分效果為:

Tokenizer: <class 'transformers.models.bert.tokenization_bert.BertTokenizer'>
Text: The problems of your past are your business. The problems of your future are my privilege.
Tokens: [UNK],pro,##ble,##ms,of,your,pa,##st,are,your,business,.,[UNK],pro,##ble,##ms,of,your,future,are,my,pr,##i,##vi,##le,##ge,.

Text: 你的過去我不愿過問,那是你的事情弛车。你的未來我希望參與齐媒,這是我的榮幸。
Tokens: 你,的,過,去,我,不,愿,過,問,纷跛,,那,是,你,的,事,情,喻括。,你,的,未,來,我,希,望,參,與,,,這,是,我,的,榮,幸,贫奠。

Text: Don’t make the user feel stupid.
Tokens: [UNK],[UNK],t,make,the,user,feel,st,##up,##id,.

Text: 中國(guó)語言研究院正式宣布唬血,“筆畫最多的漢字”的桂冠屬于“龖(dá)”字望蜡!
Tokens: 中,國(guó),語,言,研,究,院,正,式,宣,布,,,[UNK],筆,畫,最,多,的,漢,字,[UNK],的,桂,冠,屬,于,[UNK],[UNK],(,[UNK],),[UNK],字,拷恨!

其中脖律,

  • BertTokenizer中,用##符號(hào)表示非開頭的子詞腕侄,比如第1句中的problems被拆分成了三部分小泉,pro/##ble/##ms;
  • 標(biāo)點(diǎn)符號(hào)兜挨、生僻字等未出現(xiàn)的token被[UNK]代替
  • 中文基本拆分成了字的形式膏孟,并沒有看到多字詞的形式

分詞流程與代碼分析如下:
BertTokenizer類關(guān)系如下

在代碼中查看


主要做了兩件事情:

  1. 根據(jù)參數(shù)控制來對(duì)輸入文本做基礎(chǔ)分詞 (basic_tokenizer)
  2. 對(duì)于切分出來的單個(gè)詞,再切分(wordpiece_tokenizer)

basic_tokenizer是把句子切分成詞拌汇,仍然可以對(duì)著代碼看一下:

特別要注意的在 401 行:如果 tokenize_chinese_chars 參數(shù)為 True柒桑,那么所有的中文詞都會(huì)被切成字符級(jí)別!T胍ā魁淳!參數(shù)傳來的 never_split 并不會(huì)讓這些中文詞不被切分。

wordpiece_tokenizer則是將詞切成字符級(jí)別与倡,例如 doing->['do', '###ing']界逛。

這里的做法就是把一個(gè)詞送入 BERT 中做最大匹配(類似于 Jieba 分詞的正向最大匹配算法),如果前面已經(jīng)有匹配纺座,則后面的詞都會(huì)加 ’##‘息拜。

而中文,因?yàn)橐呀?jīng)在上一步被切分成字符級(jí)別净响,所以不會(huì)有任何改變少欺。

3.2 T5Tokenizer / SentencePiece

T5模型是基于SentencePiece的,我們看看它的切分效果馋贤。我用的這個(gè)版本詞匯表大小是250112赞别。

Tokenizer: <class 'transformers.models.t5.tokenization_t5.T5Tokenizer'>
Text: The problems of your past are your business. The problems of your future are my privilege.
Tokens: ▁The,▁problems,▁of,▁your,▁past,▁are,▁your,▁business,.,▁The,▁problems,▁of,▁your,▁future,▁are,▁my,▁,privilege,.

Text: 你的過去我不愿過問,那是你的事情配乓。你的未來我希望參與仿滔,這是我的榮幸。
Tokens: ▁,你的,過去,我不,愿,過,問,,,那是,你,的事情,犹芹。,你的,未來,我,希望,參與,,,這是,我的,榮,幸,崎页。

Text: Don’t make the user feel stupid.
Tokens: ▁Don,’,t,▁make,▁the,▁user,▁feel,▁stupid,.

Text: 中國(guó)語言研究院正式宣布,“筆畫最多的漢字”的桂冠屬于“龖(dá)”字腰埂!
Tokens: ▁,中國(guó),語言,研究院,正式,宣布,,“,筆,畫,最多,的,漢,字,”,的,桂,冠,屬于,“,<0xE9>,<0xBE>,<0x96>,(,dá,),”,字,!

其中实昨,

  • 最明顯的,可以看到下劃線被引入盐固,代替了空格和句子開頭特殊符號(hào)
  • 中文可以看到一些多字詞荒给,比如“未來”丈挟,“研究院”等,但有些詞其實(shí)不符合一般的分詞習(xí)慣志电,比如“的事情”曙咽、“我不”等等
  • 生僻字龖被拆成了三個(gè)基礎(chǔ)字節(jié)形式的token

參考鏈接

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末例朱,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子鱼蝉,更是在濱河造成了極大的恐慌洒嗤,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,113評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件魁亦,死亡現(xiàn)場(chǎng)離奇詭異渔隶,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)洁奈,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門间唉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人利术,你說我怎么就攤上這事呈野。” “怎么了印叁?”我有些...
    開封第一講書人閱讀 153,340評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵被冒,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我轮蜕,道長(zhǎng)昨悼,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,449評(píng)論 1 279
  • 正文 為了忘掉前任肠虽,我火速辦了婚禮,結(jié)果婚禮上玛追,老公的妹妹穿的比我還像新娘税课。我一直安慰自己,他們只是感情好痊剖,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評(píng)論 5 374
  • 文/花漫 我一把揭開白布韩玩。 她就那樣靜靜地躺著,像睡著了一般陆馁。 火紅的嫁衣襯著肌膚如雪找颓。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,166評(píng)論 1 284
  • 那天叮贩,我揣著相機(jī)與錄音击狮,去河邊找鬼佛析。 笑死,一個(gè)胖子當(dāng)著我的面吹牛彪蓬,可吹牛的內(nèi)容都是我干的寸莫。 我是一名探鬼主播,決...
    沈念sama閱讀 38,442評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼档冬,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼膘茎!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起酷誓,我...
    開封第一講書人閱讀 37,105評(píng)論 0 261
  • 序言:老撾萬榮一對(duì)情侶失蹤披坏,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后盐数,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體棒拂,經(jīng)...
    沈念sama閱讀 43,601評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評(píng)論 2 325
  • 正文 我和宋清朗相戀三年娘扩,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了着茸。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,161評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡琐旁,死狀恐怖涮阔,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情灰殴,我是刑警寧澤敬特,帶...
    沈念sama閱讀 33,792評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站牺陶,受9級(jí)特大地震影響伟阔,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜掰伸,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評(píng)論 3 307
  • 文/蒙蒙 一皱炉、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧狮鸭,春花似錦合搅、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至惯退,卻和暖如春赌髓,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評(píng)論 1 261
  • 我被黑心中介騙來泰國(guó)打工锁蠕, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留夷野,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,618評(píng)論 2 355
  • 正文 我出身青樓匿沛,卻偏偏與公主長(zhǎng)得像扫责,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子逃呼,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評(píng)論 2 344

推薦閱讀更多精彩內(nèi)容

  • transformers是huggingface提供的預(yù)訓(xùn)練模型庫(kù)鳖孤,可以輕松調(diào)用API來得到你的詞向量。trans...
    曉柒NLP與藥物設(shè)計(jì)閱讀 7,276評(píng)論 0 10
  • 本篇文章譯自 Chris McCormick的BERT Word Embeddings Tutorial 在這篇文...
    夕寶爸爸閱讀 25,885評(píng)論 1 13
  • 官方文檔:torchtext包含兩部分: 數(shù)據(jù)處理實(shí)用程序 流行的自然語言數(shù)據(jù)集 torchtext.data 的...
    QXPLUS閱讀 3,932評(píng)論 0 1
  • 只是教程的搬運(yùn)工-.- Field的使用 Torchtext采用聲明式方法加載數(shù)據(jù)抡笼,需要先聲明一個(gè)Field對(duì)象苏揣,...
    VanJordan閱讀 20,717評(píng)論 5 19
  • 這篇筆記摘自原文:BERT Word Embeddings Tutorial · Chris McCormick ...
    三方斜陽閱讀 2,263評(píng)論 0 1