Transformers documentation

Kantizasyon kavramları

You are viewing main version, which requires installation from source. If you'd like regular pip install, checkout the latest stable version (v5.22.2).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Kantizasyon kavramları

Kantize edilmiş bir sayı, yalnızca küçük bir değer kümesinden birini alabilir; int8 için 256, int4 için 16 değer. Bu nedenle her kantizasyon yöntemi yuvarlama hatası ortaya çıkarır. Yöntemler, bu hatanın model çıktısını olumsuz etkilemesini nasıl önlediklerinde farklılık gösterir. Bu sayfa, bu farklılıkların arkasındaki seçimleri açıklar: sayıların bu küçük kümeye nasıl eşlendiği, hangi tensörlerin kantize edildiği, hangi veri türlerinin kullanıldığı ve kantizasyonun ne zaman gerçekleştiği.

Transformers'ta kuantizasyona yeniyseniz, Genel Bakış ile başlayın.

Değerleri daha az bite eşleyin

Quantization, yüksek hassasiyetli değerlerin aralığını, düşük bitli bir türün temsil edebildiği küçük tamsayı kümesine eşler. int8, [-128, 127] aralığındaki 256 tamsayıyı, int4 ise 16 tamsayıyı temsil edebilir.

Affine quantization en yaygın eşleştirmedir. Bir tensörün minimum ve maksimum değerlerini alır ve tamsayı aralığını bu aralığa yayarak eşler. Aşağıdaki örnekte, değerleri -1.8 ile 2.4 arasında değişen bir tensör int8'e eşlenir ve 0.0 değeri -19'a denk gelir.

bf16  -1.8             0.0                    2.4
       ├────────────────┼──────────────────────┤
       ▼                ▼                      ▼
int8  -128             -19                    127

Eşlemeyi iki parametre belirler.

  • The scale S orijinal birimlerde bir tam sayı adımının boyutudur. S=valmax−valminqmax−qmin S = \frac{val_{max} - val_{min}}{q_{max} - q_{min}}

  • Sıfır noktası Z şu değeri temsil eden tam sayıdır: 0.0. Z=qmin−round(valminS) Z = q_{min} - round\left(\frac{val_{min}}{S}\right)

Bir değer x ölçekle bölünerek ve sıfır noktasıyla kaydırılarak tamsayıya q kuantize edilir. q=round(xS+Z) q = round\left(\frac{x}{S} + Z\right)

Dequantize işlemi eşlemeyi tersine çevirir ve x. ile yaklaşık değeri arasındaki fark yuvarlama hatasıdır. x x≈S⋅(q−Z) x \approx S \cdot (q - Z)

Yukarıdaki örnekte S yaklaşık 0.0165 ve Z -19'dur. 0.5 değeri 11'e kuantize edilir ve 11, yaklaşık 0.494'e dekuantize edilir; bu da yaklaşık 0.006'lık bir yuvarlama hatasıdır.

┌─────┐  quantize   ┌────┐ dequantize   ┌───────┐
│ 0.5 │ ──────────▶ │ 11 │ ───────────▶ │ 0.494 │
└─────┘             └────┘              └───────┘

Affine kuantizasyon iki biçimde gelir.

  • Asimetrik kuantizasyon yukarıdaki formülleri kullanır. Ağırlıklar sıfır etrafında merkezlenmediğinde temsil edilebilir değerlerin israf olmaması için tam aralığı eşler.
  • Simetrik kuantizasyon, aralığın [-a, a] olduğunu varsayar ve Z değerini 0 olarak sabitler; bu nedenle yalnızca ölçek saklanır. İşlemler daha ucuzdur, ancak ağırlıklar sıfırın bir tarafına kaydıysa temsil edilebilir bazı değerler kullanılmadan kalır.

Granülerliği seçin

