การอนุมาน AI ขนาดเล็กด้วย Firecracker: การรัน LLM ในสภาพแวดล้อม MicroVM และการเพิ่มประสิทธิภาพต้นทุน

การอนุมาน AI ขนาดเล็กด้วย Firecracker: การรัน LLM ในสภาพแวดล้อม MicroVM และการเพิ่มประสิทธิภาพต้นทุน

บทนำ

Firecracker คือโอเพนซอร์ส VMM (Virtual Machine Monitor) ที่เขียนด้วยภาษา Rust ซึ่ง AWS เปิดตัวในปี 2018 โดยเป็นเทคโนโลยีพื้นฐานที่ใช้ MicroVM บนพื้นฐานของ KVM เพื่อให้สามารถบูตระบบได้รวดเร็วกว่า VM แบบดั้งเดิมและสร้างสภาพแวดล้อมที่แยกส่วนได้อย่างเบาบาง อีกทั้งยังถูกนำไปใช้เป็นโครงสร้างพื้นฐานของ AWS Lambda และ AWS Fargate ซึ่งพิสูจน์ให้เห็นถึงความเสถียรในการใช้งานจริง

หากคุณกำลังกังวลเรื่องต้นทุนของโครงสร้างพื้นฐานสำหรับการอนุมาน (Inference) ด้วย LLM คุณอาจกำลังประสบปัญหาเรื่องการรอคอยการเปิดใช้งาน GPU Instance หรือการจัดสรรทรัพยากรที่เกินความจำเป็น บทความนี้จัดทำขึ้นสำหรับวิศวกร DevOps และสถาปนิกโครงสร้างพื้นฐานที่กำลังพิจารณาการเพิ่มประสิทธิภาพต้นทุนของโครงสร้างพื้นฐานด้าน AI Inference โดยจะอธิบายขั้นตอนการสร้างสภาพแวดล้อม LLM Inference ด้วย MicroVM ของ Firecracker รวมถึงวิธีการลดต้นทุนผ่านการเพิ่มประสิทธิภาพทรัพยากร และกลยุทธ์การขยายระบบ (Scaling) อย่างเป็นลำดับขั้นตอน เมื่ออ่านจบ คุณจะได้รับข้อมูลประกอบการตัดสินใจและแนวทางในการนำ Firecracker ไปประยุกต์ใช้กับโครงสร้างพื้นฐานด้านการอนุมานขององค์กรคุณ

Firecracker คือ Virtual Machine Monitor (VMM) แบบโอเพนซอร์สที่ AWS พัฒนาขึ้นเพื่อใช้เป็นรากฐานของ Lambda และ Fargate โดยให้บริการ MicroVM ขนาดเบาที่ทำงานบน KVM ซึ่งมีจุดเด่นคือสามารถลดเวลาในการบูตลงได้อย่างมากเมื่อเทียบกับ VM ทั่วไป ในขณะเดียวกันก็ยังคงรักษาขอบเขตความปลอดภัยที่แข็งแกร่งกว่าคอนเทนเนอร์ได้

สำหรับเวิร์กโหลดด้านการอนุมาน AI (AI inference) นั้นมีความต้องการที่จะจัดเตรียมสภาพแวดล้อมการทำงานที่แยกเป็นอิสระสำหรับแต่ละคำขอ (request) โดยที่ยังคงต้องรักษาค่าความหน่วง (latency) ให้ต่ำอยู่เสมอ Firecracker สามารถตอบโจทย์ความต้องการนี้ได้ดี จึงเริ่มมีการนำมาใช้ในโครงสร้างพื้นฐานแบบ Serverless และการรัน LLM ในสภาพแวดล้อมแบบ Multi-tenant มากขึ้น เนื่องจากเป็นตัวเลือกที่ช่วยหลีกเลี่ยงทั้งปัญหาความล่าช้าในการบูตของ VM แบบดั้งเดิม และปัญหาความอ่อนแอในการแยกส่วนของคอนเทนเนอร์ ต่อจากนี้เราจะมาสรุปความแตกต่างทางเทคนิคระหว่าง VM, คอนเทนเนอร์ และ Firecracker รวมถึงดูความเหมาะสมในการใช้งานกับเวิร์กโหลดด้านการอนุมานอย่างละเอียดครับ

นิยามของ Firecracker และความแตกต่างจาก VM/Container แบบเดิม

เกณฑ์การตัดสินใจเบื้องต้นคือ หากให้ความสำคัญกับความเร็วในการเริ่มต้นทำงาน (Startup speed) ให้เลือก Firecracker แต่หากให้ความสำคัญกับความเข้ากันได้ของการทำ Virtualization แบบทั่วไป ให้เลือก VM แบบดั้งเดิม Firecracker เป็นเทคโนโลยีการทำ Virtualization แบบโอเพนซอร์สที่ประกาศเปิดตัวในปี 2018 โดยเขียนด้วยภาษา Rust ซึ่งสร้าง MicroVM น้ำหนักเบาบน KVM ในขณะที่ VM แบบดั้งเดิมจะมีระบบจำลองอุปกรณ์ (Device emulation) แบบเต็มรูปแบบ แต่ Firecracker กลับติดตั้งเฉพาะโมเดลอุปกรณ์ที่จำเป็นขั้นต่ำเท่านั้น ทำให้มีค่า Memory overhead ต่อเธรดของ VMM (Virtual Machine Monitor) ต่ำกว่า 5 MiB การออกแบบที่ประหยัดหน่วยความจำเช่นนี้เองที่เป็นเหตุผลสำคัญที่ทำให้มันถูกนำไปใช้ในโครงสร้างพื้นฐานแบบ Multi-tenant ซึ่งต้องรัน MicroVM จำนวนหลายร้อยถึงหลายพันตัวบนโฮสต์เดียวกัน

