Lensa ML

Quantization

Langkah 1 dari 6: Kenapa Model Tidak Muat

Bit per weight menentukan tagihan memori

Bit per weight16 bit (fp16)
Weight model chat 7B dibanding dua ukuran memori GPU24 GB GPU sisa 10.5 GB13.5 GB80 GB GPU sisa 66.5 GB13.5 GB0204060806.74B weight × 2 byte = 13.5 GB
Memori weight
13.5 GB
Muat di 24 GB
Ya
Lebih kecil dari fp32
2×

Half precision memangkas weight menjadi separuhnya, yaitu 13,5 GB. Ini muat di kartu 24 GB dengan sisa 10,5 GB untuk KV cache. Format ini lazim untuk serving dan menjadi titik awal quantization.

Geser Bit per weight melewati 32, 16, 8, dan 4, lalu lihat batang weight terhadap dua garis GPU. Aturannya: memori = parameter × bit ÷ 8, jadi 6,74 miliar weight pada 4 bit menjadi sekitar 3,4 miliar byte. Label GB di sini memakai gigabyte desimal (10^9 byte). KV cache menambah lebih banyak lagi: sekitar 0,5 MB per token dalam fp16, jadi satu percakapan 4.096 token memakan 2,1 GB. File 4-bit sungguhan juga sedikit lebih besar dari batangnya, karena tiap grup weight menyimpan satu scale.

Langkah 2 dari 6: Format Angka

fp32, fp16, bf16, int8, dan int4 bit demi bit

Nilai yang disimpan (skala log)0.1
signexponentmantissaintegerfp3200111101110011001100110011001101fp1600101110011001101+5+10, maks 65504bf1600111101110011011+8+7, maks 3.39e+38int8256 level, -128 sampai 127int416 level, -8 sampai 7FormatNilai tersimpanHasilfp320.100000001dibulatkanfp160.0999755859dibulatkanbf160.100097656dibulatkan
Error relatif fp32
1.5e-8
Error relatif fp16
2.4e-4
Error relatif bf16
9.8e-4

Dalam jangkauan fp16, kedua format 16-bit membulatkan ke titik kisi terdekat. fp16 memakai 10 bit untuk mantissa dengan error 2,4e-4; bf16 memakai 7 bit dengan error 9,8e-4. Integer sama sekali tidak punya exponent, jadi int8 dan int4 butuh scale terpisah.

Geser Nilai yang disimpan, atau klik preset, lalu baca bit yang ditulis tiap format float. Float normal berarti (−1)^s × 1.m × 2^(e − bias), dengan bias 127 untuk fp32 dan bf16 serta 15 untuk fp16. Lebar mantissa menentukan jarak relatif antartetangga: 2^−10 ≈ 0,1% untuk fp16 dan 2^−7 ≈ 0,8% untuk bf16, dan pembulatan meleset paling banyak setengahnya. bf16 adalah separuh atas bilangan fp32, dirancang di Google untuk training di TPU. Itu sebabnya konversi fp32 ke bf16 hanya membuang bit mantissa.

Langkah 3 dari 6: Dari Float ke Integer

Absmax scaling dan pembulatan

Bitint4
64 weight sintetis dengan 15 level int4 (garis oranye)−0.0520+0.052Tiap weight: asli (titik abu-abu) dan hasil dequantize q × scale (tanda oranye)+0−
Scale
0.0074
Level
15
Rata-rata error mutlak
0.0019
Error maks
0.0037

int4 memberi 15 level dan memakai 12 di antaranya. Pembulatan menggeser tiap weight paling jauh setengah langkah, scale ÷ 2 = 0.0037. Weight terburuk di sini memakai 99% dari batas itu.

Geser Bit dari 2 sampai 8, lalu bandingkan rata-rata error dengan scale. Rounding error hampir seragam dalam setengah langkah, jadi rata-rata error berada di sekitar scale ÷ 4: pada int4, scale bernilai 0,0074 dan rata-rata error 0,0019. Symmetric absmax membuang satu kode: int8 bisa menyimpan −128, tetapi aturan ini tidak pernah menghasilkannya. Asymmetric quantization menambahkan zero point, q = round(w ÷ s) + z, sehingga rentang 0 sampai 6 sesudah ReLU memakai setiap level. Weight hampir simetris, jadi jarang butuh zero point.

Langkah 4 dari 6: Masalah Outlier

Satu weight besar memboroskan level

Ukuran outlier (× maks biasa)8.0×
Ukuran grup16 weight
Per-tensor: satu scale untuk semua 64 weight (int4)outlier 8.0× (di luar skala)Per-group: satu scale per 16 weight (int4)outlier 8.0× (di luar skala)
Error per-tensor
0.0123
Error per-group
0.0036
Overhead scale
+1 bit
Level terpakai (per-tensor)
3 dari 15

