Skip to content

Commit 1770675

Browse files
authored
Revert "Autoquant (pytorch#82)" (pytorch#83)
This reverts commit 8119319.
1 parent 22ed8b9 commit 1770675

File tree

7 files changed

+20
-531
lines changed

7 files changed

+20
-531
lines changed

README.md

Lines changed: 11 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
# torchao: PyTorch Architecture Optimization
1+
# torchao: PyTorch Architecture Optimization
22

33
**Note: This repository is currently under heavy development - if you have suggestions on the API or use-cases you'd like to be covered, please open an github issue**
44

5-
The `torchao` package allows you to quantize and prune your models using native PyTorch.
5+
The `torchao` package allows you to quantize and prune your models using native PyTorch.
66

77
The repo hosts both
88
1. lower precision [dtypes](./torchao/dtypes) such as nf4, uint4
@@ -38,43 +38,31 @@ pip install -e .
3838

3939
Typically quantization algorithms will have different schemes for how the activation and weights are quantized so A16W8 for instance means the activations are quantized to 16 bits wheras the weights are quantized to 8 bits. Trying out different quantization schemes in `torchao` is generally a 1 line change.
4040

41-
### Autoquantization
42-
43-
The `autoquant` api can be used to quickly and accurately quantize your model. When used as in the example below, the api first identifies the shapes
44-
of the activations that the different linear layers see, it then benchmarks these shapes across different types of quantized and non-quantized layers in order to pick the fastest one, attempting to take into account fusions where possible. Finally once the best class is found for each layer, it swaps the linear. Currently this api chooses between no quantization, int8 dynamic quantization and int8 weight only quantization for each layer.
41+
### A8W8 Dynamic Quantization
4542

46-
```python
43+
```Python
4744
import torch
48-
import torchao
45+
from torchao.quantization import quant_api
4946

50-
# inductor settings which improve torch.compile performance for quantized modules
51-
torch._inductor.config.force_fuse_int_mm_with_mul
52-
torch._inductor.config.use_mixed_mm
47+
# Fuse the int8*int8 -> int32 matmul and subsequent mul op avoiding materialization of the int32 intermediary tensor
48+
torch._inductor.config.force_fuse_int_mm_with_mul = True
5349

5450
# Plug in your model and example input
5551
model = torch.nn.Sequential(torch.nn.Linear(32, 64)).cuda().to(torch.bfloat16)
5652
input = torch.randn(32,32, dtype=torch.bfloat16, device='cuda')
5753

58-
# perform autoquantization
59-
torchao.autoquant(model, (input))
54+
# convert linear modules to quantized linear modules
55+
quant_api.change_linear_weights_to_int8_dqtensors(model)
6056

6157
# compile the model to improve performance
6258
model = torch.compile(model, mode='max-autotune')
6359
model(input)
6460
```
6561

66-
67-
### A8W8 Dynamic Quantization
68-
69-
```python
70-
# convert linear modules to quantized linear modules
71-
torchao.change_linear_weights_to_int8_dqtensors(model)
72-
```
73-
7462
### A16W8 WeightOnly Quantization
7563

7664
```python
77-
torchao.change_linear_weights_to_int8_woqtensors(model)
65+
quant_api.change_linear_weights_to_int8_woqtensors(model)
7866
```
7967

8068
This technique works best when the torch._inductor.config.use_mixed_mm option is enabled. This avoids dequantizing the weight tensor before the matmul, instead fusing the dequantization into the matmul, thereby avoiding materialization of a large floating point weight tensor.
@@ -83,7 +71,7 @@ This technique works best when the torch._inductor.config.use_mixed_mm option is
8371
### A16W4 WeightOnly Quantization
8472

8573
```python
86-
torchao.change_linear_weights_to_int4_woqtensors(model)
74+
quant_api.change_linear_weights_to_int4_woqtensors(model)
8775
```
8876

8977
Note: The quantization error incurred by applying int4 quantization to your model can be fairly significant, so using external techniques like GPTQ may be necessary to obtain a usable model.

test/test.py

Lines changed: 0 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
import torch.nn as nn
1313
from torch._inductor.utils import run_and_get_code
1414
from torch._dynamo import config
15-
import torchao
1615
from torch.ao.quantization import MinMaxObserver, QConfigMapping
1716

1817
from torchao.quantization.dynamic_quant import (
@@ -55,13 +54,6 @@
5554
_fqn_to_op_to_shape_to_count,
5655
LoggingTensorMode,
5756
)
58-
from torchao.quantization.autoquant import (
59-
AQInt8DynamicallyQuantizedLinearWeight,
60-
AQWeightOnlyQuantizedLinearWeight,
61-
AQWeightOnlyQuantizedLinearWeight2,
62-
AQWeightOnlyQuantizedLinearWeight3
63-
64-
)
6557
from torch.ao.quantization.quantize_fx import convert_to_reference_fx, prepare_fx
6658
import os
6759

@@ -888,36 +880,6 @@ def test_int8_weight_only_quant_subclass(self):
888880
Int8WeightOnlyQuantizedLinearWeight.from_float, 40, test_dtype
889881
)
890882

891-
def test_aq_int8_dynamic_quant_subclass(self):
892-
for test_dtype in [torch.float32, torch.float16, torch.bfloat16]:
893-
self._test_lin_weight_subclass_impl(
894-
AQInt8DynamicallyQuantizedLinearWeight.from_float, 35, test_dtype
895-
)
896-
897-
def test_aq_int8_weight_only_quant_subclass(self):
898-
for test_dtype in [torch.float32, torch.float16, torch.bfloat16]:
899-
self._test_lin_weight_subclass_impl(
900-
AQInt8DynamicallyQuantizedLinearWeight.from_float, 35, test_dtype
901-
)
902-
903-
def test_aq_int8_weight_only_quant_subclass(self):
904-
for test_dtype in [torch.float32, torch.float16, torch.bfloat16]:
905-
self._test_lin_weight_subclass_impl(
906-
AQWeightOnlyQuantizedLinearWeight.from_float, 35, test_dtype
907-
)
908-
909-
def test_aq_int8_weight_only_quant_2_subclass(self):
910-
for test_dtype in [torch.float32, torch.float16, torch.bfloat16]:
911-
self._test_lin_weight_subclass_impl(
912-
AQWeightOnlyQuantizedLinearWeight2.from_float, 35, test_dtype
913-
)
914-
915-
def test_aq_int8_weight_only_quant_3_subclass(self):
916-
for test_dtype in [torch.float32, torch.float16, torch.bfloat16]:
917-
self._test_lin_weight_subclass_impl(
918-
AQWeightOnlyQuantizedLinearWeight3.from_float, 35, test_dtype
919-
)
920-
921883
def test_int4_weight_only_quant_subclass(self):
922884
self._test_lin_weight_subclass_impl(
923885
Int4WeightOnlyQuantizedLinearWeight.from_float, 10, test_shape=[1, 1024, 8]
@@ -1233,51 +1195,6 @@ def test_on_dummy_distilbert(self):
12331195
print("sqnr_pt_quant", sqnr_pt_quant)
12341196
self.assertTrue(sqnr_sq >= 8.0)
12351197

1236-
class TestAutoQuant(unittest.TestCase):
1237-
def test_autoquant_one_input(self):
1238-
torch._inductor.config.epilogue_fusion = False
1239-
torch._inductor.config.use_mixed_mm = True
1240-
torch._inductor.config.force_fuse_int_mm_with_mul = True
1241-
torch._dynamo.config.automatic_dynamic_shapes = False
1242-
1243-
for m,k,n in [
1244-
(1, 1024, 1024),
1245-
(64, 1024, 1024),
1246-
(2**15, 1024, 1024),
1247-
(1, 1024, 4096),
1248-
(64, 1024, 4096),
1249-
(1, 4096, 1024),
1250-
(64, 4096, 1024),
1251-
(4096, 4096, 1024),
1252-
]:
1253-
example_input = torch.randn(m, k, device="cuda", dtype=torch.bfloat16)
1254-
model = torch.nn.Sequential(
1255-
torch.nn.ReLU(),
1256-
torch.nn.Linear(k,n),
1257-
torch.nn.ReLU(),
1258-
).to("cuda").to(torch.bfloat16)
1259-
out = model(example_input)
1260-
torchao.autoquant(model, example_input)
1261-
out2 = model(example_input)
1262-
sqnr = SQNR(out, out2)
1263-
self.assertTrue(sqnr >= 30)
1264-
1265-
def test_autoquant_multi_input(self):
1266-
m1, m2, k, n = 1, 8, 1024, 1024
1267-
model = torch.nn.Sequential(
1268-
torch.nn.ReLU(),
1269-
torch.nn.Linear(k,n),
1270-
torch.nn.ReLU(),
1271-
).cuda().to(torch.bfloat16)
1272-
example_input = torch.randn(m1, k, device="cuda", dtype=torch.bfloat16)
1273-
example_input2 = torch.randn(m2, k, device="cuda", dtype=torch.bfloat16)
1274-
torchao.change_linears_to_autoquantizable(model)
1275-
out=model(example_input)
1276-
model(example_input2)
1277-
torchao.change_autoquantizable_to_quantized(model)
1278-
out2 = model(example_input)
1279-
sqnr = SQNR(out, out2)
1280-
self.assertTrue(sqnr >= 30)
12811198

12821199
if __name__ == "__main__":
12831200
unittest.main()

torchao/__init__.py

Lines changed: 4 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,8 @@
1-
from torchao.quantization import (
2-
apply_weight_only_int8_quant,
3-
apply_dynamic_quant,
4-
change_linear_weights_to_int8_dqtensors,
5-
change_linear_weights_to_int8_woqtensors,
6-
change_linear_weights_to_int4_woqtensors,
7-
swap_conv2d_1x1_to_linear,
8-
autoquant,
9-
change_linears_to_autoquantizable,
10-
change_autoquantizable_to_quantized,
11-
)
121
from . import dtypes
2+
from .quantization.quant_api import apply_dynamic_quant
3+
from .quantization.quant_api import apply_weight_only_int8_quant
134

145
__all__ = [
15-
"dtypes",
16-
"apply_dynamic_quant",
17-
"apply_weight_only_int8_quant",
18-
"apply_dynamic_quant",
19-
"change_linear_weights_to_int8_dqtensors",
20-
"change_linear_weights_to_int8_woqtensors",
21-
"change_linear_weights_to_int4_woqtensors",
22-
"swap_conv2d_1x1_to_linear"
23-
"safe_int_mm",
24-
"autoquant",
25-
"change_linears_to_autoquantizable",
26-
"change_autoquantizable_to_quantized",
27-
"dtypes"
6+
"dtypes",
7+
"apply_dynamic_quant",
288
]

torchao/quantization/__init__.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,6 @@
2525
"dynamically_quantize_per_channel",
2626
"dequantize_per_tensor",
2727
"dequantize_per_channel",
28-
"autoquant",
29-
"change_linears_to_autoquantizable",
30-
"change_autoquantizable_to_quantized",
3128
"quant_int8_dynamic_linear",
3229
"quant_int8_matmul",
3330
"quant_int8_dynamic_per_token_linear",

0 commit comments

Comments
 (0)