Transformers documentation

Katkıda bulun

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

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

  1. 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ı.

  2. 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.

  3. src/transformers/quantizers/ dizininin içinde quantizer_your_method.py adı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.

  4. 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. True olarak 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.
  5. validate_environment ve update_dtype yö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.

  6. _process_model_before_weight_loading metodunu 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_loading metodunun, 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.

  1. Eğer kuantizasyon, uçuşta kuantizizasyonu destekliyorsa, kuantizatör sınıfına get_quantize_ops metodunu 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 bir XXXQuantize oluşturmanız ve bir convert metodu eklemeniz gerekir. convert metodunda, ağırlıkları kuantize etmeniz ve kuantize edilmiş parametrelerin sözlüğünü döndürmeniz gerekir.

  2. Eğer kuantizasyon, önceden kuantize edilmiş ağırlıkların yüklenmesini destekliyorsa, kuantizör sınıfına get_weight_conversions metodunu 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.

  3. Gerekirse _process_model_after_weight_loading metodunu yazın. Bu yöntem, ağırlıklar yüklendikten sonra modeli manipüle etmeyi gerektiren ek özelliklerin uygulanmasını sağlar.

  4. Her şeyi belgeleyin! docs/source/en/quantization altında yeni bir dosya ekleyerek kuantizasyon yönteminizin belgelendiğinden emin olun.

  5. Test eklemek için paketi docker/transformers-quantization-latest-gpu içindeki günlük Dockerfile'ımıza ekleyip ardından tests/quantization/xxx altı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ış

DosyaAmaç
utils/quantization_config.pyYourMethodConfig'ı QuantizationConfigMixin'den devralacak şekilde tanımlayın
quantizers/quantizer_your_method.pyYourMethodHfQuantizer uygulamasını HfQuantizer sınıfından devralacak şekilde oluşturun
integrations/your_method.pyConversionOps alt sınıflarını ve yardımcı işlevleri uygulayın
quantizers/auto.pyQuantizer ve config'i AUTO_QUANTIZER_MAPPING ve AUTO_QUANTIZATION_CONFIG_MAPPING içinde kaydedin
docs/source/en/quantization/your_method.mdKullanı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 memory

convert 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.weight

WeightConverter, 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}
Update on GitHub