Outlier 8,0× meregangkan scale per-tensor, sehingga 63 weight lainnya menumpuk di 3 level. Scaling per-group membatasi kerusakan pada grup outlier itu yang berisi 16 weight dan memangkas error 3,4×, dengan biaya 1 bit tambahan per weight.

Geser Ukuran outlier ke 20× dan naikkan Ukuran grup dari 8 sampai 64 untuk melihat titik saat error per-group menyusul per-tensor. Dettmers dkk. menemukan bahwa transformer di atas sekitar 6,7 miliar parameter memunculkan beberapa hidden dimension dengan aktivasi jauh lebih besar dari yang lain. LLM.int8() mempertahankan dimensi itu dalam fp16 dan mengalikan sisanya dalam int8. Metode weight-only mengambil jalur grup. GPTQ dan AWQ biasanya memakai grup berisi 128, dan satu scale fp16 di sana berbiaya 16 ÷ 128 = 0.125 bit tambahan per weight.

Langkah 5 dari 6: Weight vs Aktivasi

int4 weight-only dibanding W8A8

Batch size (sequence yang di-decode bersamaan)1
W4A16: int4 weight-onlyweight int4dequantize ke fp16matmul fp16 × fp16 (x fp16)W8A8: weight dan aktivasi dalam int8weight int8matmul int8 × int8 ke jumlah int32Waktu per langkah decode pada batch 1 di GPU ilustratiffp16memory-bound6.74 ms0.04 msW4A16memory-bound1.69 ms0.04 msW8A8memory-bound3.37 ms0.02 msbaca weight: byte ÷ 2 TB/shitung: 2 × param × batch ÷ puncak
Langkah fp16
6.74 ms
Langkah W4A16
1.69 ms
Langkah W8A8
3.37 ms
Token/s, tercepat
593

Pada batch 1, tiap langkah membaca seluruh 6,74B weight untuk hitungan yang sangat sedikit, jadi waktunya mengikuti jumlah byte. Weight int4 membaca 4× lebih sedikit byte dibanding fp16, dan W4A16 butuh 1,69 ms dibanding 6,74 ms.

Geser Batch size dari 1 sampai 512 dan lihat tiap skema beralih dari memory-bound ke compute-bound. Peralihan terjadi saat arithmetic intensity, yaitu FLOP per byte yang dibaca, mencapai puncak GPU ÷ bandwidth, yaitu 156 untuk hitungan fp16 di GPU ini. Pada decode fp16, intensity sama dengan batch size, karena tiap weight 2 byte mengerjakan 2 FLOP per sequence. Prefill memproses seluruh prompt sekaligus, jadi tetap compute-bound meski hanya untuk satu pengguna. Batang di sini mengabaikan pembacaan KV cache. W8A8 juga perlu menangani outlier aktivasi, seperti yang dilakukan SmoothQuant dengan memindahkan scale-nya ke weight.

Langkah 6 dari 6: Akurasi vs Ukuran

Error output pada layer yang di-quantize

Bitint4
Ukuran grup32 weight
per-tensorper-group, g = 320.1%1%10%100%2345678bit per weight · sumbu y: ‖y − ŷ‖ / ‖y‖ (log)
Error per-tensor
42.4%
Error per-group
14.7%
Bit per weight
4.5
Weight 7B
3.8 GB

Pada int4, scaling per-group memberi error output 14,7% dibanding 42,4% per-tensor. Pembulatan biasa masih banyak kehilangan di sini; GPTQ, AWQ, dan NF4 mencapai model 4-bit yang layak pakai dengan menyesuaikan pembulatan pada data kalibrasi atau memakai kisi yang lebih baik.

Atur Bit ke 4, lalu ubah Ukuran grup dan bandingkan error dengan readout bit per weight. Pembulatan biasa memperlakukan semua weight sama, sedangkan metode yang dipakai dalam praktik tidak. GPTQ meng-quantize satu kolom demi satu kolom dan menyesuaikan kolom sisanya untuk menutup error, memakai statistik orde kedua dari calibration set kecil; metode ini meng-quantize model 175 miliar parameter dalam sekitar empat jam GPU. AWQ mencari sekitar 1% weight channel yang melihat aktivasi besar dan memperbesarnya sebelum pembulatan. NF4 menempatkan 16 level-nya pada kuantil distribusi normal.

Apa itu quantization dalam machine learning?

Quantization menyimpan angka di dalam model dengan lebih sedikit bit, misalnya integer 8-bit atau 4-bit, bukan float 16-bit. Setiap blok weight punya satu scale, dan tiap weight disimpan sebagai integer kecil yang dikalikan dengan scale itu saat model berjalan. Ukuran model menjadi 2 sampai 4 kali lebih kecil dari fp16, dengan rounding error kecil yang terkendali.

