tico 0.1.0.dev250813__py3-none-any.whl → 0.1.0.dev250814__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 CHANGED
@@ -29,7 +29,7 @@ __all__ = [
29
29
  ]
30
30
 
31
31
  # THIS LINE IS AUTOMATICALLY GENERATED BY setup.py
32
- __version__ = "0.1.0.dev250813"
32
+ __version__ = "0.1.0.dev250814"
33
33
 
34
34
  MINIMUM_SUPPORTED_VERSION = "2.5.0"
35
35
  SECURE_TORCH_VERSION = "2.6.0"
@@ -1,9 +1,13 @@
1
1
  from tico.experimental.quantization.ptq.observers.affine_base import AffineObserverBase
2
2
  from tico.experimental.quantization.ptq.observers.base import ObserverBase
3
+ from tico.experimental.quantization.ptq.observers.ema import EMAObserver
4
+ from tico.experimental.quantization.ptq.observers.identity import IdentityObserver
3
5
  from tico.experimental.quantization.ptq.observers.minmax import MinMaxObserver
4
6
 
5
7
  __all__ = [
6
8
  "AffineObserverBase",
7
9
  "ObserverBase",
10
+ "EMAObserver",
11
+ "IdentityObserver",
8
12
  "MinMaxObserver",
9
13
  ]
@@ -0,0 +1,62 @@
1
+ # Copyright (c) 2025 Samsung Electronics Co., Ltd. All Rights Reserved
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ import torch
16
+
17
+ from tico.experimental.quantization.ptq.observers.affine_base import AffineObserverBase
18
+ from tico.experimental.quantization.ptq.utils import channelwise_minmax
19
+
20
+
21
+ class EMAObserver(AffineObserverBase):
22
+ """
23
+ Exponential-Moving-Average min/max tracker.
24
+
25
+ Why?
26
+ -----
27
+ • Smoother than raw MinMax (reduces outlier shock).
28
+ • Much cheaper than histogram/MSE observers.
29
+
30
+ The update rule follows the common "momentum" form:
31
+
32
+ ema = momentum * ema + (1 - momentum) * new_value
33
+
34
+ With momentum → 0: *fast* adaptation, momentum → 1: *slow* adaptation.
35
+ """
36
+
37
+ def __init__(
38
+ self,
39
+ *,
40
+ momentum: float = 0.9,
41
+ **kwargs,
42
+ ):
43
+ super().__init__(**kwargs)
44
+ assert 0.0 < momentum < 1.0, "momentum must be in (0, 1)"
45
+ self.momentum = momentum
46
+
47
+ @torch.no_grad()
48
+ def _update_stats(self, x: torch.Tensor):
49
+ if self.channel_axis is None:
50
+ curr_min, curr_max = x.min(), x.max()
51
+ else:
52
+ curr_min, curr_max = channelwise_minmax(x, self.channel_axis)
53
+
54
+ if (
55
+ torch.isinf(self.min_val).any() and torch.isinf(self.max_val).any()
56
+ ): # first batch → hard init
57
+ self.min_val, self.max_val = curr_min, curr_max
58
+ return
59
+
60
+ m = self.momentum
61
+ self.min_val = m * self.min_val + (1 - m) * curr_min
62
+ self.max_val = m * self.max_val + (1 - m) * curr_max
@@ -0,0 +1,74 @@
1
+ # Copyright (c) 2025 Samsung Electronics Co., Ltd. All Rights Reserved
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ """
16
+ IdentityObserver: a *no-op* observer for FP-only modules.
17
+
18
+ Motivation
19
+ ----------
20
+ Some layers should stay in full precision even when the rest of the model
21
+ is quantized. Attaching an `IdentityObserver` satisfies the wrapper API
22
+ (`_update_stats()`, `compute_qparams()`, `fake_quant()`) without actually
23
+ performing any statistics gathering or fake-quantization.
24
+ """
25
+ import torch
26
+
27
+ from tico.experimental.quantization.ptq.observers.affine_base import AffineObserverBase
28
+
29
+
30
+ class IdentityObserver(AffineObserverBase):
31
+ """
32
+ Passthrough observer that **never** alters the tensor.
33
+
34
+ • `_update_stats()` → does nothing
35
+ • `compute_qparams()` → returns (1.0, 0) *dummy* q-params
36
+ • `fake_quant()` → returns *x* unchanged
37
+ """
38
+
39
+ def __init__(self, **kwargs):
40
+ # Call parent so the usual fields (`dtype`, `qscheme`, …) exist,
41
+ # but immediately disable any stateful behaviour.
42
+ super().__init__(**kwargs)
43
+
44
+ # Deactivate statistics collection permanently.
45
+ self.enabled = False
46
+
47
+ # Pre-cache sentinel q-params so wrapper code that blindly
48
+ # accesses them won't crash.
49
+ self._cached_scale = torch.tensor(1.0)
50
+ self._cached_zp = torch.tensor(0, dtype=torch.int)
51
+
52
+ def reset(self) -> None: # (simple override – nothing to do)
53
+ """No internal state to reset."""
54
+ pass
55
+
56
+ def _update_stats(self, x: torch.Tensor) -> None:
57
+ """Skip statistic collection entirely."""
58
+ return
59
+
60
+ def compute_qparams(self):
61
+ """
62
+ Return the pre-cached (scale, zero_point) tuple.
63
+
64
+ Keeping the signature identical to other observers allows uniform
65
+ lifecycle management in wrapper code.
66
+ """
67
+ return self._cached_scale, self._cached_zp
68
+
69
+ def fake_quant(self, x: torch.Tensor):
70
+ """Identity mapping — leaves *x* in FP."""
71
+ return x
72
+
73
+ def __repr__(self) -> str:
74
+ return f"{self.__class__.__name__}()"
tico/utils/utils.py CHANGED
@@ -79,73 +79,70 @@ def enforce_type(callable):
79
79
  def check_types(*args, **kwargs):
