#
Transformers ชื่อนี้มีดียังไง?

ในส่วนนี้ เราจะมาดูกันว่า Transformer นั้นทำอะไรได้บ้าง และมาใช้งานเครื่องมือชิ้นแรกจาก library 🤗 Transformers ซึ่งก็คือฟังก์ชัน `pipeline()`

👀 เห็นปุ่ม Open in Colab ทางด้านบนขวานั่นมั้ย? ลองคลิกเปิดดู Google Colab notebook ได้ ด้านในจะมีตัวอย่างโค้ดที่เกี่ยวข้องทั้งหมดในหน้านี้ โดยปุ่นแบบนี้จะมีในทุก ๆ หน้าที่มีโค้ดตัวอย่าง

แต่หากคุณต้องการรันโค้ดตัวอย่างบนเครื่องของตนเอง เราแนะนำให้เปิดดู ติดตั้งโปรแกรม

##
Transformers, Transformers เต็มไปหมดเลย!

โมเดล Transformer นั้นสามารถนำไปใช้แก้ปัญหา NLP ที่ได้กล่าวไปก่อนหน้านี้ได้ทั้งหมดเลย ด้านล่างก็เป็นตัวอย่างหน่วยงานที่ใช้ Hugging Face และโมเดล Transformer รวมถึงยังแบ่งปันโมเดลที่สร้างกลับไปยังชุมชนด้วยเช่นกัน

library 🤗 Transformers มีฟังก์ชันในการสร้างและใช้งานโมเดลที่มีคนแบ่งมาให้ใช้ ใน Model Hub มีโมเดลที่ผ่านการเทรนมาแล้ว (หรือเรียกว่า pretrained model) มากกว่าหนึ่งพันโมเดลที่ใคร ๆ ก็สามารถดาวน์โหลดไปใช้งานได้ รวมถึงคุณเองก็เป็นส่วนหนึ่งในการแบ่งปันนี้ได้เช่นกัน

⚠️ Hugging Face Hub ไม่ได้จำกัดอยู่แค่เพียงโมเดล Transformer เท่านั้น ใคร ๆ ก็สามารถแบ่งปันโมเดลหรือชุดข้อมูลอะไรก็ได้ตามต้องการ มา สร้างบัญชี huggingface.co เพื่อใช้งานฟีเจอร์เหล่านี้ด้วยกันนะ!

ก่อนจะเจาะลึกเข้าไปถึงเบื้องหลังการทำงานของโมเดล Transformer มาดูตัวอย่างกันว่าโมเดล Transformer นั้นสามารถแก้ปัญหา NLP ได้อย่างไรบ้าง

##
การใช้งานคำสั่ง pipelines

คำสั่งพื้นฐานที่สุดของ library 🤗 Transformers คือฟังก์ชัน `pipeline()` โดยฟังก์ชันนี้จะเชื่อมต่อโมเดลกับขั้นตอนอื่น ๆ ที่สำคัญ เช่น กระบวนการจัดการข้อมูลก่อนการประมวลผล(หรือเรียกว่า preprocessing) และการจัดการข้อมูลหลังการประมวลผล(หรือเรียกว่า postprocessing) ทำให้เราสามารถใส่ข้อความเป็นอินพุตและได้คำตอบอันชาญฉลาดได้โดยตรง:

    from transformers import pipeline

    classifier = pipeline("sentiment-analysis")
    classifier("I've been waiting for a HuggingFace course my whole life.")

    [{'label': 'POSITIVE', 'score': 0.9598047137260437}]

หรือใส่ไปหลาย ๆ ประโยคก็ได้!

    classifier(
        ["I've been waiting for a HuggingFace course my whole life.", "I hate this so much!"]
    )

    [{'label': 'POSITIVE', 'score': 0.9598047137260437},
     {'label': 'NEGATIVE', 'score': 0.9994558095932007}]

โดยปกติแล้ว pipeline จะเลือก pretrained model ที่ fine-tune มาเพื่อการเข้าใจความรู้สึกของผู้เขียนในภาษาอังกฤษ ซึ่งในการใช้งานคำสั่ง `classifier` ครั้งแรก คำสั่งนี้จะไปดาวน์โหลดโมเดลมาจาก Hub และเก็บไว้ใน cache เมื่อคุณใช้งานคำสั่งนี้ซ้ำอีกครั้งจะเป็นการเรียกใช้โมเดลที่เก็บไว้ใน cache แทน จะได้ไม่ต้องดาวน์โหลดใหม่บ่อย ๆ