ความแตกต่างจาก Container นั้นชัดเจน Container จะแชร์โฮสต์เคอร์เนลจึงเริ่มต้นทำงานได้รวดเร็ว แต่ไม่มีการแยกส่วนในระดับเคอร์เนล ซึ่งมักจะกลายเป็นปัญหาด้านขอบเขตความปลอดภัยในสภาพแวดล้อมแบบ Multi-tenant ในทางกลับกัน Firecracker ได้รับการออกแบบมาให้จัดสรรเคอร์เนลเฉพาะสำหรับแต่ละ MicroVM โดยสามารถทำ InstanceStart จนถึงการเริ่มทำงานของ /sbin/init ในฝั่ง Guest ได้ภายในเวลาไม่เกิน 125 ms ทำให้ได้ทั้งคุณสมบัติการแยกส่วนเทียบเท่า VM และความเร็วในการเริ่มต้นทำงานเทียบเท่า Container ซึ่งถูกนำไปใช้ในโครงสร้างพื้นฐานแบบ Serverless อย่าง AWS Lambda และ AWS Fargate และมีผลงานพิสูจน์แล้วในการใช้งานที่ต้องเปิดและปิด Workload จำนวนมากในสภาพแวดล้อมแบบ Multi-tenant อย่างรวดเร็ว สำหรับกรณีการใช้งานอย่างการอนุมาน LLM (LLM inference) ที่ต้องการแยกใช้ VM ตามแต่ละคำขอ (Request) การผสมผสานระหว่างความเร็วในการเริ่มต้นทำงานและการแยกส่วนนี้จะเป็นปัจจัยสำคัญในการตัดสินใจ

เหตุผลที่เหมาะสมกับ AI Inference Workload

ในหน้างานการอนุมาน (Inference) ด้วย LLM โจทย์ที่ท้าทายอยู่เสมอคือการตอบสนองต่อความต้องการที่ว่า "ต้องการจองทรัพยากร GPU เพียงช่วงเวลาสั้นๆ และต้องการปล่อยคืนทันทีที่ใช้งานเสร็จ" สำหรับเอนด์พอยต์การอนุมานที่มีคำขอเข้ามาเป็นระลอก หากใช้สภาพแวดล้อมคอนเทนเนอร์ที่รันตลอดเวลา ต้นทุนในการรอคอย (Idle cost) จะสะสมเพิ่มขึ้นเรื่อยๆ ในทางกลับกัน หากใช้วิธีแบบ Serverless ที่เริ่มทำงานจากศูนย์ การหน่วงเวลาในการเริ่มต้น (Startup latency) ก็จะส่งผลเสียต่อประสบการณ์การใช้งานการอนุมาน ซึ่ง Firecracker ได้รับการออกแบบมาเพื่อตอบโจทย์จุดกึ่งกลางนี้

ประสิทธิภาพในการเริ่มต้นทำงานนั้น ใช้เวลาตั้งแต่ InstanceStart จนถึงการเริ่ม /sbin/init ของ Guest ต่ำกว่า 125 มิลลิวินาที และใช้เวลาจนกว่า API socket จะพร้อมใช้งานเพียง 8 CPU มิลลิวินาที (เวลาจริงอยู่ที่ 6-60 มิลลิวินาที โดยค่าทั่วไปอยู่ที่ประมาณ 12 มิลลิวินาที) ทำให้สามารถดำเนินงานโดยการสร้างและทำลาย MicroVM ได้ทันทีตามความต้องการ ตัวเลขเหล่านี้หมายความว่าเราสามารถบีบอัดความหน่วงตั้งแต่ผู้ใช้ส่งคำขอจนถึงการสร้าง Sandbox สำหรับการอนุมานให้เหลือในระดับที่แทบไม่รู้สึกได้ นอกจากนี้ ยังสามารถรักษาประสิทธิภาพการคำนวณได้มากกว่า 95% เมื่อเทียบกับ Bare metal ทำให้สามารถรักษาความปลอดภัยของสภาพแวดล้อมแบบแยกส่วนได้โดยไม่สูญเสียประสิทธิภาพการอนุมาน (Inference throughput) ไปมากนัก

vCPU สามารถปรับได้ตั้งแต่ 1 ถึง 32 และหน่วยความจำปรับได้ตั้งแต่ 128 MiB ขึ้นไป การที่สามารถออกแบบให้เหมาะสมกับขนาดของเวิร์กโหลดได้ ตั้งแต่ Instance ขนาดเล็กสำหรับ SLM (Small Language Model) ไปจนถึงการตั้งค่าสำหรับโมเดลขนาดใหญ่ ถือเป็นจุดแข็งในโครงสร้างพื้นฐานการอนุมานแบบ Multi-tenant ที่ต้องการการแยกส่วนระหว่างผู้เช่า (Tenant) ซึ่งช่วยให้สามารถสร้างสมดุลระหว่างความเร็วในการเริ่มต้นทำงานและขอบเขตความปลอดภัยได้เป็นอย่างดี

ขั้นตอนการทำ LLM Inference ในสภาพแวดล้อม Firecracker

ในการสร้างสภาพแวดล้อมการอนุมาน (Inference) ของ LLM บน Firecracker สิ่งที่มักจะติดขัดเป็นอันดับแรกคือการตั้งค่า Kernel และระบบเครือข่าย ในทางกลับกัน หากผ่านสองส่วนนี้ไปได้ งานที่เหลือก็จะดำเนินไปได้อย่างค่อนข้างราบรื่น ต่อจากนี้เราจะมาดูขั้นตอนตั้งแต่การสร้างอิมเมจ microVM การรันผ่าน jailer ไปจนถึงการปรับใช้โมเดล (Model Deployment) ตามลำดับ โดยจะเน้นรายละเอียดเป็นพิเศษในส่วนของการ Build Kernel และการตั้งค่าเครือข่าย เนื่องจากหากตั้งค่าตกหล่นจะส่งผลโดยตรงต่อความล้มเหลวในการบูตหรือประสิทธิภาพที่ไม่เพียงพอ ส่วนขั้นตอนที่เป็นมาตรฐานอื่นๆ จะสรุปเฉพาะประเด็นสำคัญเท่านั้น

ข้อกำหนดเบื้องต้นและการเตรียมสภาพแวดล้อม

จำเป็นต้องดำเนินการตรวจสอบการรองรับ Kernel ของ Host OS และการเปิดใช้งาน KVM ให้เรียบร้อยก่อนเป็นอันดับแรก หากติดขัดในขั้นตอนนี้ งานส่วนที่เหลือทั้งหมดจะสูญเปล่า ดังนั้นจึงไม่ควรละเลยเป็นอันขาด