80
80
  parameters = dict(zip(spec.args, args))
81
81
  parameters.update(kwargs)
82
- for name, value in parameters.items():
83
- if name == "self":
84
- # skip 'self' in spec.args
85
- continue
86
-
87
- assert (
88
- name in spec.annotations
89
- ), f"All parameter require type hints. {name} needs a type hint"
90
-
91
- type_hint = spec.annotations[name]
92
82
 
93
- # Return tuple of flattened types.
94
- # Q) What is flatten?
95
- # A) Optional/Union is not included. Below are included.
96
- # collections: List, Set, ...
97
- # primitive types: int, str, ...
98
- def _flatten_type(type_hint) -> tuple:
99
- # `get_origin` maps Union[...] and Optional[...] varieties to Union
100
- if typing.get_origin(type_hint) == typing.Union:
101
- # ex. typing.Union[list, int] -> (list, int)
102
- # ex. typing.Optional[torch.fx.Node] -> (torch.fx.Node, NoneType)
103
- actual_type = tuple(
104
- [_flatten_type(t) for t in typing.get_args(type_hint)]
105
- )
106
- else:
107
- actual_type = (type_hint,)
108
- return actual_type
83
+ # Return tuple of flattened types.
84
+ # Q) What is flatten?
85
+ # A) Optional/Union is not included. Below are included.
86
+ # collections: List, Set, ...
87
+ # primitive types: int, str, ...
88
+ def _flatten_type(type_hint) -> tuple:
89
+ # `get_origin` maps Union[...] and Optional[...] varieties to Union
90
+ if typing.get_origin(type_hint) == typing.Union:
91
+ # ex. typing.Union[list, int] -> (list, int)
92
+ # ex. typing.Optional[torch.fx.Node] -> (torch.fx.Node, NoneType)
93
+ actual_type = tuple(
94
+ _flatten_type(t) for t in typing.get_args(type_hint)
95
+ )
96
+ else:
97
+ actual_type = (type_hint,)
98
+ return actual_type
109
99
 
110
- type_hint = _flatten_type(type_hint)
100
+ # Return true if value matches with type_hint
101
+ # Return false otherwise
102
+ def _check_type(value, type_hint):
103
+ if type_hint == typing.Any:
104
+ return True
111
105
 
112
- # Return true if value matches with type_hint
113
- # Return false otherwise
114
- def _check_type(value, type_hint):
115
- if type_hint == typing.Any:
116
- return True
106
+ if isinstance(type_hint, tuple):
107
+ return any(_check_type(value, t) for t in type_hint)
117
108
 
118
- if isinstance(type_hint, tuple):
119
- return any([_check_type(value, t) for t in type_hint])
109
+ if typing.get_origin(type_hint) in (list, set):
110
+ if not isinstance(value, typing.get_origin(type_hint)):
111
+ return False
120
112
 
