Transformers documentation
Katkıda bulun
Katkıda bulun
Transformers, QLoRA, GPTQ, LLM.int8 ve AWQ gibi birçok kuantizasyon yöntemini destekler. Ancak, henüz entegre edilmemiş daha birçok kuantizasyon yaklaşımı bulunmaktadır. Bu kuantizasyon yöntemlerini Transformers ile eklemenin ve kullanmanın daha kolay hale getirilmesi için HfQuantizer sınıfını kullanın. HfQuantizer, her PyTorch modülüne uygulanan bir şey yerine, bir kuantizasyon yöntemi eklemek için tasarlanmış dahili bir yardımcı sınıftır.
Bu kılavuz, yeni bir kuantizasyon yönteminin HfQuantizer ile nasıl entegre edileceğini gösterecektir.
Gereksinimler
Transformers'a yeni bir kuantizasyon yöntemi entegre etmeden önce, yöntemin aşağıdaki gereksinimleri karşıladığından emin olun. Yalnızca PyTorch modülleriyle çalıştırılabilecek kuantizasyon yöntemleri desteklenir.
Kantizasyon yöntemi, pip ile kurulabilir bir Python paketi aracılığıyla kullanılabilir (paketin yalnızca kaynak kodundan kurulabilmesi de uygundur). İdeal olarak, pip paketinde önceden derlenmiş çekirdekler bulunur.
Yöntem, yaygın olarak kullanılan donanımlarda (CPU, GPU vb.) çalıştırılabilir.
Yöntem, nn.Module içinde sarılıdır (
~bitsandbytes.nn.Linear8bitLt,~bitsandbytes.nn.Linear4bit) ve kuantize doğrusal katman aşağıdaki tanıma sahip olmalıdır.class Linear4bit(nn.Module): def __init__(self, ...): ... def forward(self, x): return my_4bit_kernel(x, self.weight, self.bias)Bu şekilde, Transformers modelleri, nn.Linear örneklerini hedef bir sınıf ile değiştirerek kolayca kuantize edilir.
Kantizasyon yöntemi serileştirilebilir olmalıdır. Kantize ağırlıkları yerel olarak kaydedebilir veya Hub'a yükleyebilirsiniz.
Kuantizasyon çekirdeklerini/primitiflerini içeren paketin kararlı olduğundan (sık sık bozucu değişiklikler içermemesinden) emin olun.
Bazı kuantizasyon yöntemleri, veri kalibrasyonu yoluyla modelin “önceden kuantize edilmesini” gerektirebilir (AWQ). Bu durumda, Transformers içinde yalnızca çıkarımı (inference) desteklemeyi ve modelin kuantizasyonunu ML topluluğu tarafından sürdürülen üçüncü taraf kütüphanenin kendisinin ele almasını tercih ediyoruz.
Yeni HFQuantizer sınıfı oluşturun
En iyi başlangıç noktası, Finegrained Fp8 gibi başka bir kuantizasyon yöntemine göz atmaktır. Toplamda üç dosyayı güncellemeniz veya oluşturmanız gerekir: config dosyası, integration dosyası ve quantizer dosyası.
src/transformers/utils/quantization_config.py içinde yeni bir quantization config sınıfı oluşturun. Yeni quantization config'i, Transformers'ın src/transformers/__init__.py dosyasındaki _import_structure içine ekleyin.
src/transformers/quantizers/ dizininin içinde
quantizer_your_method.pyadında yeni bir dosya oluşturun ve bu dosyanın [`~quantizers.HfQuantizer`] sınıfından türetmesini sağlayın. Yeni quantizer'ı ve quantization config'ini src/transformers/quantizers/auto.py içindeki quantization auto-mapping'e eklemeyi unutmayın.Kantizasyon yönteminiz için aşağıdaki sınıf özniteliklerini ve özellik yöntemlerini tanımlayın:
requires_calibration: Kuantizasyon yönteminin veri kalibrasyonu süreci gerektirip gerektirmediğini belirtir.Trueolarak ayarlanırsa yalnızca çıkarım (kuantize ağırlıklarla) desteklenir; çıkarım ve kuantizasyon birlikte desteklenmez.is_serializable: Yöntemin serileştirilebilir olup olmadığını belirlemek için bir özellik yöntemi.is_trainable: Kuantizasyon yönteminin üzerine (PEFT yaklaşımlarıyla veya olmadan) modellerin ince ayarının yapılıp yapılamayacağını belirlemek için bir özellik yöntemi.
validate_environmentveupdate_dtypeyöntemlerini yazın. Bu yöntemler, kullanıcıların doğru yapılandırmayı kullandığından emin olmak için quantize edilmiş model oluşturulmadan önce çağrılır. Uygulama örneği için diğer quantizer'lara başvurun._process_model_before_weight_loadingmetodunu yazın. Transformers'ta, ağırlıklar yüklenmeden önce kuantize modeller önce"meta"cihazında başlatılır. Bu,_process_model_before_weight_loadingmetodunun, bazı modülleri (nn.Linear) hedef modüllerle (kuantizasyon modülleri) değiştirmek için model iskeletini manipüle etmekten sorumlu olduğu anlamına gelir.
transformers/src/integrations/ dizininde yeni bir dosya oluşturarak modül değiştirme mantığını veya başka herhangi bir yardımcı yöntemi tanımlayabilir ve ilgili yöntemleri o klasördeki __init__.py dosyasında dışa açabilirsiniz.
Eğer kuantizasyon, uçuşta kuantizizasyonu destekliyorsa, kuantizatör sınıfına
get_quantize_opsmetodunu ekleyin. transformers'ta her tensör somutlaştırılır ve üzerinde farklı bir dizi işlem uygulanır. Bizim durumumuzda kuantizasyon işlemi en sonda gerçekleşir.ConversionOps'in bir alt sınıfı olan birXXXQuantizeoluşturmanız ve birconvertmetodu eklemeniz gerekir.convertmetodunda, ağırlıkları kuantize etmeniz ve kuantize edilmiş parametrelerin sözlüğünü döndürmeniz gerekir.Eğer kuantizasyon, önceden kuantize edilmiş ağırlıkların yüklenmesini destekliyorsa, kuantizör sınıfına
get_weight_conversionsmetodunu ekleyin. transformers'ta birden çok tensörü toplayıp bunlar üzerinde işlemler uygulayabiliriz. Bu, checkpoint'te kuantize edilmiş tensörleri yeniden oluşturmak için yeniden gruplandırılması gereken tensörler olduğunda özellikle faydalıdır.Gerekirse
_process_model_after_weight_loadingmetodunu yazın. Bu yöntem, ağırlıklar yüklendikten sonra modeli manipüle etmeyi gerektiren ek özelliklerin uygulanmasını sağlar.Her şeyi belgeleyin!
docs/source/en/quantizationaltında yeni bir dosya ekleyerek kuantizasyon yönteminizin belgelendiğinden emin olun.Test eklemek için paketi
docker/transformers-quantization-latest-gpuiçindeki günlük Dockerfile'ımıza ekleyip ardındantests/quantization/xxxaltında yeni bir test dosyası oluşturmalısınız. Uygulamanın nasıl yapıldığını görmek için mevcut kuantizasyon yöntemlerine göz atabilirsiniz.
Dosyalar genel bakış
| Dosya | Amaç |
|---|---|
utils/quantization_config.py | YourMethodConfig'ı QuantizationConfigMixin'den devralacak şekilde tanımlayın |
quantizers/quantizer_your_method.py | YourMethodHfQuantizer uygulamasını HfQuantizer sınıfından devralacak şekilde oluşturun |
integrations/your_method.py | ConversionOps alt sınıflarını ve yardımcı işlevleri uygulayın |
quantizers/auto.py | Quantizer ve config'i AUTO_QUANTIZER_MAPPING ve AUTO_QUANTIZATION_CONFIG_MAPPING içinde kaydedin |
docs/source/en/quantization/your_method.md | Kullanıcılar için kullanım belgeleri |
tests/quantization/your_method/ | Entegrasyon testleri ekleyin |
get_quantize_ops ile get_weight_conversions'ı anlama
Bu iki yöntem, ağırlıkların yüklenmesi için farklı senaryoları ele alır. Her birinin ne zaman kullanılacağını anlamak önemlidir.
get_quantize_ops — Uygulama sırasında kuantizasyon
kuantize edilmemiş bir kontrol noktası (ör. float16/bfloat16 ağırlıkları) yüklerken ve yükleme sırasında kuantizasyon yaparken bunu kullanın.
Checkpoint: model.safetensors (float16 weights for example)
↓
get_quantize_ops → YourQuantize.convert()
↓
Result: Quantized weights in memoryconvert metodu her seferinde bir tensör alır, onu kuantize eder ve örneğin kuantize edilmiş parametrelerin bir sözlüğünü döndürebilir:
class YourQuantize(ConversionOps):
def convert(self, input_dict, model, full_layer_name, missing_keys, **kwargs):
# input_dict = {"layer.weight": <float16 tensor>}
value = list(input_dict.values())[0]
module, tensor_name = get_module_from_name(model, full_layer_name)
# Quantize and assign
quantized, scale, zero_point = your_quantize_fn(value)
return {full_layer_name: quantized, full_layer_name + ".scale": scale, full_layer_name + ".zero_point": zero_point}get_weight_conversions — Ön-kantlanmış kontrol noktalarını yükle
Önceden kantize edilmiş bir checkpoint yüklerken, kantize ağırlıkların birden fazla ayrı bileşen olarak (veri, ölçek ve sıfır noktası gibi) kaydedildiği ve bu bileşenlerin yükleme sırasında tek bir tensöre birleştirilmesi gerektiği durumlarda bunu kullanın. Kantizasyon yöntemlerinin tümü bu yeniden oluşturma adımını gerektirmez: örneğin FP8 gibi bazı yöntemler, ağırlıkları ve ölçekleri birleştirmeden olduğu gibi yükler. torchao gibi diğer yöntemler ise kantize tensörü, kaydedilen birden fazla bileşeninden yeniden birleştirmeyi gerektirir.
Checkpoint: model.safetensors (quantized components)
- layer._weight_qdata
- layer._weight_scale
- layer._weight_zero_point
↓
get_weight_conversions → WeightConverter + YourDeserialize.convert()
↓
Result: Reconstructed quantized tensor → layer.weightWeightConverter, source_patterns temelinde ilgili tensörleri toplar ve ardından bunları convert yönteminize iletir:
def get_weight_conversions(self):
if self.pre_quantized:
return [
WeightConverter(
source_patterns=["_weight_qdata", "_weight_scale", "_weight_zero_point"],
target_patterns="weight",
operations=[YourDeserialize(self)],
),
]
return []
class YourDeserialize(ConversionOps):
def convert(self, input_dict, model, full_layer_name, **kwargs):
# input_dict contains all collected tensors
# Reconstruct the quantized tensor from components
reconstructed_tensor = reconstruct_from_components(input_dict)
return {full_layer_name: reconstructed_tensor}