Dengan quantization, large language model bisa berjalan di satu GPU, laptop, atau ponsel. Sistem serving memuat versi 4-bit atau 8-bit dari model terbuka supaya satu kartu bisa melayani lebih banyak request, dan alat lokal seperti llama.cpp menyediakan hampir semua model dalam versi quantized. Karena decode satu token demi satu token dibatasi memory bandwidth, weight yang lebih kecil juga mempercepat pembuatan teks. QLoRA juga melakukan fine-tuning di atas basis 4-bit yang dibekukan.

Ide utama

  • Memori weight = parameter × bit ÷ 8, jadi perpindahan dari fp16 ke int4 memangkasnya 4×.
  • Float menukar jangkauan dengan presisi lewat pembagian exponent dan mantissa; bf16 mempertahankan jangkauan fp32 dengan presisi lebih rendah.
  • Absmax quantization memetakan weight terbesar ke level integer teratas dan membulatkan sisanya ke kisi seragam.
  • Satu outlier meregangkan scale untuk semua weight yang memakainya bersama, jadi scale per-group melindungi sisanya dengan biaya penyimpanan kecil.
  • Quantization weight-only mempercepat decode yang memory-bound, sedangkan W8A8 juga mempercepat kerja yang compute-bound.
  • Metode seperti GPTQ, AWQ, dan NF4 menjaga model 4-bit tetap dekat dengan presisi penuh, di titik saat pembulatan biasa tidak cukup.

Pertanyaan umum

Berapa memori yang dibutuhkan model quantized?

Kalikan jumlah parameter dengan bit per weight, lalu bagi 8 untuk mendapat byte. Model 7B memakan sekitar 14 GB dalam fp16, 7 GB dalam int8, dan 3,5 GB dalam int4. Scale per grup sedikit menambah: satu scale 16-bit per 128 weight berbiaya 0,125 bit tambahan per weight. KV cache dan aktivasi butuh memori di luar weight.

Apakah bf16 termasuk quantization?

Konversi weight fp32 ke bf16 memangkas memorinya separuh, dan sebagian alat menyebutnya quantization. Namun, dalam sebagian besar tulisan tentang LLM, quantization berarti menyimpan weight sebagai integer 8-bit atau lebih kecil dengan scale per grup. bf16 adalah float 16-bit dengan jangkauan exponent fp32, jadi tidak butuh scale; model biasanya di-train dalam bf16, lalu di-quantize dari sana.

Apa bedanya post-training quantization dan quantization-aware training?

Post-training quantization (PTQ) mengonversi model yang sudah jadi, terkadang dengan beberapa ratus sampel kalibrasi, dan butuh waktu beberapa menit sampai beberapa jam. Quantization-aware training (QAT) menyimulasikan pembulatan selama training supaya weight menyesuaikan diri. QAT biasanya lebih tahan pada bit width yang sangat rendah, tetapi butuh training pipeline dan komputasi jauh lebih besar, jadi sebagian besar rilis LLM memakai PTQ.

Berapa akurasi yang hilang pada quantization 4-bit?

Dengan metode yang baik seperti GPTQ atau AWQ, model 4-bit weight-only biasanya hanya sedikit memburuk pada perplexity dan skornya mendekati fp16 pada sebagian besar benchmark. Weight 8-bit nyaris tanpa kehilangan. Di bawah 4 bit, kualitas turun lebih cepat, dan model kecil lebih terpukul daripada model besar karena tiap weight membawa lebih banyak pengetahuan model.

Apa arti nama GGUF seperti Q4_K_M?

GGUF adalah format file model yang dipakai llama.cpp. Q4 berarti sekitar 4 bit per weight, K menandai keluarga k-quant, yang menyimpan blok kecil weight dengan scale sendiri di dalam super-block yang lebih besar, dan M adalah campuran sedang yang mempertahankan sebagian tensor sensitif pada presisi lebih tinggi. Rata-rata sebenarnya sedikit di atas jumlah bit nominalnya.

Bisakah model quantized di-fine-tune?

Tidak secara langsung, karena pembulatan ke beberapa level saja menghapus gradient update yang kecil. QLoRA mengatasinya dengan membekukan basis NF4 4-bit dan melatih adapter LoRA dalam presisi 16-bit di atasnya. Basis itu di-dequantize langsung di setiap forward pass dan backward pass, sehingga model 65B bisa di-fine-tune di satu GPU 48 GB.

Penjelasan terkait

Referensi

  1. Frantar et al. (2022), "GPTQ: Accurate Post-Training Quantization for Generative Pre-trained Transformers"
  2. Lin et al. (2023), "AWQ: Activation-aware Weight Quantization for LLM Compression and Acceleration"
  3. Dettmers et al. (2023), "QLoRA: Efficient Finetuning of Quantized LLMs"
  4. Dettmers et al. (2022), "LLM.int8(): 8-bit Matrix Multiplication for Transformers at Scale"
  5. Nagel et al. (2021), "A White Paper on Neural Network Quantization"

Terakhir diperbarui