ลดขนาดโมเดล AI

ในช่วง 1-2 ปีที่ผ่านมา หากได้ติดตามข่าวด้านไอทีและ AI เราน่าจะได้เห็นข่าวเรื่องของการออกโมเดลมาใหม่เยอะแยะมากมาย แต่ละโมเดลนั้นมีขนาดที่ใหญ่โตจนหลาย ๆ คนบอกว่า มันใหญ่จนแทบจะไม่สามารถใช้งานบนเครื่องคอมพิวเตอร์บ้านทั่ว ๆ ไปได้เลย ต้องใช้ Cloud หรือคอมพิวเตอร์ขนาดใหญ่เท่านั้น แต่ไม่นานหลังจากนั้น ก็ออกตัวเล็ก ๆ มาเพื่อให้อุปกรณ์เล็ก ๆ สามารถรันได้ แล้วเขาทำอย่างไรให้โมเดลขนาดใหญ่ ๆ ลดลงมาสู่โมเดลขนาดเล็ก ๆ ที่เราสามารถรันได้ในเครื่องของเรา SUM UP จะค่อย ๆ พาไปทำความเข้าใจกัน

ลักษณะของโมเดลพื้นฐาน

โมเดลที่เราใช้งานใน LLM หรือโมเดลทางภาษาทั้งหมด ณ วันนี้ เราจะใช้สิ่งที่เรียกว่า Neural Network หลักการของมันง่ายมากคือ เราจะเชื่อมต่อ Neuron หลาย ๆ ตัวเข้าด้วยกัน หากใครเคยเห็นภาพสิ่งนี้มาก่อน ตัว Neuron ก็คือก้อนกลม ๆ เล็ก ๆ และมีเส้นเชื่อมต่อ Neuron ซึ่งใน 1 Neuron อาจจะถูกเชื่อมต่อด้วยหลาย ๆ Neuron โดยแต่ละเส้นที่พูดถึงจะเชื่อมต่อกันโดยมีสิ่งที่เรียกว่า น้ำหนัก (Weight) หรือถ้าในโมเดลจะเรียกกันว่า Hyperparameter ซึ่งตอนที่เราเทรนโมเดลด้วยข้อมูล หลักการมันก็คือ การเข้าไปปรับค่าน้ำหนักในแต่ละชิ้น ถ้าน้ำหนักเท่านี้จะทำให้โมเดลมันเดาข้อมูลถูกเท่าไหร่ แล้วพยายามปรับให้มันเดาถูกฟิตกับข้อมูลมากที่สุด เรื่องการค้นหาชุดของน้ำหนักที่ทำให้ฟิตกับข้อมูลมากที่สุดเรียกว่าเป็นศาสตร์อีกตัวหนึ่งได้เลย ไว้จะมาเล่าในโอกาสต่อไป

ในทางทฤษฎี ยิ่งจำนวน Hyperparameter เยอะมากเท่าไหร่ ก็ยิ่งสามารถฟิตเข้ากับลักษณะการกระจายตัวของข้อมูลได้มากขึ้นเท่านั้น รองรับข้อมูลที่แตกต่างกันได้เพิ่มมากขึ้น พูดง่าย ๆ คือ ความจำมันจะดีขึ้นนั่นเอง ทำให้ถ้าเราอยากได้โมเดลที่มีความ General หรืออเนกประสงค์มาก ๆ เข้า เราจำเป็นที่จะต้องใช้โมเดลขนาดใหญ่ที่มี Hyperparameter จำนวนมาก เช่น LLM หรือ Large Language Model เป็นต้น แต่ปัญหาคือ ยิ่งจำนวน Hyperparameter เพิ่มมากขึ้น ก็จะส่งผลถึงการประมวลผล ให้เราคิดภาพเป็นสมการกำลัง 2 กับ 3 ยังไง ๆ กำลัง 3 ย่อมต้องใช้ตัวแปรเยอะกว่า ทำให้ต้องใช้พลังในการคิดเลขเยอะกว่า ลองคิดว่าถ้าโมเดลขนาด 8 พันล้าน Hyperparameter ย่อมทำงานได้เร็ว และใช้หน่วยความจำน้อยกว่าโมเดลขนาด 200 พันล้าน Hyperparameter อย่างแน่นอน

