# GPTQ

O projeto [GPT-QModel](https://github.com/ModelCloud/GPTQModel) (pacote Python `gptqmodel`) implementa o algoritmo GPTQ, uma técnica de quantização pós-treino em que cada linha da matriz de pesos é quantizada de forma independente para encontrar uma versão dos pesos que minimize o erro. Esses pesos são quantizados para int4, mas são restaurados para fp16 em tempo real durante a inferência. Isso pode economizar 4x o uso de memória, pois os pesos int4 são desquantizados em um kernel fundido, em vez da memória global da GPU. A inferência também é mais rápida, pois uma largura de bits menor leva menos tempo para comunicar.

O AutoGPTQ não é mais suportado no Transformers. Instale o GPT-QModel em vez disso.

Instale primeiro o Accelerate, o Transformers e o Optimum.

```bash
pip install --upgrade accelerate optimum transformers
```

Em seguida, execute o comando abaixo para instalar o GPT-QModel.

```bash
pip install gptqmodel --no-build-isolation
```

Crie uma classe [GPTQConfig](/docs/transformers/main/pt/main_classes/quantization#transformers.GPTQConfig) e defina o número de bits para quantização, um conjunto de dados para calibrar os pesos para a quantização e um tokenizador para preparar o conjunto de dados.

```py
from transformers import AutoModelForCausalLM, AutoTokenizer, GPTQConfig

tokenizer = AutoTokenizer.from_pretrained("facebook/opt-125m")
gptq_config = GPTQConfig(bits=4, dataset="c4", tokenizer=tokenizer)
```

Você pode passar seu próprio conjunto de dados como uma lista de strings, mas é altamente recomendável usar o mesmo conjunto de dados do artigo GPTQ.

```py
dataset = ["gptqmodel is an easy-to-use model quantization library with user-friendly apis, based on the GPTQ algorithm."]
gptq_config = GPTQConfig(bits=4, dataset=dataset, tokenizer=tokenizer)
```

Carregue um modelo para quantizar e passe [GPTQConfig](/docs/transformers/main/pt/main_classes/quantization#transformers.GPTQConfig) para [from_pretrained()](/docs/transformers/main/pt/model_doc/auto#transformers.AutoModel.from_pretrained). Defina `device_map="auto"` para descarregar automaticamente o modelo para a CPU, ajudando a caber o modelo na memória, e permitindo que os módulos do modelo sejam movidos entre a CPU e a GPU para a quantização.

```py
quantized_model = AutoModelForCausalLM.from_pretrained("facebook/opt-125m", device_map="auto", quantization_config=gptq_config)
```

Se você estiver ficando sem memória porque um conjunto de dados é grande demais (o offloading para o disco não é suportado), tente passar o parâmetro `max_memory` para alocar a quantidade de memória a ser usada no seu dispositivo (GPU e CPU).

```py
quantized_model = AutoModelForCausalLM.from_pretrained(
    "facebook/opt-125m",
    device_map="auto",
    max_memory={0: "30GiB", 1: "46GiB", "cpu": "30GiB"},
    quantization_config=gptq_config
)
```

> [!WARNING]
> Dependendo do seu hardware, pode levar algum tempo para quantizar um modelo do zero. Pode levar cerca de 5 minutos para quantizar o modelo [facebook/opt-350m](https://huggingface.co/facebook/opt-350m) em uma GPU do Google Colab de nível gratuito, mas levará cerca de 4 horas para quantizar um modelo com 175 bilhões de parâmetros em uma NVIDIA A100. Antes de quantizar um modelo, é uma boa ideia verificar no Hub se uma versão quantizada com GPTQ do modelo já existe.

Depois que um modelo é quantizado, você pode usar [push_to_hub()](/docs/transformers/main/pt/main_classes/model#transformers.utils.PushToHubMixin.push_to_hub) para enviar o modelo e o tokenizer para o Hub, onde ele pode ser facilmente compartilhado e acessado. Isso salva o [GPTQConfig](/docs/transformers/main/pt/main_classes/quantization#transformers.GPTQConfig).

```py
quantized_model.push_to_hub("opt-125m-gptq")
tokenizer.push_to_hub("opt-125m-gptq")
```

[save_pretrained()](/docs/transformers/main/pt/main_classes/model#transformers.PreTrainedModel.save_pretrained) salva um modelo quantizado localmente. Se o modelo foi quantizado com o parâmetro `device_map`, certifique-se de mover o modelo inteiro para uma GPU ou CPU antes de salvá-lo. O exemplo abaixo salva o modelo em uma CPU.

```py
quantized_model.save_pretrained("opt-125m-gptq")
tokenizer.save_pretrained("opt-125m-gptq")

# if quantized with device_map set
quantized_model.to("cpu")
quantized_model.save_pretrained("opt-125m-gptq")
```

Recarregue um modelo quantizado com [from_pretrained()](/docs/transformers/main/pt/main_classes/model#transformers.PreTrainedModel.from_pretrained) e defina `device_map="auto"` para distribuir automaticamente o modelo em todas as GPUs disponíveis, carregando-o mais rápido sem usar mais memória do que o necessário.

```py
from transformers import AutoModelForCausalLM

model = AutoModelForCausalLM.from_pretrained("{your_username}/opt-125m-gptq", device_map="auto")
```

## Marlin

[Marlin](https://github.com/IST-DASLab/marlin) é um kernel CUDA GPTQ exclusivo para 4 bits, altamente otimizado para a arquitetura de GPU NVIDIA A100 (Ampere). O carregamento, a desquantização e a execução dos pesos após a desquantização são altamente paralelizados, oferecendo uma melhoria substancial na inferência em comparação com o kernel CUDA GPTQ original. O Marlin está disponível apenas para inferência quantizada e não suporta quantização de modelos.

A inferência Marlin pode ser ativada com o parâmetro `backend` em [GPTQConfig](/docs/transformers/main/pt/main_classes/quantization#transformers.GPTQConfig).

```py

from transformers import AutoModelForCausalLM, GPTQConfig

model = AutoModelForCausalLM.from_pretrained("{your_username}/opt-125m-gptq", device_map="auto", quantization_config=GPTQConfig(bits=4, backend="marlin"))
```

## GPT-QModel

GPT-QModel é o backend ativamente mantido para GPTQ em Transformers. Originalmente, foi um fork de AutoGPTQ, mas desde então divergiu com melhorias significativas, como quantização mais rápida, menor uso de memória e padrões mais precisos.

O GPT-QModel fornece quantização assimétrica, que pode potencialmente reduzir os erros de quantização em comparação com a quantização simétrica. Ele não é compatível com checkpoints legados do AutoGPTQ, e nem todos os kernels (Marlin) suportam quantização assimétrica.

O GPT-QModel também oferece suporte mais amplo aos modelos de LLM mais recentes, a modelos multimodais (Qwen2-VL e Ovis1.6-VL), a plataformas (Linux, macOS, Windows 11) e a hardware (AMD ROCm, Apple Silicon, CPUs Intel/AMD e GPUs Intel Datacenter Max/Arc, entre outros).

Os kernels Marlin também foram atualizados para GPUs A100, e outros kernels foram atualizados para incluir auto-padding para modelos legados e modelos com características de entrada/saída não uniformes.

## Recursos

Execute a quantização GPTQ com PEFT no [notebook](https://colab.research.google.com/drive/1_TIrmuKOFhuRRiTWN94iLKUFu6ZX4ceb?usp=sharing) para uma experiência prática.