Bir tensörün tamamı için tek bir ölçek saklaması ucuzdur, ancak tek bir büyük aykırı değer aralığı genişletir ve temsil edilebilir değerleri diğer tüm ağırlıklar için daha da uzaklaştırır. Daha küçük gruplar, her ölçeğin kapsaması gereken aralığı daraltır.

  • Per-tensor, tüm tensör için tek bir ölçek ve tek bir sıfır noktası kullanır.
  • Per-channel, her çıktı kanalı için bir ölçek kullanır; bu, bir ağırlık matrisinin her satırına karşılık gelir.
  • Grup bazlı veya blok bazlı yöntem, ardışık değerlerin her grubu (örneğin 128 ağırlık) için tek bir ölçek kullanır. Her grup, ölçeği için ek depolama alanı gerektirir.

Aşağıdaki şema, üç satırlı bir ağırlık matrisinde üç seçeneği göstermektedir. Her s bir ölçek temsil eder.

per-tensor        per-channel           per-group
┌────────────┐    ┌────────────┐        ┌──────┬──────┐
│            │    │            │ s0     │  s0  │  s1  │
│            │    ├────────────┤        ├──────┼──────┤
│     s      │    │            │ s1     │  s2  │  s3  │
│            │    ├────────────┤        ├──────┼──────┤
│            │    │            │ s2     │  s4  │  s5  │
└────────────┘    └────────────┘        └──────┴──────┘

Çoğu düşük bit yöntemi grup bazlı kuantizasyon uygular. GPTQ varsayılan olarak 128 ağırlıktan oluşan grupları kullanırken, Fine-grained FP8 varsayılan olarak 128x128 blokları kullanır. Data types bölümündeki FP4 biçimleri, blok boyutunu biçimin kendisine yerleştirir.

Ağırlıkları veya aktivasyonları kuantize et

Yöntemler, hangi tensörleri kuantize ettiklerinde farklılık gösterir ve bu durum, matris çarpımının nerede çalışacağını belirler.

  • Sadece ağırlık yöntemleri, ağırlıkları düşük hassasiyette saklar ve aktivasyonları bf16 veya fp16 olarak bırakır. Her matmul işleminden önce çekirdek, ağırlıkları daha yüksek hassasiyetli bir hesaplama veri türüne (compute dtype) dekuantize eder. bitsandbytes 4-bit, AWQ, GPTQ ve HQQ bu şekilde çalışır. bitsandbytes'ta bnb_4bit_compute_dtype bu hesaplama veri türünü belirler.
  • Ağırlık ve aktivasyon yöntemleri, aktivasyonları da kuantize eder ve matmul doğrudan düşük hassasiyette çalışır. Bunun için, son nesil GPU'lardaki FP8 gibi düşük hassasiyetli matmul'u destekleyen donanıma ihtiyaç vardır. Bu şema, 8 bit ağırlık ve aktivasyonlar için genellikle W8A8 olarak yazılır.

Weight-only yöntemler bellek tasarrufu sağlar ancak her zaman daha hızlı çalışmazlar, çünkü dequantize işlemi her matmul'a ek iş yükü getirir. Model memory-bound olduğunda üretimi hızlandırırlar. Bir token'ı birer birer üretirken, bir GPU her adımda ağırlıkları bellekten okumaya, hesaplama yapmaktan çok daha fazla zaman harcar. 4-bit ağırlıkları okumak, bf16 ağırlıklara kıyasla dörtte bir oranında daha az veri taşır ve bu tasarruf, dequantize maliyetini karşılayabilir.

Ağırlık ve aktivasyon yöntemleri, modelin hesaplama sınırlı olduğu durumlarda, örneğin prefill veya büyük batch'lerde, düşük hassasiyetli matmul'un kendisinin daha hızlı olması nedeniyle faydalıdır. Bazı yöntemler bu iki durum arasında geçiş yapar. NVFP4, prefill için 4 bit ağırlıklı, 4 bit aktivasyonlu matmul ve decoding için 4 bit ağırlıklı, 16 bit aktivasyonlu matmul çalıştırır.

Veri türleri

Veri tipi, bir kuantize sayının temsil edebileceği değerleri belirler.

int8 ve int4

