r"""A config class indicating how to do quantize toward :class:`~.QATModule` 's ``activation`` and ``weight``. See :meth:`~.QATModule.set_qconfig` for detail usage. Args: weight_observer: interface to instantiate an :class:`~.Observer` indicating how to collect scales an
| 15 | |
| 16 | # use namedtuple to make class immutable, comparable and easy to print |
| 17 | class QConfig( |
| 18 | namedtuple( |
| 19 | "QConfig", |
| 20 | ["weight_observer", "act_observer", "weight_fake_quant", "act_fake_quant"], |
| 21 | ) |
| 22 | ): |
| 23 | r"""A config class indicating how to do quantize toward :class:`~.QATModule` 's |
| 24 | ``activation`` and ``weight``. See :meth:`~.QATModule.set_qconfig` for detail usage. |
| 25 | |
| 26 | Args: |
| 27 | weight_observer: interface to instantiate an :class:`~.Observer` indicating |
| 28 | how to collect scales and zero_point of wegiht. |
| 29 | act_observer: similar to ``weight_observer`` but toward activation. |
| 30 | weight_fake_quant: interface to instantiate a :class:`~.quantization.fake_quant.FakeQuantize` indicating |
| 31 | how to do fake_quant calculation. |
| 32 | act_observer: similar to ``weight_fake_quant`` but toward activation. |
| 33 | |
| 34 | Examples: |
| 35 | |
| 36 | .. code-block:: |
| 37 | |
| 38 | # Default EMA QConfig for QAT. |
| 39 | ema_fakequant_qconfig = QConfig( |
| 40 | weight_observer=partial(MinMaxObserver, dtype="qint8_narrow"), |
| 41 | act_observer=partial(ExponentialMovingAverageObserver, dtype="qint8"), |
| 42 | weight_fake_quant=partial(FakeQuantize, dtype="qint8_narrow"), |
| 43 | act_fake_quant=partial(FakeQuantize, dtype="qint8"), |
| 44 | ) |
| 45 | |
| 46 | Each parameter is a ``class`` rather than an instance. And we recommand using ``functools.partial`` |
| 47 | to add initialization parameters of the ``class``, so that don't need to provide parameters in |
| 48 | :meth:`~.QATModule.set_qconfig`. |
| 49 | |
| 50 | Usually we choose narrow version dtype (like ``qint8_narrow``) for weight related |
| 51 | paramters and normal version for activation related ones. For the result of |
| 52 | multiplication and addition as ``a * b + c * d``, if four variables are all -128 of |
| 53 | dtype ``qint8``, then the result will be ``2^15`` and cause overflow. |
| 54 | Weights are commonly calculated in this way, so need to narrow qmin to -127. |
| 55 | """ |
| 56 | |
| 57 | def __new__(cls, weight_observer, act_observer, weight_fake_quant, act_fake_quant): |
| 58 | if isinstance(act_observer, Module) or isinstance(weight_observer, Module): |
| 59 | raise ValueError( |
| 60 | "QConfig must not receive observer instance, please pass observer" |
| 61 | " class generator using `partial(Observer, ...)` instead. Use" |
| 62 | " partial(MyObserver, x=1) to override arguments to constructor if needed" |
| 63 | ) |
| 64 | return super().__new__( |
| 65 | cls, weight_observer, act_observer, weight_fake_quant, act_fake_quant |
| 66 | ) |
| 67 | |
| 68 | |
| 69 | min_max_fakequant_qconfig = QConfig( |
no outgoing calls
no test coverage detected