เมื่อคุณส่งข้อความเข้าไปยัง pipeline ในเบื้องหลังจะมีกระบวนการต่อไปนี้เกิดขึ้น:

1. ข้อความจะถูกแปลงเป็นอินพุตในรูปแบบที่โมเดลสามารถเข้าใจได้
2. ส่งอินพุตเข้าไปคำนวณในโมเดล
3. นำผลการทำนายจากโมเดลมาประมวลผลต่อเพื่อให้มนุษย์เข้าใจได้ง่าย

ในปัจจุบันงานบางอย่างสามารถใช้งานจากคำสั่ง pipeline ได้โดยตรง ได้แก่:

- `feature-extraction` (เปลี่ยนข้อความเป็น vector)
- `fill-mask` (เติมคำในช่องว่าง)
- `ner` (named entity recognition; การระบุชื่อเฉพาะ)
- `question-answering` (ถาม-ตอบ)
- `sentiment-analysis` (รับรู้ความรู้สึกของผู้เขียน)
- `summarization` (สรุปความ)
- `text-generation` (สร้างข้อความ)
- `translation` (แปลภาษา)
- `zero-shot-classification` (แยกแยะหมวดหมู่โดยไม่ต้องสอน)

มาดูกันว่าแต่อย่างใช้งานกันยังไง!

##
แยกแยะหมวดหมู่โดยไม่ต้องสอน

มาเริ่มต้นด้วยงานที่ค่อนข้างท้าทายกันซักหน่อย งานนี้ต้องการแยกแยะหมวดหมู่(หรือเรียกว่า classify) ข้อความที่ไม่เคยถูกระบุหมวดหมู่(หรือเรียกว่า label)มาก่อน เนื่องจากปกติแล้วงานในการ classify ข้อความนั้น โมเดลต้องการเข้าใจการจับคู่ระหว่างข้อความและ label แต่ในความเป็นจริงแล้ว การเอาข้อความมาให้คนคอยกำหนด label ก่อนส่งไปยังโมเดล เป็นกระบวนการที่กินเวลามากและต้องการคนที่มีความรู้เฉพาะแขนง สำหรับกรณีนี้ pipeline `zero-shot-classification` นั้นนับว่าชาญฉลาดมาก ตัว pipeline สามารถระบุกลุ่ม label ที่จะใช้ในการ classify นี้ ดังนั้นเราจึงไม่จำเป็นต้องอาศัย label จาก pretrained model คุณเห็นมาแล้วว่าโมเดลสามารถ classify ประโยคได้ว่าเป็นประโยคที่พูดแง่บวกหรือแง่ลบโดยใช้ label ทั้งสองนี้ โดย `pipeline` ฉลาดกว่านั้นเพราะสามารถ classify ข้อความโดยใช้ label อื่น ๆ ที่เราต้องการได้

    from transformers import pipeline

    classifier = pipeline("zero-shot-classification")
    classifier(
        "This is a course about the Transformers library",
        candidate_labels=["education", "politics", "business"],
    )

    {'sequence': 'This is a course about the Transformers library',
     'labels': ['education', 'business', 'politics'],
     'scores': [0.8445963859558105, 0.111976258456707, 0.043427448719739914]}

pipeline นี้เรียกว่า zero-shot เพราะว่าเราไม่ต้อง fine-tune โมเดลด้วยข้อมูลของเราก่อนจะนำไปใช้ ตัวโมเดลสามารถระบุค่าความน่าจะเป็นตาม list ของ label ที่เราต้องการได้เลย!

✏️ ลองเลย! ทดลองโดยใช้ข้อความอะไรก็ได้ของเราเองแล้วดูว่าโมเดลส่งค่าอะไรคืนให้เราบ้าง

##
การสร้างข้อความ

