#
Transformer ทำงานยังไง?

ในส่วนนี้เราจะมาดูกันว่าสถาปัตยกรรมของโมเดล Transformer ทำงานกันยังไง

##
ประวัติของ Transformer เบื้องต้น

รูปด้านล่างแสดงรายชื่อของโมเดล Transformer ตามแต่ละช่วงเวลา:

สถาปัตยกรรม Transformer ถูกสร้างขึ้นเมื่อปี 2017 เป้าหมายในการสร้างโมเดลก็เพื่องานในการแปลภาษา หลังจากนั้นก็มีโมเดลที่ได้รับแรงบันดาลใจต่อ ๆ มา เช่น

- มิถุนายน 2018: GPT, โมเดล Transformer ตัวแรก ที่มาพร้อมกับพร้อมกับโมเดลที่เทรนมาแล้ว ใช้ในการ fine-tune งานทางด้าน NLP ได้หลายงานและได้ผลลัพธ์ที่เทียบเท่างานวิจัยล่าสุด

- ตุลาคม 2018: BERT, โมเดลขนาดใหญ่อีกตัวหนึ่งที่ผ่านการเทรนมาแล้ว ซึ่งออกแบบมาสำหรับงานในการสรุปความ (อ่านต่อได้ในบทถัดไป)

- กุมภาพันธ์ 2019: GPT-2, โมเดล GPT รุ่นพัฒนาที่ดีขึ้น(และใหญ่ขึ้นด้วย) แต่ว่าไม่ได้เปิดให้ใช้สาธารณะในทันทีเนื่องจากอาจมีการนำไปใช้ในด้านไม่ดี

- ตุลาคม 2019: DistilBERT, โมเดล BERT ขนาดย่อ ซึ่งเร็วกว่า 60% และใช้หน่วยความจำลดลง 40% แต่ยังคงประสิทธิภาพไว้ที่ 97% ของโมเดล BERT ปกติ

- ตุลาคม 2019: BART และ T5, โมเดลที่ผ่านการเทรนมาแล้วทั้งสองตัวที่ใช้สถาปัตยกรรมเดียวกันกับโมเดล Transformer ต้นฉบับ (โมเดลแรกที่ทำแบบนี้)

- พฤษภาคม 2020, GPT-3, โมเดล GPT-2 ที่ใหญ่ขึ้นไปอีกซึ่งสามารถทำงานได้หลายอย่างโดยไม่ต้องการการ fine-tune (หรือเรียกว่า zero-shot learning)

ที่จริงแล้วยังมีโมเดลอื่น ๆ อีกมากนอกเหนือจากรายชื่อที่กล่าวไป ในที่นี้ต้องการที่จะเน้นย้ำอีกครั้งในส่วนของประเภทของโมเดล Transformer ซึ่งสามารถแบ่งได้ดังนี้:

- กลุ่ม GPT (หรือเรียกว่า โมเดล Transformer แบบ auto-regressive)
- กลุ่ม BERT (หรือเรียกว่า โมเดล Transformer แบบ auto-encoding)
- กลุ่ม BART/T5 (หรือเรียกว่า โมเดล Transformer แบบ sequence-to-sequence)

โดยเราจะกล่าวถึงแต่ละกลุ่มในรายละเอียดกันภายหลัง

##
Transformers ก็คือโมเดลบริบททางภาษาแบบหนึ่งนั่นแหละ

โมเดล Transformer ที่กล่าวไปด้านบนทั้งหมด (GPT, BERT, BART, T5 เป็นต้น) ถูกเทรนให้เป็นโมเดลบริบททางภาษา (หรือเรียกว่า language model) นั่นคือโมเดลเหล่านี้ถูกเทรนผ่านข้อความดิบขนาดใหญ่เรียนรู้ด้วยตนเอง (หรือเรียกว่า self-supervised) การ self-supervised นั้นคือการเทรนแบบหนึ่งซึ่งเป้าหมายในการเทรนจะถูกคำนวณออกมาอัตโนมัติจาก input ที่ใส่เข้าไป ดังนั้นการเทรนแบบนี้จึงไม่จำเป็นต้อง label ข้อมูลเลย!

โมเดลประเภทนี้จะเข้าในภาษาที่ถูกเทรนมาในเชิงสถิติ แต่ในการใช้งานจริงอาจไม่มีประโยชน์เท่าไหร่ ดังนั้นโมเดลที่ผ่านการเทรนแบบนี้มาจึงถูกนำไปใช้ในกระบวนการ transfer learning ซึ่งก็คือโมเดลนี้จะถูกนำไป fine-tune ต่อในงานอื่นที่มี label จากมนุษย์