Firecracker เป็นเทคโนโลยี MicroVM ที่เขียนด้วยภาษา Rust ซึ่งใช้ KVM บน Linux โดยมีเงื่อนไขว่า Host ต้องมี Kernel ที่รองรับ KVM หากสร้างบนระบบคลาวด์ จำเป็นต้องเลือก Bare Metal Instance หรือ Instance Type ที่รองรับ Nested Virtualization เนื่องจากในกรณีที่เป็นการซ้อน Virtualization บน Virtual Machine ปกติ อาจมีบางกรณีที่ไม่สามารถทำงานได้ จึงเป็นเรื่องสำคัญที่ต้องตรวจสอบการรองรับ Virtualization ของสภาพแวดล้อม Host ไว้ล่วงหน้า

องค์ประกอบที่ต้องเตรียมสามารถแบ่งออกเป็น 3 ส่วนหลัก ได้แก่ Host OS ที่มี Linux Kernel ซึ่งเปิดใช้งาน KVM Module แล้ว, Guest Image ที่ประกอบด้วย Rootfs และ Kernel Image ขั้นต่ำที่จำเป็นสำหรับ Inference Runtime และการรันโมเดล, และสุดท้ายคือการตั้งค่าเครือข่าย เช่น SDK หรือ CLI สำหรับจัดการ Firecracker API Socket และ Tap Device

ในกรณีที่คาดว่าจะใช้สำหรับการทำ LLM Inference จำเป็นต้องเตรียมพื้นที่จัดเก็บข้อมูลสำหรับวางไฟล์ Weight ของโมเดลไว้ที่ฝั่ง Guest รวมถึง Image ที่มี Library ซึ่ง Inference Runtime จำเป็นต้องใช้ ในกรณีที่โมเดลมีขนาดใหญ่ วิธีการแจกจ่าย Image ไม่ว่าจะเป็นการติดตั้งลงใน Local Disk ล่วงหน้าหรือการ Mount หลังจากเปิดเครื่อง จะส่งผลต่อเวลาในการบูตและความซับซ้อนในการดำเนินงาน ดังนั้นหากพิจารณาควบคู่ไปกับการออกแบบการเปิดใช้งาน Instance ในขั้นตอนถัดไป จะช่วยลดการทำงานซ้ำซ้อนได้

การเริ่มต้นและการตั้งค่า Firecracker Instance

การเริ่มต้นใช้งาน Firecracker สามารถทำได้ด้วยการควบคุมแบบแมนนวลผ่าน API socket แต่ในการใช้งานจริง (Production) นิยมใช้วิธีการทำอัตโนมัติผ่าน SDK หรือเลเยอร์การจัดการ (Orchestration layer) มากกว่า

ขั้นตอนการเริ่มต้นนั้นเรียบง่าย โดยเริ่มจากการรันกระบวนการ VMM (Virtual Machine Monitor) แล้วระบุจำนวน vCPU, ขนาดหน่วยความจำ, kernel image และพาธของ root file system ผ่าน REST API บน UNIX socket แม้ค่าเริ่มต้นจะเป็น vCPU 1 และหน่วยความจำ 128 MiB แต่สำหรับการอนุมาน (Inference) ด้วย LLM นั้นไม่เพียงพออย่างแน่นอน จึงจำเป็นต้องปรับตั้งค่า vCPU ให้เป็น 1–32 และเพิ่มหน่วยความจำให้เป็นระดับหลาย GB ตามขนาดของโมเดล

สิ่งที่สำคัญคือ แนวคิดในการจัดสรรหน่วยความจำให้มากเกินความจำเป็นมักจะส่งผลเสีย การกำหนดขนาดตามปริมาณน้ำหนักของโมเดล (Model weights) และค่าที่วัดได้จริงของ KV cache จะเป็นประโยชน์มากกว่าทั้งในด้านความหนาแน่นในการเริ่มต้นใช้งาน (Startup density) และความคุ้มค่าของต้นทุน เพราะการจัดสรรที่มากเกินไปจะทำให้อัตราการเปลี่ยนแปลง (Mutation rate) ลดลง และส่งผลให้จำนวน microVM ที่สามารถรันพร้อมกันต่อหนึ่งโฮสต์คอร์ลดลงตามไปด้วย

เมื่อตั้งค่าเสร็จสิ้นแล้ว ให้เรียกใช้ InstanceStart API เพื่อเริ่มการทำงานของ /sbin/init ในฝั่ง Guest ตามข้อกำหนดแล้ว ระยะเวลาตั้งแต่เริ่มจนถึงการทำงานของ /sbin/init จะอยู่ที่ภายใน 125 มิลลิวินาที ซึ่งความเร็วในการตอบสนองนี้เองที่เป็นรากฐานสำคัญในการออกแบบระบบ Auto-scaling และการประมวลผลคำขอจำนวนมากพร้อมกัน

การปรับใช้และการรันโมเดลสำหรับ Inference

หลังจากที่ Firecracker ไมโคร VM เริ่มทำงานแล้ว จะเข้าสู่ขั้นตอนการรันเซิร์ฟเวอร์สำหรับอนุมาน (Inference Server) และไฟล์โมเดลที่วางไว้ในระบบไฟล์ root วิธีการส่งผ่านโมเดลมีหลักๆ สองวิธี คือวิธีเขียนน้ำหนักโมเดลลงในอิมเมจ rootfs ไว้ล่วงหน้า และวิธีเมานต์จากที่จัดเก็บข้อมูลภายนอกผ่านบล็อกดีไวซ์หลังจากที่ระบบเริ่มทำงานแล้ว วิธีแรกมีข้อดีคือสามารถอนุมานได้ทันทีหลังจากเริ่มระบบ แต่ต้องสร้างอิมเมจใหม่ทุกครั้งที่มีการอัปเดตโมเดล ส่วนวิธีหลังนั้นอัปเดตได้ง่ายกว่า แต่จะมีขั้นตอนการเมานต์และเวลาในการโหลดเพิ่มเข้ามาในลำดับการเริ่มระบบ ตัวอย่างเช่น หากเขียนโมเดลระดับ 7B พารามิเตอร์ในรูปแบบ fp16 ลงใน rootfs จะได้อิมเมจขนาดประมาณ 14GB ซึ่งอาจทำให้ข้อดีเรื่องความเร็วในการเริ่มทำงานของไมโคร VM ลดน้อยลง ในทางปฏิบัติจึงควรตัดสินใจเลือกโดยพิจารณาจากกรณีการใช้งาน หากมีความถี่ในการอัปเดตโมเดลสูงให้เลือกวิธีเมานต์บล็อกดีไวซ์ และหากมีความถี่ในการอัปเดตต่ำโดยให้ความสำคัญกับความเร็วในการเริ่มทำงานเป็นอันดับแรกให้เลือกวิธีเขียนลงในอิมเมจล่วงหน้า