121
- if typing.get_origin(type_hint) in (list, set):
122
- if not isinstance(value, typing.get_origin(type_hint)):
113
+ for v in value:
114
+ if not any(_check_type(v, t) for t in typing.get_args(type_hint)):
123
115
  return False
124
116
 
125
- for v in value:
126
- if not any(
127
- [_check_type(v, t) for t in typing.get_args(type_hint)]
128
- ):
129
- return False
117
+ return True
130
118
 
131
- return True
119
+ if typing.get_origin(type_hint) is dict:
120
+ if not isinstance(value, typing.get_origin(type_hint)):
121
+ return False
132
122
 
133
- if typing.get_origin(type_hint) is dict:
134
- if not isinstance(value, typing.get_origin(type_hint)):
123
+ for k, v in value.items():
124
+ k_type, v_type = typing.get_args(type_hint)
125
+ if not _check_type(k, k_type):
126
+ return False
127
+ if not _check_type(v, v_type):
135
128
  return False
136
129
 
137
- for k, v in value.items():
138
- k_type, v_type = typing.get_args(type_hint)
139
- if not _check_type(k, k_type):
140
- return False
141
- if not _check_type(v, v_type):
142
- return False
130
+ return True
131
+
132
+ # TODO: Support more type hints
133
+ return isinstance(value, type_hint)
143
134
 
144
- return True
135
+ for name, value in parameters.items():
136
+ if name == "self":
137
+ # skip 'self' in spec.args
138
+ continue
145
139
 
146
- # TODO: Support more type hints
147
- return isinstance(value, type_hint)
140
+ assert (
141
+ name in spec.annotations
142
+ ), f"All parameter require type hints. {name} needs a type hint"
148
143
 
144
+ type_hint = spec.annotations[name]
145
+ type_hint = _flatten_type(type_hint)
149
146
  type_check_result = _check_type(value, type_hint)
150
147
  if not type_check_result:
151
148
  raise ArgTypeError(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: tico
3
- Version: 0.1.0.dev250813
3
+ Version: 0.1.0.dev250814
4
4
  Summary: Convert exported Torch module to circle
5
5
  Home-page: UNKNOWN
6
6
  License: UNKNOWN
@@ -1,4 +1,4 @@
1
- tico/__init__.py,sha256=SL1CaKezytxIZbCthWmNK0MGO-5Erit1aRwOxaT6SxU,1883
1
+ tico/__init__.py,sha256=Y5AdGv7QfIPC6o_P2M2S16JtXG5LLmtIfUU7gq6scYQ,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
@@ -60,9 +60,11 @@ tico/experimental/quantization/ptq/__init__.py,sha256=ZoPdEwZ1i1n5pBFChx8GuUrkfR
60
60
  tico/experimental/quantization/ptq/dtypes.py,sha256=xfCBtq6mQmUYRwsoFgII6gvRl1raQi0Inj9pznDuKwQ,2236
61
61
  tico/experimental/quantization/ptq/mode.py,sha256=lT-T8vIv8YWcwrjT7xXVhOw1g7aoAdh_3PWB-ptPKaI,1052
62
62
  tico/experimental/quantization/ptq/qscheme.py,sha256=uwhv7bCxOOXB3I-IKlRyr_u4eXOq48uIqGy4TLDqGxY,1301
63
- tico/experimental/quantization/ptq/observers/__init__.py,sha256=Sxdr1xAKhmdUfwwzsNfer0JVGiT3Xo6I1Bw3TRkp3C0,325
63
+ tico/experimental/quantization/ptq/observers/__init__.py,sha256=wyrO0KTZve78aFWTwvsOE82Vu2kbCxJv8aqjiO1QL2s,524
64
64
  tico/experimental/quantization/ptq/observers/affine_base.py,sha256=e2Eba64nrxKQyE4F_WJ7WTSsk3xe6bkdGUKaoLFWGFw,4638
65
65
  tico/experimental/quantization/ptq/observers/base.py,sha256=Wons1MzpqK1mfcy-ppl-B2Dum0edXg2dWW2Lw3V18tw,3280
66
+ tico/experimental/quantization/ptq/observers/ema.py,sha256=WZiYWEHrkgizAwnRCtfOm9JPHfZrjZTxMr6X9Wuovmo,2061
67
+ tico/experimental/quantization/ptq/observers/identity.py,sha256=jdlNH52z8ANOZbs_0KFZ4iEstVfNC1OUzQsm1a9FFpM,2595
66
68
  tico/experimental/quantization/ptq/observers/minmax.py,sha256=mLHkwIzWFzQXev7EU7w1333KckwRjukc3_cUPJOnUfs,1486
67
69
  tico/experimental/quantization/ptq/utils/__init__.py,sha256=PL9IZgiWoMtsXVljeOy7KymmLVP238SXEFRLXYK72WQ,126
68
70
  tico/experimental/quantization/ptq/utils/reduce_utils.py,sha256=3kWawLB91EcvvHlCrNqqfZF7tpgr22htBSA049mKw_4,973
@@ -214,15 +216,15 @@ tico/utils/serialize.py,sha256=mEuusEzi82WFsz3AkowgWwxSLeo50JDxyOj6yYDQhEI,1914
214
216
  tico/utils/signature.py,sha256=R2GV0alRpXEbZISqPKyxCUWbgDcsrQ2ovbVG3737IzA,9595
215
217
  tico/utils/torch_compat.py,sha256=oc6PztVsXdHcQ3iaVR90wLLxrGaj6zFHWZ8K9rRS6q8,1795
216
218
  tico/utils/trace_decorators.py,sha256=ddLIiKQfSaQrxgF1kNpwjFTQnXENzeSfcr1kuAW4jGI,3221
217
- tico/utils/utils.py,sha256=A5p3iAAxRGDsZJh4ybp-Qo3MX3vk5RrmSY-R3rXqVeI,12976
219
+ tico/utils/utils.py,sha256=aySftYnNTsqVAMcGs_3uX3-hz577a2cj4p1aVV-1XeQ,12747
218
220
  tico/utils/validate_args_kwargs.py,sha256=aY7hyDaZKrZn0ev0liUFZdHS8__0Vpp5QyqDEobZ_zM,27163
219
221
  tico/utils/mx/__init__.py,sha256=IO6FP_xYbGy0dW0HL26GXD3ouxARaxCK7bz9dn4blPQ,26
220
222
  tico/utils/mx/elemwise_ops.py,sha256=V6glyAHsVR1joqpsgnNytatCD_ew92xNWZ19UFDoMTA,10281
221
223
  tico/utils/mx/formats.py,sha256=uzNWyu-1onUlwQfX5cZ6fZSUfHMRqorper7_T1k3jfk,3404
222
224
  tico/utils/mx/mx_ops.py,sha256=RcfUTYVi-wilGB2sC35OeARdwDqnixv7dG5iyZ-fQT8,8555
223
- tico-0.1.0.dev250813.dist-info/LICENSE,sha256=kp4JLII7bzRhPb0CPD5XTDZMh22BQ7h3k3B7t8TiSbw,12644
224
- tico-0.1.0.dev250813.dist-info/METADATA,sha256=CYADXCywzXQsqDipD-SWVOIKjxDRTaWHL1tv_LuQAkA,8450
225
- tico-0.1.0.dev250813.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
226
- tico-0.1.0.dev250813.dist-info/entry_points.txt,sha256=kBKYSS_IYrSXmUYevmmepqIVPScq5vF8ulQRu3I_Zf0,59
227
- tico-0.1.0.dev250813.dist-info/top_level.txt,sha256=oqs7UPoNSKZEwqsX8B-KAWdQwfAa7i60pbxW_Jk7P3w,5
228
- tico-0.1.0.dev250813.dist-info/RECORD,,
225
+ tico-0.1.0.dev250814.dist-info/LICENSE,sha256=kp4JLII7bzRhPb0CPD5XTDZMh22BQ7h3k3B7t8TiSbw,12644
226
+ tico-0.1.0.dev250814.dist-info/METADATA,sha256=CWbuRvOwPOiqf8FwnG5H8tij1fQqH3k_JpO8zhtXQfg,8450
227
+ tico-0.1.0.dev250814.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
228
+ tico-0.1.0.dev250814.dist-info/entry_points.txt,sha256=kBKYSS_IYrSXmUYevmmepqIVPScq5vF8ulQRu3I_Zf0,59
229
+ tico-0.1.0.dev250814.dist-info/top_level.txt,sha256=oqs7UPoNSKZEwqsX8B-KAWdQwfAa7i60pbxW_Jk7P3w,5
230
+ tico-0.1.0.dev250814.dist-info/RECORD,,