int8 ve int4, eşit aralıklı tam sayıları temsil eder ve yukarıdaki afin dönüşümü kullanır. int4 yalnızca 16 değeri temsil edebildiğinden, int8'e kıyasla daha fazla doğruluk kaybına uğrar. int4 kullanan yöntemler genellikle doğruluğu korumak için grup bazlı kuantizasyon yapar veya kalibrasyon kullanır.

Çoğu donanımın 4 bitlik bir depolama tipi bulunmadığından, iki int4 değeri birleştirilerek tek bir bayta sığdırılır. Örneğin, ilk değer alttaki 4 biti, ikinci değer ise üstteki 4 biti kullanabilir. Çekirdekler, değerlerle işlem yapmadan önce bu değerleri ayrıştırır.

┌──────┐  ┌──────┐        ┌──────┬──────┐
│ val1 │  │ val2 │        │ val2 │ val1 │
│ 0101 │  │ 0011 │   →    │ 0011 │ 0101 │  1 byte
└──────┘  └──────┘        └──────┴──────┘
  int4      int4            high   low

Bazı 4-bit türler, temsil edilebilir değerlerini ağırlıkların dağılımına uyacak şekilde eşit olmayan aralıklarla yerleştirir. bitsandbytes NF4, ağırlıkların çoğunun bulunduğu sıfıra yakın bölgede daha fazla değer barındırır.

FP8

FP8, işaret, üstel kısım ve mantısa bileşenlerinden oluşan kayan nokta düzenini 8 bit içinde korur. Temsil edilebilir değerleri, sıfıra yakın bölgede birbirine daha yakın, büyük mutlak değerlerde ise daha uzak aralıklarla dağılır; bu da ağırlıklardaki ve aktivasyonlardaki değer dağılımına uygundur.

FP8 iki varyant olarak gelir.

  • E4M3, 4 üs biti ve 3 mantis bitine sahiptir. Daha hassastır ancak daha küçük bir aralığı kapsar. Çıkarım sırasında ağırlıklar ve aktivasyonlar için standart seçimdir.
  • E5M2, 5 üs biti ve 2 mantis bitine sahiptir. Daha az hassasiyetle daha geniş bir aralığı kapsar.
E4M3   ┌─┬───────┬─────┐
       │S│E E E E│M M M│
       └─┴───────┴─────┘
E5M2   ┌─┬─────────┬───┐
       │S│E E E E E│M M│
       └─┴─────────┴───┘
  S sign   E exponent   M mantissa

FP8 matmulları, NVIDIA'nın 8.9 veya daha yüksek hesaplama yeteneğine sahip GPU'ları (Ada, Hopper, Blackwell), AMD Instinct MI300 ve Intel XPU gibi donanım desteği gerektirir. Transformers, FP8'i Fine-grained FP8, FBGEMM FP8 ve compressed-tensors aracılığıyla destekler.

Blok ölçekleriyle FP4

FP4, 1 işaret biti, 2 üs biti ve 1 mantis bitine (E2M1) sahiptir. Sadece 0, 0,5, 1, 1,5, 2, 3, 4 ve 6 değerlerini, pozitif ve negatif olarak temsil eder. Bu kadar az değerle FP4 formatları, tensör başına tek bir ölçekle çalışamaz. Ölçekleri her küçük değer bloğuna bağlar ve ölçekleri formatın bir parçası olarak saklar.

BiçimBlok boyutuBlok başına ölçekEk ölçek
MXFP432 değer8-bit iki kuvveti (E8M0)None
NVFP416 değerFP8Her tensör için bir FP32 ölçeği

MXFP4, bir microscaling biçimidir. İki tabanlı bir ölçek yalnızca üssü kaydırır, bu nedenle uygulanması ucuzdur; ancak yalnızca iki tabanlı değerlere oturabilir. NVFP4, daha küçük bloklar ve iki tabanlı değerler arasında değer alabilen bir FP8 ölçeği kullanır. Bu, tensör başına bir ölçek maliyeti karşılığında FP8 blok ölçeklerini aralıkta tutarak daha fazla doğruluk sağlar. Four Over Six ve FP-Quant da NVFP4 veya MXFP4 ağırlıkları üretir.