ซึ่งการคำนวณที่ว่านี้ เราสามารถทำได้บน CPU หรือ GPU หรือถ้าเครื่องใหม่ ๆ หน่อยที่มี NPU ก็จะใช้งานได้เช่นกัน ตัวอย่างเช่น หากเราต้องการใช้ GPU ในการทำงาน เราจะต้องโหลดข้อมูลไปลงในหน่วยความจำของ GPU ปัญหาคือ หากโมเดลนั้นมีขนาดใหญ่มากกว่าหน่วยความจำของ GPU ก็จะทำให้โมเดลนี้ไม่สามารถรันบนเครื่องของเราได้ และขึ้น Error ออกมาว่า Memory Limit Exceeded แล้วตัดตัวเองไปเลย ทำให้การจะรันพวกโมเดลขนาดใหญ่ ๆ จะต้องเป็นเครื่องจำพวก Cluster หรือ Server ที่มี GPU ขนาดใหญ่ ๆ เท่านั้น ไม่สามารถรันบนเครื่องของเราได้นั่นเอง แล้วถ้าเราอยากจะทำให้โมเดลนั้นรันบนเครื่องเราได้ เราก็จำเป็นที่จะต้องทำการย่อส่วนโมเดลของให้เล็กมากพอที่จะเสียบเข้าไปในหน่วยความจำของอุปกรณ์ที่เราต้องการได้นั่นเอง

Pruning : ตัดออกมันซะเลยสิ

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

วิธีการดูว่าเราจะเลือกตัดส่วนไหนก็มีหลายวิธีอีก เช่น Weight-Pruning คือ เราจะให้เครื่องไปตัดส่วนเส้น หรือ Neuron ที่มี Weight ค่าน้อยมาก ๆ ที่เลือกทำแบบนั้นเพราะถ้า Weight น้อยมากจริง ๆ เอาข้อมูลคูณเข้าไปยังไงก็ได้ค่าน้อยมาก ๆ จะส่งผลกระทบต่อการตัดสินใจของโมเดลน้อยมาก ๆ ทำให้ในทางทฤษฎี หากเราตัดก้อนที่มี Weight เล็กมาก ๆ ประสิทธิภาพมักจะใกล้เคียงของเดิมก่อนตัดมาก ๆ

หรือกระทั่งการตัดออกทั้ง Layer ทั้งยวงไปเลย เราเรียกว่า Structured Pruning การตัดลักษณะนี้ มักจะใช้กับส่วนใดส่วนหนึ่งของโมเดลที่อาจจะกินพลังการประมวลผลเยอะ เช่น Neuron บางประเภทที่ใช้วิธีการคำนวณที่ GPU ไม่มีตัวเร่งความเร็ว ทำให้การตัดส่วนพวกนี้ออกไปเลยจะทำให้การทำงานเร็วขึ้นกว่าเดิมได้อย่างแน่นอน แต่ต้องแลกมากับผลกระทบต่อเรื่องประสิทธิภาพของโมเดลที่อาจจะแย่ลงอย่างเห็นได้ชัดก็เป็นได้

Quantisation : ลดขนาดของ Hyperparameter เอา

หากคิดว่า การตัดบางส่วนของโมเดลมันโหดเกินไป เป็นเหมือนการยอมตัดแขนตัดขาเพื่อลดน้ำหนัก งั้นมาลองอีกวิธีที่นุ่มนิ่มมากขึ้นอย่างการทำ Quantisation กัน เปรียบเทียบกันมันคือ การดูดไขมันออกไป ทำให้แต่ละส่วนมีน้ำหนักที่เบาขึ้น แต่ถ้าพูดในความเป็นจริง มันคือการลดความละเอียดของ Hyperparameter ลง เช่น จากเดิม Hyperparameter 1 ตัว จะต้องใช้ 64 Bits แต่ถ้าเราใช้ตัวเลขอีกแบบที่ใช้พื้นที่เล็กลง อาจจะเหลือ 16 หรือ 8 Bits ทำให้ลดขนาดไปได้หลายเท่าตัว แต่ต้องแลกมากับความละเอียดของทศนิยม เช่น จากเดิม เราเก็บตัวเลขละเอียดสุดได้ 0.0001 แต่พอลดขนาดลงไป มันอาจจะเก็บได้ละเอียดสุดแค่ 0.01 เท่านั้น ตัวเลขที่เก็บได้ก็จะละเอียดน้อยลง เช่น Weight เส้นหนึ่งมีค่าเป็น 1.4532335 แต่พอเราทำ Quantisation แล้วอาจจะเหลือแค่ 1.45 ซึ่งถ้าตัวเลขด้านหลังทศนิยมไกล ๆ มันไม่ได้ส่งผลถึงผลการทำงานของโมเดล การทำ Quantisation ของโมเดลเลยถือว่าเป็นตัวเลือกในการทำงานที่ดีมาก ๆ เลยทีเดียว

