ถ้าคุณลองไปถาม engineer สัก 3 คนว่า token คืออะไร คุณจะได้คำตอบที่ไม่ซ้ำกันเลยครับ: “มันคือคำหนึ่งคำ”, “มันคือส่วนย่อยของคำ”, “มันคือตัวอักษรประมาณ 4 ตัว” จริงๆ ทั้ง 3 คำตอบนี้ก็ถูกส่วนหนึ่ง และก็ผิดส่วนหนึ่งครับ
คำตอบที่จริงใจที่สุดคือ token คือ อะไรก็ตามที่ tokenizer บอกว่าเป็นนั่นแหละครับ — ซึ่งเจ้า tokenizer เนี่ยมันก็คือตาราง lookup ที่สร้างขึ้นมาด้วย algorithm ที่ไม่ได้สนใจเรื่องไวยากรณ์ ความหมาย หรือวิธีการที่มนุษย์อ่านหนังสือเลยแม้แต่นิดเดียว เราลองมาดูการทำงานของมันกันครับ

ลองเล่นด้วยตัวเอง
ลองพิมพ์อะไรก็ได้ที่ช่องข้างล่างนี้ครับ ในเมนู dropdown คุณสามารถสลับวิธีหั่นข้อความได้ 3 แบบที่ต่างกันโดยสิ้นเชิง ลองเลือกประโยคเดียวกันแล้วดูว่ามันเปลี่ยนไปอย่างไรนะครับ
มี 3 จุดที่น่าสังเกตเวลาเราสลับกลยุทธ์การหั่นครับ:
- Character: ใช้จำนวนคำศัพท์ (vocabulary) น้อยมาก แต่สายอักขระ (sequence) จะยาวเหยียด
- Word: ดูสั้นและสะอาดตา — จนกระทั่งคุณพิมพ์คำที่สะกดผิดหรือชื่อเฉพาะ แล้วจะเห็นว่ามันกลายเป็น “คำใหม่” ที่โมเดลไม่เคยเห็นมาก่อนทันที
- Subword (BPE): นี่คือสิ่งที่ GPT, Claude, LLaMA และ Gemini ใช้จริงๆ ครับ คำที่ใช้บ่อยจะถูกมองเป็นคำเต็มๆ ส่วนคำที่หายากจะถูกหั่นย่อย โดยขนาดคำศัพท์จะคงที่อยู่ที่ประมาณ 50,000–200,000 คำ
สิ่งที่น่าลองเล่นเมื่ออยู่ในโหมด BPE:
- ช่องว่าง (space) เป็นของคำถัดไป: token ไม่ใช่คำว่า
helloแต่เป็น␣helloครับ นี่คือเหตุผลว่าทำไม"hello"กับ" hello"ถึงเป็นคนละ token และมี ID ต่างกัน - คำทั่วไปคือ 1 token: คำอย่าง
the,and,is,you— พวกนี้คือ token เดียวจบ - คำหายากจะถูกหั่น: ลองใช้ preset Rare words ดูครับ เช่น
antidisestablishmentarianism,Tchaikovskyหรือคำที่สะกดผิด พวกนี้จะถูกหั่นเป็น 3, 5 หรือบางทีก็ 7+ ชิ้นเลย - ตัวเลขนั้นแปลกประหลาด: มีเหตุผลเบื้องหลังครับ
tiktokenจะใช้ regex แยกกลุ่มตัวเลขเป็นชุดละ 1-3 ตัว ก่อน จะทำ BPE นั่นคือเหตุผลว่าทำไม2026อาจจะเป็น token เดียว แต่2027อาจจะโดนแยกเป็น 3 token - ภาษาอื่นมีราคาแพงกว่า: ลองใช้ preset Thai ดูครับ จากนั้นลองสลับไปใช้
o200k_baseของ GPT-4o แล้วจะเห็นว่าจำนวน token ลดลง — OpenAI เพิ่มขนาดคำศัพท์จาก ~100K เป็น ~200K เพื่อให้ภาษาอื่นนอกจากภาษาอังกฤษมี token เฉพาะของตัวเองมากขึ้นครับ
ทำไมมันถึงออกมาเป็นแบบนี้?
tokenizer ที่พวก GPT, LLaMA และ Gemini ใช้ ส่วนใหญ่ถูกสร้างด้วย Byte Pair Encoding (BPE) หรือพี่น้องใกล้เคียงอย่าง WordPiece (BERT) และ Unigram LM (T5, Gemma) โดยเดิมที BPE เป็นทริคการบีบอัดข้อมูลตั้งแต่ปี 1994 โดย Philip Gage และถูกนำกลับมาใช้ใหม่ในโลก NLP ปี 2016 โดย Sennrich, Haddow และ Birch1 เพื่อใช้ในการแปลภาษาครับ ตัว algorithm มีแค่ 4 ขั้นตอนสั้นๆ:
- เริ่มต้นโดยให้ตัวอักษรทุกตัวเป็น 1 token
- หาคู่ของตัวอักษรที่อยู่ติดกันและเจอบ่อยที่สุดในข้อมูลที่ใช้เทรน (training corpus)
- ยุบ (merge) คู่นั้นให้กลายเป็น token ใหม่ 1 ตัว
- ทำซ้ำไปเรื่อยๆ จนกว่าจะได้จำนวน token ตามที่ต้องการ (เช่น 50,000–200,000 ตัว)
แค่นี้เลยครับ ไม่มีการใช้นักภาษาศาสตร์มาช่วยตรวจ ไม่มีกฎไวยากรณ์ tokenizer ไม่รู้ด้วยซ้ำว่าคำคืออะไร กริยาคืออะไร หรือภาษาอังกฤษต้องมีช่องว่าง มันแค่ยุบคู่ที่เจอบ่อยที่สุดไปเรื่อยๆ จนกว่าเราจะสั่งให้หยุด (GPT-2 ล้ำไปกว่านั้นโดยการรัน BPE บน raw bytes บวกกับ regex pre-tokenizer2 — นั่นคือเหตุผลว่าทำไม tokenizer รุ่นใหม่ของ OpenAI ถึงสามารถอ่าน UTF-8 ได้ทุกอย่างโดยไม่มีตัว <UNK> หลุดออกมา และเป็นเหตุผลที่การแยกกลุ่มตัวเลขทำงานอย่างที่เราเห็นครับ)
ลองดูการทำงานของมันได้ที่ข้างล่างนี้ครับ เริ่มจากตัวอักษรดิบๆ แล้วดูขั้นตอนการยุบรวม:
จะเห็นว่าการยุบรวมจะค่อยๆ ไต่ระดับความถี่ขึ้นไปเรื่อยๆ: จากตัวอักษร → คู่ตัวอักษรที่เจอบ่อย → คำลงท้าย (suffix) → จนกลายเป็นคำเต็มที่ใช้บ่อย tokenizer เหมือนเข้าไปสร้างระบบโครงสร้างคำภาษาอังกฤษขึ้นมาใหม่จากศูนย์แบบงูๆ ปลาๆ ด้วยความบังเอิญครับ นั่นคือเหตุผลว่าทำไม subword token ถึงมีหน้าตาแบบนั้น
ราคาที่ต้องจ่ายจากการเลือกใช้ผิด
ตอนนี้คุณเห็นแล้วว่า BPE ทำงานยังไง มาดูกันครับว่าการเลือกกลยุทธ์ส่งผลต่อ “เงิน” และ “จำนวน token” อย่างไรบ้าง จากเนื้อหาเดียวกัน 4 กลยุทธ์ กับ 4 ตัวอย่างประโยคครับ:
มี 2 จุดที่น่าประหลาดใจในตารางนี้ครับ อย่างแรกคือ ในภาษาไทย การแยกคำแบบพื้นฐาน (naive word-splitting) จะบอกว่ามีแค่ 5 token — เพราะภาษาไทยไม่มีช่องว่าง ประโยคทั้งประโยคเลยถูกมองเป็น “คำเดียว” ตามช่องว่าง ซึ่งโมเดลไม่มีทางเข้าใจความหมายจากแกงโฮะ 5 token นี้ได้เลย อย่างที่สองคือ BPE ของ GPT-4 กินไปถึง 58 token สำหรับประโยคภาษาไทยเดียวกัน — ซึ่งแพงกว่าการแยกเป็นตัวอักษร (48) ซะอีก เพราะการยุบคำที่เรียนรู้มาจากภาษาอังกฤษมันใช้ไม่ได้กับภาษาอื่นเลยครับ แต่ใน GPT-4o ที่เทรนคำศัพท์ใหม่ จำนวนจะลดลงเหลือ 37 — ดีขึ้นครับ แต่ก็ยังแพงกว่าภาษาอังกฤษถึง 7 เท่าถ้าเทียบตามความหมายต่อคำ
Petrov et al. (2023) ได้วัดค่านี้อย่างเป็นระบบในหลายภาษาและ tokenizer พบว่าเนื้อหาเดียวกันอาจมีราคาแพงกว่าภาษาอังกฤษได้ถึง ~15 เท่า ในบางภาษาครับ3 นี่ไม่ใช่แค่เรื่องงานวิจัย แต่มันคือปัญหาเรื่องราคาในโลกแห่งความจริงสำหรับใครก็ตามที่อยากสร้างโปรเจกต์นอกโลกภาษาอังกฤษครับ
ทำไมเรื่องนี้ถึงสำคัญ
เมื่อคุณเข้าใจแล้วว่า token คือ ผลผลิตทางสถิติ (statistical artifacts) ไม่ใช่หน่วยทางภาษาศาสตร์ พฤติกรรมแปลกๆ ของ LLM ก็จะไม่ใช่เรื่องลึกลับอีกต่อไปครับ:
- ทำไม LLM ถึงสะกดคำหรือนับตัวอักษรไม่เก่ง? เพราะพวกมันไม่เห็นตัวอักษรครับ มันเห็น
␣strawberryเป็น token ก้อนเดียวหรือสองก้อน การถามว่ามีตัวrกี่ตัวในนั้น ก็เหมือนถามคุณว่าคำว่า “strawberry” มีหัวตัวอักษรกี่หัวนั่นแหละครับ (ตัวการใหญ่คือ tokenization ครับ แต่เรื่อง transformer arithmetic และ positional limits ก็มีส่วนด้วย) - ทำไมวิธีการเขียน prompt ถึงสำคัญมาก? เพราะการเขียนต่างกันนิดเดียวอาจทำให้ token เปลี่ยนไปเป็นคนละชุดเลย
"Don't"กับ"Do not"อาจจะดูเหมือนกันสำหรับคุณ แต่สำหรับโมเดล มันคือลำดับ token ที่ต่างกันซึ่งชี้ไปยัง pattern ที่เรียนรู้มาคนละแบบ Sclar et al. (2023) แสดงให้เห็นว่าความแม่นยำอาจเหวี่ยงได้หลายสิบจุดแค่เปลี่ยนตัวคั่นอักขระเพียงตัวเดียว4 ซึ่งมันสมเหตุสมผลขึ้นทันทีเมื่อเราจำได้ว่าการเปลี่ยนแปลงที่ดูเหมือนแค่ “ความสวยงาม” นั้นจริงๆ คือการเปลี่ยน token ครับ - ทำไมภาษาอื่นถึงแพงกว่ามาก? เพราะการยุบคำถูกครอบงำด้วยข้อมูลภาษาอังกฤษที่ใช้เทรนครับ ภาษาไทยหรือญี่ปุ่นเลยมี token เฉพาะตัวน้อยกว่า ตัวอักษรแต่ละตัวเลยมักจะกลายเป็น 1 token หรือถูกแยกตามรอยต่อของ UTF-8 byte
- ทำไมโมเดลชอบ “หลอน” (hallucinate) เวลาเจอคำหายาก? เพราะคำหายากจะถูกหั่นเป็น token ชุดที่ไม่ค่อยได้เห็น ข้อมูลต่อ token ยิ่งน้อย = พฤติกรรมยิ่งเชื่อถือไม่ได้ครับ
ทำไมการตะคอกใส่ LLM ถึงได้ผล
เหล่า prompt engineer มักจะซุบซิบเรื่องทริคนี้ในงานคอนเฟอเรนซ์ครับ: การเขียนบางส่วนของ prompt ด้วย ตัวพิมพ์ใหญ่ทั้งหมด (ALL CAPS) มักจะทำให้โมเดลทำงานได้ดีขึ้นอย่างประหลาด “DO NOT include the explanation.” (ห้ามใส่คำอธิบายมาเด็ดขาด) “URGENT: the user is on a free plan.” (ด่วน: ผู้ใช้ใช้แพลนฟรีอยู่)
คนส่วนใหญ่นึกว่ามันเป็นทริคทางจิตวิทยา เหมือนโมเดลจะรับรู้ความโกรธของเราได้ แต่จริงๆ แล้วข้างใน LLM ไม่มีเครื่องตรวจจับการตะคอกหรอกครับ มันมีแค่ token
ลองใช้ preset SHOUTING ในตัว tokenizer ข้างบนดูครับ สังเกตดูว่าคำพิมพ์ใหญ่ตัวไหนที่โดนหั่นและตัวไหนที่ไม่โดน:
urgent→ 1 token.URGENT→ 3 tokens:UR+G+ENTโมเดลเห็นคำว่าurgentบ่อยพอที่จะให้เป็น token เฉพาะ แต่URGENTนั้นหายากจน BPE ไม่เคยยุบรวมมันเป็นคำเดียวimportant→ 1 token, ID15693ส่วนIMPORTANT→ ก็ 1 token เหมือนกัน แต่ ID คือ99843— ซึ่งเป็นคนละตัวกันอย่างสิ้นเชิง ตัวอักษรเหมือนกัน ความหมายสำหรับคุณเหมือนกัน แต่สำหรับโมเดล มันคือคำคนละคำในพจนานุกรมที่ไม่เกี่ยวข้องกันเลยdo not→ 2 tokens.DO NOT→ ก็ 2 tokens เหมือนกัน แต่ ID ต่างกันคนละโลก คู่ตัวพิมพ์เล็กอยู่ในละแวก “การสนทนาทั่วไป” ส่วนคู่ตัวพิมพ์ใหญ่อยู่ในละแวก “stack trace และหัวข้อคำเตือน”
พวกนี้ไม่ใช่ token ตัวเดียวกันที่ติดธงว่า “เสียงดัง” นะครับ แต่มันคือ คนละ token ที่อยู่ในคนละย่านของคลังคำศัพท์โมเดล และมีประวัติทางสถิติที่ต่างกัน
แล้วคำอย่าง IMPORTANT, URGENT, DO NOT, WARNING และ ERROR มักจะไปปรากฏที่ไหนในข้อมูลที่ใช้เทรนล่ะครับ?
- ไฟล์ README ตรงส่วนที่คนเขียนอยากให้คุณอ่านจริงๆ
- Stack traces และ error ของระบบ
- ข้อความทางกฎหมายและคำเตือนเรื่องความปลอดภัย
- GitHub issue templates ที่มีแถบสีแดงตัวหนา
พูดง่ายๆ คือ: มันคือข้อความที่มนุษย์เขียนขึ้นเมื่อพวกเขาต้องการให้ผู้อ่าน ตั้งใจฟังและห้ามทำพลาดเด็ดขาด คำอธิบายหนึ่งที่เป็นไปได้สำหรับทริคการตะคอกคือ โมเดลได้เรียนรู้ทางสถิติว่าข้อความที่อยู่ใกล้ token เหล่านี้มักจะตามด้วยการตอบสนองที่ระมัดระวังและซีเรียส ไม่ใช่เพราะมันเข้าใจความเร่งด่วน แต่เพราะข้อมูลที่มันเห็นมามันเป็นแบบนั้นครับ
ดังนั้นเวลาคุณตะโกนใส่ GPT-4 ว่า DO NOT INCLUDE MARKDOWN คุณไม่ได้กำลังข่มขู่มันครับ แต่คุณกำลังผลักมันเข้าไปอยู่ในส่วนของ weights ที่เคยอ่าน GitHub issue templates ที่เกรี้ยวกราดมานับสิบล้านครั้ง ตรรกะเดียวกันนี้ยังอธิบายเรื่องเล่าอื่นๆ ของการเขียน prompt ได้ด้วยครับ:
- การพูด “Please” และ “Thank you” บางทีก็ได้ผล: ข้อความที่สุภาพในข้อมูลเทรน มักจะตามด้วยการตอบสนองที่มีประโยชน์และรูปแบบดี (เช่น บทสนทนาของ support หรือคำตอบใน Stack Overflow ที่ถูกยอมรับ)
- “You are an expert ___” (คุณคือผู้เชี่ยวชาญด้าน…) ได้ผล: ข้อความที่ตามหลังประโยคนี้ โดยเฉลี่ยแล้วมักจะเป็นข้อความที่ระมัดระวังและมีการอ้างอิงมากกว่า โมเดลไม่ใช่ผู้เชี่ยวชาญครับ มันแค่เข้าสู่โหมด autocomplete ที่เลียนแบบหน้าตาของผู้เชี่ยวชาญเท่านั้นเอง
- การขู่โมเดลบางทีก็ได้ผล: งานวิจัย “EmotionPrompt” ของ Li et al. ได้วัดผลเรื่องนี้ในเชิงประจักษ์: ประโยคอย่าง “this is very important to my career” (นี่สำคัญต่ออาชีพการงานของฉันมาก) ช่วยเพิ่มคะแนน benchmark ได้หลายจุดใน LLM หลายตัว5 กลไกเบื้องหลังยังเป็นที่ถกเถียงกันอยู่ แต่ผลลัพธ์นั้นเกิดขึ้นจริงครับ
ถ้ามองในมุมกว้าง prompt engineering ก็คือการ หาชุด token ที่จะพาโมเดลลงไปอยู่ในย่านที่มีประโยชน์ในข้อมูลการเทรนของมัน นั่นเองครับ การใช้ ALL CAPS เป็นวิธีที่ง่ายที่สุดวิธีหนึ่ง เพราะข้อมูลได้สอนโมเดลมาว่า IMPORTANT คือสัญญาณสากลของมนุษย์ที่บอกว่า ได้โปรดอย่าทำพังนะ
เพราะฉะนั้น ตะโกนใส่ LLM ของคุณไปเถอะครับ มันไม่ได้ยินคุณหรอก แต่ token ของมันน่ะได้ยินเต็มๆ เลย
บทสรุป
token ไม่ใช่คำครับ token คือชิ้นส่วนของข้อความที่ algorithm BPE บังเอิญไปยุบรวมกันระหว่างการเทรน และมันจะถูกแช่แข็งไว้อย่างนั้นตลอดไปในคลังคำศัพท์ที่โมเดลหนีไปไหนไม่ได้ ทุกสิ่งที่ LLM “รู้” ล้วนถูกกรองผ่านพจนานุกรมที่มันไม่ได้เลือกเอง
ครั้งต่อไปที่คุณแปลกใจกับพฤติกรรมของ LLM — ไม่ว่าจะเป็นการนับเลขพลาด การตอบภาษาไทยแปลกๆ หรือการเซนซิทีฟกับช่องว่าง — ลองเปิดดู tokenizer ข้างบนนี้แล้วดูว่าจริงๆ แล้วโมเดลเห็นอะไร คำตอบมักจะอยู่ในนั้นเสมอครับ
อ่านเพิ่มเติม
- Andrej Karpathy — “Let’s build the GPT Tokenizer” — วิดีโอสอนสร้าง BPE จากศูนย์ ยาว 2 ชั่วโมง พร้อม repo github.com/karpathy/minbpe เป็นบทนำที่ดีที่สุดบนอินเทอร์เน็ตแล้วครับ
- OpenAI’s
tiktokenที่ github.com/openai/tiktoken — tokenizer อย่างเป็นทางการของ GPT-3.5 / 4 / 4o รวมถึง source code ของ regex pre-tokenizer - SentencePiece โดย Kudo & Richardson — library เบื้องหลัง LLaMA, T5, Gemma และ tokenizer ส่วนใหญ่ที่ไม่ใช่ของ OpenAI งานวิจัย: arxiv.org/abs/1808.06226
Interactive tokenizer ในบทความนี้รันด้วย gpt-tokenizer โดย niieani ครับ
References
Rico Sennrich, Barry Haddow, Alexandra Birch. Neural Machine Translation of Rare Words with Subword Units. ACL 2016. arxiv.org/abs/1508.07909. งานวิจัยที่นำ BPE มาสู่โลก NLP ↩︎
Alec Radford, Jeffrey Wu, Rewon Child, David Luan, Dario Amodei, Ilya Sutskever. Language Models are Unsupervised Multitask Learners. OpenAI, 2019. นำเสนอ byte-level BPE บวกกับ regex pre-tokenizer ที่เป็นเบื้องหลังพฤติกรรมส่วนใหญ่ของ tiktoken ↩︎
Aleksandar Petrov, Emanuele La Malfa, Philip H.S. Torr, Adel Bibi. Language Model Tokenizers Introduce Unfairness Between Languages. NeurIPS 2023. วัดความแตกต่างของราคา token ในแต่ละภาษา ↩︎
Melanie Sclar, Yejin Choi, Yulia Tsvetkov, Alane Suhr. Quantifying Language Models’ Sensitivity to Spurious Features in Prompt Design. 2023. แสดงให้เห็นว่าการเปลี่ยนรูปแบบเพียงเล็กน้อยส่งผลต่อความแม่นยำอย่างมาก ↩︎
Cheng Li, Jindong Wang, Yixuan Zhang, Kaijie Zhu, Wenxin Hou, Jianxun Lian, Fang Luo, Qiang Yang, Xing Xie. Large Language Models Understand and Can be Enhanced by Emotional Stimuli. 2023. งานวิจัย “EmotionPrompt” — หลักฐานเชิงประจักษ์ว่าการใช้คำกระตุ้นอารมณ์ช่วยเพิ่มประสิทธิภาพ LLM ได้จริง ↩︎
