Sentence Piece เป็น tokenizer ข้อความที่ไม่ได้รับการดูแลและ detokenizer ส่วนใหญ่สำหรับระบบการสร้างข้อความบน Neural Network ซึ่งขนาดคำศัพท์ถูกกำหนดไว้ล่วงหน้าก่อนการฝึกโมเดลประสาท Sentence Piece ใช้ หน่วยคำย่อย (เช่น การเข้ารหัสไบต์คู่ (BPE) [Sennrich et al.]) และ โมเดลภาษายูนิแกรม [Kudo.]) พร้อมส่วนขยายของการฝึกอบรมโดยตรงจากประโยคดิบ Sentence Piece ช่วยให้เราสามารถสร้างระบบ end-to-end ล้วนๆ ที่ไม่ขึ้นอยู่กับการประมวลผลก่อน/หลังการประมวลผลเฉพาะภาษา
นี่ไม่ใช่ผลิตภัณฑ์อย่างเป็นทางการของ Google
สำหรับผู้ที่ไม่คุ้นเคยกับ Sentence Piece ในฐานะซอฟต์แวร์/อัลกอริธึม คุณสามารถอ่านคำแนะนำแบบคร่าวๆ ได้ที่นี่
คุณสมบัติ | ประโยคชิ้น | คำย่อย-nmt | เวิร์ดพีซ |
---|---|---|---|
อัลกอริทึมที่รองรับ | BPE, ยูนิแกรม, ถ่าน, คำ | บีพีอี | บีพีอี* |
โอเอส? | ใช่ | ใช่ | ภายในของ Google |
การทำให้คำย่อยเป็นมาตรฐาน | ใช่ | เลขที่ | เลขที่ |
ไลบรารีหลาม (pip) | ใช่ | เลขที่ | ไม่มี |
ไลบรารี C++ | ใช่ | เลขที่ | ไม่มี |
จำเป็นต้องแบ่งกลุ่มล่วงหน้าหรือไม่? | เลขที่ | ใช่ | ใช่ |
การทำให้เป็นมาตรฐานที่ปรับแต่งได้ (เช่น NFKC) | ใช่ | เลขที่ | ไม่มี |
การสร้างรหัสโดยตรง | ใช่ | เลขที่ | ไม่มี |
โปรดทราบว่าอัลกอริทึม BPE ที่ใช้ใน Word Piece นั้นแตกต่างจาก BPE ดั้งเดิมเล็กน้อย
Sentence Piece คือการนำ หน่วยคำย่อย ไปใช้ใหม่ ซึ่งเป็นวิธีที่มีประสิทธิภาพในการบรรเทาปัญหาคำศัพท์แบบเปิดในการแปลด้วยเครื่องประสาท Sentence Piece รองรับอัลกอริธึมการแบ่งส่วนสองแบบ ได้แก่ การเข้ารหัสคู่ไบต์ (BPE) [Sennrich et al.] และ โมเดลภาษายูนิแกรม [Kudo.] นี่คือความแตกต่างในระดับสูงจากการใช้งานอื่นๆ
โดยทั่วไปโมเดลการแปลด้วยเครื่องประสาทเทียมจะทำงานโดยใช้คำศัพท์ที่ตายตัว ซึ่งแตกต่างจากอัลกอริธึมการแบ่งส่วนคำที่ไม่ได้รับการดูแลส่วนใหญ่ ซึ่งใช้คำศัพท์ที่ไม่มีที่สิ้นสุด Sentence Piece ฝึกรูปแบบการแบ่งส่วนเพื่อให้ขนาดคำศัพท์สุดท้ายได้รับการแก้ไข เช่น 8k, 16k หรือ 32k
โปรดทราบว่า Sentence Piece ระบุขนาดคำศัพท์สุดท้ายสำหรับการฝึกอบรม ซึ่งแตกต่างจาก subword-nmt ที่ใช้จำนวนการดำเนินการผสาน จำนวนการดำเนินการผสานเป็นพารามิเตอร์เฉพาะของ BPE และไม่สามารถใช้ได้กับอัลกอริธึมการแบ่งส่วนอื่นๆ รวมถึงยูนิแกรม คำ และอักขระ
การใช้คำย่อยก่อนหน้านี้จะถือว่าประโยคอินพุตนั้นมีโทเค็นล่วงหน้า ข้อจำกัดนี้จำเป็นสำหรับการฝึกอบรมที่มีประสิทธิภาพ แต่ทำให้การประมวลผลล่วงหน้ามีความซับซ้อน เนื่องจากเราต้องเรียกใช้โทเค็นไนเซอร์ที่ขึ้นอยู่กับภาษาล่วงหน้า การใช้งาน Sentence Piece นั้นเร็วพอที่จะฝึกโมเดลจากประโยคดิบ สิ่งนี้มีประโยชน์สำหรับการฝึกอบรม tokenizer และ detokenizer สำหรับภาษาจีนและญี่ปุ่นที่ไม่มีช่องว่างที่ชัดเจนระหว่างคำ
ขั้นตอนแรกของการประมวลผลภาษาธรรมชาติคือโทเค็นข้อความ ตัวอย่างเช่น โทเค็นไนเซอร์ภาษาอังกฤษมาตรฐานจะแบ่งข้อความ "Hello world" ลงในสามโทเค็นต่อไปนี้
[สวัสดี] [โลก] [.]
ข้อสังเกตประการหนึ่งคืออินพุตดั้งเดิมและลำดับโทเค็นนั้น ไม่สามารถแปลงกลับได้ เช่น ข้อมูลที่ไม่มีช่องว่างระหว่าง “โลก” และ “” หลุดออกจากลำดับโทเค็น เนื่องจาก เช่น Tokenize(“World.”) == Tokenize(“World .”)
Sentence Piece ถือว่าข้อความที่ป้อนเป็นเพียงลำดับของอักขระ Unicode ช่องว่างยังได้รับการจัดการเหมือนสัญลักษณ์ปกติ ในการจัดการช่องว่างเป็นโทเค็นพื้นฐานอย่างชัดเจน ก่อนอื่น Sentence Piece จะหนีช่องว่างด้วยสัญลักษณ์เมตา " " (U+2581) ดังนี้
สวัสดีชาวโลก.
จากนั้นจึงแบ่งข้อความนี้ออกเป็นชิ้นเล็กๆ เช่น
[สวัสดี] [ ว] [ld] [.]
เนื่องจากช่องว่างจะถูกเก็บไว้ในข้อความที่แบ่งส่วน เราจึงสามารถแยกข้อความออกจากข้อความได้โดยไม่มีความคลุมเครือ
detokenized = ''.join(pieces).replace('▁', ' ')
คุณลักษณะนี้ทำให้สามารถทำการดีโทเคนได้โดยไม่ต้องอาศัยทรัพยากรเฉพาะภาษา
โปรดทราบว่าเราไม่สามารถใช้การแปลงแบบไม่สูญเสียแบบเดียวกันได้เมื่อแยกประโยคด้วยตัวแบ่งคำมาตรฐาน เนื่องจากจะถือว่าช่องว่างเป็นสัญลักษณ์พิเศษ ลำดับโทเค็นไม่ได้เก็บข้อมูลที่จำเป็นเพื่อกู้คืนประโยคต้นฉบับ
การทำให้คำย่อยเป็นมาตรฐาน [Kudo.] และ BPE-dropout Provilkov และคณะเป็นวิธีการทำให้เป็นมาตรฐานอย่างง่ายที่ช่วยเพิ่มข้อมูลการฝึกอบรมด้วยการสุ่มตัวอย่างคำย่อยได้ทันที ซึ่งช่วยปรับปรุงความแม่นยำและความทนทานของโมเดล NMT
หากต้องการเปิดใช้งานการทำให้คำย่อยเป็นมาตรฐาน คุณต้องการรวมไลบรารี Sentence Piece (C++/Python) เข้ากับระบบ NMT เพื่อสุ่มตัวอย่างการแบ่งส่วนหนึ่งสำหรับการอัปเดตพารามิเตอร์แต่ละรายการ ซึ่งแตกต่างจากการเตรียมข้อมูลออฟไลน์มาตรฐาน นี่คือตัวอย่างของไลบรารี Python คุณจะพบว่า 'นิวยอร์ก' มีการแบ่งส่วนที่แตกต่างกันในแต่ละ SampleEncode (C++)
หรือ encode with enable_sampling=True (Python)
รายละเอียดของพารามิเตอร์การสุ่มตัวอย่างจะพบได้ใน Sentencepiece_processor.h
>>> 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']
SentencePixel มีเครื่องห่อ Python ที่รองรับทั้งการฝึกอบรมและการแบ่งส่วน Sentence Piece คุณสามารถติดตั้งแพ็คเกจไบนารี Python ของ Sentence Piece ได้ด้วย
pip install sentencepiece
สำหรับรายละเอียดเพิ่มเติม โปรดดูโมดูล Python
จำเป็นต้องใช้เครื่องมือและไลบรารีต่อไปนี้เพื่อสร้าง Sentence Piece:
บน Ubuntu สามารถติดตั้งเครื่องมือสร้างได้ด้วย apt-get:
% sudo apt-get install cmake build-essential pkg-config libgoogle-perftools-dev
จากนั้นคุณสามารถสร้างและติดตั้งเครื่องมือบรรทัดคำสั่งได้ดังนี้
% git clone https://github.com/google/sentencepiece.git
% cd sentencepiece
% mkdir build
% cd build
% cmake ..
% make -j $(nproc)
% sudo make install
% sudo ldconfig -v
บน OSX/macOS ให้แทนที่คำสั่งสุดท้ายด้วย sudo update_dyld_shared_cache
คุณสามารถดาวน์โหลดและติดตั้งประโยคโดยใช้ตัวจัดการการพึ่งพา vcpkg:
git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.sh
./vcpkg integrate install
./vcpkg install sentencepiece
พอร์ตประโยคใน vcpkg ได้รับการปรับปรุงให้ทันสมัยโดยสมาชิกทีม Microsoft และผู้ร่วมให้ข้อมูลในชุมชน หากเวอร์ชันล้าสมัย โปรดสร้างปัญหาหรือดึงคำขอบนที่เก็บ vcpkg
คุณสามารถดาวน์โหลดวงล้อได้จากหน้าเผยแพร่ GitHub เราสร้างลายเซ็น SLSA3 โดยใช้ slsa-framework/slsa-github-generator ของ OpenSSF ในระหว่างกระบวนการเผยแพร่ วิธีตรวจสอบไบนารี่รีลีส:
attestation.intoto.jsonl
จากหน้าเผยแพร่ GitHubslsa-verifier -artifact-path < the-wheel > -provenance attestation.intoto.jsonl -source github.com/google/sentencepiece -tag < the-tag >
pip ติดตั้ง wheel_file.whl
% spm_train --input=<input> --model_prefix=<model_name> --vocab_size=8000 --character_coverage=1.0 --model_type=<type>
--input
: ไฟล์คลังข้อมูล ดิบ หนึ่งประโยคต่อบรรทัด ไม่จำเป็นต้องเรียกใช้ tokenizer, Normalizer หรือ Preprocessor ตามค่าเริ่มต้น Sentence Piece จะทำให้อินพุตเป็นมาตรฐานด้วย Unicode NFKC คุณสามารถส่งรายการไฟล์ที่คั่นด้วยเครื่องหมายจุลภาคได้--model_prefix
: คำนำหน้าชื่อโมเดลเอาต์พุต <model_name>.model
และ <model_name>.vocab
ถูกสร้างขึ้น--vocab_size
: ขนาดคำศัพท์ เช่น 8000, 16000 หรือ 32000--character_coverage
: จำนวนอักขระที่ครอบคลุมโดยโมเดล ค่าเริ่มต้นที่ดีคือ: 0.9995
สำหรับภาษาที่มีชุดอักขระที่หลากหลาย เช่น ญี่ปุ่นหรือจีน และ 1.0
สำหรับภาษาอื่นที่มีชุดอักขระขนาดเล็ก--model_type
: ประเภทของโมเดล เลือกจาก unigram
(ค่าเริ่มต้น), bpe
, char
หรือ word
ประโยคอินพุตจะต้องถูก pretokenized เมื่อใช้ประเภท word
ใช้ --help
flag เพื่อแสดงพารามิเตอร์ทั้งหมดสำหรับการฝึก หรือดูภาพรวมที่นี่
% spm_encode --model=<model_file> --output_format=piece < input > output
% spm_encode --model=<model_file> --output_format=id < input > output
ใช้แฟล็ก --extra_options
เพื่อแทรกมาร์กเกอร์ BOS/EOS หรือย้อนกลับลำดับอินพุต
% spm_encode --extra_options=eos (add </s> only)
% spm_encode --extra_options=bos:eos (add <s> and </s>)
% spm_encode --extra_options=reverse:bos:eos (reverse input and add <s> and </s>)
SentencePix รองรับการแบ่งส่วน nbest และการสุ่มตัวอย่างการแบ่งส่วนด้วยแฟล็ก --output_format=(nbest|sample)_(piece|id)
% spm_encode --model=<model_file> --output_format=sample_piece --nbest_size=-1 --alpha=0.5 < input > output
% spm_encode --model=<model_file> --output_format=nbest_id --nbest_size=10 < input > output
% spm_decode --model=<model_file> --input_format=piece < input > output
% spm_decode --model=<model_file> --input_format=id < input > output
ใช้การตั้งค่าสถานะ --extra_options
เพื่อถอดรหัสข้อความในลำดับย้อนกลับ
% spm_decode --extra_options=reverse < input > output
% 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
% 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.
คุณจะพบว่าประโยคอินพุตดั้งเดิมได้รับการกู้คืนจากลำดับรหัสคำศัพท์
% spm_export_vocab --model=<model_file> --output=<output file>
<output file>
เก็บรายการคำศัพท์และความน่าจะเป็นของบันทึกการปล่อยก๊าซเรือนกระจก รหัสคำศัพท์สอดคล้องกับหมายเลขบรรทัดในไฟล์นี้
โดยค่าเริ่มต้น SentencePiece จะใช้โทเค็นที่ไม่รู้จัก (), BOS (<S>) และ EOS (</s>) ซึ่งมี IDs เท่ากับ 0, 1 และ 2 ตามลำดับ เราสามารถกำหนดการแมปนี้ใหม่ได้ในขั้นตอนการฝึกอบรมดังต่อไปนี้
% spm_train --bos_id=0 --eos_id=1 --unk_id=5 --input=... --model_prefix=... --character_coverage=...
เมื่อตั้งค่า -1 id เช่น bos_id=-1
โทเค็นพิเศษนี้จะถูกปิดใช้งาน โปรดทราบว่า ID ที่ไม่รู้จักไม่สามารถปิดใช้งานได้ เราสามารถกำหนดรหัสสำหรับการเติม (<pad>) เป็น --pad_id=3
หากคุณต้องการกำหนดโทเค็นพิเศษอื่น โปรดดูใช้สัญลักษณ์แบบกำหนดเอง
spm_encode
ยอมรับตัวเลือก --vocabulary
และ --vocabulary_threshold
ดังนั้น spm_encode
จะสร้างเฉพาะสัญลักษณ์ที่ปรากฏในคำศัพท์ด้วย (อย่างน้อยก็มีความถี่พอสมควร) พื้นหลังของคุณสมบัตินี้มีอธิบายอยู่ในหน้าคำย่อย-nmt
การใช้งานโดยพื้นฐานแล้วจะเหมือนกับของ subword-nmt
สมมติว่า L1 และ L2 เป็นสองภาษา (ภาษาต้นทาง/ภาษาเป้าหมาย) ให้ฝึกโมเดล SPM ที่ใช้ร่วมกัน และรับคำศัพท์ที่เป็นผลลัพธ์สำหรับแต่ละภาษา:
% cat {train_file}.L1 {train_file}.L2 | shuffle > train
% spm_train --input=train --model_prefix=spm --vocab_size=8000 --character_coverage=0.9995
% spm_encode --model=spm.model --generate_vocabulary < {train_file}.L1 > {vocab_file}.L1
% spm_encode --model=spm.model --generate_vocabulary < {train_file}.L2 > {vocab_file}.L2
คำสั่ง shuffle
ถูกใช้ในกรณีที่ spm_train
โหลดคอร์ปัส 10M บรรทัดแรกตามค่าเริ่มต้น
จากนั้นจึงแบ่งกลุ่มฝึก/ทดสอบคลังข้อมูลด้วยตัวเลือก --vocabulary
% spm_encode --model=spm.model --vocabulary={vocab_file}.L1 --vocabulary_threshold=50 < {test_file}.L1 > {test_file}.seg.L1
% spm_encode --model=spm.model --vocabulary={vocab_file}.L2 --vocabulary_threshold=50 < {test_file}.L2 > {test_file}.seg.L2