ตัวอย่างงานดังกล่าวได้แก่ การเดาคำต่อไปหลังจากอ่านคำในประโยค n คำ สิ่งนี้เรียกว่า causal language model เนื่องจาก output ขึ้นอยู่กับ input ในอดีตและปัจจุบันเท่านั้น

อีกตัวอย่างหนึ่งได้แก่ การเติมคำในช่องว่าง (หรือเรียกว่า masked language modeling) เป็นการเดาคำที่เว้นว่างไว้ในประโยค โดยในที่นี้จะใช้คำว่า `[MASK]` แทนการเว้นว่าง

##
Transformers มัน ใหญ่ มาก

ถ้าไม่นับพวกโมเดลแปลก ๆ อย่าง DistilBERT การจะได้มาซึ่งผลลัพธ์ที่ดีขึ้นก็ต้องเพิ่มขนาดโมเดลและขนาดข้อมูลที่นำมาเทรนโมเดล

ซึ่งในการเทรนโมเดลโดยเฉพาะโมเดลขนาดใหญ่ต้องการข้อมูลในการเทรนจำนวนมาก ดังนั้นการเทรนแต่ละครั้งจึงกินทั้งทรัพยากรเวลาและทรัพยากรในการคำนวณมากขึ้นไปอีก ซึ่งหมายถึงผลกระทบต่อสิ่งแวดล้อมดังแสดงในภาพด้านล่าง

รูปภาพทำขึ้นเพื่อจะสื่อสารไปยังทีมพัฒนาต่าง ๆ ให้เห็นถึงผลกระทบต่อสิ่งแวดล้อมในการเทรนโมเดลขนาดใหญ่(มาก ๆ) และหากต้องการจะทดลองเพื่อหา hyperparameter ที่ดีสุด ผลกระทบย่อมเพิ่มขึ้นอีกเป็นเงาตามตัว

ลองนึกสภาพว่าหากแต่ละทีมวิจัย, กลุ่มการศึกษา, หรือบริษัทเอกชนใด ๆ ต้องการเทรนโมเดลซักโมเดลหนึ่ง โดยเริ่มต้นมาจากศูนย์ทุกครั้ง จะก่อให้เกิดค่าใช้จ่ายที่ไม่จำเป็นอย่างใหญ่หลวงมาก

เพราะฉะนั้นการแบ่งปันโมเดลที่เทรนไว้แล้วจึงเป็นเรื่องสำคัญอย่างมาก การแบ่งปัน weight ของโมเดลและสร้างสิ่งต่าง ๆ ผ่าน weight ที่มีคนทำมาแล้วจะช่วยลดค่าใช้จ่ายและลดค่า carbon footprint โดยทั่วกัน

##
Transfer Learning

Pretraining เป็นการเทรนโมเดลจากศูนย์ ซึ่งก็คือ weight ในโมเดลเริ่มต้นจากค่าสุ่ม และเริ่มเทรนโดยไม่มีความรู้อะไรเลย

โดยมากแล้วการ pretrain จะใช้ข้อมูลขนาดใหญ่มาก ๆ ดังนั้นจึงต้องการข้อมูลภาษาขนาดใหญ่และใช้เวลาเทรนหลายสัปดาห์

Fine-tuning เป็นการเทรนโมเดลหลังจากการ pretrain ซึ่งก็คือ นำ language model ที่ผ่านการ pretrain แล้ว มาเทรนเพิ่มเติมด้วยชุดข้อมูลที่เฉพาะเจาะจงในงานที่ต้องการ ว่าแต่ ทำไมไม่เทรนโมเดลสำหรับงานสุดท้ายไปทีเดียวเลยล่ะ? มันมีเหตุผลอยู่ ดังนี้:

