背景
隨著ChatGPT迅速出圈,最近幾個月開源的大模型也是遍地開花。目前,開源的大語言模型主要有三大類:ChatGLM衍生的大模型(wenda、ChatSQL等)、LLaMA衍生的大模型(Alpaca、Vicuna、BELLE、Phoenix、Chimera等)、Bloom衍生的大模型(Bloomz、BELLE、Phoenix等)。其中,ChatGLM-6B主要以中英雙語進(jìn)行訓(xùn)練,LLaMA主要以英語為主要語言的拉丁語系進(jìn)行訓(xùn)練,而Bloom使用了46種自然語言、13種編程語言進(jìn)行訓(xùn)練。
模型 | 訓(xùn)練數(shù)據(jù)量 | 模型參數(shù) | 訓(xùn)練數(shù)據(jù)范圍 | 詞表大小 | HF分詞器的分詞算法 | HF分詞器(Tokenizer) |
---|---|---|---|---|---|---|
LLaMA | 1T~1.4T tokens(其中,7B/13B使用1T,33B/65B使用1.4T) | 7B~65B | 以英語為主要語言的拉丁語系 | 32000 | BBPE | LlamaTokenizer(基于SentencePiece工具實現(xiàn) )/LlamaTokenizerFast(基于Huggingface底層的BaseTokenizer實現(xiàn)) |
ChatGLM-6B | 約 1T tokens | 6B | 中英雙語 | 130528 | BBPE | ChatGLMTokenizer(基于SentencePiece工具實現(xiàn)) |
Bloom | 1.6TB預(yù)處理文本,轉(zhuǎn)換為 350B 唯一 tokens | 300M~176B | 46種自然語言,13種編程語言 | 250680 | BBPE | BloomTokenizerFast(基于Huggingface底層的BaseTokenizer實現(xiàn)) |
目前來看,在開源大模型中,LLaMA無疑是其中最閃亮的星。但是,與ChatGLM-6B和Bloom原生支持中文不同。LLaMA 原生僅支持 Latin 或 Cyrillic 語系,對于中文支持不是特別理想。原版LLaMA模型的詞表大小是32K,而多語言模型(如:XLM-R、Bloom)的詞表大小約為250K。以中文為例,LLaMA詞表中的中文token比較少(只有幾百個)。這將導(dǎo)致了兩個問題:
- LLaMA 原生tokenizer詞表中僅包含少量中文字符,在對中文字進(jìn)行tokenzation時,一個中文漢字往往被切分成多個token(2-3個Token才能組合成一個漢字),顯著降低編解碼的效率。
- 預(yù)訓(xùn)練中沒有出現(xiàn)過或者出現(xiàn)得很少的語言學(xué)習(xí)得不充分。
為了解決這些問題,我們可能就需要進(jìn)行中文詞表擴展。比如:在中文語料庫上訓(xùn)練一個中文tokenizer模型,然后將中文 tokenizer 與 LLaMA?原生的 tokenizer 進(jìn)行合并,通過組合它們的詞匯表,最終獲得一個合并后的 tokenizer 模型。
本文將介紹使用SentencePiece
工具如何使用中文語料訓(xùn)練一個分詞模型。
預(yù)備知識
講解 SentencePiece 之前,我們先講解下分詞器(Tokenizer)。
那什么是分詞器?簡單點說就是將字符序列轉(zhuǎn)化為數(shù)字序列,對應(yīng)模型的輸入。
通常情況下,Tokenizer有三種粒度:word/char/subword
- word: 按照詞進(jìn)行分詞,如:
Today is sunday
. 則根據(jù)空格或標(biāo)點進(jìn)行分割[today, is, sunday, .]
- character:按照單字符進(jìn)行分詞,就是以char為最小粒度。 如:
Today is sunday.
則會分割成[t, o, d,a,y, .... ,s,u,n,d,a,y, .]
- subword:按照詞的subword進(jìn)行分詞。如:
Today is sunday.
則會分割成[to, day,is , s,un,day, .]
可以看到這三種粒度分詞截然不同,各有利弊。
對于word粒度分詞:
- 優(yōu)點:詞的邊界和含義得到保留;
- 缺點:1)詞表大,稀有詞學(xué)不好;2)OOV(可能超出詞表外的詞);3)無法處理單詞形態(tài)關(guān)系和詞綴關(guān)系,會將兩個本身意思一致的詞分成兩個毫不相同的ID,在英文中尤為明顯,如:cat, cats。
對于character粒度分詞:
- 優(yōu)點:詞表極小,比如:26個英文字母幾乎可以組合出所有詞,5000多個中文常用字基本也能組合出足夠的詞匯;
- 缺點:1)無法承載豐富的語義,英文中尤為明顯,但中文卻是較為合理,中文中用此種方式較多。2)序列長度大幅增長;
最后為了平衡以上兩種方法, 又提出了基于 subword 進(jìn)行分詞:它可以較好的平衡詞表大小與語義表達(dá)能力;常見的子詞算法有Byte-Pair Encoding (BPE) / Byte-level BPE(BBPE)、Unigram LM、WordPiece、SentencePiece等。
- BPE:即字節(jié)對編碼。其核心思想是從字母開始,不斷找詞頻最高、且連續(xù)的兩個token合并,直到達(dá)到目標(biāo)詞數(shù)。
- BBPE:BBPE核心思想將BPE的從字符級別擴展到子節(jié)(Byte)級別。BPE的一個問題是如果遇到了unicode編碼,基本字符集可能會很大。BBPE就是以一個字節(jié)為一種“字符”,不管實際字符集用了幾個字節(jié)來表示一個字符。這樣的話,基礎(chǔ)字符集的大小就鎖定在了256(2^8)。采用BBPE的好處是可以跨語言共用詞表,顯著壓縮詞表的大小。而壞處就是,對于類似中文這樣的語言,一段文字的序列長度會顯著增長。因此,BBPE based模型可能比BPE based模型表現(xiàn)的更好。然而,BBPE sequence比起B(yǎng)PE來說略長,這也導(dǎo)致了更長的訓(xùn)練/推理時間。BBPE其實與BPE在實現(xiàn)上并無大的不同,只不過基礎(chǔ)詞表使用256的字節(jié)集。
- WordPiece:WordPiece算法可以看作是BPE的變種。不同的是,WordPiece基于概率生成新的subword而不是下一最高頻字節(jié)對。WordPiece算法也是每次從詞表中選出兩個子詞合并成新的子詞。BPE選擇頻數(shù)最高的相鄰子詞合并,而WordPiece選擇使得語言模型概率最大的相鄰子詞加入詞表。
- Unigram:它和 BPE 以及 WordPiece 從表面上看一個大的不同是,前兩者都是初始化一個小詞表,然后一個個增加到限定的詞匯量,而 Unigram Language Model 卻是先初始一個大詞表,接著通過語言模型評估不斷減少詞表,直到限定詞匯量。
- SentencePiece:SentencePiece它是谷歌推出的子詞開源工具包,它是把一個句子看作一個整體,再拆成片段,而沒有保留天然的詞語的概念。一般地,它把空格也當(dāng)作一種特殊字符來處理,再用BPE或者Unigram算法來構(gòu)造詞匯表。SentencePiece除了集成了BPE、ULM子詞算法之外,SentencePiece還能支持字符和詞級別的分詞。
下圖是一些主流模型使用的分詞算法,比如:GPT-1 使用的BPE實現(xiàn)分詞,LLaMA/BLOOM/GPT2/ChatGLM使用BBPE實現(xiàn)分詞。BERT/DistilBERT/Electra使用WordPiece進(jìn)行分詞,XLNet則采用了SentencePiece進(jìn)行分詞。
從上面的表格中我們也可以看到當(dāng)前主流的一些開源大模型有很多基于 BBPE 算法使用 SentencePiece 實現(xiàn)分詞器,從Huggingface Transformers
庫的源碼中也能看到很多分詞器基于SentencePiece工具實現(xiàn),下面來講解SentencePiece
工具的具體使用。
SentencePiece 簡介
SentencePiece 是一種無監(jiān)督的文本 tokenizer 和 detokenizer,主要用于基于神經(jīng)網(wǎng)絡(luò)的文本生成系統(tǒng),其中,詞匯量在神經(jīng)網(wǎng)絡(luò)模型訓(xùn)練之前就已經(jīng)預(yù)先確定了。 SentencePiece 實現(xiàn)了subword單元(例如,字節(jié)對編碼 (BPE))和 unigram 語言模型),并可以直接從原始句子訓(xùn)練字詞模型(subword model)。 這使得我們可以制作一個不依賴于特定語言的預(yù)處理和后處理的純粹的端到端系統(tǒng)。
SentencePiece 特性
唯一Token數(shù)量是預(yù)先確定的
神經(jīng)網(wǎng)絡(luò)機器翻譯模型通常使用固定的詞匯表進(jìn)行操作。 與大多數(shù)假設(shè)無限詞匯量的無監(jiān)督分詞算法不同,SentencePiece 在訓(xùn)練分詞模型時,使最終的詞匯表大小固定,例如:8k、16k 或 32k。
從原始句子進(jìn)行訓(xùn)練
以前的子詞(sub-word)實現(xiàn)假設(shè)輸入句子是預(yù)標(biāo)記(pre-tokenized)的。 這種約束是有效訓(xùn)練所必需的,但由于我們必須提前運行依賴于語言的分詞器,因此使預(yù)處理變得復(fù)雜。 SentencePiece 的實現(xiàn)速度足夠快,可以從原始句子訓(xùn)練模型。 這對于訓(xùn)練中文和日文的tokenizer和detokenizer很有用,因為在這些詞之間不存在明確的空格。
空格被視為基本符號
自然語言處理的第一步是文本 tokenization。
例如,標(biāo)準(zhǔn)的英語分詞器(tokenizer)將對文本Hello world
進(jìn)行分段。 分為[Hello] [World] [.]
這三個token。 這種情況將導(dǎo)致原始輸入和標(biāo)記化(tokenized)序列不可逆轉(zhuǎn)換。 例如,“World”和“.”之間沒有空格的信息??崭駥臉?biāo)記化序列中刪除,例如:Tokenize(“World.”) == Tokenize(“World .”)
但是,SentencePiece 將輸入文本視為一系列 Unicode 字符。 空格也作為普通符號處理。 為了明確地將空格作為基本標(biāo)記處理,SentencePiece 首先使用元符號 "▁" (U+2581) 轉(zhuǎn)義空格。
Hello▁World.
然后,將這段文本分割成小塊,例如:
[Hello] [▁Wor] [ld] [.]
由于空格保留在分段文本中,我們可以毫無歧義地對文本進(jìn)行detokenize。
ini
復(fù)制代碼
detokenized?=?''.join(pieces).replace('?',?'?')
此特性可以在不依賴特定于語言的資源的情況下執(zhí)行detokenization。
注意: 在使用標(biāo)準(zhǔn)分詞器拆分句子時,我們不能應(yīng)用相同的無損轉(zhuǎn)換,因為它們將空格視為特殊符號。 標(biāo)記化(Tokenized)序列不保留恢復(fù)原始句子所需的信息。
子詞正則化和 BPE-dropout
子詞正則化和 BPE-dropout 是簡單的正則化方法,它們實際上通過實時子詞采樣來增強訓(xùn)練數(shù)據(jù),這有助于提高神經(jīng)網(wǎng)絡(luò)機器翻譯(NMT)模型的準(zhǔn)確性和魯棒性。
為了啟用子詞正則化,你可以將 SentencePiece 庫(C++/Python)集成到 NMT 系統(tǒng)中,以便為每個參數(shù)更新采樣一個分段,這與標(biāo)準(zhǔn)的離線數(shù)據(jù)準(zhǔn)備不同。
下面是 Python 庫的示例。
less
復(fù)制代碼
>>>?import?sentencepiece?as?spm >>>?s?=?spm.SentencePieceProcessor(model_file='spm.model') >>>?for?n?in?range(5): ...?????s.encode('New?York',?out_type=str,?enable_sampling=True,?alpha=0.1,?nbest_size=-1) ... ['▁',?'N',?'e',?'w',?'▁York'] ['▁',?'New',?'▁York'] ['▁',?'New',?'▁Y',?'o',?'r',?'k'] ['▁',?'New',?'▁York'] ['▁',?'New',?'▁York']
您會發(fā)現(xiàn)New York
在每個 SampleEncode (C++) 或 使用 enable_sampling=True (Python)進(jìn)行編碼的調(diào)用時的分段方式都不同。 采樣參數(shù)的詳細(xì)信息可在 sentencepiece_processor.h 中找到。
SentencePiece 技術(shù)優(yōu)勢
- 純數(shù)據(jù)驅(qū)動:SentencePiece 從句子中訓(xùn)練 tokenization 和 detokenization 模型。 并不總是需要Pre-tokenization(Moses tokenizer/MeCab/KyTea) 。
- 獨立于語言:SentencePiece 將句子視為 Unicode 字符序列。 沒有依賴于語言的邏輯。
- 多子詞算法:支持 BPE 和 unigram 語言模型。
- 子詞正則化:SentencePiece 實現(xiàn)子詞正則化和 BPE-dropout 的子詞采樣,有助于提高 NMT 模型的魯棒性和準(zhǔn)確性。
- 快速且輕量級:分割速度約為 50k 句子/秒,內(nèi)存占用約為 6MB。
- Self-contained:只要使用相同的模型文件,就可以獲得相同的tokenization/detokenization。
- 直接詞匯 ID 生成:SentencePiece 管理詞匯到 ID 的映射,可以直接從原始句子生成詞匯 ID 序列。
- 基于 NFKC 的 normalization:SentencePiece 執(zhí)行基于 NFKC 的文本 normalization。
SentencePiece與其他實現(xiàn)的比較
特性 | SentencePiece | subword-nmt | WordPiece |
---|---|---|---|
支持的算法 | BPE, unigram, char, word | BPE | BPE* |
是否開源? | Yes | Yes | Google internal |
是否支持子詞正則化 | Yes | No | No |
是否提供 Python 庫 (pip) | Yes | No | N/A |
是否提供 C++ 庫 | Yes | No | N/A |
是否需要預(yù)分割? | No | Yes | Yes |
是否可自定義 normalization (例如:NFKC) | Yes | No | N/A |
是否直接id生成 | Yes | No | N/A |
注意:WordPiece 中使用的 BPE 算法與原始 BPE 略有不同。
環(huán)境安裝
SentencePiece分為兩部分:訓(xùn)練模型和使用模型。其中,訓(xùn)練模型部分是用C語言實現(xiàn)的,可編譯二進(jìn)程程序執(zhí)行,訓(xùn)練結(jié)束后生成一個model文件和一個詞典文件。
模型使用部分同時支持二進(jìn)制程序和Python調(diào)用兩種方式,訓(xùn)練完生成的詞典數(shù)據(jù)是明文,可編輯,因此,也可以用其他任何語言進(jìn)行讀取和使用。
從 C++ 源構(gòu)建和安裝 SentencePiece 命令行工具
由于我們需要命令行工具模型訓(xùn)練,因此,我們需要先安裝 SentencePiece 命令行工具。
構(gòu)建 SentencePiece 需要以下工具和庫:
- cmake
- C++11 編譯器
- gperftools 庫(可選的,可以獲得 10-40% 的性能提升)
在 Ubuntu 上,可以使用 apt-get 安裝構(gòu)建工具:
arduino
復(fù)制代碼
sudo?apt-get?install?cmake?build-essential?pkg-config?libgoogle-perftools-dev
接下來,按如下方式構(gòu)建和安裝命令行工具。
bash
復(fù)制代碼
git?clone?https://github.com/google/sentencepiece.git? cd?sentencepiece mkdir?build cd?build cmake?.. make?-j?$(nproc) make?install ldconfig?-v
查看命令使用文檔:
bash
復(fù)制代碼
spm_train?--help
使用pip安裝sentencepiece庫
SentencePiece 提供了支持 SentencePiece 訓(xùn)練和分割的 Python 包裝器。 由于后續(xù)會基于Python語言使用模型,因此,使用 pip 安裝 SentencePiece 的 Python 二進(jìn)制包。
復(fù)制代碼
pip?install?sentencepiece
訓(xùn)練模型
由于官網(wǎng)只提供英語和日語數(shù)據(jù),如果使用中文進(jìn)行模型訓(xùn)練的話,需要先下載中文訓(xùn)練數(shù)據(jù)。本文使用 紅樓夢(需要自行預(yù)先清洗下數(shù)據(jù))進(jìn)行模型訓(xùn)練。
css
復(fù)制代碼
spm_train?--input=/workspace/data/book/hongluomeng_clean.txt?--model_prefix=/workspace/model/book/hongluomeng-tokenizer?--vocab_size=4000?--character_coverage=0.9995?--model_type=bpe
參數(shù)說明:
- --input: 訓(xùn)練語料文件,可以傳遞以逗號分隔的文件列表。文件格式為每行一個句子。 無需運行tokenizer、normalizer或preprocessor。 默認(rèn)情況下,SentencePiece 使用 Unicode NFKC 規(guī)范化輸入。
- --model_prefix:輸出模型名稱前綴。 訓(xùn)練完成后將生成 <model_name>.model 和 <model_name>.vocab 文件。
- --vocab_size:訓(xùn)練后的詞表大小,例如:8000、16000 或 32000
- --character_coverage:模型覆蓋的字符數(shù)量,對于字符集豐富的語言(如日語或中文)推薦默認(rèn)值為 0.9995,對于其他字符集較小的語言推薦默認(rèn)值為 1.0。
- --model_type:模型類型。 可選值:unigram(默認(rèn))、bpe、char 或 word 。 使用word類型時,必須對輸入句子進(jìn)行pretokenized。
運行過程:
scss
復(fù)制代碼
>?spm_train?--input=/workspace/data/book/hongluomeng_clean.txt?--model_prefix=/workspace/model/book/hongluomeng-tokenizer?--vocab_size=4000?--character_coverage=0.9995?--model_type=bpe sentencepiece_trainer.cc(77)?LOG(INFO)?Starts?training?with?:? trainer_spec?{ ??input:?/workspace/data/book/hongluomeng_clean.txt ??input_format:? ??model_prefix:?/workspace/model/book/hongluomeng-tokenizer ??model_type:?BPE ??vocab_size:?4000 ??self_test_sample_size:?0 ??character_coverage:?0.9995 ??input_sentence_size:?0 ??shuffle_input_sentence:?1 ??seed_sentencepiece_size:?1000000 ??shrinking_factor:?0.75 ??max_sentence_length:?4192 ??num_threads:?16 ??num_sub_iterations:?2 ??max_sentencepiece_length:?16 ??split_by_unicode_script:?1 ??split_by_number:?1 ??split_by_whitespace:?1 ??split_digits:?0 ??pretokenization_delimiter:? ??treat_whitespace_as_suffix:?0 ??allow_whitespace_only_pieces:?0 ??required_chars:? ??byte_fallback:?0 ??vocabulary_output_piece_score:?1 ??train_extremely_large_corpus:?0 ??hard_vocab_limit:?1 ??use_all_vocab:?0 ??unk_id:?0 ??bos_id:?1 ??eos_id:?2 ??pad_id:?-1 ??unk_piece:?<unk> ??bos_piece:?<s> ??eos_piece:?</s> ??pad_piece:?<pad> ??unk_surface:???? ??enable_differential_privacy:?0 ??differential_privacy_noise_level:?0 ??differential_privacy_clipping_threshold:?0 } normalizer_spec?{ ??name:?nmt_nfkc ??add_dummy_prefix:?1 ??remove_extra_whitespaces:?1 ??escape_whitespaces:?1 ??normalization_rule_tsv:? } denormalizer_spec?{} trainer_interface.cc(351)?LOG(INFO)?SentenceIterator?is?not?specified.?Using?MultiFileSentenceIterator. trainer_interface.cc(183)?LOG(INFO)?Loading?corpus:?/workspace/data/book/hongluomeng_clean.txt trainer_interface.cc(378)?LOG(WARNING)?Found?too?long?line?(4224?>?4192). trainer_interface.cc(380)?LOG(WARNING)?Too?long?lines?are?skipped?in?the?training. trainer_interface.cc(381)?LOG(WARNING)?The?maximum?length?can?be?changed?with?--max_sentence_length=<size>?flag. trainer_interface.cc(407)?LOG(INFO)?Loaded?all?3144?sentences trainer_interface.cc(414)?LOG(INFO)?Skipped?6?too?long?sentences. trainer_interface.cc(423)?LOG(INFO)?Adding?meta_piece:?<unk> trainer_interface.cc(423)?LOG(INFO)?Adding?meta_piece:?<s> trainer_interface.cc(423)?LOG(INFO)?Adding?meta_piece:?</s> trainer_interface.cc(428)?LOG(INFO)?Normalizing?sentences... trainer_interface.cc(537)?LOG(INFO)?all?chars?count=866703 trainer_interface.cc(548)?LOG(INFO)?Done:?99.95%?characters?are?covered. trainer_interface.cc(558)?LOG(INFO)?Alphabet?size=3986 trainer_interface.cc(559)?LOG(INFO)?Final?character?coverage=0.9995 trainer_interface.cc(591)?LOG(INFO)?Done!?preprocessed?3144?sentences. trainer_interface.cc(597)?LOG(INFO)?Tokenizing?input?sentences?with?whitespace:?3144 trainer_interface.cc(608)?LOG(INFO)?Done!?3395 bpe_model_trainer.cc(159)?LOG(INFO)?Updating?active?symbols.?max_freq=10909?min_freq=13 trainer_interface.cc(686)?LOG(INFO)?Saving?model:?/workspace/model/book/hongluomeng-tokenizer.model trainer_interface.cc(698)?LOG(INFO)?Saving?vocabs:?/workspace/model/book/hongluomeng-tokenizer.vocab
模型輸出文件(詞表及模型權(quán)重):
shell
復(fù)制代碼
>?ls?-al?/workspace/model/book total?328 drwxr-xr-x??2?root?root???4096?May?19?01:55?. drwxrwxrwx?21?root?root???4096?May?19?01:55?.. -rw-r--r--??1?root?root?285840?May?19?01:55?hongluomeng-tokenizer.model -rw-r--r--??1?root?root??38885?May?19?01:55?hongluomeng-tokenizer.vocab
查看詞表:
bash
復(fù)制代碼
>?head?-n20?/workspace/model/book/hongluomeng-tokenizer.vocab <unk>???0 <s>?????0 </s>????0 :“??????-0 ?!?????-1 寶玉????-2 笑道????-3 ?”??????-4 太太????-5 什么????-6 鳳姐????-7 了一????-8 賈母????-9 也不????-10 ,???????-11 。??????-12 了??????-13 不??????-14 的??????-15 一??????-16
使用模型
基于命令行使用模型
將原始文本編碼成句子片段(token)。
shell
復(fù)制代碼
>?echo?"白日依山盡,黃河入海流。"?|?spm_encode?--model=/workspace/model/book/hongluomeng-tokenizer.model ▁?白?日?依?山?盡?,?黃?河?入?海?流?。
將原始文本編碼成句子片段(Token)id。注意:--output_format
參數(shù)默認(rèn)為piece
。
shell
復(fù)制代碼
>?echo?"白日依山盡,黃河入海流。"?|?spm_encode?--model=/workspace/model/book/hongluomeng-tokenizer.model?--output_format=id 60?254?70?333?468?400?14?733?1476?317?603?510?15
將句子片段(token) id 解碼為原始文本。
shell
復(fù)制代碼
>?echo?"60?254?70?333?468?400?14?733?1476?317?603?510?15"?|?spm_decode?--model=/workspace/model/book/hongluomeng-tokenizer.model?--input_format=id 白日依山盡,黃河入海流。
基于模型文件導(dǎo)出詞匯表。
css
復(fù)制代碼
#?spm_export_vocab?--model=<模型文件>?--output=<輸出文件> spm_export_vocab?--model=/workspace/model/book/hongluomeng-tokenizer.model?--output=/workspace/output/hongluomeng.vocab
其中,--output
指定輸出文件,里面存儲著詞匯列表和 emission log probabilities。 詞匯表 id 對應(yīng)于此文件中的行號。
官網(wǎng)還提供了端到端(包括:訓(xùn)練(spm_train),編碼(spm_encode)和解碼(spm_decode))示例,如下所示:
scss
復(fù)制代碼
%?spm_train?--input=data/botchan.txt?--model_prefix=m?--vocab_size=1000 unigram_model_trainer.cc(494)?LOG(INFO)?Starts?training?with?: input:?"../data/botchan.txt" ...?<snip> unigram_model_trainer.cc(529)?LOG(INFO)?EM?sub_iter=1?size=1100?obj=10.4973?num_tokens=37630?num_tokens/piece=34.2091 trainer_interface.cc(272)?LOG(INFO)?Saving?model:?m.model trainer_interface.cc(281)?LOG(INFO)?Saving?vocabs:?m.vocab %?echo?"I?saw?a?girl?with?a?telescope."?|?spm_encode?--model=m.model ▁I?▁saw?▁a?▁girl?▁with?▁a?▁?te?le?s?c?o?pe?. %?echo?"I?saw?a?girl?with?a?telescope."?|?spm_encode?--model=m.model?--output_format=id 9?459?11?939?44?11?4?142?82?8?28?21?132?6 #?原來輸入的句子是從詞匯表id序列中還原出來 %?echo?"9?459?11?939?44?11?4?142?82?8?28?21?132?6"?|?spm_decode?--model=m.model?--input_format=id I?saw?a?girl?with?a?telescope.
基于Python庫使用模型
python
復(fù)制代碼
>>>?import?sentencepiece?as?spm >>>? >>>?sp?=?spm.SentencePieceProcessor() >>>? >>>?text="這賈雨村原系胡州人氏,也是詩書仕宦之族,因他生于末世,父母祖宗根基已盡,人口衰喪,只剩得他一身一口,在家鄉(xiāng)無益,因進(jìn)京求取功名,再整基業(yè)。" >>>? >>>?sp.Load("/workspace/model/book/hongluomeng-tokenizer.model") True >>>?print(sp.EncodeAsPieces(text)) ['▁',?'這',?'賈',?'雨',?'村',?'原',?'系',?'胡',?'州',?'人',?'氏',?',',?'也',?'是',?'詩',?'書',?'仕',?'宦',?'之',?'族',?',',?'因',?'他',?'生',?'于',?'末',?'世',?',',?'父',?'母',?'祖',?'宗',?'根',?'基',?'已',?'盡',?',',?'人',?'口',?'衰',?'喪',?',',?'只',?'剩',?'得',?'他',?'一',?'身',?'一',?'口',?',',?'在',?'家',?'鄉(xiāng)',?'無',?'益',?',',?'因',?'進(jìn)',?'京',?'求',?'取',?'功',?'名',?',',?'再',?'整',?'基',?'業(yè)',?'。']
除此之外,我們還可以將訓(xùn)練的新詞表并與原來的詞表進(jìn)行合并。具體可參考Chinese-LLaMA-Alpaca在通用中文語料上基于sentencepiece訓(xùn)練的20K中文詞表并與原版LLaMA模型的32K詞表(HF實現(xiàn)LLaMA分詞基于BBPE算法,底層調(diào)用的也是sentencepiece的方法)進(jìn)行合并的代碼。
結(jié)語
本文主要給大家講解了SentencePiece的基本原理及使用方法。如果我們分析某個領(lǐng)域相關(guān)問題,可以基于該領(lǐng)域的書籍和文檔使用SentencePiece去訓(xùn)練一個分詞模型。SentencePiece并不限于被分析的內(nèi)容本身。訓(xùn)練數(shù)據(jù)越多,模型效果越好。
參考文檔:
- SentencePiece
- BPE、WordPiece和SentencePiece
- 大模型中的分詞器tokenizer:BPE、WordPiece、Unigram LM、SentencePiece
- sentencepiece原理與實踐
- 【OpenLLM 008】大模型基礎(chǔ)組件之分詞器-萬字長文全面解讀LLM中的分詞算法與分詞器(tokenization & tokenizers):BPE/WordPiece/ULM & beyond
- Summary of the tokenizers
大模型詞表擴充必備工具SentencePiece - 掘金
sentencepiece原理與實踐?
https://github.com/google/sentencepiece/blob/master/python/README.md?文章來源:http://www.zghlxwxcb.cn/news/detail-680698.html
NLP筆記:中文分詞工具簡介-騰訊云開發(fā)者社區(qū)-騰訊云?文章來源地址http://www.zghlxwxcb.cn/news/detail-680698.html
到了這里,關(guān)于NLP-分詞器:SentencePiece【參考Chinese-LLaMA-Alpaca在通用中文語料上訓(xùn)練的20K中文詞表并與原版LLaMA模型的32K詞表進(jìn)行合并的代碼】的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!