|
5 | 5 |
|
6 | 6 | import numpy as np
|
7 | 7 | import torch
|
| 8 | +from io import StringIO |
| 9 | +import sys |
8 | 10 |
|
9 | 11 | import coremltools as ct
|
10 | 12 | from coremltools.optimize.coreml.experimental._post_training_quantization import (
|
11 | 13 | _get_activation_calibration_stats,
|
12 | 14 | )
|
| 15 | +from coremltools.test.optimize.coreml.test_passes import TestCompressionPasses |
| 16 | +import coremltools.optimize as cto |
13 | 17 |
|
14 | 18 |
|
15 | 19 | class TestActivationQuantization:
|
@@ -72,6 +76,45 @@ def forward(self, img): # convert + flatten
|
72 | 76 |
|
73 | 77 |
|
74 | 78 | class TestGetActivationStats(TestActivationQuantization):
|
| 79 | + |
| 80 | + def test_activation_quantization(self): |
| 81 | + """ |
| 82 | + Test the usage of linear_quantize_activations. |
| 83 | + """ |
| 84 | + sample_data = [] |
| 85 | + for _ in range(3): |
| 86 | + input_data = np.random.rand(5, 10, 4, 4) |
| 87 | + sample_data.append({"data": input_data}) |
| 88 | + |
| 89 | + mlmodel = self._get_test_mlmodel_conv_relu() |
| 90 | + activation_quant_config = cto.coreml.OptimizationConfig( |
| 91 | + global_config=cto.coreml.experimental.OpActivationLinearQuantizerConfig( |
| 92 | + mode="linear_symmetric", weight_threshold=10 |
| 93 | + ) |
| 94 | + ) |
| 95 | + |
| 96 | + def _run_quantization_with_group_size(group_size, expected_batch_size): |
| 97 | + buffer = StringIO() |
| 98 | + original_stderr = sys.stderr |
| 99 | + sys.stderr = buffer |
| 100 | + mlmodel_activation_quantized = cto.coreml.experimental.linear_quantize_activations( |
| 101 | + mlmodel, |
| 102 | + activation_quant_config, |
| 103 | + sample_data, |
| 104 | + calibration_op_group_size=group_size, |
| 105 | + ) |
| 106 | + sys.stderr = original_stderr |
| 107 | + output = buffer.getvalue() |
| 108 | + assert f"tensors batch-by-batch: {expected_batch_size} batches" in output |
| 109 | + |
| 110 | + # when setting group size to -1, all intermediate outputs are in the same batch, |
| 111 | + # hence we will only get 1 batch |
| 112 | + _run_quantization_with_group_size(-1, 1) |
| 113 | + # when setting group size to 1, all intermediate outputs are split into different batches, |
| 114 | + # hence there will be 3 batches |
| 115 | + _run_quantization_with_group_size(1, 3) |
| 116 | + |
| 117 | + |
75 | 118 | def test_get_activation_calibration_stats_basic(self):
|
76 | 119 | """
|
77 | 120 | Calibration a floating point model with sample data.
|
@@ -113,7 +156,7 @@ def test_get_activation_calibration_stats_concat_surrounding_ops(self):
|
113 | 156 | sample_data.append({"data_0": input_data})
|
114 | 157 |
|
115 | 158 | # Loading a floating point mlmodel
|
116 |
| - mlmodel = self._get_test_mlmodel_conv_concat() |
| 159 | + mlmodel = TestCompressionPasses._get_test_mlmodel_conv_concat() |
117 | 160 |
|
118 | 161 | activation_stats = _get_activation_calibration_stats(mlmodel, sample_data)
|
119 | 162 |
|
|
0 commit comments