- โมเดลที่ผ่านการ pretrain มาแล้วมีความเข้าใจความเหมือนบางอย่างในชุดข้อมูลที่นำมา fine-tune ดังนั้น การ fine-tune จึงสามารถนำความรู้ที่ได้จากการ pretrain มาใช้ประโยชน์ได้ทันที (เช่น โมเดลที่ pretrain มาแล้วทางด้าน NLP พอจะมีเข้าใจเบื้องต้นเกี่ยวกับภาษาที่เรากำลังใช้อยู่ในเชิงสถิติ)
- เนื่องจากโมเดลที่ผ่านการ pretrain มาแล้วนั้นถูกเทรนด้วยข้อมูลขนาดใหญ่มาก การใช้ข้อมูลเพียงเล็กน้อยในการ fine-tune ก็สามารถให้ผลเป็นที่พึงพอใจได้
- และด้วยเหตุผลเดียวกันนี้ เวลาและทรัพยากรที่ใช้เพื่อให้ได้ผลลัพธ์ที่ดีก็น้อยกว่าเช่นกัน

ตัวอย่างเช่น เราสามารถใช้โมเดล pretrain ในภาษาอังกฤษและ fine-tune ด้วยข้อมูลภาษาจากใน arXiv (แหล่งข้อมูลค้นคว้าวิจัยทางด้านวิทยาศาสตร์) ทำให้ได้โมเดลที่เก่งทางด้านวิทยาศาสตร์และการวิจัย การ fine-tune นี้ต้องการข้อมูลเพียงเล็กน้อยเท่านั้น ความรู้ความเข้าใจทางภาษาของโมเดลถูกส่งต่อมาจากโมเดล pretrain ดังนั้นกระบวนการนี้จึงเรียกว่า transfer learning

ด้วยเหตุนี้การ fine-tune จึงใช้เวลา ข้อมูล ค่าใช้จ่าย และผลกระทบต่อสิ่งแวดล้อมน้อยกว่า รวมถึงว่าเราสามารถทดลองรูปแบบการ fine-tune ต่าง ๆ ได้ง่ายกว่าและเร็วกว่าอีกด้วย เนื่องจากการเทรนแบบนี้มีเงื่อนไขต่ำกว่าการเทรนเต็มรูปแบบ

กระบวนการดังกล่าวนี้ยังให้ผลลัพธ์ที่ดีกว่าการเทรนทุกอย่างจากศูนย์อีกด้วย(เว้นแต่ว่าคุณจะมีข้อมูลเยอะมากจริง ๆ) และนี่ก็เป็นอีกสาเหตุหนึ่งที่คุณควรใช้โมเดล pretrain ที่ใกล้เคียงกับงานที่คุณต้องการทำที่สุดและแค่ fine-tune มันออกมา

##
สถาปัตยกรรมทั่วไป

ในส่วนนี้เราจะพูดถึงสถาปัตยกรรมทั่วไปของโมเดล Transformer ไม่ต้องกังวลไปหากคุณไม่เข้าใจเนื้อหาบางส่วนตอนนี้ เนื้อหาในส่วนหลังจะอธิบานเรื่องเหล่านี้ในรายละเอียดเพิ่มเติมให้

##
เริ่มต้น

โมเดล Transformer ประกอบด้วยส่วนใหญ่ ๆ สองส่วน ได้แก่:

- ส่วนเข้ารหัส (หรือเรียกว่า Encoder) (ซ้าย): encoder รับ input เข้ามาและสร้างตัวแทน input เหล่านั้น โดยตัวแทนเหล่านี้เรียกว่า feature นั่นหมายความว่าโมเดลจะปรับแต่งตัวเองให้เข้าใจ input ได้ในส่วนนี้
- ส่วนถอดรหัส (หรือเรียกว่า Decoder) (ขวา): decoder สร้าง output ออกมาเป็นข้อมูลลำดับ (หรือเรียกว่า sequence) โดยอาศัย feature และ input อื่น ๆ นั่นหมายถึงโมเดลปรับแต่งตัวเองให้สร้าง output ได้ในส่วนนี้

แต่ละส่วนดังกล่าวสามารถแยกใช้อิสระต่อกันได้ ขึ้นอยู่กับว่าใช้ในงานอะไร เช่น:

- โมเดลที่ใช้ encoder อย่างเดียว: สำหรับงานที่ต้องการให้เข้าใจ input เช่น การแยกหมวดหมู่ประโยคและการระบุชนิดของคำในประโยค
- โมเดลที่ใช้ decoder อย่างเดียว: สำหรับงานในการสร้าง output ออกมา เช่น การสร้างข้อความ
- โมเดลที่ใช้ทั้ง encoder และ decoder หรือ โมเดล sequence-to-sequence สำหรับงานในการสร้าง output ที่ต้องการ input เข้ามาด้วย เช่น การแปลภาษาหรือการสรุปความ