Aynı blok fikri 8 bit'te de karşımıza çıkar. MXFP8, FP8 değerlerini iki'nin kuvveti blok ölçekleriyle saklar ve Fine-grained FP8 bunu yükler.

Codebook'lar

4 bit'in altında, bazı yöntemler her ağırlığı en yakın temsil edilebilir değere yuvarlamayı bırakır. Ağırlık gruplarını vektörler olarak birlikte kuantize ederler. Bir kod kitabı (codebook), öğrenilmiş vektörlerden oluşan bir seti barındırır ve her ağırlık grubu, en yakın vektörünün indeksi olarak saklanır. AQLM varsayılan olarak 8 ağırlıklık gruplar ve 16 bitlik bir indeks kullanır; bu da ağırlık başına 2 bite karşılık gelir. VPTQ de kod kitapları kullanır. İyi kod kitaplarını bulmak, kalibrasyon verileri üzerinde uzun bir optimizasyon gerektirdiğinden, bu modeller önceden kuantize edilir ve checkpoint olarak yüklenir.

Kantizasyonun gerçekleştiği zaman

Bir model, eğitimden sonra veya eğitim sırasında kuantize edilir. Transformers'taki çoğu yöntem, kuantizasyonu eğitimden sonra gerçekleştirir.

Eğitim sonrası nicelleştirme

Eğitim sonrası kuantizasyon (PTQ), bir modelin ne öğrendiğini değiştirmeden, zaten eğitilmiş bir modeli kuantize eder. PTQ yöntemleri, veri gerektirip gerektirmediklerine göre farklılık gösterir ve bu durum, bir yöntemin belgenin içeriğinde hangi gruba girdiğini belirler.

  • Kalibrasyon verisi olmadan, ölçekler yalnızca ağırlıklardan gelir ve kuantizasyon, model yüklenirken çalışacak kadar hızlıdır. bitsandbytes, HQQ ve torchao bu şekilde çalışır. Bu yöntemler Yükleme sırasında kuantizasyon altında listelenmiştir.
  • Kalibrasyon verisiyle, yöntem küçük bir veri setini modelden geçirir ve her katmanı nasıl kuantize edeceğine karar vermek için aktivasyonları kullanır. Kalibrasyon genellikle 4 bit ve altı için daha iyi doğruluk sağlar, ancak dakikalardan saatlere kadar sürebilir.

Kalibrasyon yöntemleri, aktivasyonları farklı şekillerde kullanır. GPTQ, bir katmanı sütun sütun olarak kuantize eder ve her sütunun yuvarlama hatasını telafi etmek için kalan sütunları ayarlar. AWQ, en büyük aktivasyonlara sahip ağırlık kanallarını bulur ve onları korumak için yuvarlamadan önce ölçekler.

kalibrasyon çalıştırmalarının nasıl yapıldığı, Transformers'te yöntemin nasıl kullanılacağını belirler.

  • GPTQ, dataset parametresini GPTQConfig sınıfına geçirdiğinizde from_pretrained içinde kalibrasyon yapar; bu nedenle Yükleme sırasında kuantizasyon başlığı altında listelenir.
  • AWQ, AutoRound, AQLM ve VPTQ gibi diğer kalibrasyon yöntemleri, kendi kütüphanelerinde kalibrasyon yapar. Transformers sonucu yüklediği için bunlar Önceden kantize edilmiş checkpoint'leri yükleme altında listelenir.

Kantizasyona duyarlı eğitim

Kantizasyon farkında eğitim (QAT), eğitim sırasında kantizasyonu simüle eder. İleri geçiş, kantizasyonun yapacağı gibi değerleri yuvarlarken, gradyanlar tam hassasiyetli ağırlıkları günceller; böylece model, yuvarlama hatasına tolerans göstermeyi öğrenir. QAT genellikle çok düşük bit genişliklerinde en iyi doğruluğu sağlar, ancak modelin eğitilmesini gerektirir.

BitNet modelleri, 1.58-bit ağırlıkları döngüde olacak şekilde bu yöntemle eğitilir ve Transformers, eğitilmiş kontrol noktalarını yükler.

Kaynaklar

Update on GitHub