ในกรณีที่โมเดลมีขนาดใหญ่ การใช้เทคนิคการทำ Quantization หรือ LoRA adapter เพื่อลดขนาดโมเดลจะช่วยให้สามารถจัดการภายในไมโคร VM ได้ง่ายขึ้นโดยใช้หน่วยความจำที่น้อยลง หากใช้การทำ INT4 Quantization โมเดลขนาด 14GB ที่กล่าวไปข้างต้นอาจลดขนาดลงเหลือประมาณ 4GB ซึ่งจะส่งผลต่อการออกแบบการจัดสรรหน่วยความจำให้กับไมโคร VM โดยตรง สำหรับแนวคิดเกี่ยวกับวิธีการที่เน้นประสิทธิภาพของพารามิเตอร์ สามารถดูข้อมูลอ้างอิงสำหรับการตัดสินใจในการนำไปใช้งานได้ที่ PEFT (Parameter-Efficient Fine-Tuning) คืออะไร? เทคโนโลยีที่ช่วยลดต้นทุนการปรับแต่ง AI โมเดลได้ถึง 90%

สำหรับตัวเซิร์ฟเวอร์อนุมานนั้น โดยทั่วไปจะเป็นการตั้งค่าให้กระบวนการที่ทำงานอยู่ภายใน Guest รับคำขอผ่าน vsock หรืออินเทอร์เฟซเครือข่าย การสื่อสารผ่าน vsock ช่วยให้ไม่ต้องตั้งค่าเครือข่ายระหว่าง Host และ Guest แต่ในกรณีที่ต้องใช้งานร่วมกับ REST client หรือ Load Balancer ที่มีอยู่เดิม การตั้งค่าเครือข่ายผ่าน TAP interface อาจจัดการได้ง่ายกว่า ในช่วงเริ่มต้นของการดำเนินงาน แนวทางที่เป็นจริงคือการตรวจสอบการทำงานด้วยคำขอเดี่ยวผ่าน REST API เพื่อให้แน่ใจว่าไม่มีปัญหาเรื่อง Latency หรือการใช้หน่วยความจำ และเมื่อระบบมีความเสถียรแล้วจึงค่อยเปลี่ยนไปสู่การปรับใช้แบบกลุ่ม (Bulk Deployment) จากชั้น Orchestration ต่อไป

วิธีการลดต้นทุนการทำ Inference อย่างเป็นรูปธรรม

เราจะสามารถลดต้นทุนการอนุมาน (Inference cost) ลงได้มากน้อยเพียงใด? กุญแจสำคัญอยู่ที่ความแม่นยำในการจัดสรรทรัพยากรและการเลือกรูปแบบการประมวลผลให้เหมาะสมกับลักษณะของภาระงาน (Workload)

ไม่ใช่เรื่องแปลกที่จะพบ Micro-VM ที่มีการจัดสรร vCPU และหน่วยความจำมากเกินความจำเป็น หากเรากำหนดทรัพยากรแบบคงที่โดยอิงจากภาระงานสูงสุด (Peak load) ในช่วงการประมวลผลการอนุมาน ส่วนที่เหลือทิ้งในช่วงเวลาปกติจะกลายเป็นต้นทุนที่สะสมเพิ่มขึ้น การปรับจำนวน vCPU และปริมาณหน่วยความจำให้ละเอียดตามปริมาณคำขอจริงและขนาดของโมเดล เพื่อตัดส่วนเกินออกนั้น แม้จะเป็นงานที่ดูเรียบง่ายแต่กลับให้ผลลัพธ์ที่คุ้มค่าอย่างยิ่ง

เพียงแค่เปลี่ยนกระบวนการที่ไม่จำเป็นต้องใช้ความเรียลไทม์ให้เป็นแบบ Batch ก็สามารถเปลี่ยนต้นทุนต่อการอนุมานหนึ่งครั้งได้อย่างมหาศาล เราไม่จำเป็นต้องจัดการกระบวนการที่ต้องการความรวดเร็วทันที เช่น การตอบกลับของ Chatbot กับกระบวนการที่ยอมรับความล่าช้าได้บ้าง เช่น การสร้างรายงานหรือการวิเคราะห์ Log ด้วยรูปแบบการประมวลผลเดียวกัน หากนำกระบวนการหลังมารวมกลุ่มประมวลผล จะช่วยกระจาย Overhead ที่เกิดจากการเปิด-ปิด Micro-VM ไปตามจำนวนรายการการอนุมาน ส่งผลให้ต้นทุนต่อรายการลดลง

การเพิ่มประสิทธิภาพการจัดสรรทรัพยากร

การจัดสรร vCPU และหน่วยความจำแบบค่อยเป็นค่อยไปตามขนาดของโมเดลและจำนวนการทำงานพร้อมกัน (Concurrency) คือพื้นฐานของการออกแบบทรัพยากร

ใน Firecracker คุณสามารถกำหนดค่า vCPU ได้ตั้งแต่ 1 ถึง 32 และหน่วยความจำเริ่มต้นที่ 128 MiB ได้อย่างอิสระ ความยืดหยุ่นนี้ส่งผลดีต่อการอนุมาน (Inference) ของ AI อย่างคาดไม่ถึง เนื่องจากปริมาณทรัพยากรที่จำเป็นสำหรับการทดสอบการรัน SLM (Small Language Model) ขนาดเล็กแบบเดี่ยว กับสภาพแวดล้อมการใช้งานจริงที่ต้องประมวลผลหลายคำขอแบบขนานนั้นมีความแตกต่างกันอย่างสิ้นเชิง

