Please check out the following short program that reproduces the bug I was facing.

  
      gist.github.com
  
  
    https://gist.github.com/rguthrie3/2ac45905be0cc4277361084335df87f7 18
bug.py
import torch
import torch.autograd as autograd
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim


class WorkingModule(nn.Module):

    def __init__(self):
This file has been truncated. show original




  
  
    
    
  
  


Imagine in each module that self.params is just some transition matrix.  The goal is to sum up the scores of each transition, where params[i][j] is the score of transitioning to i from j.
Both WorkingModule and BuggyModule have a forward() function that correctly computes this score.
WorkingModule does what you would expect.  If you check its gradient after calling backward(), you will see 1’s in the places where there was a transition, and 0’s elsewhere.  BuggyModule though, doesn’t backpropagate to self.params!  The difference is that in this case, the sequence was wrapped in an autograd.Variable, and the transition indices are accessed with .data.
I understand the dangers of .data and how it might cut off your backprop, but how is it cutting off the backprop from score to params?  The only way sequence is ever involved is just providing an index.  In principle, score should not be cut off from params in the computation graph unless I am missing something.  In addition, I think that sequence[i].data should be evaluated before being passed to the indexing function, so I am not sure how there is any difference at all as far as constructing the “score” computation graph is concerned.