Transformers documentation

Kontribusi

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

and get access to the augmented documentation experience

to get started

Kontribusi

Transformers mendukung banyak metode kuantisasi seperti QLoRA, GPTQ, LLM.int8, dan AWQ. Namun, masih ada banyak pendekatan kuantisasi lain yang belum terintegrasi. Untuk memudahkan penambahan dan penggunaan metode kuantisasi ini dengan Transformers, gunakan kelas HfQuantizer. HfQuantizer dirancang sebagai kelas helper internal untuk menambahkan metode kuantisasi, bukan sesuatu yang diterapkan ke setiap modul PyTorch.

Panduan ini akan menunjukkan cara mengintegrasikan metode kuantisasi baru dengan HfQuantizer.

Persyaratan

Sebelum mengintegrasikan metode kuantisasi baru ke dalam Transformers, pastikan metode tersebut memenuhi persyaratan berikut. Hanya metode kuantisasi yang dapat dijalankan dengan modul PyTorch yang didukung.

  • Metode kuantisasi tersedia melalui paket Python yang dapat diinstal via pip (tidak masalah jika Anda hanya dapat menginstal paket dari sumber). Idealnya, kernel yang sudah dikompilasi sebelumnya disertakan dalam paket pip.

  • Metode ini dapat dijalankan pada perangkat keras yang umum digunakan (CPU, GPU, dll.).

  • Metode ini dibungkus dalam nn.Module (~bitsandbytes.nn.Linear8bitLt, ~bitsandbytes.nn.Linear4bit), dan lapisan linear terkuantisasi harus memiliki definisi berikut.

    class Linear4bit(nn.Module):
        def __init__(self, ...):
            ...
    
        def forward(self, x):
            return my_4bit_kernel(x, self.weight, self.bias)

    Dengan cara ini, model Transformers dapat dikuantisasi dengan mudah dengan mengganti instance nn.Linear dengan kelas target.

  • Metode kuantisasi harus dapat diserialisasi. Anda dapat menyimpan bobot terkuantisasi secara lokal atau mengirimkannya ke Hub.

  • Pastikan paket yang berisi kernel/primitif kuantisasi sudah stabil (tidak ada perubahan yang sering merusak kompatibilitas).

Beberapa metode kuantisasi mungkin memerlukan “pre-quantizing” model melalui kalibrasi data (AWQ). Dalam kasus ini, kami lebih memilih untuk hanya mendukung inferensi di Transformers dan membiarkan pustaka pihak ketiga yang dipelihara oleh komunitas ML menangani kuantisasi model itu sendiri.

