Various quantized/quantizable/intrinsic modules purpose

vadimkantorov: <p>PyTorch has evolved to have many different modules related to quantization helping in different workflows.</p>
<p>Can anyone explain what all of them are and in what usecases/flows are they useful (for a quantization novice it’s quite confusing)? (preferable with some examples as the official docs are too terse IMO) Almost all of these 9 namespaces contain e.g. a version of <code>LinearReLU</code> or <code>Linear</code>, so wondering how they are all <code>LinearReLU</code>’s different and useful. The most confusing for me is the duality of <code>torch.ao.nn.quantizable</code>+<code>torch.ao.nn.quantized</code> and of <code>torch.ao.nn.intrinsic</code>+<code>torch.ao.nn.intrinsic.quantized</code> . What is <code>intrinsic</code> designed to mean? Which of these are designed for the user to use directly / which are sort of internal? Are any of these deprecated?</p>
<p>The basic question of <code>LinearReLU</code> is quite important as it’s the workhorse of feed-forward MLPs found in transformers and is the first target when first considering quantizing the transformers…</p>
<p>Thank you!</p>
<ol>
<li><a href="https://pytorch.org/docs/stable/quantization-support.html#module-torch.ao.nn.intrinsic" rel="noopener nofollow ugc"><code>torch.ao.nn.intrinsic</code></a></li>
<li><a href="https://pytorch.org/docs/stable/quantization-support.html#module-torch.ao.nn.intrinsic.qat" rel="noopener nofollow ugc"><code>torch.ao.nn.intrinsic.qat</code></a></li>
<li><a href="https://pytorch.org/docs/stable/quantization-support.html#module-torch.ao.nn.intrinsic.quantized" rel="noopener nofollow ugc"><code>torch.ao.nn.intrinsic.quantized</code></a></li>
<li><a href="https://pytorch.org/docs/stable/quantization-support.html#module-torch.ao.nn.intrinsic.quantized.dynamic" rel="noopener nofollow ugc"><code>torch.ao.nn.intrinsic.quantized.dynamic</code></a></li>
<li><a href="https://pytorch.org/docs/stable/quantization-support.html#module-torch.ao.nn.qat" rel="noopener nofollow ugc"><code>torch.ao.nn.qat</code></a></li>
<li><a href="https://pytorch.org/docs/stable/quantization-support.html#module-torch.ao.nn.qat.dynamic" rel="noopener nofollow ugc"><code>torch.ao.nn.qat.dynamic</code></a></li>
<li><a href="https://pytorch.org/docs/stable/quantization-support.html#module-torch.ao.nn.quantized.modules" rel="noopener nofollow ugc"><code>torch.ao.nn.quantized.modules</code></a></li>
<li><a href="https://pytorch.org/docs/stable/quantization-support.html#torch-ao-nn-quantizable" rel="noopener nofollow ugc"><code>torch.ao.nn.quantizable</code></a></li>
<li><a href="https://pytorch.org/docs/stable/quantization-support.html#module-torch.ao.nn.quantized.dynamic" rel="noopener nofollow ugc"><code>torch.ao.nn.quantized.dynamic</code></a></li>
</ol>

andrewor: <p>Hi Vadim,</p>
<p>Yes, these namespaces can certainly be confusing! I’ll try to clarify what these mean on a high level:</p>
<ul>
<li>Intrinsic means fused modules, like conv + relu, linear + relu, conv + bn etc. Some of these have special logic that changes the numerics (the ones with BN) and some don’t</li>
<li>QAT means <a href="https://pytorch.org/docs/stable/quantization.html#quantization-aware-training-for-static-quantization" rel="noopener nofollow ugc">quantization-aware training</a></li>
<li>dynamic means <a href="https://pytorch.org/tutorials/prototype/fx_graph_mode_ptq_dynamic.html" rel="noopener nofollow ugc">dynamic quantization</a></li>
<li>quantized means the ops will take in quantized inputs and produce quantized outputs</li>
<li>quantizable means the ops will take in fp32 inputs and produce fp32 outputs, but these modules will be swapped to the quantized versions during convert. These are only for special modules like LSTMs that have a C++ aten implementations that are not easy to quantize in python.</li>
</ul>
<p>From the user’s perspective, you shouldn’t have to worry about the differences between them. The quantization workflow should take care of swapping between the modules for you automatically. Please let me know if I can help clarify anything else.</p>
<p>Best,<br>
-Andrew</p>

vadimkantorov: <p>Seems not fully accurate, as <a href="https://pytorch.org/docs/stable/generated/torch.ao.nn.intrinsic.quantized.dynamic.LinearReLU.html#torch.ao.nn.intrinsic.quantized.dynamic.LinearReLU" class="inline-onebox" rel="noopener nofollow ugc">LinearReLU — PyTorch 2.0 documentation</a> is in quantized namespace but in fact accepts float32 inputs as shown in the code example, same for quantized.linear_dynamic: <a href="https://github.com/pytorch/pytorch/issues/69364#issue-1070574995" class="inline-onebox" rel="noopener nofollow ugc">[feature request] quantized and low-level int8 operators (matmul, gemm etc) on CUDA + integrate LLM.int8 + integrate ZeroQuant? · Issue #69364 · pytorch/pytorch · GitHub</a></p>
<p>Regarding quantizable, there’s only two modules: LSTM and MultiheadAttention. But it’s clear that more modules are replaced by <code>convert</code>, right? Some QuantStub or FakeQuant modules?</p>
<p>What would be useful is to group these namespaces somehow or reduce their amount. Maybe some “fused logical” modules can be put in torch.nn, especially for those that stand as placeholders and don’t do any quantization by themselves? This often happens in domain libraries like torchvision: <a href="https://github.com/pytorch/vision/blob/08c9938f3e69b4fb2d710a038479264f3c23b133/torchvision/ops/misc.py#L68" rel="noopener nofollow ugc"><code>ConvNormActivation</code></a> and similar high-level modules.</p>
<p>I think more explanation is needed on internal details as the quantization abstraction “leaks” and it’s important for the enduser to understand what exactly is going on. And also there’s a lot of vendors’ replacement modules: nvidia pytorch_quantization toolkit and so on.</p>
<p>For now, as a novice it’s too many very similar-named namespaces and LinearReLU classes in them <img src="https://discuss.pytorch.org/images/emoji/apple/slight_smile.png?v=12" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20"></p>
<p>Maybe MLP/transformer feedfoward can be a good example / tutorial to showcase quantization and usage of LinearReLU</p>