currently I use this way to compute masked loss for seq2seq model:
'''
target_sentences: [batch_size, max_length] int64
batch_target_len_array: [batch_size] int64, each element is the valid length of the corresponding target sentence. 
'''
for step in range(max_length):
    decoder_output, decoder_hidden = decoder(
        decoder_input, decoder_hidden, encoder_outputs)
    if np.sum(batch_target_len_array > step) == 0:
        break
    mask_vector = torch.from_numpy((batch_target_len_array > step).astype(np.int32)).byte()
    index_vector = Variable(torch.masked_select(torch.arange(0, batch_size), mask_vector).long()).cuda()
    valid_output = torch.index_select(decoder_output, 0, index_vector)
    valid_target = torch.index_select(target_sentences[:, step], 0, index_vector)

    step_loss = criterion(valid_output, valid_target)
    loss += step_loss
    decoder_input = target_sentences[:, step]  # Teacher forcing