ในการทำงานจริง มักจะมีการตัดสินใจว่า "เผื่อทรัพยากรไว้ให้มากหน่อยดีกว่า" แต่สำหรับภาระงานด้านการอนุมาน (Inference workload) แล้ว วิธีนี้มักจะส่งผลตรงกันข้าม เนื่องจากการจัดสรร vCPU มากเกินไปจะลดความหนาแน่นในการเริ่มต้น (Startup density) ต่อไมโคร VM หนึ่งตัว และลดจำนวนอินสแตนซ์การอนุมานที่สามารถทำงานบนโฮสต์เดียวกันได้ เนื่องจาก Overhead ของเธรด VMM ถูกจำกัดไว้ไม่เกิน 5 MiB ดังนั้นต้นทุนส่วนเกินส่วนใหญ่จึงเกิดจากการออกแบบทรัพยากรที่ฝั่ง Guest เป็นหลัก

หลักเกณฑ์ในการตัดสินใจเชิงปฏิบัติแบ่งออกเป็น 2 แนวทางหลัก คือ สำหรับ SLM ที่มีน้ำหนักเบาหรือโมเดลที่ผ่านการทำ Quantization แล้ว ให้จัดสรรทรัพยากรขนาดเล็กในระดับ 1-2 vCPU และหน่วยความจำหลักร้อย MiB โดยให้ความสำคัญกับความหนาแน่นในการเริ่มต้นเป็นอันดับแรก ในขณะที่การจัดการกับโมเดลขนาดใหญ่หรือโมเดลที่ใช้ Context window ยาว จะใช้วิธีค่อยๆ เพิ่ม vCPU และหน่วยความจำไปพร้อมกับการตรวจสอบความสมดุลระหว่าง Throughput และ Latency นอกจากนี้ หากมีการนำการทำ Quantization ของโมเดลหรือการลดขนาดด้วย PEFT มาใช้ร่วมด้วย ก็จะช่วยเพิ่มโอกาสในการลดการจัดสรรทรัพยากรลงได้อีกด้วย

การเลือกใช้ระหว่าง Batch Inference และ Real-time Inference

หากมีการเชื่อมต่อพร้อมกันจำนวนน้อยและต้องการการตอบสนองทันที การอนุมานแบบเรียลไทม์ (Real-time inference) จะเหมาะสมกว่า แต่หากสามารถประมวลผลข้อมูลจำนวนมากพร้อมกันได้ การอนุมานแบบแบตช์ (Batch inference) จะเหมาะสมกว่า ในการอนุมานแบบเรียลไทม์ คุณสมบัติของ Firecracker ที่สามารถเริ่มการทำงานของอินสแตนซ์ได้ภายในเวลาไม่เกิน 125 มิลลิวินาที นับตั้งแต่ InstanceStart ไปจนถึงการเริ่มทำงานของ guest /sbin/init นั้นมีประโยชน์อย่างมาก สำหรับแอปพลิเคชันเชิงโต้ตอบอย่างแชทบอท ความเร็วในการเริ่มต้นนี้ส่งผลโดยตรงต่อประสบการณ์ของผู้ใช้งาน

ในทางกลับกัน สำหรับเวิร์กโหลดที่มีข้อจำกัดด้านเวลาตอบสนองไม่เข้มงวด เช่น การวิเคราะห์บันทึก (Log analysis) หรือการสร้างรายงาน การเปลี่ยนไปใช้การอนุมานแบบแบตช์จะมีประสิทธิภาพมากกว่า หากรวบรวมคำขอหลายรายการเข้าสู่กระบวนการอนุมานเดียว จะช่วยเพิ่มประสิทธิภาพการใช้งาน GPU (Graphics Processing Unit) และมีแนวโน้มที่จะลดต้นทุนการประมวลผลต่อ microVM ลงได้

ในทางปฏิบัติ เกณฑ์การตัดสินใจคือ หากช่วงเวลาที่คำขอเข้ามามีความถี่สูงและต้องการค่าความหน่วง (Latency) ต่ำ ควรเปิดใช้งานพูลของ microVM สำหรับการอนุมานแบบเรียลไทม์ทิ้งไว้ตลอดเวลา ในทางกลับกัน หากช่วงเวลาที่คำขอเข้ามามีความถี่ต่ำและสามารถยอมรับการรอคอยได้บ้าง ควรใช้การตั้งค่าที่สะสมคำขอไว้ในคิวแล้วประมวลผลแบบแบตช์เป็นระยะ การออกแบบให้ทั้งสองรูปแบบอยู่ร่วมกันภายในคลัสเตอร์ Firecracker เดียวกัน และจัดสรรตามลักษณะของเวิร์กโหลด ถือเป็นวิธีที่ช่วยให้รักษาสมดุลระหว่างต้นทุนและการตอบสนองได้ดีที่สุด

กลยุทธ์การขยายระบบ (Scaling) ด้วย Firecracker

กลไกการปรับจำนวน microVM ตามปริมาณการเพิ่มขึ้นหรือลดลงของทราฟฟิกการอนุมาน (Inference traffic) ถือเป็นหัวใจสำคัญของการเพิ่มประสิทธิภาพด้านต้นทุน เราจะมาดูวิธีการออกแบบที่เฉพาะเจาะจงโดยพิจารณาจาก 2 มุมมอง ได้แก่ รูปแบบการใช้งาน Horizontal Scaling และการกระจายคำขอผ่าน Load balancing

รูปแบบการทำ Horizontal Scaling (ตารางเปรียบเทียบ)

เมื่อปริมาณทราฟฟิกการอนุมาน (inference traffic) เพิ่มขึ้นอย่างรวดเร็ว เราจะเพิ่ม microVM อย่างไรเพื่อลดต้นทุนการรอคอยที่ไม่จำเป็น? เกณฑ์ในการตัดสินใจคือความเร็วในการเริ่มต้นทำงาน (startup speed) และความสามารถในการคาดการณ์ปริมาณคำขอ (request predictability) หากปริมาณคำขอมีความผันผวนน้อยและคาดการณ์ได้ง่าย การเลือกใช้การขยายขนาดแบบ Pool-based จะเหมาะสมกว่า แต่หากมีการพุ่งสูงขึ้นอย่างกะทันหันบ่อยครั้ง การออกแบบโดยเน้นการเริ่มต้นทำงานแบบ On-demand จะเหมาะสมกว่า