ทีนี้ เรามาดูกันว่า pipeline จะใช้สร้างข้อความได้ยังไง โดยหลักการแล้ว เพียงคุณส่งข้อความสั้น ๆ ไปให้โมเดล โมเดลจะเดาข้อความที่เหลือทั้งหมดให้อัตโนมัติ วิธีการนี้ก็คล้าย ๆ กับการที่โทรศัพท์มือถือเดาข้อความที่เรากำลังจะพิมพ์ สิ่งที่ควรทราบเพิ่มเติมคือ การสร้างข้อความนั้นมีการสุ่มรวมอยู่ในกระบวนการด้วย ดังนั้นหากเราทดสอบซ้ำ ๆ แล้วได้ผลลัพธ์ไม่เหมือนกันก็นับเป็นเรื่องปกติ ตัวอย่างการสร้างข้อความสามารถดูได้ดังตัวอย่างด้านล่าง

    from transformers import pipeline

    generator = pipeline("text-generation")
    generator("In this course, we will teach you how to")

    [{'generated_text': 'In this course, we will teach you how to understand and use '
                        'data flow and data interchange when handling user data. We '
                        'will be working with one or more of the most commonly used '
                        'data flows — data flows of various types, as seen by the '
                        'HTTP'}]

คุณสามารถควบคุมจำนวนข้อความที่สร้างขึ้นได้โดยกำหนดค่าที่ argument `num_return_sequences` และกำหนดความยาวของข้อความที่สร้างขึ้นมาด้วย argument `max_length`

✏️ ลองเลย! ปรับค่า argument `num_return_sequences` และ `max_length` ให้สร้างข้อความขึ้นมาสองประโยค ประโยคละ 15 คำ

##
การใช้งานโมเดลใด ๆ จาก Hub ใน pipeline

ตัวอย่างที่ผ่านมาเป็นการใช้โมเดลเริ่มต้นสำหรับงานใด ๆ แต่ในบางครั้งเราอาจต้องเลือกโมเดลที่เฉพาะเจาะจงสำหรับแต่ละงานจาก Hub ใน pipeline ตัวอย่างเช่นการสร้างข้อความ ลองเข้าไปที่ Model Hub และเลือกหมวดหมู่ทางด้านซ้ายเพื่อดูว่ามีโมเดลใดให้ใช้บ้างสำหรับงานแต่ละอย่าง คุณจะได้เพจที่หน้าตา ดังนี้

ลองใช้โมเดล `distilgpt2` โดยสามารถทำตามได้ดังนี้:

    from transformers import pipeline

    generator = pipeline("text-generation", model="distilgpt2")
    generator(
        "In this course, we will teach you how to",
        max_length=30,
        num_return_sequences=2,
    )

    [{'generated_text': 'In this course, we will teach you how to manipulate the world and '
                        'move your mental and physical capabilities to your advantage.'},
     {'generated_text': 'In this course, we will teach you how to become an expert and '
                        'practice realtime, and with a hands on experience on both real '
                        'time and real'}]

คุณสามารถปรับค่าการค้นหาโมเดลได้ด้วยการคลิกที่หมวดหมู่ภาษา และเลือกโมเดลที่สามารถสร้างข้อความในภาษาอื่นได้ ซึ่งใน Model Hub นี้จะมีโมเดลที่รองรับหลายภาษาเช่นกัน

เมื่อคุณเลือกโมเดลโดยการคลิกที่ชื่อโมเดล คุณจะเห็นว่าจะมีแถบ widget เล็ก ๆ ขึ้นมาให้คุณลองก่อนแบบออนไลน์ ด้วยวิธีการนี้ คุณสามารถทดสอบความสามารถของโมเดลได้ก่อนจะดาวน์โหลดไปใช้

✏️ ลองเลย! ใช้ตัวกรองหาโมเดลสร้างข้อความสำหรับภาษาอื่น แนะนำให้ลองกับ widget บน pipeline ดูก่อนเลย

###
The Inference API

โมเดลทั้งหมดสามารถทดสอบได้โดยตรงผ่านเว็บบราวเซอร์โดยใช้ API ประเมินผล(หรือเรียกว่า Inference API) ซึ่งสามารถใช้ได้ผ่านเว็บไซต์ Hugging Face คุณสามารถเล่นกับโมเดลต่าง ๆ ได้โดยตรงที่หน้านี้โดยกำหนดข้อความอินพุตได้ตามต้องการและดูว่าโมเดลประมวลผลข้อมูลเหล่านั้นยังไง

Inference API ที่อยู่เบื้องหลัง widget นี้สามารถนำไปใช้งานในเชิงพาณิชย์ได้แบบง่าย ๆ เลยหากคุณต้องการนำไปใช้ในงานของคุณ โปรดดูรายละเอียดเพิ่มเติมได้ที่หน้ารายการราคา

##
เติมคำในช่องว่าง