Buat kelas HFQuantizer baru

  1. Titik awal terbaik adalah dengan melihat metode kuantisasi lain seperti Finegrained Fp8. Anda harus memperbarui atau membuat tiga file secara total: file konfigurasi, file integrasi, dan file kuantizer.

  2. Buat kelas konfigurasi kuantisasi baru di dalam src/transformers/utils/quantization_config.py. Tambahkan konfigurasi kuantisasi baru tersebut ke _import_structure di dalam file src/transformers/__init__.py Transformers.

  3. Buat file baru di dalam src/transformers/quantizers/ bernama quantizer_your_method.py, dan buat file tersebut mewarisi dari [`~quantizers.HfQuantizer]. Pastikan untuk menambahkan quantizer dan quantization config baru ke dalam auto-mapping quantization di src/transformers/quantizers/auto.py.

  4. Definisikan atribut kelas dan metode properti berikut untuk metode kuantisasi Anda:

    • requires_calibration: Apakah metode kuantisasi memerlukan proses kalibrasi data. Jika disetel ke True, Anda hanya dapat mendukung inferensi (dengan bobot terkuantisasi) dan bukan inferensi serta kuantisasi.
    • is_serializable: Metode properti untuk menentukan apakah metode tersebut dapat diserialisasi atau tidak.
    • is_trainable: Metode properti untuk menentukan apakah Anda dapat melakukan fine-tuning model di atas metode kuantisasi (dengan atau tanpa pendekatan PEFT).
  5. Tulis metode validate_environment dan update_dtype. Metode-metode ini dipanggil sebelum membuat model terkuantisasi untuk memastikan pengguna menggunakan konfigurasi yang tepat. Lihat implementasi pada quantizer lain sebagai contoh.

  6. Tulis metode _process_model_before_weight_loading. Di Transformers, model terkuantisasi diinisialisasi terlebih dahulu pada perangkat "meta" sebelum memuat bobot. Artinya, metode _process_model_before_weight_loading bertugas memanipulasi kerangka model untuk mengganti beberapa modul (nn.Linear) dengan modul target (modul kuantisasi).

Anda dapat mendefinisikan logika penggantian modul atau metode utilitas lainnya dengan membuat file baru di transformers/src/integrations/ dan mengekspos metode yang relevan di file __init__.py pada folder tersebut.

  1. Tambahkan metode get_quantize_ops ke kelas quantizer jika kuantisasi mendukung kuantisasi on the fly. Di transformers, kami materialisasi setiap tensor dan menerapkan serangkaian operasi yang berbeda pada tensor tersebut. Dalam kasus kami, operasi kuantisasi terjadi di akhir. Anda perlu membuat XXXQuantize, yaitu subclass dari ConversionOps, dan menambahkan metode convert. Di dalam metode convert, Anda perlu mengkuantisasi bobot dan mengembalikan dictionary berisi parameter yang telah dikuantisasi.

  2. Tambahkan metode get_weight_conversions ke kelas quantizer jika kuantisasi mendukung pemuatan bobot yang sudah dikuantisasi. Di transformers, kita dapat mengumpulkan beberapa tensor dan menerapkan operasi pada tensor tersebut. Hal ini sangat berguna ketika kita memiliki tensor di checkpoint yang perlu dikelompokkan kembali untuk membuat ulang tensor yang telah dikuantisasi.

  3. Tulis metode _process_model_after_weight_loading jika diperlukan. Metode ini memungkinkan implementasi fitur tambahan yang memerlukan manipulasi model setelah pemuatan bobot.

  4. Dokumentasikan semuanya! Pastikan metode kuantisasi Anda terdokumentasi dengan menambahkan file baru di bawah docs/source/en/quantization.

  5. Anda sebaiknya menambahkan tes dengan menambahkan paket tersebut ke Dockerfile nightly kami di dalam docker/transformers-quantization-latest-gpu, lalu menambahkan file tes baru di tests/quantization/xxx. Silakan periksa metode kuantisasi yang sudah ada untuk melihat bagaimana implementasinya.

Ikhtisar file

FileTujuan
utils/quantization_config.pyDefinisikan YourMethodConfig yang mewarisi dari QuantizationConfigMixin
quantizers/quantizer_your_method.pyImplementasikan YourMethodHfQuantizer yang mewarisi dari HfQuantizer
integrations/your_method.pyImplement subclass ConversionOps dan fungsi bantu
quantizers/auto.pyDaftarkan quantizer dan config di AUTO_QUANTIZER_MAPPING dan AUTO_QUANTIZATION_CONFIG_MAPPING
docs/source/en/quantization/your_method.mdDokumentasikan penggunaan untuk pengguna
tests/quantization/your_method/Tambahkan uji integrasi

Memahami get_quantize_ops vs get_weight_conversions

Dua metode ini menangani skenario yang berbeda untuk memuat bobot. Memahami kapan harus menggunakan masing-masing metode sangat penting.

get_quantize_ops — Kuantisasi secara langsung

Gunakan ini saat memuat checkpoint non-kuantisasi (misalnya, bobot float16/bfloat16) dan melakukan kuantisasi saat pemuatan.

Checkpoint: model.safetensors (float16 weights for example)
     ↓
get_quantize_ops → YourQuantize.convert()
     ↓
Result: Quantized weights in memory

Metode convert menerima satu tensor pada satu waktu, melakukan kuantisasi, dan dapat mengembalikan kamus parameter terkuantisasi, misalnya:

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 — Memuat checkpoint yang sudah dikuantisasi

Gunakan ini saat memuat checkpoint yang sudah dikuantisasi di mana bobot terkuantisasi disimpan sebagai beberapa komponen terpisah (seperti data, skala, dan titik nol), dan komponen-komponen ini perlu digabungkan menjadi satu tensor saat dimuat. Tidak semua metode kuantisasi memerlukan langkah rekonstruksi ini: misalnya, beberapa metode seperti FP8 hanya memuat bobot dan skala apa adanya, tanpa menggabungkannya. Metode lain, seperti torchao, memang memerlukan perakitan ulang tensor terkuantisasi dari beberapa komponen tersimpannya.

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 mengumpulkan tensor terkait berdasarkan source_patterns, lalu meneruskannya ke metode convert Anda:

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