# SDNQ

[SDNQ](https://github.com/Disty0/sdnq) (SD.Next Quantization) adalah backend kuantifikasi tanpa pelatihan yang mendukung berbagai dtype bobot (int8 hingga 2-bit, FP8, dan format float ber-bit rendah lainnya) dengan koreksi SVD opsional, rotasi Hadamard, dan matmul INT8/FP8 terkuantifikasi untuk inferensi yang lebih cepat. Berjalan di CUDA, ROCm, XPU, MPS, dan CPU.

Instal pustaka `sdnq` untuk menggunakan backend ini.

```bash
pip install sdnq
```

## Muat checkpoint prekuantisasi

Konfigurasi kuantisasi dari checkpoint SDNQ yang sudah dikuantisasi disimpan di `config.json`-nya, sehingga dimuat seperti model lainnya, tanpa perlu argumen `quantization_config`. Satu-satunya persyaratan adalah `sdnq` terpasang.

```python
import torch
from diffusers import DiffusionPipeline

pipe = DiffusionPipeline.from_pretrained(
    "Disty0/Z-Image-Turbo-SDNQ-uint4-svd-r32",
    dtype=torch.bfloat16,
).to("cuda")  # or "mps", "xpu", "cpu"

image = pipe("a cat holding a sign that says hello").images[0]
image.save("output.png")
```

> [!TIP]
> Set `DIFFUSERS_SDNQ_TRANSFORMERS=1` (sebelum mengimpor Diffusers) saat Anda memuat model Transformers yang dikuantisasi SDNQ secara mandiri, seperti text encoder yang dikuantisasi atau komponen LLM mandiri dalam pipeline modular. Variabel ini memungkinkan `sdnq` mendaftarkan dirinya ke Transformers agar model terkuantisasi dapat dimuat dengan benar. Anda tidak membutuhkannya saat transformer diffusers yang dikuantisasi SDNQ dimuat bersamanya, karena pemuatan transformer tersebut sudah mengimpor `sdnq` dan mendaftarkannya. Pengaturan ini nonaktif secara default sehingga pipeline yang tidak menggunakan SDNQ tidak akan pernah mengimpor `sdnq`.

## Kuantisasi model secara langsung

Lewatkan [SDNQConfig](/docs/diffusers/main/id/api/quantization#diffusers.SDNQConfig) ke `from_pretrained` untuk mengkuantisasi model saat dimuat. Gunakan [PipelineQuantizationConfig](/docs/diffusers/main/id/api/quantization#diffusers.PipelineQuantizationConfig) untuk mengkuantisasi komponen pipeline tertentu.

```python
import torch
from diffusers import DiffusionPipeline, PipelineQuantizationConfig, SDNQConfig

pipeline_quant_config = PipelineQuantizationConfig(
    quant_mapping={"transformer": SDNQConfig(weights_dtype="uint4", use_svd=True)}
)
pipe = DiffusionPipeline.from_pretrained(
    "Tongyi-MAI/Z-Image-Turbo",
    quantization_config=pipeline_quant_config,
    dtype=torch.bfloat16,
).to("cuda")  # or "mps", "xpu", "cpu"
```

Atau kuantisasi satu komponen model secara langsung.

```python
import torch
from diffusers import ZImageTransformer2DModel, SDNQConfig

transformer = ZImageTransformer2DModel.from_pretrained(
    "Tongyi-MAI/Z-Image-Turbo",
    subfolder="transformer",
    quantization_config=SDNQConfig(weights_dtype="int8"),
    dtype=torch.bfloat16,
)
```

Semua argumen diteruskan ke [`sdnq.SDNQConfig`](https://github.com/Disty0/sdnq). Lihat dokumentasi SDNQ untuk daftar lengkap dtype dan opsi yang didukung.

## Memilih lapisan mana yang akan dikuantisasi

Beberapa lapisan lebih sensitif terhadap kuantisasi daripada yang lain, dan melewati lapisan yang sensitif tersebut meningkatkan kualitas dengan biaya memori yang kecil. SDNQ menangani ini secara bawaan: ia menyediakan daftar lompatan bawaan (satu yang generik plus daftar per-model untuk banyak arsitektur) yang diterapkan secara otomatis, sehingga lapisan sensitif yang umum tetap tidak terkuantisasi tanpa konfigurasi apa pun. Untuk kontrol yang lebih halus, ia juga dapat memilih lapisan secara dinamis, mengukur kesalahan kuantisasi per lapisan, dan melewati yang berada di atas ambang batas kerugian. Lihat [panduan kuantisasi dinamis SDNQ](https://github.com/vladmandic/sdnext/wiki/SDNQ-Quantization#dynamic-loss-threshold) untuk detailnya.

## Inferensi lebih cepat dengan matmul terkuantisasi

Secara default, SDNQ melakukan dequantisasi bobot kembali ke dtype komputasi sebelum setiap matmul. Mengaktifkan quantized matmul alih-alih menjalankan matmul langsung dalam dtype presisi rendah (INT8/FP8/FP16), yang lebih cepat pada perangkat keras dengan instalasi [Triton](https://github.com/triton-lang/triton) yang berfungsi (CUDA, ROCm, atau XPU).

Aktifkan pada model yang dimuat dengan `apply_sdnq_options_to_model`, yang membaca konfigurasi kuantisasi yang ada pada model dan menerapkan ulang opsi tersebut secara langsung. Ini juga berfungsi untuk checkpoint prequantized, di mana tidak ada `SDNQConfig` yang diteruskan.

```python
import torch
from diffusers import DiffusionPipeline
from sdnq.common import use_torch_compile as triton_is_available
from sdnq.loader import apply_sdnq_options_to_model

pipe = DiffusionPipeline.from_pretrained(
    "Disty0/Z-Image-Turbo-SDNQ-uint4-svd-r32",
    dtype=torch.bfloat16,
).to("cuda")  # or "mps", "xpu", "cpu"

if triton_is_available and (torch.cuda.is_available() or torch.xpu.is_available()):
    pipe.transformer = apply_sdnq_options_to_model(pipe.transformer, use_quantized_matmul=True)
    pipe.text_encoder = apply_sdnq_options_to_model(pipe.text_encoder, use_quantized_matmul=True)
```

## torch.compile

Model terkuantisasi SDNQ kompatibel dengan [torch.compile](../optimization/fp16#torchcompile) untuk percepatan lebih lanjut, termasuk saat digunakan bersama [group offloading](../optimization/memory#group-offloading).

```python
transformer.compile(fullgraph=True)
```

## Simpan model terkuantisasi

Model terkuantisasi dapat diserialisasi dengan `save_pretrained` dan dimuat ulang tanpa `quantization_config`.

```python
transformer.save_pretrained("z-image-turbo-sdnq-int8")
```

## Sumber daya

- [Repositori SDNQ](https://github.com/Disty0/sdnq)
- [Model SDNQ prekuantisasi di Hub](https://huggingface.co/models?search=sdnq)

