prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Size Mismatch in AdaptiveSoftmax when targets are not specified
  Following up on #212 , I'm updating `sequence_generator.py` to generate text from a pre-trained language model (initially trained with adaptive softmax). When computing log probabilities, and the targets are set to none, I receive a size mismatch exception in the line below, possibly because the dictionary size is smaller than the adaptive softmax cut-off: 
  
  https://github.com/pytorch/fairseq/blob/388c520be21752cacb9fe3b1712038f32e0e9a5f/fairseq/modules/adaptive_softmax.py#L126
  
  I imagine this could be solved by some sort of truncation to the output of tail[i].input
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `fairseq/modules/adaptive_softmax.py`
  Content:
  ```
  1 # Copyright (c) 2017-present, Facebook, Inc.
  2 # All rights reserved.
  3 #
  4 # This source code is licensed under the license found in the LICENSE file in
  5 # the root directory of this source tree. An additional grant of patent rights
  6 # can be found in the PATENTS file in the same directory.
  7 
  8 
  9 import torch.nn.functional as F
  10 from torch import nn
  11 
  12 
  13 class AdaptiveSoftmax(nn.Module):
  14     """
  15     This is an implementation of the efficient softmax approximation for
  16     graphical processing units (GPU), described in the paper "Efficient softmax
  17     approximation for GPUs" (http://arxiv.org/abs/1609.04309).
  18     """
  19 
  20     def __init__(self, vocab_size, input_dim, cutoff, dropout):
  21         super().__init__()
  22 
  23         if vocab_size > cutoff[-1]:
  24             cutoff = cutoff + [vocab_size]
  25 
  26         output_dim = cutoff[0] + len(cutoff) - 1
  27 
  28         self.vocab_size = vocab_size
  29         self.cutoff = cutoff
  30         self.dropout = dropout
  31 
  32         self.lsm = nn.LogSoftmax(dim=1)
  33         self.head = nn.Linear(input_dim, output_dim, bias=False)
  34         self.tail = nn.ModuleList()
  35 
  36         for i in range(len(cutoff) - 1):
  37             self.tail.append(
  38                 nn.Sequential(
  39                     nn.Linear(input_dim, input_dim // 4 ** i, bias=False),
  40                     nn.Dropout(dropout),
  41                     nn.Linear(input_dim // 4 ** i, cutoff[i + 1] - cutoff[i], bias=False)
  42                 )
  43             )
  44 
  45         def init_weights(m):
  46             if hasattr(m, 'weight'):
  47                 nn.init.xavier_uniform_(m.weight)
  48 
  49         self.apply(init_weights)
  50 
  51     def adapt_target(self, target):
  52         """
  53         In order to be efficient, the AdaptiveSoftMax does not compute the
  54         scores for all the word of the vocabulary for all the examples. It is
  55         thus necessary to call the method adapt_target of the AdaptiveSoftMax
  56         layer inside each forward pass.
  57         """
  58 
  59         target = target.view(-1)
  60         new_target = [target.clone()]
  61         target_idxs = []
  62 
  63         for i in range(len(self.cutoff) - 1):
  64             mask = target.ge(self.cutoff[i]).mul(target.lt(self.cutoff[i + 1]))
  65             new_target[0][mask] = self.cutoff[0] + i - 1
  66 
  67             if mask.any():
  68                 target_idxs.append(mask.nonzero().squeeze(1))
  69                 new_target.append(target[mask].add(-self.cutoff[i]))
  70             else:
  71                 target_idxs.append(None)
  72                 new_target.append(None)
  73 
  74         return new_target, target_idxs
  75 
  76     def forward(self, input, target):
  77         """
  78         Args:
  79             input: (b x t x d)
  80             target: (b x t)
  81         Returns:
  82             2 lists: output for each cutoff section and new targets by cut off
  83         """
  84 
  85         input = input.contiguous().view(-1, input.size(-1))
  86         input = F.dropout(input, p=self.dropout, training=self.training)
  87 
  88         new_target, target_idxs = self.adapt_target(target)
  89         output = [self.head(input)]
  90 
  91         for i in range(len(target_idxs)):
  92             if target_idxs[i] is not None:
  93                 output.append(self.tail[i](input.index_select(0, target_idxs[i])))
  94             else:
  95                 output.append(None)
  96 
  97         return output, new_target
  98 
  99     def get_log_prob(self, input, target):
  100         """
  101         Computes the log probabilities for all the words of the vocabulary,
  102         given a 2D tensor of hidden vectors.
  103         """
  104 
  105         bsz, length, dim = input.size()
  106         input = input.contiguous().view(-1, dim)
  107 
  108         if target is not None:
  109             _, target_idxs = self.adapt_target(target)
  110         else:
  111             target_idxs = None
  112 
  113         head_y = self.head(input)
  114         log_probs = head_y.new_zeros(input.size(0), self.vocab_size)
  115 
  116         head_sz = self.cutoff[0] + len(self.tail)
  117         log_probs[:, :head_sz] = self.lsm(head_y)
  118         tail_priors = log_probs[:, self.cutoff[0] - 1: head_sz - 1].clone()
  119 
  120         for i in range(len(self.tail)):
  121             start = self.cutoff[i]
  122             end = self.cutoff[i + 1]
  123 
  124             if target_idxs is None:
  125                 tail_out = log_probs[:, start:end]
  126                 tail_out.copy_(self.tail[i](input))
  127                 log_probs[:, start:end] = self.lsm(tail_out).add_(tail_priors[:, i, None])
  128             elif target_idxs[i] is not None:
  129                 idxs = target_idxs[i]
  130                 tail_out = log_probs[idxs, start:end]
  131                 tail_out.copy_(self.tail[i](input[idxs]))
  132                 log_probs[idxs, start:end] = self.lsm(tail_out).add_(tail_priors[idxs, i, None])
  133 
  134         log_probs = log_probs.view(bsz, length, -1)
  135         return log_probs
  136
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/fairseq/modules/adaptive_softmax.py b/fairseq/modules/adaptive_softmax.py
  --- a/fairseq/modules/adaptive_softmax.py
  +++ b/fairseq/modules/adaptive_softmax.py
  @@ -22,6 +22,9 @@
   
           if vocab_size > cutoff[-1]:
               cutoff = cutoff + [vocab_size]
  +        else:
  +            assert vocab_size == cutoff[
  +                -1], 'cannot specify cutoff smaller than vocab size'
   
           output_dim = cutoff[0] + len(cutoff) - 1
  
verification_info: {"golden_diff": "diff --git a/fairseq/modules/adaptive_softmax.py b/fairseq/modules/adaptive_softmax.py\n--- a/fairseq/modules/adaptive_softmax.py\n+++ b/fairseq/modules/adaptive_softmax.py\n@@ -22,6 +22,9 @@\n \n         if vocab_size > cutoff[-1]:\n             cutoff = cutoff + [vocab_size]\n+        else:\n+            assert vocab_size == cutoff[\n+                -1], 'cannot specify cutoff smaller than vocab size'\n \n         output_dim = cutoff[0] + len(cutoff) - 1\n", "issue": "Size Mismatch in AdaptiveSoftmax when targets are not specified\nFollowing up on #212 , I'm updating `sequence_generator.py` to generate text from a pre-trained language model (initially trained with adaptive softmax). When computing log probabilities, and the targets are set to none, I receive a size mismatch exception in the line below, possibly because the dictionary size is smaller than the adaptive softmax cut-off: \r\n\r\nhttps://github.com/pytorch/fairseq/blob/388c520be21752cacb9fe3b1712038f32e0e9a5f/fairseq/modules/adaptive_softmax.py#L126\r\n\r\nI imagine this could be solved by some sort of truncation to the output of tail[i].input\n", "before_files": [{"content": "# Copyright (c) 2017-present, Facebook, Inc.\n# All rights reserved.\n#\n# This source code is licensed under the license found in the LICENSE file in\n# the root directory of this source tree. An additional grant of patent rights\n# can be found in the PATENTS file in the same directory.\n\n\nimport torch.nn.functional as F\nfrom torch import nn\n\n\nclass AdaptiveSoftmax(nn.Module):\n    \"\"\"\n    This is an implementation of the efficient softmax approximation for\n    graphical processing units (GPU), described in the paper \"Efficient softmax\n    approximation for GPUs\" (http://arxiv.org/abs/1609.04309).\n    \"\"\"\n\n    def __init__(self, vocab_size, input_dim, cutoff, dropout):\n        super().__init__()\n\n        if vocab_size > cutoff[-1]:\n            cutoff = cutoff + [vocab_size]\n\n        output_dim = cutoff[0] + len(cutoff) - 1\n\n        self.vocab_size = vocab_size\n        self.cutoff = cutoff\n        self.dropout = dropout\n\n        self.lsm = nn.LogSoftmax(dim=1)\n        self.head = nn.Linear(input_dim, output_dim, bias=False)\n        self.tail = nn.ModuleList()\n\n        for i in range(len(cutoff) - 1):\n            self.tail.append(\n                nn.Sequential(\n                    nn.Linear(input_dim, input_dim // 4 ** i, bias=False),\n                    nn.Dropout(dropout),\n                    nn.Linear(input_dim // 4 ** i, cutoff[i + 1] - cutoff[i], bias=False)\n                )\n            )\n\n        def init_weights(m):\n            if hasattr(m, 'weight'):\n                nn.init.xavier_uniform_(m.weight)\n\n        self.apply(init_weights)\n\n    def adapt_target(self, target):\n        \"\"\"\n        In order to be efficient, the AdaptiveSoftMax does not compute the\n        scores for all the word of the vocabulary for all the examples. It is\n        thus necessary to call the method adapt_target of the AdaptiveSoftMax\n        layer inside each forward pass.\n        \"\"\"\n\n        target = target.view(-1)\n        new_target = [target.clone()]\n        target_idxs = []\n\n        for i in range(len(self.cutoff) - 1):\n            mask = target.ge(self.cutoff[i]).mul(target.lt(self.cutoff[i + 1]))\n            new_target[0][mask] = self.cutoff[0] + i - 1\n\n            if mask.any():\n                target_idxs.append(mask.nonzero().squeeze(1))\n                new_target.append(target[mask].add(-self.cutoff[i]))\n            else:\n                target_idxs.append(None)\n                new_target.append(None)\n\n        return new_target, target_idxs\n\n    def forward(self, input, target):\n        \"\"\"\n        Args:\n            input: (b x t x d)\n            target: (b x t)\n        Returns:\n            2 lists: output for each cutoff section and new targets by cut off\n        \"\"\"\n\n        input = input.contiguous().view(-1, input.size(-1))\n        input = F.dropout(input, p=self.dropout, training=self.training)\n\n        new_target, target_idxs = self.adapt_target(target)\n        output = [self.head(input)]\n\n        for i in range(len(target_idxs)):\n            if target_idxs[i] is not None:\n                output.append(self.tail[i](input.index_select(0, target_idxs[i])))\n            else:\n                output.append(None)\n\n        return output, new_target\n\n    def get_log_prob(self, input, target):\n        \"\"\"\n        Computes the log probabilities for all the words of the vocabulary,\n        given a 2D tensor of hidden vectors.\n        \"\"\"\n\n        bsz, length, dim = input.size()\n        input = input.contiguous().view(-1, dim)\n\n        if target is not None:\n            _, target_idxs = self.adapt_target(target)\n        else:\n            target_idxs = None\n\n        head_y = self.head(input)\n        log_probs = head_y.new_zeros(input.size(0), self.vocab_size)\n\n        head_sz = self.cutoff[0] + len(self.tail)\n        log_probs[:, :head_sz] = self.lsm(head_y)\n        tail_priors = log_probs[:, self.cutoff[0] - 1: head_sz - 1].clone()\n\n        for i in range(len(self.tail)):\n            start = self.cutoff[i]\n            end = self.cutoff[i + 1]\n\n            if target_idxs is None:\n                tail_out = log_probs[:, start:end]\n                tail_out.copy_(self.tail[i](input))\n                log_probs[:, start:end] = self.lsm(tail_out).add_(tail_priors[:, i, None])\n            elif target_idxs[i] is not None:\n                idxs = target_idxs[i]\n                tail_out = log_probs[idxs, start:end]\n                tail_out.copy_(self.tail[i](input[idxs]))\n                log_probs[idxs, start:end] = self.lsm(tail_out).add_(tail_priors[idxs, i, None])\n\n        log_probs = log_probs.view(bsz, length, -1)\n        return log_probs\n", "path": "fairseq/modules/adaptive_softmax.py"}], "after_files": [{"content": "# Copyright (c) 2017-present, Facebook, Inc.\n# All rights reserved.\n#\n# This source code is licensed under the license found in the LICENSE file in\n# the root directory of this source tree. An additional grant of patent rights\n# can be found in the PATENTS file in the same directory.\n\n\nimport torch.nn.functional as F\nfrom torch import nn\n\n\nclass AdaptiveSoftmax(nn.Module):\n    \"\"\"\n    This is an implementation of the efficient softmax approximation for\n    graphical processing units (GPU), described in the paper \"Efficient softmax\n    approximation for GPUs\" (http://arxiv.org/abs/1609.04309).\n    \"\"\"\n\n    def __init__(self, vocab_size, input_dim, cutoff, dropout):\n        super().__init__()\n\n        if vocab_size > cutoff[-1]:\n            cutoff = cutoff + [vocab_size]\n        else:\n            assert vocab_size == cutoff[\n                -1], 'cannot specify cutoff smaller than vocab size'\n\n        output_dim = cutoff[0] + len(cutoff) - 1\n\n        self.vocab_size = vocab_size\n        self.cutoff = cutoff\n        self.dropout = dropout\n\n        self.lsm = nn.LogSoftmax(dim=1)\n        self.head = nn.Linear(input_dim, output_dim, bias=False)\n        self.tail = nn.ModuleList()\n\n        for i in range(len(cutoff) - 1):\n            self.tail.append(\n                nn.Sequential(\n                    nn.Linear(input_dim, input_dim // 4 ** i, bias=False),\n                    nn.Dropout(dropout),\n                    nn.Linear(input_dim // 4 ** i, cutoff[i + 1] - cutoff[i], bias=False)\n                )\n            )\n\n        def init_weights(m):\n            if hasattr(m, 'weight'):\n                nn.init.xavier_uniform_(m.weight)\n\n        self.apply(init_weights)\n\n    def adapt_target(self, target):\n        \"\"\"\n        In order to be efficient, the AdaptiveSoftMax does not compute the\n        scores for all the word of the vocabulary for all the examples. It is\n        thus necessary to call the method adapt_target of the AdaptiveSoftMax\n        layer inside each forward pass.\n        \"\"\"\n\n        target = target.view(-1)\n        new_target = [target.clone()]\n        target_idxs = []\n\n        for i in range(len(self.cutoff) - 1):\n            mask = target.ge(self.cutoff[i]).mul(target.lt(self.cutoff[i + 1]))\n            new_target[0][mask] = self.cutoff[0] + i - 1\n\n            if mask.any():\n                target_idxs.append(mask.nonzero().squeeze(1))\n                new_target.append(target[mask].add(-self.cutoff[i]))\n            else:\n                target_idxs.append(None)\n                new_target.append(None)\n\n        return new_target, target_idxs\n\n    def forward(self, input, target):\n        \"\"\"\n        Args:\n            input: (b x t x d)\n            target: (b x t)\n        Returns:\n            2 lists: output for each cutoff section and new targets by cut off\n        \"\"\"\n\n        input = input.contiguous().view(-1, input.size(-1))\n        input = F.dropout(input, p=self.dropout, training=self.training)\n\n        new_target, target_idxs = self.adapt_target(target)\n        output = [self.head(input)]\n\n        for i in range(len(target_idxs)):\n            if target_idxs[i] is not None:\n                output.append(self.tail[i](input.index_select(0, target_idxs[i])))\n            else:\n                output.append(None)\n\n        return output, new_target\n\n    def get_log_prob(self, input, target):\n        \"\"\"\n        Computes the log probabilities for all the words of the vocabulary,\n        given a 2D tensor of hidden vectors.\n        \"\"\"\n\n        bsz, length, dim = input.size()\n        input = input.contiguous().view(-1, dim)\n\n        if target is not None:\n            _, target_idxs = self.adapt_target(target)\n        else:\n            target_idxs = None\n\n        head_y = self.head(input)\n        log_probs = head_y.new_zeros(input.size(0), self.vocab_size)\n\n        head_sz = self.cutoff[0] + len(self.tail)\n        log_probs[:, :head_sz] = self.lsm(head_y)\n        tail_priors = log_probs[:, self.cutoff[0] - 1: head_sz - 1].clone()\n\n        for i in range(len(self.tail)):\n            start = self.cutoff[i]\n            end = self.cutoff[i + 1]\n\n            if target_idxs is None:\n                tail_out = log_probs[:, start:end]\n                tail_out.copy_(self.tail[i](input))\n                log_probs[:, start:end] = self.lsm(tail_out).add_(tail_priors[:, i, None])\n            elif target_idxs[i] is not None:\n                idxs = target_idxs[i]\n                tail_out = log_probs[idxs, start:end]\n                tail_out.copy_(self.tail[i](input[idxs]))\n                log_probs[idxs, start:end] = self.lsm(tail_out).add_(tail_priors[idxs, i, None])\n\n        log_probs = log_probs.view(bsz, length, -1)\n        return log_probs\n", "path": "fairseq/modules/adaptive_softmax.py"}]}