Model Quantization
Model kuantizasyonu, modelleri küçültmek ve çıkarımı hızlandırmak için ağırlıkları ve aktivasyonları INT8 gibi daha düşük hassasiyetli biçimlerde saklar. Nasıl çalıştığını ve PTQ ile QAT arasındaki farkı öğren.
Model nicemleme, bir sinir ağının ağırlıklarını ve çoğu zaman aktivasyonlarını 32 bit kayan noktalı sayılardan (FP32), 16 bit kayan noktalı sayılar (FP16), 8 bit tam sayılar (INT8) veya 4 bit tam sayılar gibi daha düşük hassasiyetli biçimlere dönüştürür. Böylece her değeri depolamak ve taşımak için daha az bit gerekir; ayrıca tam sayı aritmetiği çoğu işlemcide daha hızlı çalışır ve daha az enerji tüketir. INT8 model, FP32 özgün modelinin dörtte biri boyutundadır. Bu sayede nesne algılama modelleri telefonlarda, kameralarda ve diğer uç yapay zekâ cihazlarında gerçek zamanlı çalışabilir; ayrıca büyük dil modelleri (LLMs) tek bir GPU üzerine sığabilir.
Niceleme Nasıl Çalışır#
Niceleme, gerçek sayılardan oluşan bir aralığı küçük bir tam sayı düzeyleri kümesine eşler. Yaygın afin yöntemde her kayan noktalı x bir tam sayı q = round(x / scale) + zero_point olarak saklanır ve x ≈ (q - zero_point) × scale olarak geri elde edilir. Ölçek, düzeyler arasındaki adım büyüklüğünü belirler; sıfır noktası ise 0 kayan noktalı değerinin tam bir tam sayıya eşlenmesini sağlar. INT8 için 256 düzey bulunur; bu nedenle aralık dikkatle seçilmelidir: çok geniş bir aralık, hiç karşılaşılmayan değerlere düzey harcar; çok dar bir aralık ise uç değerleri kırpar. Ağırlıklar önceden bilindiğinden aralıkları doğrudan eğitilmiş modelden alınır ve çoğu zaman her çıkış kanalı için ayrı hesaplanır. Aktivasyonlar girdiye bağlıdır; bu nedenle modelden temsili küçük bir görüntü veya metin örnekleri kümesi geçirilerek kalibrasyon sırasında aralıkları ölçülür.
import numpy as np
rng = np.random.default_rng(0)
weights = rng.normal(0, 0.05, size=1000).astype(np.float32)
# Affine INT8 quantization maps the observed float range onto 256 integer levels
scale = (weights.max() - weights.min()) / 255
zero_point = np.round(-128 - weights.min() / scale)
q = np.clip(np.round(weights / scale + zero_point), -128, 127).astype(np.int8)
# Dequantize to measure the rounding error the model has to tolerate
restored = (q.astype(np.float32) - zero_point) * scale
print(f"Size: {weights.nbytes} -> {q.nbytes} bytes")
print(f"Max error: {np.abs(weights - restored).max():.5f} (half a step: {scale / 2:.5f})")Size: 4000 -> 1000 bytes çıktısını verir ve en büyük hata 0.00068'dir; bu değer niceleme adımının yarısına eşittir. Ağırlıklar dörtte bir boyuta iner ve hiçbir değer özgün hâlinden yarım adımdan fazla sapmaz.
Eğitim Sonrası Niceleme ve Niceleme Farkındalıklı Eğitim#
- Eğitim sonrası niceleme (PTQ): Önceden eğitilmiş bir modeli dönüştürür ve aktivasyon aralıklarını belirlemek için küçük bir kalibrasyon kümesi kullanır. Dakikalar sürer ve bu örneklerin dışında eğitim verisi gerektirmez. Dinamik niceleme, çıkarım sırasında aktivasyon aralıklarını anlık hesaplayan bir PTQ çeşididir; yalnızca ağırlıkları niceleme ise aktivasyonları kayan noktalı biçimde bırakır.
- Niceleme farkındalıklı eğitim (QAT): İleri geçişte değerleri yuvarlayarak eğitim veya ince ayar sırasında nicelemeyi taklit eder; böylece ağırlıklar yuvarlamaya dayanmayı öğrenir. Ek eğitim maliyeti karşılığında PTQ'nun neden olduğu doğruluk kaybının çoğunu telafi eder.
Ekipler genellikle PTQ ile başlar ve yalnızca doğruluktaki düşüş çok fazlaysa QAT'ye geçer:
LLM'lerin kendine özgü yöntemleri vardır. GPTQ ve AWQ gibi yalnızca ağırlıkları niceleyen 4 bitlik yöntemler, aktivasyonları 16 bitte tutarken milyarlarca parametreyi sıkıştırır; GGUF biçimi, yerel çıkarım için niceleme uygulanmış modelleri saklar. Yeni GPU'lar FP8 gibi düşük hassasiyetli kayan noktalı biçimlerde yerel hesaplama yapar.
Niceleme ve İlişkili Teknikler#
- Karma hassasiyet: Eğitimi hızlandırmak için ağırlıkların ana kopyasını FP32'de tutarken çoğu işlemi FP16 veya BF16 ile yürütme tekniğidir. Niceleme çıkarımı hedefler ve çoğu zaman tam sayılara geçerek daha ileri gider.
- Model budama: İşlem sayısını azaltmak için ağırlıkları veya kanalların tamamını kaldırır. Kalan her işlemi daha ucuz hâle getiren nicelemeyle sıklıkla birlikte kullanılır.
- Bilgi damıtma: Büyük bir öğretmen modeli taklit etmesi için küçük bir öğrenci modeli eğitir. Öğrenci model, dağıtımdan önce çoğu zaman niceleme işleminden geçirilir.
Uygulamada Niceleme#
Hız artışı donanım desteğine bağlıdır: INT8 model yalnızca NVIDIA GPU'larda TensorRT, Intel CPU'larda OpenVINO ve telefonlardaki sinir işleme birimleri (NPUs) gibi INT8 çekirdeklerine sahip işlemcilerde daha hızlı çalışır. Ultralytics YOLO26, quantize=8 ile dışa aktarma sırasında PTQ uygular ve data veri kümesindeki görüntülerle kalibrasyon yapar; model.train(quantize=8) ise bunun yerine bir kontrol noktasına QAT ile ince ayar yapar. Bu örnek, Google'ın Android ve gömülü cihazlar için çalışma zamanı olan LiteRT biçiminde bir INT8 modeli dışa aktarır:
from ultralytics import YOLO
# Önceden eğitilmiş bir YOLO26 nano modeli yükle
model = YOLO("yolo26n.pt")
# INT8 eğitim sonrası niceleme; aktivasyon aralıklarını kalibre etmek için coco8.yaml dosyasındaki görüntüler kullanılır
model.export(format="litert", quantize=8, data="coco8.yaml")COCO üzerinde TensorRT ile ölçüldüğünde, INT8 PTQ YOLO26n modelinin mAP50-95 değerini yalnızca 0.403'ten 0.393'e düşürür; YOLO26s için düşüş daha büyüktür: 0.479'dan 0.441'e. QAT ise YOLO26s değerini yeniden 0.471'e çıkarır.










