4.3 Weight-only INT4
Hiểu lưu trữ và tính toán W4A16, bù sai số bậc hai của GPTQ, scale theo activation của AWQ, và Marlin biến lưu trữ INT4 thành lợi ích suy luận thế nào
W8A8 ở mục 4.2 phải xử lý đồng thời weight và activation. Mục này đi đường khác: giữ activation ở FP16/BF16 và chỉ nén weight xuống 4-bit, tức W4A16. Ở pha decode mỗi bước đọc lại toàn bộ bộ weight từ bộ nhớ GPU. Thu nhỏ weight còn một phần tư thì thời gian đọc cũng thu theo. Cái khó là 4-bit chỉ có 16 mã, và khoảng cách tick khoảng 17× so với 8-bit (mục 4.1), nên cần cách giữ sai số đừng làm hỏng đầu ra quá nhiều.
GPTQ và AWQ là hai cách sửa chính: cái trước giống chỉnh các mảnh còn lại mỗi lần đặt một mảnh puzzle; cái sau tìm các mảnh quan trọng nhất trước rồi bảo vệ chúng. Marlin rồi giúp GPU đọc và tính các weight 4-bit đó hiệu quả.
⏰ Độ mới của thông tin: Phần thuật toán theo từng bài báo tương ứng. Chọn kernel và gợi ý toolchain của vLLM dựa trên vLLM v0.32.0 (phát hành 2026-10-18).
📑 Mục lục
- 1. Lưu trữ và tính toán W4A16
- 2. GPTQ: lượng tử hóa rồi bù dần
- 3. AWQ: tìm kênh cần bảo vệ từ activation
- 4. Marlin: đừng để unpack làm chậm tính toán
- 5. So sánh GPTQ và AWQ thế nào
- Tóm tắt
- Danh sách tự kiểm
- Tài liệu tham khảo
1. Lưu trữ và tính toán W4A16
Weight INT4 nằm trong bộ nhớ GPU theo kiểu đóng gói: một từ 32-bit chứa tám mã 4-bit, cộng thêm một Scale mỗi nhóm, và các scheme bất đối xứng còn lưu zero-point. Lúc suy luận kernel đọc các mã, dequantize trên chip thành FP16/BF16, rồi nhân với activation 16-bit.
Vậy khi thấy “mô hình INT4”, hãy tách hai thứ: kiểu lưu trữ của weight là INT4; kiểu đầu vào của lệnh nhân vẫn là 16-bit. Đường này tiết kiệm băng thông đọc weight, không tiết kiệm tính toán nhân.
Bên trái hình dưới là một nhóm weight trong bộ nhớ (xanh = mã INT4, vàng = Scale FP16, ô trắng = zero-point chỉ với scheme bất đối xứng). Bên phải là kernel khôi phục chúng trên chip thành weight FP16 (xanh lá) rồi nhân với activation 16-bit (đỏ):
Các tham số nhóm cũng chiếm chỗ. Khi mỗi 128 weight INT4 chia sẻ một Scale FP16, trung bình mỗi weight là:
Thêm zero-point và căn chỉnh thì còn lớn hơn một chút. Tiết kiệm được bao nhiêu thời gian phụ thuộc unpack và dequantize có gộp với nhân ma trận trong một kernel hay không, và phần còn lại của bước còn bao nhiêu đọc KV, Attention, v.v.
2. GPTQ: lượng tử hóa rồi bù dần
2.1 Hàm mục tiêu phải gồm cả đầu vào
Nếu chỉ cực tiểu , sai số mỗi weight được chấm ngang nhau. Sau lớp tuyến tính, có sai số bị đầu vào phóng đại và có sai số triệt tiêu. GPTQ dùng đầu vào calibration và đổi mục tiêu sang sai số tái tạo trên đầu ra lớp:
Lấy một cột weight kênh đầu ra , và viết :
mô tả, dưới đầu vào thực, sai số theo mỗi hướng đắt bao nhiêu và các kênh đầu vào tương quan thế nào. Nó chỉ đến từ mục tiêu tái tạo của đúng một lớp tuyến tính đó; bạn không cần Hessian của toàn bộ loss mô hình ngôn ngữ.
2.2 Trực giác bù sai số
Khi một mảnh puzzle lệch, bạn có thể chỉnh nhẹ các mảnh lân cận còn tự do để bù. GPTQ cũng vậy: mỗi lần cố định một weight, bạn trải sai số của nó sang các weight chưa lượng tử hóa.
Lấy ví dụ 2 chiều. Nếu hai cột của đầu vào calibration gần như giống nhau, đầu ra chủ yếu phụ thuộc . Lượng tử hóa thành 0.30 vượt 0.04; trong lúc còn tự do, trừ 0.04 khỏi nó thì đầu ra hầu như không đổi. Khi hai cột không hoàn toàn giống nhau, mức bù do quyết, không phải cộng trừ đơn giản.
Gọi là tập chỉ số các weight chưa cố định, và là ma trận con tương ứng. Sau khi cố định thành giá trị đã lượng tử hóa , bù tối ưu là:
Phần tử thứ biến đúng thành ; phần còn lại là chỉnh cho các weight còn lại. là giá trị đã dequantize cùng thang với weight gốc, không phải mã nguyên. Bản triển khai chính thức còn thêm damping để ổn định số học và dùng phân tích Cholesky kèm cập nhật theo khối để giảm chi phí.
Đừng lẫn hai con “128”: update block size quyết bao nhiêu cột bạn xử lý một lần và tần suất lan truyền sai số theo batch; Group Size quyết bao nhiêu weight chia sẻ một Scale.
2.3 Chi phí và hiệu quả
Bài báo báo cáo GPTQ mất khoảng 4 GPU-giờ để lượng tử hóa một mô hình GPT 175B tham số, rằng mất độ chính xác không đáng kể khi xuống 3–4 bit, và đó là lần đầu một mô hình 175B chạy được trên một GPU duy nhất. Lượng tử hóa là chi phí offline một lần; suy luận không còn cần .
3. AWQ: tìm kênh cần bảo vệ từ activation
3.1 Weight lớn chưa chắc quan trọng nhất
Với , sai số weight đánh vào đầu ra thành . Mức quan trọng của một weight phụ thuộc activation nhân với nó lớn bao nhiêu, không phụ thuộc bản thân weight lớn bao nhiêu.
Bài AWQ nêu hai điểm: chỉ bảo vệ 1% weight nổi bật đã cắt sai số lượng tử hóa rất nhiều; và bạn nên tìm các kênh nổi bật đó từ phân phối activation, không phải từ weight.
3.2 Dùng scale thay vì mixed precision
Cách bảo vệ thẳng nhất là giữ 1% đó ở FP16, nhưng layout lưu trữ mixed-precision khó với kernel. AWQ dùng scale thay thế: trước lượng tử hóa, phóng đại weight kênh nổi bật bằng và chia đầu vào tương ứng cho . Dùng lại ký hiệu ở mục 4.2:
sinh mã low-bit; dequantize bằng Scale và zero-point. Sau phóng đại, miễn là khoảng cách tick lượng tử hóa của nhóm không tăng cùng hệ số, chia lại cho để lại sai số hiệu dụng nhỏ hơn trên kênh đó. Phóng quá mạnh thì mở rộng cả dải của nhóm, làm hại các weight khác trong nhóm, nên AWQ tìm hệ số scale trên dữ liệu calibration và ghép với clipping để kiểm soát tổng sai số.
Thứ bạn triển khai vẫn là layout INT4 thông thường, không lưu riêng weight FP16, nên kernel hiệu quả hỗ trợ dễ. TinyChat đi kèm bài báo nhanh hơn Hugging Face FP16 hơn 3× trên GPU desktop và mobile.
3.3 So với SmoothQuant
Cả hai đều dùng scale theo cặp, nhưng mục tiêu khác:
| 📊 Phương pháp | Xử lý gì | Hướng scale | Cấu hình điển hình |
|---|---|---|---|
| SmoothQuant | Outlier activation khiến activation INT8 khó | Làm phẳng activation; đẩy độ khó sang weight | INT8 W8A8 |
| AWQ | Sai số weight kênh nổi bật bị activation lớn phóng đại | Phóng đại weight nổi bật; cắt sai số tương đối của chúng | INT4 W4A16 |
Riêng bước tìm scale của AWQ vẫn để lại weight số thực; bạn vẫn phải lượng tử hóa và đóng gói sau. Khi so phương pháp, hãy tách ba sản phẩm trung gian: weight số thực đã scale, weight số thực Fake-Quant (QDQ), và weight đóng gói triển khai thật.
4. Marlin: đừng để unpack làm chậm tính toán
Khi mã đã sẵn, vẫn còn một bài kỹ thuật. Đường ngây thơ bung toàn bộ INT4 của lớp thành FP16, ghi lại bộ nhớ GPU, rồi gọi GEMM thường. Việc đó thêm một vòng đọc/ghi lớn và trả lại hết băng thông vừa tiết kiệm.
Marlin đưa đọc weight, unpack, dequantize và nhân ma trận vào một pipeline kernel. Bên trái hình là đường ngây thơ, nơi weight FP16 đã bung (xanh lá) ghi lại bộ nhớ rồi bị đọc lại; bên phải là Marlin, nơi chuyển dữ liệu xanh và tính trên chip vàng lệch nhau một tile và chạy cùng lúc:
Weight được sắp sẵn theo layout hợp đọc lúc chạy, rồi tiling và đệm nhiều tầng từ module 2 chồng chuyển dữ liệu với tính toán. Bài báo báo cáo gần trần tăng tốc lý thuyết 4× với batch 16–32, vẫn còn lợi rõ ở 64–128 khi tốc độ tăng thu hẹp, và tới khoảng 2.8× end-to-end khi gắn vào backend vLLM.
Khi batch đủ lớn, tính toán lại thành bottleneck và lợi thế đọc ít weight bị pha loãng. Điều đó khớp phân tích Roofline ở chương 1.
4.1 Chọn kernel trong vLLM
Trong vLLM v0.32.0, tên phương pháp lượng tử hóa và kernel đã tách:
--quantizationđặtawq,awq_marlin, hoặcauto_awqđều resolve về cùng cấu hìnhauto_awq; GPTQ vớigptq,gptq_marlin, vàauto_gptqcũng vậy. Để trống thì vLLM tự nhận từquant_methodtrong checkpoint.- Kernel nào thực sự chạy do vLLM kiểm các ứng viên theo thứ tự ưu tiên cho lớp hiện tại. Trên CUDA, các ứng viên weight INT4 W4A16 chính theo thứ tự là Machete (chỉ Hopper, compute capability 9.0), Marlin (Turing trở lên), Conch, Exllama, Triton, v.v. Cái đầu tiên vượt kiểm thắng.
- Log khởi động in dòng kiểu
Using MarlinLinearKernel for AutoAWQMarlinLinearMethod. Khi một lớp AWQ không đủ điều kiện, bạn thấy “Falling back to unoptimized AWQ kernels”. - Để loại một kernel khi so sánh, dùng biến môi trường
VLLM_DISABLED_KERNELS.
GPTQ/AWQ quyết sai số của encoding; kernel quyết encoding đó chạy nhanh bao nhiêu. Muốn biết đường nào bạn thực sự đi, đọc log khởi động. Đừng chỉ nhìn tên mô hình.
5. So sánh GPTQ và AWQ thế nào
5.1 Tách bốn chiều trước
Một chuỗi kiểu “GPTQ, INT4 W4A16, Group Size 128, Marlin” trả lời bốn câu khác nhau:
| 📊 Chiều | Ví dụ | Trả lời gì |
|---|---|---|
| Thuật toán lượng tử hóa | GPTQ hoặc AWQ | Sai số lượng tử hóa được kiểm soát thế nào |
| Định dạng và độ rộng bit | INT4 W4A16 | Weight được mã hóa thế nào; activation giữ độ chính xác nào |
| Độ hạt lượng tử hóa | Group Size 128 | Bao nhiêu weight chia sẻ một nhóm Scale |
| Triển khai thực thi | Marlin, Machete | Các mã được đọc và tính thế nào |
W4A16 không khóa một thuật toán, và cùng một thuật toán có thể ghép với nhóm và kernel khác nhau.
Hình dưới đặt hai thuật toán cạnh nhau. Bên trái, GPTQ lượng tử hóa từng cột (xanh đặc = đã lượng tử hóa, xanh gạch chéo = cột hiện tại) và bù sai số sang các weight còn nổi bên phải (xanh lá). Bên phải, AWQ tìm kênh nổi bật từ độ lớn activation (đỏ đặc), phóng đại weight tương ứng, rồi lượng tử hóa cả nhóm. Cả hai đường cuối cùng xuất cùng một checkpoint INT4 thông thường:
Khi cả bốn đã cố định, mới so bản thân thuật toán:
| 📊 Chiều | GPTQ | AWQ |
|---|---|---|
| Dữ liệu calibration dùng để | Dựng ; đo sai số đầu ra lớp | Thu thập activation; tìm scale theo kênh |
| Đòn bẩy chính | Lượng tử hóa từng cột; bù các weight còn lại | Phóng đại kênh nổi bật; cắt sai số tương đối của chúng |
| Tính offline | Giải bài tái tạo mỗi lớp; cập nhật mọi weight | Tìm hệ số scale theo kênh; không viết lại weight từng cái |
| Tốc độ suy luận | Phụ thuộc layout xuất và kernel | Cũng phụ thuộc layout xuất và kernel |
“AWQ luôn nhanh hơn” và “GPTQ luôn chính xác hơn” đều thiếu tiền đề. So sánh công bằng ít nhất phải cố định mô hình gốc, độ rộng bit, Group Size, tập calibration, độ dài đầu vào và tải, rồi ghi kernel nào thực sự được nạp.
5.2 Lượng tử hóa bằng công cụ nào
- LLM Compressor: do dự án vLLM duy trì; hỗ trợ GPTQ, AWQ và SmoothQuant; xuất
compressed-tensorsmà vLLM nạp trực tiếp. Ví dụ INT4 W4A16 trong tài liệu vLLM dùngGPTQModifier(scheme="W4A16"). - GPTQModel: tập trung họ GPTQ; tài liệu ghi các mô hình tương thích có thể dùng kernel Marlin và Machete của vLLM.
- AutoAWQ: không còn được duy trì. Tài liệu vLLM khuyên chuyển sang AWQ trong LLM Compressor. Checkpoint AutoAWQ sẵn có vẫn nạp bình thường.
5.3 Thứ tự gỡ lỗi
- Xác nhận checkpoint: cấu hình lượng tử hóa có đủ không, và mô hình gốc cùng phiên bản có khớp không.
- Đọc log nạp: kernel nào thắng, và có fallback không.
- Kiểm chất lượng trước: đánh giá trên tập nhiệm vụ độc lập; đừng chọn vài đầu ra đẹp.
- Rồi mới đo hiệu năng: nhìn riêng decode batch nhỏ, batch lớn và prompt dài. Bộ nhớ lượng tử hóa giải phóng cũng có thể đổ vào concurrency cao hơn.
📝 Tóm tắt
- W4A16 chỉ nén weight. Lưu trữ là INT4; đầu vào nhân vẫn 16-bit. Thứ bạn tiết kiệm là băng thông đọc weight.
- GPTQ đo sai số đầu ra lớp bằng đầu vào calibration và, qua , bù sai số mỗi weight sang các weight chưa lượng tử hóa.
- AWQ tìm kênh nổi bật theo độ lớn activation và bảo vệ chúng bằng scale thay vì mixed precision, nên layout triển khai vẫn đều.
- Marlin gộp unpack, dequantize và nhân ma trận thành một pipeline. Batch nhỏ gần tăng tốc lý thuyết 4×; lợi ích thu hẹp khi batch lớn.
- Trong vLLM v0.32.0, alias phương pháp AWQ/GPTQ được thống nhất và kernel được chọn tự động theo ưu tiên. Tin log khởi động.
- Trước khi so GPTQ và AWQ, hãy cố định định dạng, độ hạt và kernel trước.
🎯 Danh sách tự kiểm
- Tính được dung lượng trung bình mỗi weight INT4 dưới Group Size 128 với Scale FP16
- Giải thích được vì sao gần đầu ra lớp hơn là chỉ nhìn sai số weight
- Minh họa được ý bù của GPTQ với hai kênh đầu vào tương quan cao
- Phân biệt được update block size của GPTQ với Group Size lượng tử hóa
- Giải thích được vì sao AWQ tìm kênh nổi bật từ activation chứ không từ weight, và vì sao dùng scale thay mixed precision
- Đối chiếu được hướng và mục đích của scale theo cặp ở AWQ và SmoothQuant
- Giải thích được vì sao tăng tốc của Marlin thu hẹp khi batch lớn
- Từ log khởi động vLLM, nói được mô hình INT4 thực sự dùng kernel nào
📚 Tài liệu tham khảo
- GPTQ: Accurate Post-Training Quantization for Generative Pre-trained Transformers (Frantar et al., 2022)
- GPTQ official code
- AWQ: Activation-aware Weight Quantization for LLM Compression and Acceleration (Lin et al., 2023)
- AWQ official code
- MARLIN: Mixed-Precision Auto-Regressive Parallel Inference on Large Language Models (Frantar et al., 2024)
- Marlin official code
- vLLM v0.32.0 — INT4 W4A16 (LLM Compressor)
- vLLM v0.32.0 — AutoAWQ
- vLLM v0.32.0 — GPTQModel
- vLLM v0.32.0 — linear-layer kernel selection source