รูปแบบการใช้งานเกณฑ์การประเมินจุดตัดสินใจ
Pool-based (เตรียม microVM ไว้ล่วงหน้า)ลด Latency ในการเริ่มต้นใช้ประโยชน์จากคุณสมบัติการเริ่มต้นทำงานที่ใช้เวลาไม่เกิน 125 มิลลิวินาทีตั้งแต่ InstanceStart จนถึงการเริ่มต้นระบบ Guest ทำให้สามารถจัดสรรจาก Pool ที่เตรียมไว้ได้ทันที เหมาะสำหรับกรณีที่คาดการณ์ทราฟฟิกได้อย่างมั่นคง
On-demand (เริ่มทำงานเมื่อมีคำขอเข้ามา)ประสิทธิภาพการใช้ทรัพยากรสร้าง microVM เฉพาะในจังหวะที่จำเป็นเพื่อลดต้นทุนให้เหลือน้อยที่สุด โดยอ้างอิงจาก Throughput การเริ่มต้นทำงานที่ 5 microVM ต่อวินาทีต่อ 1 Host Core เหมาะสำหรับกรณีที่รับมือกับความผันผวนของโหลดที่เกิดขึ้นกะทันหันได้ดี
Hybrid (คงจำนวน Pool ขั้นต่ำ + เพิ่มแบบ On-demand)ความสมดุลระหว่างความพร้อมใช้งานและต้นทุนโครงสร้างที่คงจำนวนหนึ่งไว้ในสถานะรอคอยและสร้างส่วนเกินแบบไดนามิก รองรับการพุ่งสูงขึ้นที่คาดไม่ถึงได้ง่าย แต่มีภาระในการบริหารจัดการเพื่อปรับขนาด Pool

ไม่ว่าจะใช้วิธีใด สิ่งสำคัญคือต้องวางแผนความจุโดยเข้าใจความสัมพันธ์ระหว่างจำนวน Physical Core ของโฮสต์และ Throughput การเริ่มต้นทำงานของ microVM การกำหนดจำนวน Pool ไว้มากเกินไปจะทำให้เกิดต้นทุนการรอคอยอย่างต่อเนื่อง ดังนั้นแนวทางที่สมจริงคือการสังเกตการณ์รูปแบบทราฟฟิกจริงในช่วงระยะเวลาหนึ่งก่อนที่จะกำหนดพารามิเตอร์เริ่มต้น

การทำ Load Balancing และการกระจายคำขอ Inference

เกณฑ์การตัดสิน: คือการกำหนดว่าจะส่งคำขอ (request) ไปที่ใด

การที่การขยายขนาด (scaling) ในระดับ microVM จะใช้งานได้จริงหรือไม่นั้น ขึ้นอยู่กับเกณฑ์ที่ Load Balancer ใช้ในการกระจายคำขอ เนื่องจากการอนุมาน (inference) ของ LLM มีระยะเวลาการประมวลผลต่อคำขอที่ผันผวนอย่างมากตามความยาวของ Prompt และจำนวน Token ที่สร้างขึ้น การใช้วิธี Round Robin แบบทั่วไปจึงมักทำให้เกิดปัญหาความหน่วง (latency) ที่ไม่เท่ากัน เนื่องจากคำขอถัดไปอาจไปกองรวมกันอยู่ที่ microVM ที่กำลังประมวลผลค้างอยู่

แนวทางการรับมือมีสองด้าน ดังนี้:

  • การกระจายตามจำนวนการเชื่อมต่อขั้นต่ำ (Least Connections): เป็นวิธีที่เลือก microVM ที่กำลังประมวลผลคำขอน้อยที่สุดเป็นอันดับแรก ซึ่งถือว่าเข้ากันได้ดีกับการอนุมานของ LLM ที่มีระยะเวลาการประมวลผลแตกต่างกันมาก
  • การวางคิว (Queueing) ไว้ที่ส่วนหน้า: เป็นการตั้ง Request Queue ไว้หน้า Load Balancer เพื่อให้ microVM แต่ละตัวดึงงานไปทำตามความสามารถในการประมวลผลของตน เมื่อใช้ร่วมกับการขยายขนาดแบบ Pool-based จะสามารถจัดสรรงานให้ microVM ที่กำลังรออยู่ได้ทันที

ในส่วนของการแบ่งเงื่อนไข หากเป็นการอนุมานแบบ Batch การรวบรวมคำขอไว้จำนวนหนึ่งก่อนแล้วค่อยกระจายจะช่วยเพิ่ม Throughput โดยรวมได้ง่ายกว่า ส่วนการอนุมานแบบ Real-time การออกแบบให้ส่งคำขอแต่ละรายการไปยัง microVM ที่อยู่หน้าคิวทันทีจะเหมาะสมกว่า

นอกจากนี้ การตั้งค่าช่วงเวลาการตรวจสอบสถานะ (Health check) ให้สั้นจนเกินไปจะส่งผลกระทบต่อประสิทธิภาพของเครือข่าย ดังนั้นการพิจารณาสมดุลกับอัตราการใช้งาน Host core จึงเป็นประเด็นสำคัญในทางปฏิบัติ การออกแบบชั้น Load Balancing ยังเชื่อมโยงโดยตรงกับจุดรวบรวมตัวชี้วัดการตรวจสอบ (Monitoring metrics) ที่จะกล่าวถึงในส่วนถัดไป

การตรวจสอบและการดำเนินงานสภาพแวดล้อม Firecracker AI Inference

หากโหลดมีความเสถียร การตรวจสอบเป็นระยะผ่านแดชบอร์ดจะเป็นแนวทางหลัก แต่หากเกิดการพุ่งสูงขึ้นอย่างกะทันหัน การตอบสนองทันทีโดยเริ่มจากระบบแจ้งเตือนจะเป็นหัวใจสำคัญ สิ่งที่ต้องเฝ้าระวัง ครอบคลุมทั้งสถานะการใช้งานทรัพยากรในระดับ microVM และสถานะการประมวลผลคำขอ โดยความละเอียดในการเก็บ เมทริกซ์ (Metrics) จะส่งผลต่อความแม่นยำในการตัดสินใจเชิงปฏิบัติการ ต่อไปเราจะมาดูรายการที่ต้องจัดเก็บและวิธีการวิเคราะห์โดยละเอียด ในขั้นตอนการดำเนินงานนั้น การออกแบบการแสดงผลข้อมูล (Visualization) ที่เหมาะสมกับ Firecracker ถือเป็นสิ่งสำคัญ