ซึ่งเราจะเจาะลงไปในรายละเอียดของแต่ละสถาปัตยกรรมกันต่อในภายหลัง

##
Attention layers

ฟีเจอร์สำคัญของโมเดล Transformer ก็คือโมเดลนี้ถูกสร้างขึ้นมาจาก layer พิเศษที่ชื่อว่า attention layer ซึ่งเป็นสาเหตุที่ชื่อของงานวิจัยที่พูดถึงสถาปัตยกรรม Transformer เป็นครั้งแรกถูกตั้งชื่อว่า “Attention Is All You Need” (Attention เป็นทุกอย่างให้เธอแล้ว) เราจะมาอธิบายเกี่ยวกับ attention layer ในรายละเอียดกันในช่วงหลังของคอร์สนี้ แต่สำหรับตอนนี้ คุณแค่เข้าใจว่า attention layer ทำหน้าที่บอกให้โมเดลให้ความสนใจ(attend)กับคำที่ตำแหน่งใดเป็นพิเศษจากประโยคส่งให้(รวมถึงบอกให้มองข้ามคำที่ตำแหน่งอื่นด้วย)เมื่อต้องการอธิบายความหมายของคำใด ๆ

เพื่อให้เห็นภาพมากขึ้น ลองนึกถึงงานในการแปลข้อความจากภาษาอังกฤษเป็นภาษาฝรั่งเศส ตัวอย่างเช่นประโยค “You like this course” โมเดลแปลภาษาต้องสนใจไปที่คำว่า “You” เพื่อให้ได้คำแปลของคำว่า “like” ที่เหมาะสม เนื่องจากในภาษาฝรั่งเศสคำว่า “like” นั้นเปลี่ยนรูปไปตามประธานในประโยค คำอื่น ๆ ที่เหลือในประโยคไม่ได้ส่งผลต่อการแปลคำว่า “like” เลย ในลักษณะเดียวกัน การแปลคำว่า “this” โมเดลต้องสนใจไปที่คำว่า “course” เนื่องจากคำว่า “this” ในภาษาฝรั่งเศสจะแปลออกมาว่าอย่างไรขึ้นอยู่กับว่าคำนั้นเป็นเพศชายหรือหญิง(ในบางภาษาคำแต่ละคำจะมีเพศกำกับไว้แม้ว่าจะไม่ได้เป็นสิ่งมีชีวิตที่มีเพศจริง ๆ ก็ตาม โดยไวยากรณ์ของภาษานั้น ๆ จะผันตามเพศของคำ) และแน่นอนคำอื่น ๆ ในประโยคไม่ได้ส่งผลต่อการแปลว่าคำว่า “this” เลย และเมื่อประโยคซับซ้อนมากยิ่งขึ้น(ส่งผลให้กฎไวยากรณ์ซับซ้อนมากยิ่งขึ้น) โมเดลยิ่งต้องให้ความสนใจไปยังคำที่ไกลออกไปในประโยคเพื่อแปลคำแต่ละคำให้เหมาะสม

แนวคิดเดียวกันนี้ใช้ได้กับงาน NLP อื่น ๆ นั่นคือ คำแต่ละคำมีความหมายในตัวมันเอง โดยความหมายเหล่านี้ส่งผลมาจากบริบทของคำ ซึ่งก็คือคำอื่นที่อยู่รอบ ๆ คำนั้น ๆ

ตอนนี้คุณก็พอจะเข้าใจแล้วว่า attention layer คืออะไร ลองมาดูรายละเอียดของสถาปัตยกรรม Transformer กัน

##
สถาปัตยกรรมต้นฉบับ

ในตอนแรก Transformer ออกแบบมาเพื่องานแปลภาษา ระหว่างการเทรน ตัว encoder รับ input เป็นประโยคในภาษาหนึ่ง ในขณะที่ decoder เองก็รับประโยคเดียวกันในภาษาเป้าหมาย โดย attention layer ใน encoder สามารถใช้คำทั้งหมดในประโยคได้(เนื่องจากการแปลคำใด ๆ ขึ้นอยู่กับคำที่อาจจะอยู่ข้างหน้าหรือข้างหลังคำนั้น ๆ ก็ได้) ในขณะที่ decoder ต้องสร้างคำเป็นลำดับออกมาทีละคำ นั่นคือ decoder สามารถสนใจคำที่แปลออกมาก่อนได้เท่านั้น ตัวอย่างเช่น เมื่อเราแปลคำในภาษาเป้าหมายไป 3 คำแรก เราก็จะเอา 3 คำนี้ส่งไปยัง decoder รวมกับ input อื่นจาก encoder เพื่อทำนายคำที่ 4 ออกมา