pipeline ต่อไปก็หรือการเติมคำในช่องว่าง หรือ `fill-mask` โดยพื้นฐานแล้วงานนี้ก็คือการเติมคำในช่องว่างที่เว้นไว้ระหว่างข้อความที่กำหนดให้ เช่น

    from transformers import pipeline

    unmasker = pipeline("fill-mask")
    unmasker("This course will teach you all about <mask> models.", top_k=2)

    [{'sequence': 'This course will teach you all about mathematical models.',
      'score': 0.19619831442832947,
      'token': 30412,
      'token_str': ' mathematical'},
     {'sequence': 'This course will teach you all about computational models.',
      'score': 0.04052725434303284,
      'token': 38163,
      'token_str': ' computational'}]

argument `top_k` ควบคุมจำนวนข้อความที่ต้องการแสดง โดยโมเดลจะเติมคำลงไปที่คำพิเศษที่เขียนว่า `<mask>` ซึ่งหมายถึง คำที่ละไว้ ทั้งนี้ โมเดลเติมคำในช่องว่างโมเดลอื่นอาจใช้คำที่ละไว้นี้เป็นอย่างอื่น ดังนั้น โปรดรับรู้ไว้เสมอว่า หากจะใช้โมเดลใดให้ศึกษาให้แน่ชัดว่าโมเดลนั้นใช้คำที่ละไว้ว่าอะไร วิธีการหนึ่งที่ทำได้คือให้ตรวจสอบคำที่ละไว้ที่ใช้ใน widget นี้

✏️ ลองเลย! หาโมเดล `bert-base-cased` ใน Hub และตรวจสอบคำที่ละไว้ที่ใช้ใน widget ของ Inference API โมเดลนี้ทำนายอะไรออกมาหากเราใส่ประโยคที่ใส่เข้าไปในตัวอย่าง `pipeline` ด้านบน

##
การระบุชื่อเฉพาะ

การระบุชื่อเฉพาะ(หรือเรียกว่า Named entity recognition; NER) คืองานที่โมเดลจะต้องหาว่าส่วนใดในประโยคหมายถึงชื่อเฉพาะของ คน สัตว์ สิ่งของ สถานที่ หรือองค์กรใด ๆ มาดูตัวอย่างกัน:

    from transformers import pipeline

    ner = pipeline("ner", grouped_entities=True)
    ner("My name is Sylvain and I work at Hugging Face in Brooklyn.")

    [{'entity_group': 'PER', 'score': 0.99816, 'word': 'Sylvain', 'start': 11, 'end': 18},
     {'entity_group': 'ORG', 'score': 0.97960, 'word': 'Hugging Face', 'start': 33, 'end': 45},
     {'entity_group': 'LOC', 'score': 0.99321, 'word': 'Brooklyn', 'start': 49, 'end': 57}
    ]

ในส่วนนี้ โมเดลสามารถระบุได้ว่า Sylvian เป็นชื่อคน (PER) Hugging Face เป็นชื่อหน่วยงาน (ORG), และ Brooklyn เป็นชื่อสถานที่ (LOC)

เราเพิ่มตัวเลือก `grouped_entities=True` ตอนสร้างฟังก์ชัน pipeline เพื่อระบุให้ pipeline จับกลุ่มคำที่เป็นการระบุชื่อเฉพาะของสิ่ง ๆ เดียว ในที่นี้ โมเดลจับกลุ่มคำว่า “Hugging” และ “Face” เข้าไปเป็นชื่อองค์กรองค์กรเดียว แม้ว่าจะเป็นการรวมคำหลายคำเข้าด้วยกันก็ตาม ซึ่งจริง ๆ แล้ว ในบทต่อไปเราจะเห็นว่าการประมวลผลนั้นจะแบ่งคำบางคำออกมาเป็นส่วนที่แยกย่อยลงไปอีก ตัวอย่างเช่น คำว่า `Sylvian` ถูกแบ่งออกเป็น 4 ส่วน ได้แก่ `S`, `##yl`, `##va`, และ `##in` และระหว่างการ post-processing ตัว pipeline ก็จะนำแต่ละส่วนนี้มาประกอบเข้าด้วยกัน

✏️ ลองเลย! หาโมเดลใน Model Hub ที่ทำงานเกี่ยวกับการระบุชื่อเฉพาะ(หรือเรียกว่า part-of-speech tagging ย่อว่า POS)ในภาษาอังกฤษ รู้มั้ยว่าโมเดลนี้ทำนายอะไรในตัวอย่างประโยคข้างต้น?