การเก็บและวิเคราะห์ Performance Metrics

สถานการณ์ที่ว่า "เมื่อ microVM เพิ่มจำนวนขึ้น ก็ไม่รู้ว่าจะต้องดูเมทริกซ์ตัวไหน" เป็นสิ่งที่มักเกิดขึ้นในหน้างานปฏิบัติการ Firecracker มีกลไกที่สามารถดึงข้อมูลสถิติของ CPU usage, memory usage, network throughput และ block I/O ในระดับ microVM ได้ ซึ่งโครงสร้างที่นิยมใช้คือการให้เอเจนต์ฝั่งโฮสต์รวบรวมข้อมูลเหล่านี้แล้วส่งไปยังฐานข้อมูลอนุกรมเวลา (time-series database)

แกนหลักในการวิเคราะห์แบ่งออกเป็น 2 ส่วนใหญ่ๆ ส่วนแรกคือประสิทธิภาพการสตาร์ท microVM โดยจะบันทึกเวลาตั้งแต่ InstanceStart จนถึงการเริ่มเริ่มต้นระบบของเกสต์ (guest initialization) อย่างต่อเนื่อง เพื่อตรวจสอบว่ามีความล่าช้าที่ผิดไปจากการกระจายตัวในช่วงเวลาปกติหรือไม่ ส่วนที่สองคือ throughput ของการอนุมาน (inference throughput) ซึ่งจะใช้การรวมกันระหว่างเวลาที่ใช้ในการประมวลผลต่อหนึ่งคำขอและจำนวนการประมวลผลพร้อมกันต่อ microVM เพื่อตัดสินว่าการจัดสรรทรัพยากรนั้นเพียงพอหรือเกินความจำเป็นหรือไม่

เนื่องจากประสิทธิภาพของเครือข่ายมีความสัมพันธ์กับอัตราการใช้งานของโฮสต์คอร์ (host core usage) ดังนั้นเมื่อพบว่า throughput ลดลง การตรวจสอบอัตราการใช้งานของโฮสต์คอร์ไปพร้อมกันจะช่วยให้แยกแยะสาเหตุได้รวดเร็วขึ้น เช่นเดียวกันกับ storage I/O การวิเคราะห์โดยคำนึงถึงความสัมพันธ์กับอัตราการใช้งานของโฮสต์คอร์ก็เป็นวิธีที่มีประสิทธิภาพ การนำตัวชี้วัดเหล่านี้มาประกอบกันจะช่วยให้สามารถแยกแยะระหว่างค่าความผิดปกติที่เกิดขึ้นเพียงครั้งเดียวกับปัญหาการขาดแคลนทรัพยากรเชิงโครงสร้างได้

คำถามที่พบบ่อย: ความท้าทายในการนำ Firecracker มาใช้

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

Firecracker ช่วยลดต้นทุนได้มากน้อยเพียงใด

เกณฑ์การตัดสิน: ขอบเขตของการลดต้นทุนจะเปลี่ยนไปอย่างมากตามความถี่ในการเริ่มทำงานของเวิร์กโหลดและระดับการทบทวนการตั้งค่าทรัพยากร

MicroVM ของ Firecracker มีการควบคุมหน่วยความจำส่วนเกิน (Memory Overhead) ของเธรด VMM ไว้ที่ 5 MiB หรือน้อยกว่า และสามารถเริ่มต้นด้วยการกำหนดค่าขั้นต่ำที่ vCPU 1 และหน่วยความจำ 128 MiB ได้ สิ่งนี้ช่วยให้ลด "การคงทรัพยากรไว้ในช่วงเวลาที่ไม่ได้ใช้งาน" ซึ่งเป็นสิ่งที่หลีกเลี่ยงไม่ได้ในสภาพแวดล้อมคอนเทนเนอร์ที่ทำงานตลอดเวลา โดยเฉพาะอย่างยิ่งในเวิร์กโหลดการอนุมาน (Inference Workload) ที่มีการร้องขอเข้ามาเป็นระยะ ความเร็วในการเริ่มต้นทำงานที่ใช้เวลา CPU เพียงประมาณ 8 CPU ms จนกว่า API Socket จะพร้อมใช้งาน (เวลาจริงหรือ Wall-clock time อยู่ที่ประมาณ 6–60 ms ขึ้นอยู่กับสภาพแวดล้อม โดยค่าทั่วไปอยู่ที่ประมาณ 12 ms) จะส่งผลดีอย่างมาก

ในการตรวจสอบประสิทธิภาพการลดต้นทุน การเปรียบเทียบภายใต้เงื่อนไขต่อไปนี้ถือเป็นแนวทางปฏิบัติจริง:

  • อัตราส่วนเวลาทำงานระหว่างอินสแตนซ์ที่ทำงานตลอดเวลา (Always-on) กับ MicroVM ที่เริ่มทำงานตามคำขอ (Request-driven)
  • ขอบเขตที่สามารถจำกัดการจัดสรรทรัพยากร (vCPU/หน่วยความจำ) ต่อการอนุมาน 1 รายการ จากการกำหนดค่าขั้นต่ำ
  • อัตราส่วนระหว่างการประมวลผลแบบแบตช์ (Batch processing) กับการประมวลผลที่ต้องการการตอบสนองทันที

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

สามารถย้ายจากสภาพแวดล้อม Kubernetes เดิมได้หรือไม่

