โมเดลเล็ก (โดยทั่วไป 0.5B-7B หรือต่ำกว่า 10B parameters) มี redundancy น้อยกว่าโมเดลใหญ่ ทำให้ quantization ลงไปที่ 4-bit หรือต่ำกว่ามักสูญเสียคุณภาพมากกว่า (โดยเฉพาะ reasoning และ knowledge tasks) ดังนั้นต้องเลือกเทคนิคอย่างระมัดระวัง
1. ประเภทหลักของ Quantization
| ประเภท | คำอธิบาย | เหมาะกับโมเดลเล็กไหม | ข้อดี / ข้อเสีย |
|---|---|---|---|
| Post-Training Quantization (PTQ) | Quantize หลังฝึกเสร็จ ไม่ต้อง train ใหม่ ใช้ calibration data เล็กน้อย | ใช้ได้ดี แต่ต้องระวังที่ ≤4-bit | เร็ว ง่าย ต้นทุนต่ำ / คุณภาพลดลงมากกว่าที่ bit ต่ำ |
| Quantization-Aware Training (QAT) | จำลอง quantization ระหว่าง training/fine-tuning | แนะนำมากสำหรับโมเดลเล็ก | คุณภาพดีกว่ามากที่ 4-bit หรือต่ำกว่า / ใช้ทรัพยากรมากกว่า |
สรุปสำหรับโมเดลเล็ก: ถ้าคุณภาพสำคัญ ควรใช้ QAT หรืออย่างน้อย PTQ ที่มีการ calibrate ดี (AWQ/GPTQ) อย่าใช้ naive rounding
2. เทคนิค PTQ ที่นิยมใช้กับโมเดลเล็กปี 2026
A. Weight-only Quantization (W4A16 หรือ W8A16)
AWQ (Activation-aware Weight Quantization) - ปกป้อง channel ที่สำคัญโดยดูจาก activation magnitude มักให้คุณภาพดีที่สุดในกลุ่ม PTQ 4-bit แนะนำสำหรับ GPU serving (ใช้กับ Marlin/Machete kernel)
GPTQ - ใช้ Hessian-based error compensation ทีละ layer เสถียรและมี checkpoint พร้อมใช้เยอะ คุณภาพใกล้เคียง AWQ แต่บางงาน (เช่น coding) อาจด้อยกว่าเล็กน้อย
bitsandbytes NF4 - ออกแบบมาเพื่อ QLoRA (fine-tuning) ใช้ได้สะดวกมาก (quantize ตอนโหลด) แต่ throughput ช้ากว่า AWQ/GPTQ สำหรับ inference
B. รูปแบบเฉพาะสำหรับ Edge / CPU / Mobile
GGUF (llama.cpp) - Q4_K_M หรือ Q5_K_M เป็นมาตรฐานชุมชน โดย Q5_K_M มักแนะนำสำหรับโมเดลเล็กเพราะรักษาคุณภาพได้ดีกว่า Q4 รองรับ CPU, Apple Silicon และ GPU หลากหลาย
MLX (Apple Silicon) - 4-bit native บน Mac ให้ประสิทธิภาพดีมาก
C. เทคนิคช่วยลด Outlier (สำคัญมากสำหรับโมเดลเล็ก)
- SmoothQuant - ย้ายปัญหา outlier จาก activation ไปที่ weight (เหมาะกับ W8A8)
- Rotation-based (SpinQuant, QuaRot, Hadamard) - กระจาย outlier ให้กระจายตัวดีขึ้น
- Group-wise / Block-wise scaling - ใช้ scale แยกตามกลุ่ม (group size 64 หรือ 128) เพื่อลดผลกระทบของ outlier
3. คำแนะนำตามขนาดโมเดลและเป้าหมาย
| ขนาดโมเดล | ความแม่นยำที่แนะนำ | เทคนิคที่เหมาะ | หมายเหตุ |
|---|---|---|---|
| 1B-3B | 5-6 bit หรือ INT8 | QAT + INT4, หรือ GGUF Q5_K_M / Q6 | 4-bit PTQ มักเสียคุณภาพชัดเจน |
| 3B-7B | 4-bit ที่ดี | AWQ หรือ GPTQ (group 128) + calibration ดี | ถ้ามี QAT version ให้เลือกอันนั้น |
| Edge / Mobile | INT8 หรือ W4A16 | AWQ W4A16, GGUF Q4/Q5, หรือ QAT INT4 | หลีกเลี่ยง quantize embedding layer ถ้าเป็นไปได้ |
4. Best Practices สำหรับโมเดลเล็ก
- อย่า quantize aggressive เกินไป - โมเดลเล็กมี "ความซ้ำซ้อน" น้อย 4-bit PTQ อาจสูญเสีย 5-10% คุณภาพ (เทียบกับโมเดลใหญ่ที่เสียแค่ 1-2%)
- ใช้ Calibration Data ที่ดี - ควรใช้ข้อมูลที่ใกล้เคียงกับ workload จริง (ไม่ใช่แค่ WikiText)
- Mixed Precision - เก็บ layer ที่ sensitive (เช่น embedding, lm_head, หรือบาง attention) ไว้ที่ precision สูงกว่า
- ทดสอบบน task จริง - Perplexity อย่างเดียวไม่พอ ควรดู reasoning, coding หรือ domain-specific metrics
- ถ้าทำได้ ให้ใช้ QAT - โดยเฉพาะถ้าเป็นโมเดลที่คุณ fine-tune เอง QAT จะช่วยให้ 4-bit ใกล้เคียง INT8 มากขึ้น
5. เครื่องมือที่ใช้งานจริงปี 2026
- GPU Serving: vLLM + AWQ/GPTQ (Marlin kernel), TensorRT-LLM, SGLang
- Local / Edge: llama.cpp (GGUF), Ollama, MLX, ExecuTorch / LiteRT (mobile)
- Fine-tuning: bitsandbytes NF4 + QLoRA
- สร้าง Quantized Checkpoint: AutoAWQ, AutoGPTQ, LLM Compressor, Olive
สรุปสั้น ๆ
- เริ่มจาก AWQ หรือ GPTQ 4-bit ถ้าต้องการความเร็วและ memory
- ถ้าคุณภาพสำคัญ ไปทาง QAT หรือใช้ Q5/Q6 ใน GGUF
- หลีกเลี่ยง sub-4-bit เว้นแต่จำเป็นจริง ๆ
วิธีทำ AWQ ทีละขั้นตอน (ด้วย AutoAWQ)
หมายเหตุ: AutoAWQ (casper-hansen) ถูก archive ไปแล้วกลางปี 2025 แต่ยังใช้งานได้ดี และ vLLM แนะนำให้ใช้ llm-compressor เป็นทางเลือกใหม่ โค้ดด้านล่างยังใช้ได้กับ AutoAWQ เวอร์ชันสุดท้าย
ขั้นตอนที่ 1: ติดตั้ง
pip install autoawq autoawq-kernels
# หรือถ้าใช้ llm-compressor (แนะนำสำหรับอนาคต)
# pip install llmcompressor
ขั้นตอนที่ 2: เขียนสคริปต์ Quantize
from awq import AutoAWQForCausalLM
from transformers import AutoTokenizer
model_path = "microsoft/Phi-3.5-mini-instruct" # หรือ Qwen/Qwen2.5-3B-Instruct, google/gemma-2-2b-it
quant_path = "Phi-3.5-mini-instruct-AWQ"
quant_config = {
"zero_point": True, # แนะนำเปิด (ดีกว่าสำหรับคุณภาพ)
"q_group_size": 128, # ค่ามาตรฐาน (ดูรายละเอียดด้านล่าง)
"w_bit": 4, # 4-bit
"version": "GEMM" # GEMM สำหรับ batch มากกว่า 1, GEMV สำหรับ batch=1
}
# โหลดโมเดล
model = AutoAWQForCausalLM.from_pretrained(
model_path,
low_cpu_mem_usage=True,
use_cache=False
)
tokenizer = AutoTokenizer.from_pretrained(model_path, trust_remote_code=True)
# Quantize (ใช้ calibration data อัตโนมัติจาก pileval หรือ C4)
model.quantize(
tokenizer,
quant_config=quant_config,
max_calib_samples=128, # 128 ตัวอย่างเพียงพอ
max_calib_seq_len=512 # หรือ 2048 ถ้าอยากละเอียด
)
# บันทึก
model.save_quantized(quant_path)
tokenizer.save_pretrained(quant_path)
print(f"Saved to {quant_path}")
ขั้นตอนที่ 3: โหลดและใช้งาน
from awq import AutoAWQForCausalLM
from transformers import AutoTokenizer
model = AutoAWQForCausalLM.from_quantized(
"Phi-3.5-mini-instruct-AWQ",
fuse_layers=True, # เพิ่มความเร็ว
device_map="auto"
)
tokenizer = AutoTokenizer.from_pretrained("Phi-3.5-mini-instruct-AWQ")
หรือใช้กับ vLLM:
vllm serve Phi-3.5-mini-instruct-AWQ --quantization awq
เวลาที่ใช้โดยประมาณ: โมเดล 3B-7B ใช้ 5-15 นาทีบน RTX 4090 / A100 และต้องการ GPU ที่มี VRAM พอโหลดโมเดล FP16 ได้ชั่วขณะ
การตั้งค่า Group Size (q_group_size)
Group size คือจำนวน weights ที่แชร์ scale และ zero-point เดียวกัน
| Group Size | คุณภาพ | ขนาดไฟล์ / Metadata | คำแนะนำ |
|---|---|---|---|
| 128 (มาตรฐาน) | ดีที่สุดโดยรวม | ปกติ | ใช้ค่านี้เป็นค่าเริ่มต้น เกือบทุกโมเดล |
| 64 | ดีขึ้นเล็กน้อยในบางโมเดล | ใหญ่ขึ้นเล็กน้อย | ใช้เมื่อโมเดลเล็กมาก หรือต้องการคุณภาพสูงสุด (เช่น Falcon บางตัวบังคับ 64) |
| 32 | ดีขึ้นอีกนิด | ใหญ่ขึ้นชัดเจน | ใช้เฉพาะ layer ที่ sensitive หรือทดลอง |
| None / Per-channel | ดีที่สุด | ใหญ่ที่สุด | ไม่ค่อยใช้ใน practice เพราะ overhead สูง |
คำแนะนำสำหรับโมเดลเล็ก (1B-7B): เริ่มที่ 128 เสมอ ถ้าคุณภาพลดลงมาก (โดยเฉพาะ reasoning) ให้ลอง 64 และอย่าใช้ group size ที่ไม่ตรงกับที่ quantize ไว้ตอนโหลด (จะได้ผลลัพธ์เพี้ยน)
เปรียบเทียบผลบนโมเดลเล็ก (Phi / Gemma / Qwen)
จากข้อมูลปี 2025-2026 (benchmark หลายแหล่ง):
| โมเดล | ขนาด | AWQ 4-bit (group 128) | GPTQ 4-bit | GGUF Q4_K_M | หมายเหตุ |
|---|---|---|---|---|---|
| Phi-3.5-mini / Phi-4-mini | ~3.8B | คุณภาพดีมาก ใกล้ FP16 | ใกล้เคียง AWQ | ดี | Phi ทน quantization ได้ดีเพราะฝึกด้วย synthetic data คุณภาพสูง |
| Gemma-2-2B / Gemma-2-9B | 2B / 9B | AWQ มักดีกว่า GPTQ เล็กน้อย | ดี | ดีมาก (โดยเฉพาะ Q5) | โมเดลเล็กมาก (2B) แนะนำพิจารณา Q5 หรือ INT8 ถ้าคุณภาพสำคัญ |
| Qwen2.5-3B / Qwen2.5-7B | 3B / 7B | AWQ แข็งแรง โดยเฉพาะ coding | ใกล้เคียง | ดี | Qwen มักได้ผลดีกับ AWQ |
แนวโน้มทั่วไปสำหรับโมเดลเล็ก:
- โมเดลต่ำกว่า 7B 4-bit PTQ (AWQ/GPTQ) มักเสียคุณภาพ 5-10% บน reasoning/coding (มากกว่าโมเดลใหญ่ที่เสียแค่ 1-2%)
- AWQ มักชนะ GPTQ เล็กน้อยในด้านคุณภาพโดยรวม (โดยเฉพาะ perplexity และ MMLU)
- บน HumanEval (coding) AWQ มักรักษาคุณภาพได้ดีกว่า GPTQ
- ถ้าคุณภาพสำคัญมาก ใช้ Q5_K_M (GGUF) หรือ QAT แทน 4-bit PTQ
ตัวอย่างขนาดหลัง Quantize (โดยประมาณ):
- Phi-3.5-mini FP16 ≈ 7.6 GB → AWQ 4-bit ≈ 2.1-2.5 GB
- Qwen2.5-3B FP16 ≈ 6 GB → AWQ 4-bit ≈ 1.8-2.2 GB
- Gemma-2-2B FP16 ≈ 4-5 GB → AWQ 4-bit ≈ 1.3-1.6 GB
คำแนะนำสรุปสำหรับโมเดลเล็ก
- ใช้ group_size = 128 เป็นค่าเริ่มต้น
- Calibration data ควรใกล้เคียงกับงานจริง (ถ้าเป็นไปได้)
- ทดสอบทั้ง perplexity + task จริง (HumanEval, GSM8K, domain ของคุณ)
- ถ้าโมเดลเล็กมาก (ต่ำกว่า 3B) และคุณภาพสำคัญ ให้ลอง Q5 หรือ INT8 ก่อน
- สำหรับ production GPU ให้ใช้ AWQ + Marlin kernel ใน vLLM ซึ่งให้ throughput สูงสุด
ทีม Devsign ช่วยเลือกและ deploy โมเดล AI ให้เหมาะกับฮาร์ดแวร์ขององค์กร ทั้ง GPU serving และ Edge device พร้อมวัดคุณภาพและ throughput จริงก่อนขึ้น production