เราอาจจะเห็นได้จากโมเดลบางตัวที่เขียนต่อท้ายว่า Quantised พวกนี้แหละคือโมเดลที่ผ่านการ Quantise Weight มาแล้ว ทำให้ถ้าเขาทำมาดี ๆ การ Quantise อาจจะยังทำให้ผลประสิทธิภาพที่ดีพอ ๆ กับโมเดลขนาดเต็ม ๆ ที่รันบนเครื่องเราไม่ไวก็เป็นได้ แต่โดยทั่ว ๆ ไป โมเดลที่โดน Quantise ด้วยขนาด Hyperparameter สักครึ่งหนึ่ง ความแม่นยำของโมเดลอาจจะหายไปไม่เยอะมาก ระดับ 10-20% หรือถ้าเล่นท่าแปลก ๆ Quantise มั่ว ๆ มันก็สามารถตกไปถึง 40-50% ได้เลย

Knowledge Distillation : เราเก็งข้อสอบให้โมเดล

ลองคิดเป็นภาพความเป็นจริง หากเราใกล้สอบ และถ้าเราจะต้องนั่งอ่านหนังสือหลายร้อยหน้า ทำความเข้าใจอะไรอีกมากมายจนหัวจะระเบิดก่อน แต่ถ้าเรามีทางลัดล่ะ เราก็ไปนั่งหาสรุป และเก็งข้อสอบเรื่องที่เราจะต้องสอบจริง ๆ มานั่งอ่าน จำมันเข้าไปเลย ก็ย่อมจะใช้เวลาในการอ่านและจำน้อยกว่าการที่ต้องมานั่งอ่านทั้งหมดใหม่อีกครั้งแน่นอน นี่แหละคือหลักการของการทำ Knowledge Distillation

พูดในเชิงการทำงานจริง คือการใช้โมเดลที่มีขนาดเล็กลงเพื่อเลียนแบบพฤติกรรมของโมเดลที่มีขนาดใหญ่กว่า โดยข้อมูลที่ใช้ในการสอนจะต้องเป็นข้อมูลที่มันมั่นใจว่าตรงกับข้อมูลจริงให้มากที่สุด ตัดส่วนที่เป็นขยะ และส่วนที่ไม่จำเป็นออกไปให้ได้เยอะที่สุด ด้วยหลักการนี้ก็ควรจะทำให้โมเดลที่มีขนาดเล็กกว่า หรือจำนวน Hyperparameter น้อยกว่ามีความสามารถใกล้เคียงหรือมากกว่าโมเดลที่มีขนาดใหญ่กว่า เลยทำให้กลายเป็นอีกเทคนิคหนึ่งที่ใช้ในการย่อขนาดโมเดลกันนั่นเอง

สรุป

การย่อขนาดโมเดลเรียกว่าเป็นศาสตร์และศิลป์เลยล่ะ เราจะชั่งน้ำหนักเรื่องของขนาดและประสิทธิภาพของโมเดลแต่ละส่วนมากน้อยขนาดไหน บางครั้ง ก็ไม่ได้ใช้เพียงเทคนิคเดียวอันเดียวเท่านั้น แต่ใช้หลาย ๆ เทคนิครวมกัน เช่น เราทำ Quantisation แล้วปรากฏว่าเจอว่าบางเส้นโดน Quantised ไปแล้ว จากเดิมอาจจะเป็น 0.0043 แล้วกลายเป็นว่า เหลือ 0.00 เท่ากับว่าไม่มีค่าอะไร เราก็สามารถ Prune หรือลบมันออกไปได้เลยเหมือนกัน หรือกระทั่งการคิดวิธีการใหญ่ ๆ ออกมาเพื่อลดขนาดก็มีมาเรื่อย ๆ บางอันได้ผล ลดขนาดได้เยอะ แต่ก็ลดประสิทธิภาพลงไปแบบเท่าตัว หรือบางตัวลดได้น้อยมาก แล้วดันลดประสิทธิภาพหายไปครึ่งหนึ่งด้วยพวกนี้มันก็มีเหมือนกัน มีตัวที่รอด และตัวที่ไม่รอด สนุกกว่านั้นคือตัวที่หลาย ๆ คนบอกรอดแต่อาจจะไม่รอดในโมเดลของเราก็ได้ นี่แหละความสนุกของงาน AI ลองกันไปลองกันมา คิดหาวิธีใหม่ ๆ แบบรัว ๆ Paper มีออกมาเยอะมาก ๆ ก็รอดูกันต่อไปว่านักคอมพิวเตอร์จะสร้างเทคนิคอะไรออกมาให้เราได้ทดสอบกันแบบตื่นเต้น ๆ กันอีก

AUTHOR

I believe in technology and sharing, as they enable us with a better world via several clicks. Especially, programming is one of the most powerful tools which inspire people to make their dreams come true. I want to share, publicise and innovate new technology so as to change our world in the way we could hardly imagine.