หากต้องการทำ Lift & Shift เวิร์กโหลดที่มีอยู่โดยใช้หน่วยเป็นคอนเทนเนอร์ มักจะมีต้นทุนการย้ายที่สูง แต่หากค่อยๆ แยกส่วนออกมาทีละน้อยจากบริการบางอย่าง เช่น Inference Endpoint จะสามารถดำเนินการได้อย่างราบรื่นกว่า เนื่องจากการจัดการ Pod ของ Kubernetes และการจัดการ MicroVM ของ Firecracker มีการทำ Abstraction ของหน่วยประมวลผลที่แตกต่างกัน จึงไม่สามารถนำ Manifest หรือ Container Image ที่มีอยู่มาใช้ได้โดยตรง ในทางปฏิบัติจึงมีการนำ Firecracker มาใช้เป็น Sandbox สำหรับ Container Runtime บน Kubernetes ซึ่งในกรณีนี้จำเป็นต้องเตรียมกลไกสำหรับสั่งการให้ kubelet เริ่มทำงาน MicroVM แยกต่างหาก

เมื่อพิจารณาถึงการย้ายข้อมูล การกำหนดค่าที่สมจริงคือการไม่เปลี่ยนคลัสเตอร์เดิมทั้งหมดในคราวเดียว แต่ให้แยกเฉพาะ Node Pool สำหรับการอนุมาน (Inference) ไปไว้บนโครงสร้างพื้นฐานของ Firecracker แล้วคงส่วน API Gateway และ Orchestration Layer ไว้ในสภาพแวดล้อม Kubernetes เดิม เนื่องจากจำเป็นต้องออกแบบวิธีการแชร์ทรัพยากร GPU และการตั้งค่าเครือข่าย (การทำงานร่วมกับ CNI Plugin) ใหม่โดยตั้งสมมติฐานว่าแตกต่างจากโครงสร้างเดิม จึงไม่สามารถย้าย Network Policy หรือกลไกการจัดการ Secret ที่มีอยู่มาใช้ได้ทันที ในช่วงเริ่มต้นของการย้ายแบบค่อยเป็นค่อยไป การกำหนดเส้นทาง (Routing) คำขออนุมานบางส่วนไปยังโครงสร้างพื้นฐานของ Firecracker และตรวจสอบการทำงานควบคู่ไปกับสภาพแวดล้อมเดิม จะช่วยลดความเสี่ยงในการย้ายข้อมูลได้

Inference Latency จะดีขึ้นเมื่อเทียบกับสภาพแวดล้อม Container หรือไม่

ในด้านความหน่วงของการเริ่มต้นระบบ (Startup Latency) Firecracker มีความได้เปรียบเหนือสภาพแวดล้อมแบบคอนเทนเนอร์อย่างชัดเจน ตามข้อกำหนดทางเทคนิค ระยะเวลาตั้งแต่ InstanceStart จนถึงการเริ่มทำงานของ /sbin/init ในเกสต์นั้นอยู่ที่ 125 มิลลิวินาทีหรือน้อยกว่า และใช้เวลา CPU จนกว่า API socket จะพร้อมใช้งานอยู่ที่ 8 CPU มิลลิวินาที (เวลาจริงอยู่ที่ 6-60 มิลลิวินาที โดยมีค่าทั่วไปอยู่ที่ประมาณ 12 มิลลิวินาที) ในสภาพแวดล้อมแบบ Auto-scaling ที่มีการทำ Cold start บ่อยครั้ง หรือในโครงสร้างพื้นฐานสำหรับการอนุมาน (Inference) แบบ Serverless ที่ต้องสร้างอินสแตนซ์ใหม่สำหรับทุกคำขอ ความแตกต่างนี้มักส่งผลโดยตรงต่อความหน่วงที่ผู้ใช้ได้รับ

ในทางกลับกัน สำหรับความเร็วในการประมวลผลการอนุมานนั้นมีเงื่อนไขที่แตกต่างออกไป ประสิทธิภาพการคำนวณของเกสต์นั้นระบุว่าสูงกว่า 95% เมื่อเทียบกับ Bare metal ซึ่งทำให้การทำ Forward pass ของโมเดลมีแนวโน้มที่จะทำงานด้วยความเร็วเทียบเท่ากับสภาพแวดล้อมแบบคอนเทนเนอร์ กล่าวคือ ส่วนที่ได้รับประโยชน์จากการปรับปรุงนี้คือช่วง "ตั้งแต่เริ่มทำงานจนถึงเริ่มตอบสนอง" เป็นหลัก จึงควรทราบว่าเวลาในการโหลดโมเดลและเวลาในการถ่ายโอนค่าน้ำหนัก (Weights) ไปยังหน่วยความจำ GPU จะไม่ถูกลดทอนลง

ดังนั้น ในการดำเนินงานที่เปิดเครื่องทิ้งไว้ตลอดเวลาและมีการรักษา Warm pool ไว้ ความแตกต่างเมื่อเทียบกับคอนเทนเนอร์จึงมีแนวโน้มที่จะน้อยลง ในทางกลับกัน หากมีความผันผวนของความต้องการสูงและมีการทำ Scale-in/out บ่อยครั้ง คุณลักษณะการเริ่มต้นระบบของ Firecracker ก็ถือว่ามีส่วนช่วยในการปรับปรุงความหน่วงได้ดีกว่า ทั้งนี้ ผลลัพธ์ที่แท้จริงจะขึ้นอยู่กับสภาพแวดล้อมและภาระงาน (Workload) จึงจำเป็นต้องมีการตรวจสอบด้วยตนเองภายในองค์กร

ผู้เขียน・ผู้ตรวจสอบ

Yusuke Ishihara

Yusuke Ishihara

เริ่มเขียนโปรแกรมตั้งแต่อายุ 13 ปี ด้วย MSX หลังจบการศึกษาจากมหาวิทยาลัย Musashi ได้ทำงานพัฒนาระบบขนาดใหญ่ รวมถึงระบบหลักของสายการบิน และโครงสร้าง Windows Server Hosting/VPS แห่งแรกของญี่ปุ่น ร่วมก่อตั้ง Site Engine Inc. ในปี 2008 ก่อตั้ง Unimon Inc. ในปี 2010 และ Enison Inc. ในปี 2025 นำทีมพัฒนาระบบธุรกิจ การประมวลผลภาษาธรรมชาติ และแพลตฟอร์ม ปัจจุบันมุ่งเน้นการพัฒนาผลิตภัณฑ์และการส่งเสริม AI/DX โดยใช้ generative AI และ Large Language Models (LLM)