tico 0.1.0.dev250805__py3-none-any.whl → 0.1.0.dev250806__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- tico/__init__.py +1 -1
- tico/experimental/quantization/algorithm/gptq/quantizer.py +16 -3
- tico/experimental/quantization/evaluation/evaluate.py +1 -4
- tico/experimental/quantization/evaluation/metric.py +86 -66
- {tico-0.1.0.dev250805.dist-info → tico-0.1.0.dev250806.dist-info}/METADATA +2 -1
- {tico-0.1.0.dev250805.dist-info → tico-0.1.0.dev250806.dist-info}/RECORD +10 -10
- {tico-0.1.0.dev250805.dist-info → tico-0.1.0.dev250806.dist-info}/LICENSE +0 -0
- {tico-0.1.0.dev250805.dist-info → tico-0.1.0.dev250806.dist-info}/WHEEL +0 -0
- {tico-0.1.0.dev250805.dist-info → tico-0.1.0.dev250806.dist-info}/entry_points.txt +0 -0
- {tico-0.1.0.dev250805.dist-info → tico-0.1.0.dev250806.dist-info}/top_level.txt +0 -0
tico/__init__.py
CHANGED
@@ -17,6 +17,7 @@ import types
|
|
17
17
|
from typing import Any, Callable, Dict, List, Optional
|
18
18
|
|
19
19
|
import torch
|
20
|
+
from tqdm.auto import tqdm
|
20
21
|
|
21
22
|
from tico.experimental.quantization.algorithm.gptq.gptq import GPTQ
|
22
23
|
from tico.experimental.quantization.algorithm.gptq.utils import (
|
@@ -181,7 +182,9 @@ class GPTQQuantizer(BaseQuantizer):
|
|
181
182
|
target_layers = [model]
|
182
183
|
|
183
184
|
quantizers: Dict[str, Any] = {}
|
184
|
-
for l_idx, layer in enumerate(
|
185
|
+
for l_idx, layer in enumerate(
|
186
|
+
tqdm(target_layers, desc="Quantizing layers", unit="layer")
|
187
|
+
):
|
185
188
|
# 1) Identify quantizable submodules within the layer
|
186
189
|
full = find_layers(layer)
|
187
190
|
sequential = [list(full.keys())]
|
@@ -210,7 +213,12 @@ class GPTQQuantizer(BaseQuantizer):
|
|
210
213
|
|
211
214
|
# Run layer forward over all cached batches to build Hessian/statistics
|
212
215
|
batch_num = self.num_batches
|
213
|
-
for batch_idx in
|
216
|
+
for batch_idx in tqdm(
|
217
|
+
range(batch_num),
|
218
|
+
desc=f"[L{l_idx}] collecting",
|
219
|
+
leave=False,
|
220
|
+
unit="batch",
|
221
|
+
):
|
214
222
|
cache_args_batch = gather_single_batch_from_list(
|
215
223
|
self.cache_args, batch_idx
|
216
224
|
)
|
@@ -238,7 +246,12 @@ class GPTQQuantizer(BaseQuantizer):
|
|
238
246
|
gptq[name].free()
|
239
247
|
|
240
248
|
# 4) After quantization, re-run the layer to produce outputs for the next layer
|
241
|
-
for batch_idx in
|
249
|
+
for batch_idx in tqdm(
|
250
|
+
range(batch_num),
|
251
|
+
desc=f"[L{l_idx}] re-forward",
|
252
|
+
leave=False,
|
253
|
+
unit="batch",
|
254
|
+
):
|
242
255
|
cache_args_batch = gather_single_batch_from_list(
|
243
256
|
self.cache_args, batch_idx
|
244
257
|
)
|
@@ -114,7 +114,6 @@ def evaluate(
|
|
114
114
|
input_data: InputDataType = None,
|
115
115
|
*,
|
116
116
|
mode="plot",
|
117
|
-
metrics: List[str] = ["peir"],
|
118
117
|
custom_metrics: Dict[str, Callable] = dict(),
|
119
118
|
) -> Optional[Dict[str, Any]]:
|
120
119
|
"""
|
@@ -140,8 +139,6 @@ def evaluate(
|
|
140
139
|
The mode of operation. Options are:
|
141
140
|
- "plot": Plot the results (default)
|
142
141
|
- "return": Return the results.
|
143
|
-
metrics
|
144
|
-
A list of metric names for comparison.
|
145
142
|
custom_metrics
|
146
143
|
A dictionary of metric names and corresponding callable functions for comparison.
|
147
144
|
Example: {'mse': mean_squared_error, 'cosine_similarity': cosine_similarity_fn}
|
@@ -205,7 +202,7 @@ def evaluate(
|
|
205
202
|
)
|
206
203
|
|
207
204
|
# Computes the comparison score based on the provided metrics.
|
208
|
-
metric_calculator = MetricCalculator(
|
205
|
+
metric_calculator = MetricCalculator(custom_metrics)
|
209
206
|
results: Dict[str, Any] = metric_calculator.compute(torch_output, circle_output)
|
210
207
|
|
211
208
|
if mode == "return":
|
@@ -12,98 +12,118 @@
|
|
12
12
|
# See the License for the specific language governing permissions and
|
13
13
|
# limitations under the License.
|
14
14
|
|
15
|
-
from typing import Any, Callable, Dict, List
|
15
|
+
from typing import Any, Callable, Dict, List, Optional
|
16
16
|
|
17
17
|
import numpy as np
|
18
18
|
import torch
|
19
19
|
|
20
20
|
|
21
|
-
def
|
21
|
+
def compute_max_abs_diff(base: torch.Tensor, target: torch.Tensor) -> float:
|
22
22
|
"""
|
23
|
-
|
24
|
-
|
25
|
-
This function computes the PEIR between two tensors using the formula:
|
26
|
-
PEIR = max(abs(tensor1 - tensor2)) / (max(tensor1) - min(tensor2))
|
23
|
+
Return the *maximum* absolute element-wise difference between two tensors.
|
27
24
|
"""
|
28
|
-
assert base.shape == target.shape,
|
29
|
-
|
30
|
-
target_tensor = target.numpy()
|
31
|
-
assert (
|
32
|
-
base_tensor.dtype == np.float32 and target_tensor.dtype == np.float32
|
33
|
-
), f"dtype should be float32: base({base_tensor.dtype}), target({target_tensor.dtype})"
|
34
|
-
|
35
|
-
base_tensor = base_tensor.reshape(-1)
|
36
|
-
target_tensor = target_tensor.reshape(-1)
|
25
|
+
assert base.shape == target.shape, "shape mismatch"
|
26
|
+
return (base.detach() - target.detach()).abs().max().item()
|
37
27
|
|
38
|
-
assert (
|
39
|
-
base_tensor.shape == target_tensor.shape
|
40
|
-
), f"Shape mismatch: {base_tensor.shape} != {target_tensor.shape}"
|
41
28
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
min_value = min([base_tensor.min(), target_tensor.min()])
|
47
|
-
max_value = max([base_tensor.max(), target_tensor.max()])
|
29
|
+
def compute_peir(base: torch.Tensor, target: torch.Tensor) -> float:
|
30
|
+
"""
|
31
|
+
Peak-Error-to-Interval Ratio (PEIR).
|
48
32
|
|
49
|
-
|
50
|
-
interval = 1.0 if interval == 0.0 else interval # Avoid zero interval
|
33
|
+
PEIR = max(|base - target|) / (max(base) - min(base))
|
51
34
|
|
52
|
-
|
35
|
+
The interval denominator uses the reference (*base*) tensor only — this
|
36
|
+
makes PEIR independent of quantisation error in `target`.
|
37
|
+
"""
|
38
|
+
assert base.shape == target.shape, "shape mismatch"
|
39
|
+
peak_error = (base.detach() - target.detach()).abs().max().item()
|
40
|
+
interval = (base.detach().max() - base.detach().min()).item()
|
41
|
+
interval = 1.0 if interval == 0.0 else interval # avoid divide-by-zero
|
42
|
+
return peak_error / interval
|
53
43
|
|
54
44
|
|
55
45
|
class MetricCalculator:
|
56
46
|
"""
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
47
|
+
Lightweight registry-and-dispatcher for **pair-wise tensor comparison metrics**.
|
48
|
+
|
49
|
+
Purpose
|
50
|
+
-------
|
51
|
+
Consolidate all metrics used to assess the discrepancy between a reference
|
52
|
+
(usually FP32) tensor and its quantized counterpart, while letting the caller
|
53
|
+
choose *at runtime* which subset to evaluate.
|
54
|
+
|
55
|
+
Built-in metrics
|
56
|
+
----------------
|
57
|
+
Key Description
|
58
|
+
-------------------- -------------------------------------------------
|
59
|
+
"diff" / "max_abs_diff" Maximum absolute element-wise difference
|
60
|
+
"peir" Peak-Error-to-Interval Ratio
|
61
|
+
|
62
|
+
Usage pattern
|
63
|
+
-------------
|
64
|
+
>>> calc = MetricCalculator(custom_metrics={'mse': mse_fn})
|
65
|
+
>>> stats = calc.compute(fp_outs, q_outs, metrics=['diff', 'mse'])
|
66
|
+
|
67
|
+
• **Instantiation** registers any extra user metrics
|
68
|
+
(signature: ``fn(base: Tensor, target: Tensor) -> float``).
|
69
|
+
• **compute(...)** takes two *equal-length* lists of tensors and an optional
|
70
|
+
list of metric names.
|
71
|
+
— If *metrics* is *None*, every registered metric is evaluated.
|
72
|
+
— Returns a dict: ``{metric_name -> [value for each tensor pair]}``.
|
73
|
+
|
74
|
+
Implementation notes
|
75
|
+
--------------------
|
76
|
+
* All tensors are detached before calculation to avoid autograd overhead.
|
77
|
+
* Registrations are stored in `self.registry` (str → callable).
|
78
|
+
* Duplicate metric names between built-ins and custom metrics raise an error
|
79
|
+
at construction time to prevent silent shadowing.
|
64
80
|
"""
|
65
81
|
|
66
|
-
builtin_metrics = {
|
82
|
+
builtin_metrics: Dict[str, Callable[[torch.Tensor, torch.Tensor], float]] = {
|
83
|
+
"diff": compute_max_abs_diff,
|
84
|
+
"max_abs_diff": compute_max_abs_diff,
|
67
85
|
"peir": compute_peir,
|
68
86
|
}
|
69
87
|
|
70
88
|
def __init__(
|
71
89
|
self,
|
72
|
-
|
73
|
-
|
90
|
+
custom_metrics: Optional[
|
91
|
+
Dict[str, Callable[[torch.Tensor, torch.Tensor], float]]
|
92
|
+
] = None,
|
74
93
|
):
|
75
|
-
self.
|
76
|
-
|
77
|
-
|
78
|
-
if
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
self.metrics = self.metrics | custom_metrics
|
88
|
-
|
94
|
+
self.registry: Dict[str, Callable] = self.builtin_metrics.copy()
|
95
|
+
if custom_metrics:
|
96
|
+
dup = self.registry.keys() & custom_metrics.keys()
|
97
|
+
if dup:
|
98
|
+
raise RuntimeError(f"Duplicate metric names: {dup}")
|
99
|
+
assert custom_metrics is not None
|
100
|
+
self.registry.update(custom_metrics) # type: ignore[arg-type]
|
101
|
+
|
102
|
+
# ----------------------------------------------------------------- #
|
103
|
+
# Public API #
|
104
|
+
# ----------------------------------------------------------------- #
|
89
105
|
def compute(
|
90
|
-
self,
|
106
|
+
self,
|
107
|
+
base_outputs: List[torch.Tensor],
|
108
|
+
target_outputs: List[torch.Tensor],
|
109
|
+
metrics: Optional[List[str]] = None,
|
91
110
|
) -> Dict[str, List[Any]]:
|
92
111
|
"""
|
93
|
-
Compute
|
112
|
+
Compute selected metrics for every (base, target) pair.
|
94
113
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
114
|
+
Parameters
|
115
|
+
----------
|
116
|
+
metrics
|
117
|
+
List of metric names to evaluate **this call**.
|
118
|
+
• None → evaluate *all* registered metrics.
|
99
119
|
"""
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
120
|
+
sel = metrics or list(self.registry)
|
121
|
+
unknown = set(sel) - self.registry.keys()
|
122
|
+
if unknown:
|
123
|
+
raise RuntimeError(f"Unknown metric(s): {unknown}")
|
124
|
+
|
125
|
+
results: Dict[str, List[Any]] = {m: [] for m in sel}
|
126
|
+
for base, tgt in zip(base_outputs, target_outputs):
|
127
|
+
for m in sel:
|
128
|
+
results[m].append(self.registry[m](base, tgt))
|
109
129
|
return results
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: tico
|
3
|
-
Version: 0.1.0.
|
3
|
+
Version: 0.1.0.dev250806
|
4
4
|
Summary: Convert exported Torch module to circle
|
5
5
|
Home-page: UNKNOWN
|
6
6
|
License: UNKNOWN
|
@@ -13,6 +13,7 @@ Requires-Dist: circle-schema
|
|
13
13
|
Requires-Dist: packaging
|
14
14
|
Requires-Dist: pyyaml
|
15
15
|
Requires-Dist: torch
|
16
|
+
Requires-Dist: tqdm
|
16
17
|
|
17
18
|
# TICO
|
18
19
|
|
@@ -1,4 +1,4 @@
|
|
1
|
-
tico/__init__.py,sha256=
|
1
|
+
tico/__init__.py,sha256=ElClZCa-CW2dIDsOnUp1MCbDGvocTAgpyklSI4vEPiQ,1883
|
2
2
|
tico/pt2_to_circle.py,sha256=gu3MD4Iqc0zMZcCZ2IT8oGbyj21CTSbT3Rgd9s2B_9A,2767
|
3
3
|
tico/config/__init__.py,sha256=xZzCXjZ84qE-CsBi-dfaL05bqpQ3stKKfTXhnrJRyVs,142
|
4
4
|
tico/config/base.py,sha256=q5xMqGxTUZs4mFqt5c7i_y9U00fYgdMGl9nUqIVMlCo,1248
|
@@ -13,7 +13,7 @@ tico/experimental/quantization/algorithm/__init__.py,sha256=IO6FP_xYbGy0dW0HL26G
|
|
13
13
|
tico/experimental/quantization/algorithm/gptq/__init__.py,sha256=IO6FP_xYbGy0dW0HL26GXD3ouxARaxCK7bz9dn4blPQ,26
|
14
14
|
tico/experimental/quantization/algorithm/gptq/gptq.py,sha256=Qn9b_2ki7B64DcVEY25NMkww3PdZ5EqYQQXfYhNDQ6I,5555
|
15
15
|
tico/experimental/quantization/algorithm/gptq/quant.py,sha256=Rl4wAOCmlE0U09BtNCDbccaSNohRHCNLwFi3zCqZfNo,5127
|
16
|
-
tico/experimental/quantization/algorithm/gptq/quantizer.py,sha256=
|
16
|
+
tico/experimental/quantization/algorithm/gptq/quantizer.py,sha256=5Sai9gD__6mt7rrUJutJ2L-BV_2biUXcvZC1H-a16Vc,11467
|
17
17
|
tico/experimental/quantization/algorithm/gptq/utils.py,sha256=leGKayf-xbSjVwwAGTA5RsxUKrhDiklOQdlsLifjdrs,1811
|
18
18
|
tico/experimental/quantization/algorithm/pt2e/__init__.py,sha256=IO6FP_xYbGy0dW0HL26GXD3ouxARaxCK7bz9dn4blPQ,26
|
19
19
|
tico/experimental/quantization/algorithm/pt2e/quantizer.py,sha256=mdTvsG87bo8fu0GaWqSM8iBCs-4f4EfUlVtk-Ko6M34,2546
|
@@ -42,8 +42,8 @@ tico/experimental/quantization/algorithm/smoothquant/quantizer.py,sha256=rQMtnqM
|
|
42
42
|
tico/experimental/quantization/algorithm/smoothquant/smooth_quant.py,sha256=O1h7IojcsJaprFvRM9tsAuR3q7vTjKKRi88jD-nH79Y,6175
|
43
43
|
tico/experimental/quantization/evaluation/__init__.py,sha256=IO6FP_xYbGy0dW0HL26GXD3ouxARaxCK7bz9dn4blPQ,26
|
44
44
|
tico/experimental/quantization/evaluation/backend.py,sha256=CZL9rZOA0t8cH7PHp6u9l7dGqWNvTj9bKOvwo0PVul0,692
|
45
|
-
tico/experimental/quantization/evaluation/evaluate.py,sha256=
|
46
|
-
tico/experimental/quantization/evaluation/metric.py,sha256=
|
45
|
+
tico/experimental/quantization/evaluation/evaluate.py,sha256=kfa_GvFaX6DoSTAmuCImMJqF2jgqtnor5UpC7wVmGPI,7877
|
46
|
+
tico/experimental/quantization/evaluation/metric.py,sha256=ma8nrvt3jjKlE8d7iK3uABTkxOSrEDb8hHevdoc2pIw,5011
|
47
47
|
tico/experimental/quantization/evaluation/utils.py,sha256=82RG_e5LuKfWo786wEZUVwXY93nNl901n04fB7D0Z6k,5909
|
48
48
|
tico/experimental/quantization/evaluation/executor/__init__.py,sha256=IO6FP_xYbGy0dW0HL26GXD3ouxARaxCK7bz9dn4blPQ,26
|
49
49
|
tico/experimental/quantization/evaluation/executor/backend_executor.py,sha256=3kLu3_rcsreA_NK42yRgRgubPtZmVp7QCRvaqLNw10E,1522
|
@@ -206,9 +206,9 @@ tico/utils/mx/__init__.py,sha256=IO6FP_xYbGy0dW0HL26GXD3ouxARaxCK7bz9dn4blPQ,26
|
|
206
206
|
tico/utils/mx/elemwise_ops.py,sha256=V6glyAHsVR1joqpsgnNytatCD_ew92xNWZ19UFDoMTA,10281
|
207
207
|
tico/utils/mx/formats.py,sha256=uzNWyu-1onUlwQfX5cZ6fZSUfHMRqorper7_T1k3jfk,3404
|
208
208
|
tico/utils/mx/mx_ops.py,sha256=RcfUTYVi-wilGB2sC35OeARdwDqnixv7dG5iyZ-fQT8,8555
|
209
|
-
tico-0.1.0.
|
210
|
-
tico-0.1.0.
|
211
|
-
tico-0.1.0.
|
212
|
-
tico-0.1.0.
|
213
|
-
tico-0.1.0.
|
214
|
-
tico-0.1.0.
|
209
|
+
tico-0.1.0.dev250806.dist-info/LICENSE,sha256=kp4JLII7bzRhPb0CPD5XTDZMh22BQ7h3k3B7t8TiSbw,12644
|
210
|
+
tico-0.1.0.dev250806.dist-info/METADATA,sha256=_lGucGVdG9FrBy8SvOy1BxwlH3mxLLk5HpZWIUPdA48,8450
|
211
|
+
tico-0.1.0.dev250806.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
|
212
|
+
tico-0.1.0.dev250806.dist-info/entry_points.txt,sha256=kBKYSS_IYrSXmUYevmmepqIVPScq5vF8ulQRu3I_Zf0,59
|
213
|
+
tico-0.1.0.dev250806.dist-info/top_level.txt,sha256=oqs7UPoNSKZEwqsX8B-KAWdQwfAa7i60pbxW_Jk7P3w,5
|
214
|
+
tico-0.1.0.dev250806.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|