เพื่อให้กระบวนการเทรนเร็วมากขึ้น(เมื่อโมเดลเข้าถึงประโยคในภาษาเป้าหมายได้) decoder จะรับประโยคในภาษาเป้าหมายไปทั้งประโยค แต่แค่ไม่อนุญาตให้เข้าถึงคำที่กำลังจะแปลในอนาคต(ลองคิดดูว่าถ้ากำลังทำนายคำในประโยคเป้าหมายตำแหน่งที่ 2 แล้วโมเดลก็เข้าถึงคำในตำแหน่งที่ 2 ในประโยคเป้าหมายได้ ปัญหามันก็ดูจะแก้ได้ง่ายเกินไปแหละ) หรืออีกนัยหนึ่งคือ ขณะที่กำลังทำนายคำที่ 4 ในประโยค ตัว attention layer จะเข้าถึงได้แค่คำที่ตำแหน่ง 1 ถึง 3 เท่านั้น

รูปด้านล่างแสดงสถาปัตยกรรม Transformer โดย encoder อยู่ด้านซ้ายและ decoder อยู่ด้านขวา:

หมายเหตุไว้หน่อยว่า attention layer แรกใน decoder สนใจไปที่ input (ในอดีต)ทั้งหมดของ decoder แต่ attention layer ที่สองใช้ output ของ encoder ด้วย นั่นคือ มันสามารถเข้าถึงประโยค input ทั้งหมดเพื่อทำนายคำในปัจจุบันได้ ส่วนนี้มีประโยชน์มากเนื่องจากแต่ละภาษาก็มีหลักไวยากรณ์ในการวางตำแหน่งคำที่ต่างกัน หรือบริบทที่ถูกกล่าวถึงทีหลังในประโยคอาจส่งผลต่อการหาคำแปลที่เหมาะสมของคำในปัจจุบัน

attention mask เป็นอีกส่วนประกอบที่ใช้ได้กับทั้ง encoder และ decoder เพื่อป้องกันไม่ให้โมเดลสนใจไปยังคำบางคำ ตัวอย่างเช่น คำพิเศษบางคำที่เอามาเติมในประโยคให้ประโยคใน input ที่ความยาวเท่ากับเวลาประมวลผลประโยคพร้อมกัน

##
สถาปัตยกรรม(หรือเรียกว่า Architecture) vs. จุดเซฟ(หรือเรียกว่า checkpoints)

ดังที่เราได้เรียนรู้โมเดล Transformer มาในคอร์สนี้ คุณจะเห็นคำที่ความหมายคล้าย ๆ กัน อย่างเช่น architecture และ checkpoint รวมถึง model อย่างไรก็ตาม คำแหล่านี้มีความหมายแตกต่างกันเล็กน้อย ดังนี้:

- Architecture: เป็นโครงสร้างของโมเดล นั่นคือ เป็นการกำหนดนิยามของ layer (เช่น บอกว่า มีทั้งหมดกี่ layer และ layer แต่ละ layer เป็นประเภทใด) รวมถึงบอกว่า layer นั้น ๆ จะมีกระบวนการการทำอะไรบ้าง
- Checkpoints: เป็นเพียงการเซฟ weight หรือค่าคงที่ของ parameter ในแต่ละ layer ที่จะเอาไปใช้ใน architecture ที่กำหนดได้
- Model: เป็นคำกว้าง ๆ ไม่ได้ระบุความหมายเฉพาะเจาะจงเหมือนคำว่า “architecture” หรือ “checkpoint” ซึ่งจริง ๆ อาจจะหมายถึงคำใดก็ได้ แต่ในคอร์สนี้จะใช้คำว่า architecture หรือ checkpoint ไปเลยเพื่อหลีกเลี่ยงความสับสน

ยกตัวอย่างง่าย ๆ เช่น BERT เป็น architecture ในขณะที่ `bert-base-cased` เป็น checkpoint ที่เซฟ weight จากการเทรน BERT ที่ทีม Google ปล่อยออกมาตอนเปิดให้ใช้งานครั้งแรก โดยเราสามารถเรียกสิ่งเหล่านี้ว่า”โมเดล BERT” หรือ “โมเดล `bert-base-cased`” ก็ถือว่าถูกต้องทั้งคู่