Autograd gradients compared to FDM

Noah_Foster: <p>I am currently Experimenting with a Transformer Class Neural Operator and am seeing a bit of an error. When I calculate the gradient of the output for example dv/dx using traditional Finite Difference Method (FDM) and compare the same gradient output to the AutoGrad, they are similar but not quite there. Comparing to the FDM method on the underlying dataset too…<br>
<div class="lightbox-wrapper"><a class="lightbox" href="https://discuss.pytorch.org/uploads/default/original/3X/e/2/e21530dd26cfcc3f210ce89752d6504461d9db1d.png" data-download-href="https://discuss.pytorch.org/uploads/default/e21530dd26cfcc3f210ce89752d6504461d9db1d" title="image"><img src="https://discuss.pytorch.org/uploads/default/optimized/3X/e/2/e21530dd26cfcc3f210ce89752d6504461d9db1d_2_690x178.png" alt="image" data-base62-sha1="wg1jbWZiNjIUmYFbYcFYNLT9p0N" width="690" height="178" srcset="https://discuss.pytorch.org/uploads/default/optimized/3X/e/2/e21530dd26cfcc3f210ce89752d6504461d9db1d_2_690x178.png, https://discuss.pytorch.org/uploads/default/optimized/3X/e/2/e21530dd26cfcc3f210ce89752d6504461d9db1d_2_1035x267.png 1.5x, https://discuss.pytorch.org/uploads/default/optimized/3X/e/2/e21530dd26cfcc3f210ce89752d6504461d9db1d_2_1380x356.png 2x" data-dominant-color="DC9DAA"><div class="meta"><svg class="fa d-icon d-icon-far-image svg-icon" aria-hidden="true"><use href="#far-image"></use></svg><span class="filename">image</span><span class="informations">2294×593 56.7 KB</span><svg class="fa d-icon d-icon-discourse-expand svg-icon" aria-hidden="true"><use href="#discourse-expand"></use></svg></div></a></div></p>
<p>…shows that the Auto-grad is a bit off. The dataset also reached grid convergence so a 2nd order FDM can be considered ground truth, where the FDM method on the model is more accurate as seen in the last picture.</p>
<p>The only thing I can think of is that both the input and the output to the model are unit normalized (separately, not the same std, mean). However, based on my maths, that would mean that the gradients can be unnormalized by a combination of the std (my chain rule logic could be wrong here). However, the Autograd output is not a mulitple of the FDM output, meaning that multiplying the output by some combination of std won’t align the methods.</p>
<p>Due to the complexities of autograd, I am unable to calculate the same method but for a non-normalized input. Unless I include the normalization within the model, is this really the only option for further comparison or is there more complex things at play here between input queries and keys of cross attention?</p>

soulitzer: <p>If I understand correctly, you computed gradient of model w/o normalization using FDM.<br>
The chain rule implies that autograd output is a linear function of FDM output, but its not necessarily a multiple.<br>
To take into account the normalization, you could you could recompute just the normalization.<br>
Then do torch.autograd.grad(input_after_norm, inputs=(input_before_norm,), grad_output=(fdm_output,))</p>

Noah_Foster: <p>Yep, so I made the adjustment by wrapping the model. Within the wrapped module:</p>
<ol>
<li>The input (isotropic grid coordinates (X,Y) is normalized.</li>
<li>The model is inferred.</li>
<li>The output is un-normalized to get the real output.</li>
</ol>
<p>So now when inferring through the wrapped model, you pass the <strong>a</strong>) non-normalized input coordinates, and you get <strong>b</strong>) non-normalized output velocity distribution. So, when using autograd on the wrapped model to get the derivatives of <strong>b</strong>) with respect to <strong>a</strong>), you would expect the gradients to be nearly identical to when using FDM to get the same gradients. But I am seeing a consistent error:</p>
<p><div class="lightbox-wrapper"><a class="lightbox" href="https://discuss.pytorch.org/uploads/default/original/3X/e/9/e9bb08552454846a4faa7b645f5f912b0c8e5495.png" data-download-href="https://discuss.pytorch.org/uploads/default/e9bb08552454846a4faa7b645f5f912b0c8e5495" title="image"><img src="https://discuss.pytorch.org/uploads/default/optimized/3X/e/9/e9bb08552454846a4faa7b645f5f912b0c8e5495_2_690x172.png" alt="image" data-base62-sha1="xlFXTjAPDrTgVs3qnN7PgXmP66x" width="690" height="172" srcset="https://discuss.pytorch.org/uploads/default/optimized/3X/e/9/e9bb08552454846a4faa7b645f5f912b0c8e5495_2_690x172.png, https://discuss.pytorch.org/uploads/default/optimized/3X/e/9/e9bb08552454846a4faa7b645f5f912b0c8e5495_2_1035x258.png 1.5x, https://discuss.pytorch.org/uploads/default/optimized/3X/e/9/e9bb08552454846a4faa7b645f5f912b0c8e5495_2_1380x344.png 2x" data-dominant-color="D58E9E"><div class="meta"><svg class="fa d-icon d-icon-far-image svg-icon" aria-hidden="true"><use href="#far-image"></use></svg><span class="filename">image</span><span class="informations">2255×565 51.5 KB</span><svg class="fa d-icon d-icon-discourse-expand svg-icon" aria-hidden="true"><use href="#discourse-expand"></use></svg></div></a></div></p>
<p>In the centre the error appears to be roughly 30%.</p>
<p>I am fairly confident in my application of the wrapped model. So, is there any interactions in the backwards pass of autograd (maybe layernorms, softmax, accumulated precision overflow etc) that could introduce significant or accumulated errors?</p>
<p>If this is the case, could it be that training would also be affected since this is the primary mechanism of neural networks.</p>

soulitzer: <p>Hmm just to double check, we could use <a href="https://pytorch.org/docs/stable/generated/torch.autograd.gradcheck.gradcheck.html" class="inline-onebox" rel="noopener nofollow ugc">torch.autograd.gradcheck.gradcheck — PyTorch 2.3 documentation</a> to validate the gradients. Underneath it compares the analytical gradient of autograd with that computed by FDM as you are doing.</p>