# torchao

[torchao](https://github.com/pytorch/ao) menyediakan dtype berkinerja tinggi dan optimasi berdasarkan kuantisasi serta sparsity untuk inferensi dan pelatihan model PyTorch. Dukungan tersedia untuk model apa pun dalam modalitas apa pun, selama model tersebut mendukung pemuatan dengan [Accelerate](https://hf.co/docs/accelerate/index) dan berisi lapisan `torch.nn.Linear`.

Pastikan Pytorch 2.5+ dan torchao terinstal dengan perintah di bawah ini.

```bash
uv pip install -U torch torchao
```

Setiap dtype kuantisasi tersedia sebagai instance terpisah dari kelas [AOBaseConfig](https://docs.pytorch.org/ao/main/api_reference/generated/torchao.core.config.AOBaseConfig.html). Hal ini menyediakan opsi konfigurasi yang lebih fleksibel dengan mengekspos lebih banyak argumen yang tersedia.

Lewatkan `AOBaseConfig` dari dtype kuantisasi, seperti [Int4WeightOnlyConfig](https://docs.pytorch.org/ao/main/api_reference/generated/torchao.quantization.Int4WeightOnlyConfig.html) ke [TorchAoConfig](/docs/diffusers/main/id/api/quantization#diffusers.TorchAoConfig) di [from_pretrained()](/docs/diffusers/main/id/api/models/overview#diffusers.ModelMixin.from_pretrained).

```py
import torch
from diffusers import DiffusionPipeline, PipelineQuantizationConfig, TorchAoConfig
from torchao.quantization import Int8WeightOnlyConfig

pipeline_quant_config = PipelineQuantizationConfig(
    quant_mapping={"transformer": TorchAoConfig(Int8WeightOnlyConfig(group_size=128, version=2))}
)
pipeline = DiffusionPipeline.from_pretrained(
    "black-forest-labs/FLUX.1-dev",
    quantization_config=pipeline_quant_config,
    dtype=torch.bfloat16,
    device_map="cuda"  # or "mps", "xpu", "cpu"
)
```

`device_map="cuda"` mengkuantisasi setiap layer di GPU saat dimuat. Proses ini cepat, tetapi secara sementara membutuhkan memori GPU tambahan untuk bobot asli dan bobot terkuantisasi. Jika model sudah menggunakan sebagian besar memori GPU Anda, proses pemuatan dapat gagal dengan error out-of-memory. Dalam kasus tersebut, hilangkan `device_map` dan pindahkan pipeline ke GPU setelah pemuatan:

```py
pipeline = DiffusionPipeline.from_pretrained(
    "black-forest-labs/FLUX.1-dev",
    quantization_config=pipeline_quant_config,
    torch_dtype=torch.bfloat16,
)
pipeline.to("cuda")  # or "mps", "xpu", "cpu"
```

Tanpa `device_map`, Diffusers melakukan kuantisasi lapisan di CPU. Proses ini lebih lambat, tetapi menghindari lonjakan memori GPU sementara selama kuantisasi. Untuk mengurangi penggunaan memori GPU lebih lanjut, gunakan [enable_model_cpu_offload()](/docs/diffusers/main/id/api/pipelines/overview#diffusers.DiffusionPipeline.enable_model_cpu_offload) sebagai gantinya. Anda juga dapat melakukan kuantisasi pada komponen tambahan, seperti text encoder.

## torch.compile

torchao mendukung [torch.compile](../optimization/fp16#torchcompile) yang dapat mempercepat inferensi dengan satu baris kode.

```python
import torch
from diffusers import DiffusionPipeline, PipelineQuantizationConfig, TorchAoConfig
from torchao.quantization import Int4WeightOnlyConfig

pipeline_quant_config = PipelineQuantizationConfig(
    quant_mapping={"transformer": TorchAoConfig(Int4WeightOnlyConfig(group_size=128))}
)
pipeline = DiffusionPipeline.from_pretrained(
    "black-forest-labs/FLUX.1-dev",
    quantization_config=pipeline_quant_config,
    dtype=torch.bfloat16,
    device_map="cuda"  # or "mps", "xpu", "cpu"
)

pipeline.transformer.compile(transformer, mode="max-autotune", fullgraph=True)
```

Lihat [tabel](https://github.com/huggingface/diffusers/pull/10009#issue-2688781450) ini untuk benchmark kecepatan inferensi dan penggunaan memori dengan Flux dan CogVideoX. Benchmark lebih lanjut pada berbagai perangkat keras juga tersedia di [repository](https://github.com/pytorch/ao/tree/main/torchao/quantization#benchmarks) torchao.

> [!TIP]
> Skema kuantisasi pasca-pelatihan FP8 di torchao efektif untuk GPU dengan kemampuan komputasi minimal 8.9 (RTX-4090, Hopper, dll.). FP8 sering memberikan kompromi terbaik antara kecepatan, memori, dan kualitas saat menghasilkan gambar dan video. Kami merekomendasikan untuk menggabungkan FP8 dan torch.compile jika GPU Anda kompatibel.

## Jenis kuantisasi yang didukung

torchao mendukung kuantisasi hanya-berat (weight-only) serta kuantisasi berat dan aktivasi dinamis untuk int8, float3-float8, dan uint1-uint7.

Kuantisasi hanya-berat menyimpan bobot model dalam tipe data bit rendah tertentu tetapi melakukan komputasi dengan tipe data presisi yang lebih tinggi, seperti `bfloat16`. Hal ini menurunkan kebutuhan memori dari bobot model tetapi mempertahankan puncak memori untuk komputasi aktivasi.

Kuantisasi aktivasi dinamis menyimpan bobot model dalam dtype ber-bit rendah, sekaligus melakukan kuantisasi aktivasi secara on-the-fly untuk menghemat memori tambahan. Hal ini menurunkan kebutuhan memori dari bobot model, sekaligus mengurangi overhead memori dari komputasi aktivasi. Namun, hal ini terkadang dapat menimbulkan tradeoff kualitas, sehingga disarankan untuk menguji berbagai model secara menyeluruh.

Lihat [dokumentasi resmi torchao](https://docs.pytorch.org/ao/stable/index.html) untuk pemahaman yang lebih baik tentang metode kuantisasi yang tersedia. Daftar lengkap opsi konfigurasi tersedia [di sini](https://docs.pytorch.org/ao/main/workflows/inference.html#inference-workflows).

Beberapa contoh konfigurasi kuantisasi populer adalah sebagai berikut:

| **Kategori** | **Kelas Konfigurasi** |
|---|---|
| **Kuantisasi bilangan bulat** | [`Int4WeightOnlyConfig`](https://docs.pytorch.org/ao/stable/api_reference/generated/torchao.quantization.Int4WeightOnlyConfig.html), [`Int8WeightOnlyConfig`](https://docs.pytorch.org/ao/stable/api_reference/generated/torchao.quantization.Int8WeightOnlyConfig.html), [`Int8DynamicActivationInt8WeightConfig`](https://docs.pytorch.org/ao/stable/api_reference/generated/torchao.quantization.Int8DynamicActivationInt8WeightConfig.html) |
| **Kuantisasi floating point 8-bit** | [`Float8WeightOnlyConfig`](https://docs.pytorch.org/ao/stable/api_reference/generated/torchao.quantization.Float8WeightOnlyConfig.html), [`Float8DynamicActivationFloat8WeightConfig`](https://docs.pytorch.org/ao/stable/api_reference/generated/torchao.quantization.Float8DynamicActivationFloat8WeightConfig.html) |
| **Kuantisasi bilangan bulat tak bertanda** | [`IntxWeightOnlyConfig`](https://docs.pytorch.org/ao/stable/api_reference/generated/torchao.quantization.IntxWeightOnlyConfig.html) |

## Menserialisasi dan Mendeserialisasi model terkuantisasi

Untuk mengserialisasi model terkuantisasi dalam dtype tertentu, pertama muat model dengan dtype kuantisasi yang diinginkan, lalu simpan menggunakan metode [save_pretrained()](/docs/diffusers/main/id/api/models/overview#diffusers.ModelMixin.save_pretrained).

```python
import torch
from diffusers import AutoModel, TorchAoConfig
from torchao.quantization import Int8WeightOnlyConfig

quantization_config = TorchAoConfig(Int8WeightOnlyConfig())
transformer = AutoModel.from_pretrained(
    "black-forest-labs/Flux.1-Dev",
    subfolder="transformer",
    quantization_config=quantization_config,
    dtype=torch.bfloat16,
)
transformer.save_pretrained("/path/to/flux_int8wo", safe_serialization=False)
```

Untuk memuat model kuantisasi yang telah diserialisasi, gunakan metode [from_pretrained()](/docs/diffusers/main/id/api/models/overview#diffusers.ModelMixin.from_pretrained).

```python
import torch
from diffusers import FluxPipeline, AutoModel

transformer = AutoModel.from_pretrained("/path/to/flux_int8wo", dtype=torch.bfloat16, use_safetensors=False)
pipe = FluxPipeline.from_pretrained("black-forest-labs/Flux.1-Dev", transformer=transformer, dtype=torch.bfloat16)
pipe.to("cuda")  # or "mps", "xpu", "cpu"

prompt = "A cat holding a sign that says hello world"
image = pipe(prompt, num_inference_steps=30, guidance_scale=7.0).images[0]
image.save("output.png")
```

Jika Anda menggunakan `torch<=2.6.0`, beberapa metode kuantisasi, seperti `uint4` weight-only, tidak dapat dimuat secara langsung dan dapat menyebabkan `UnpicklingError` saat mencoba memuat model, tetapi berfungsi sesuai harapan saat menyimpannya. Untuk mengatasi hal ini, Anda dapat memuat state dict secara manual ke dalam model. Namun, perhatikan bahwa ini memerlukan penggunaan `weights_only=False` di `torch.load`, sehingga hanya harus dijalankan jika bobot diperoleh dari sumber yang dapat dipercaya.

```python
import torch
from accelerate import init_empty_weights
from diffusers import FluxPipeline, AutoModel, TorchAoConfig
from torchao.quantization import IntxWeightOnlyConfig

# Serialize the model
transformer = AutoModel.from_pretrained(
    "black-forest-labs/Flux.1-Dev",
    subfolder="transformer",
    quantization_config=TorchAoConfig(IntxWeightOnlyConfig(dtype=torch.uint4)),
    dtype=torch.bfloat16,
)
transformer.save_pretrained("/path/to/flux_uint4wo", safe_serialization=False, max_shard_size="50GB")
# ...

# Load the model
state_dict = torch.load("/path/to/flux_uint4wo/diffusion_pytorch_model.bin", weights_only=False, map_location="cpu")
with init_empty_weights():
    transformer = AutoModel.from_config("/path/to/flux_uint4wo/config.json")
transformer.load_state_dict(state_dict, strict=True, assign=True)
```

> [!TIP]
> API [AutoModel](/docs/diffusers/main/id/api/models/auto_model#diffusers.AutoModel) didukung untuk PyTorch >= 2.6 seperti yang ditunjukkan pada contoh di bawah ini.

## Sumber daya

- [API Kuantisasi TorchAO](https://docs.pytorch.org/ao/stable/index.html)
- [Contoh Diffusers-TorchAO](https://github.com/sayakpaul/diffusers-torchao)