##
ถาม-ตอบคำถาม

pipeline การถามตอบคำถาม(หรือเรียกว่า `question-answering`) เป็นการตอบคำถามโดยใช้ข้อมูลจากกบริบทที่ให้มา เช่น:

    from transformers import pipeline

    question_answerer = pipeline("question-answering")
    question_answerer(
        question="Where do I work?",
        context="My name is Sylvain and I work at Hugging Face in Brooklyn",
    )

    {'score': 0.6385916471481323, 'start': 33, 'end': 45, 'answer': 'Hugging Face'}

โปรดทราบเอาไว้ว่า pipeline นี้ทำงานโดยการเอาข้อมูลจากบริบทที่ได้มาไปประมวลผล แต่จะไม่ได้สร้างคำตอบออกมา

##
การสรุปความ

การสรุปความเป็นงานในการลดข้อความลงมาให้เป็นข้อความที่สั้นลงโดยเก็บรักษาใจความสำคัญให้ได้มากที่สุด ตัวอย่างเช่น:

    from transformers import pipeline

    summarizer = pipeline("summarization")
    summarizer(
        """
        America has changed dramatically during recent years. Not only has the number of
        graduates in traditional engineering disciplines such as mechanical, civil,
        electrical, chemical, and aeronautical engineering declined, but in most of
        the premier American universities engineering curricula now concentrate on
        and encourage largely the study of engineering science. As a result, there
        are declining offerings in engineering subjects dealing with infrastructure,
        the environment, and related issues, and greater concentration on high
        technology subjects, largely supporting increasingly complex scientific
        developments. While the latter is important, it should not be at the expense
        of more traditional engineering.

        Rapidly developing economies such as China and India, as well as other
        industrial countries in Europe and Asia, continue to encourage and advance
        the teaching of engineering. Both China and India, respectively, graduate
        six and eight times as many traditional engineers as does the United States.
        Other industrial countries at minimum maintain their output, while America
        suffers an increasingly serious decline in the number of engineering graduates
        and a lack of well-educated engineers.
    """
    )

    [{'summary_text': ' America has changed dramatically during recent years . The '
                      'number of engineering graduates in the U.S. has declined in '
                      'traditional engineering disciplines such as mechanical, civil '
                      ', electrical, chemical, and aeronautical engineering . Rapidly '
                      'developing economies such as China and India, as well as other '
                      'industrial countries in Europe and Asia, continue to encourage '
                      'and advance engineering .'}]

คุณสามารถระบุ `max_length` หรือ `min_length` เพื่อให้ได้ผลลัพธ์ที่ต้องการได้เหมือนการสร้างข้อความ

##
การแปลภาษา

สำหรับการแปลภาษาแล้ว คุณสามารถใช้โมเดลเริ่มต้นได้เลยหากคุณกำหนดคู่ภาษาตั้งต้นและภาษาปลายทางที่ชื่องาน(เช่น `"translation_en_to_fr"`) แต่มีวิธีที่ง่ายกว่าก็คือให้เลือกโมเดลที่ต้องการจาก Model Hub ตัวอย่างด้านล่างแสดงการแปลภาษาจากภาษาฝรั่งเศสไปยังภาษาอังกฤษ:

    from transformers import pipeline

    translator = pipeline("translation", model="Helsinki-NLP/opus-mt-fr-en")
    translator("Ce cours est produit par Hugging Face.")

    [{'translation_text': 'This course is produced by Hugging Face.'}]

คุณสามารถกำหนด argument `max_length` หรือ `min_length` เพื่อระบุผลลัพธ์ที่ต้องการเหมือนการสร้างข้อความและการสรุปความ

✏️ ลองเลย! ลองค้นหาโมเดลแปลภาษาในภาษาอื่น ๆ และทดลองแปลภาษาจากข้อความด้านบนไปยังภาษาอื่น ๆ

คำสั่ง pipeline ที่แสดงด้านบนเป็นเพียงตัวอย่างเบื้องต้นเท่านั้น การใช้งานของคำสั่งนี้ค่อนข้างเฉพาะเจาะจงและไม่สามารถแก้ไขอะไรเบื้องหลังได้มากนัก ในบทหลัง ๆ คุณจะได้เรียนรู้หลักการทำงานเบื้องหลังของฟังก์ชัน `pipeline()` และวิธีการปรับแต่งการทำงาน