How pytorch simulates bias during quantization aware training

Jonson: <p>It seems that pytorch qat doesn’t simulate bias quantization error during qat. And I found that <code>qat.Conv2d</code> only fake-quantize <code>weight</code> and <code>activation</code>. So pytorch’s quantization strategy does not quantize the <code>bias</code>, right?</p>

jerryzh168: <p>yes, we do not quantize bias. there have been some internal discussions on this before, the problem of quantizing bias is that it needs to be quantized with the quantization parameters of input and weight, but the input can come from dynamic paths e.g.:</p>
<pre><code class="lang-python">if x &gt; 0:
    y = myConv1(x)
else:
    y = myConv2(x)
  
z = myConv3(y)
</code></pre>
<p>and we have no way of getting this information in eager mode. currently we pass in bias in fp32 and it will be quantized inside the quantized ops like quantized::conv2d with quantization parameters of input and weight: y = conv(x_q,w_q) + bias/(w_scale*x_scale).</p>
<p>However, for qat, I think currently we do not simulate this behavior, I’m not sure how much impact this has though, we’ll discuss about it, thanks for the question.</p>

babak_hss: <aside class="quote no-group" data-username="jerryzh168" data-post="2" data-topic="97368">
<div class="title">
<div class="quote-controls"></div>
<img loading="lazy" alt="" width="24" height="24" src="https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/jerryzh168/48/15217_2.png" class="avatar"> jerryzh168:</div>
<blockquote>
<p>y = conv(x_q,w_q) + bias/(w_scale*x_scale)</p>
</blockquote>
</aside>
<p>So, if I want to transfer the quantization aware trained network to my hardware, how exactly should i implement the bias part?<br>
should I use the above formula to quantize it?</p>

jerryzh168: <p>right now the quantization for bias is not modeled in quantization aware training, so there might be a little bit of discrepancy between the qat model and the model after convert, but I think it won’t matter too much.</p>

babak_hss: <p>Thank you for the response, Jerry.<br>
So, what should I do with the bias parameter of the batch-norm module when I want to implement my quantized model on hardware? the final converted model (quantized) still has this parameter (in FP) in the quantized version of ConvBnReLU2d.</p>
<ul>
<li>Would bias be totally ignored when we recall the quantized model for some input X  (model.eval() )?</li>
<li>or the intermediate feature values are temporarily converted to FP to apply bias to them and then are converted back to INT8/INT32?</li>
<li>or bias is also converted to INT8 with a simple choice of sale or zero-point without the influence of the qat part?</li>
</ul>

jerryzh168: <p>bias is an input to quantized::conv2d op, it is applied in quantized::conv2d op itself, with this formula:</p>
<aside class="quote no-group" data-username="jerryzh168" data-post="2" data-topic="97368">
<div class="title">
<div class="quote-controls"></div>
<img loading="lazy" alt="" width="24" height="24" src="https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/jerryzh168/48/15217_2.png" class="avatar"> jerryzh168:</div>
<blockquote>
<p>y = conv(x_q,w_q) + bias/(w_scale*x_scale)</p>
</blockquote>
</aside>
<p>this is in int32. then we’ll requantize y with output_scale and output_zero_point<br>
cc <a class="mention" href="/u/dskhudia">@dskhudia</a> could you link the fbgemm implementation  for conv?</p>

jerryzh168: <p>We find modeling bias in qat is not very important since it doesn’t affect accuracy too much. one workaround you can do is to remove bias from Conv and add the bias explicitly outside of conv, so that adding bias can be modeled with add.</p>

Jonson: <p>Thanks for your reply, modeling bias with <code>add</code> op sounds good!</p>

christophezei: <p>hello can you explain more how to remove bias from conv ?</p>

jerryzh168: <p>just set bias to None in conv, but add an additional add after conv</p>