We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Empty training examples throwing runtime error
I'm getting an error with the OpenSubtitles (2009 and 2018) and the Cornell Movie datasets with length 0 examples being loaded. My guess is that there are empty messages in the datasets, which could easily be removed with some preprocessing or a flag to avoid such examples. However, I'm having trouble finding such a flag and would appreciate any help you can provide. I do not have this issue arise on other datasets that I have explored so far. 

I'm a bit puzzled as to why others haven't seemed to run into this problem and was hoping you could help point me in the right direction, especially if I'm missing an easy fix. Thanks.

**Error:**
```
Traceback (most recent call last):
 File "examples/train_model.py", line 16, in <module>
   TrainLoop(opt).train()
 File "/data/odemasi/packages/ParlAI/parlai/scripts/train_model.py", line 523, in train
   world.parley()
 File "/data/odemasi/packages/ParlAI/parlai/core/worlds.py", line 654, in parley
   batch_act = self.batch_act(agent_idx, batch_observations[agent_idx])
 File "/data/odemasi/packages/ParlAI/parlai/core/worlds.py", line 627, in batch_act
   batch_actions = a.batch_act(batch_observation)
 File "/data/odemasi/packages/ParlAI/parlai/core/torch_agent.py", line 1206, in batch_act
   output = self.train_step(batch)
 File "/data/odemasi/packages/ParlAI/parlai/core/torch_generator_agent.py", line 478, in train_step
   raise e
 File "/data/odemasi/packages/ParlAI/parlai/core/torch_generator_agent.py", line 454, in train_step
   scores, preds, _ = self.model(batch.text_vec, batch.label_vec)
 File "/data/odemasi/anaconda3/envs/parlai_venv/lib/python3.7/site-packages/torch/nn/modules/module.py", line 489, in __call__
   result = self.forward(*input, **kwargs)
 File "/data/odemasi/packages/ParlAI/parlai/core/torch_generator_agent.py", line 214, in forward
   encoder_states = prev_enc if prev_enc is not None else self.encoder(xs)
 File "/data/odemasi/anaconda3/envs/parlai_venv/lib/python3.7/site-packages/torch/nn/modules/module.py", line 489, in __call__
   result = self.forward(*input, **kwargs)
 File "/data/odemasi/packages/ParlAI/parlai/agents/seq2seq/modules.py", line 226, in forward
   xes = pack_padded_sequence(xes, x_lens, batch_first=True)
 File "/data/odemasi/anaconda3/envs/parlai_venv/lib/python3.7/site-packages/torch/nn/utils/rnn.py", line 148, in pack_padded_sequence
   return PackedSequence(torch._C._VariableFunctions._pack_padded_sequence(input, lengths, batch_first))
RuntimeError: Length of all samples has to be greater than 0, but found an element in 'lengths' that is <= 0
```


**Resulted from:**
python examples/train_model.py \
-t cornell_movie \
-bs 32 \
--hiddensize 1024 \
--dict-minfreq 2 \
--dict-lower True \
--dict-file cornell_dict \
-m seq2seq \
-mf cornell_seq2seq 

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `parlai/agents/seq2seq/seq2seq.py`
Content:
```
1 #!/usr/bin/env python3
2 
3 # Copyright (c) Facebook, Inc. and its affiliates.
4 # This source code is licensed under the MIT license found in the
5 # LICENSE file in the root directory of this source tree.
6 
7 from parlai.core.torch_generator_agent import TorchGeneratorAgent
8 from .modules import Seq2seq, opt_to_kwargs
9 
10 import torch
11 import torch.nn as nn
12 
13 import json
14 
15 
16 class Seq2seqAgent(TorchGeneratorAgent):
17     """Agent which takes an input sequence and produces an output sequence.
18 
19     This model supports encoding the input and decoding the output via one of
20     several flavors of RNN. It then uses a linear layer (whose weights can
21     be shared with the embedding layer) to convert RNN output states into
22     output tokens. This model supports greedy decoding, selecting the
23     highest probability token at each time step, as well as beam
24     search.
25 
26     For more information, see the following papers:
27     - Neural Machine Translation by Jointly Learning to Align and Translate
28       `(Bahdanau et al. 2014) <arxiv.org/abs/1409.0473>`_
29     - Sequence to Sequence Learning with Neural Networks
30       `(Sutskever et al. 2014) <arxiv.org/abs/1409.3215>`_
31     - Effective Approaches to Attention-based Neural Machine Translation
32       `(Luong et al. 2015) <arxiv.org/abs/1508.04025>`_
33     """
34 
35     @classmethod
36     def add_cmdline_args(cls, argparser):
37         """Add command-line arguments specifically for this agent."""
38         agent = argparser.add_argument_group('Seq2Seq Arguments')
39         agent.add_argument('-hs', '--hiddensize', type=int, default=128,
40                            help='size of the hidden layers')
41         agent.add_argument('-esz', '--embeddingsize', type=int, default=128,
42                            help='size of the token embeddings')
43         agent.add_argument('-nl', '--numlayers', type=int, default=2,
44                            help='number of hidden layers')
45         agent.add_argument('-dr', '--dropout', type=float, default=0.1,
46                            help='dropout rate')
47         agent.add_argument('-bi', '--bidirectional', type='bool',
48                            default=False,
49                            help='whether to encode the context with a '
50                                 'bidirectional rnn')
51         agent.add_argument('-att', '--attention', default='none',
52                            choices=['none', 'concat', 'general', 'dot',
53                                     'local'],
54                            help='Choices: none, concat, general, local. '
55                                 'If set local, also set attention-length. '
56                                 '(see arxiv.org/abs/1508.04025)')
57         agent.add_argument('-attl', '--attention-length', default=48, type=int,
58                            help='Length of local attention.')
59         agent.add_argument('--attention-time', default='post',
60                            choices=['pre', 'post'],
61                            help='Whether to apply attention before or after '
62                                 'decoding.')
63         agent.add_argument('-rnn', '--rnn-class', default='lstm',
64                            choices=Seq2seq.RNN_OPTS.keys(),
65                            help='Choose between different types of RNNs.')
66         agent.add_argument('-dec', '--decoder', default='same',
67                            choices=['same', 'shared'],
68                            help='Choose between different decoder modules. '
69                                 'Default "same" uses same class as encoder, '
70                                 'while "shared" also uses the same weights. '
71                                 'Note that shared disabled some encoder '
72                                 'options--in particular, bidirectionality.')
73         agent.add_argument('-lt', '--lookuptable', default='unique',
74                            choices=['unique', 'enc_dec', 'dec_out', 'all'],
75                            help='The encoder, decoder, and output modules can '
76                                 'share weights, or not. '
77                                 'Unique has independent embeddings for each. '
78                                 'Enc_dec shares the embedding for the encoder '
79                                 'and decoder. '
80                                 'Dec_out shares decoder embedding and output '
81                                 'weights. '
82                                 'All shares all three weights.')
83         agent.add_argument('-soft', '--numsoftmax', default=1, type=int,
84                            help='default 1, if greater then uses mixture of '
85                                 'softmax (see arxiv.org/abs/1711.03953).')
86         agent.add_argument('-idr', '--input-dropout', type=float, default=0.0,
87                            help='Probability of replacing tokens with UNK in training.')
88 
89         super(Seq2seqAgent, cls).add_cmdline_args(argparser)
90         return agent
91 
92     @staticmethod
93     def model_version():
94         """Return current version of this model, counting up from 0.
95 
96         Models may not be backwards-compatible with older versions.
97         Version 1 split from version 0 on Aug 29, 2018.
98         Version 2 split from version 1 on Nov 13, 2018
99         To use version 0, use --model legacy:seq2seq:0
100         To use version 1, use --model legacy:seq2seq:1
101         (legacy agent code is located in parlai/agents/legacy_agents).
102         """
103         return 2
104 
105     def __init__(self, opt, shared=None):
106         """Set up model."""
107         super().__init__(opt, shared)
108         self.id = 'Seq2Seq'
109 
110     def build_model(self, states=None):
111         """Initialize model, override to change model setup."""
112         opt = self.opt
113         if not states:
114             states = {}
115 
116         kwargs = opt_to_kwargs(opt)
117         self.model = Seq2seq(
118             len(self.dict), opt['embeddingsize'], opt['hiddensize'],
119             padding_idx=self.NULL_IDX, start_idx=self.START_IDX,
120             end_idx=self.END_IDX, unknown_idx=self.dict[self.dict.unk_token],
121             longest_label=states.get('longest_label', 1),
122             **kwargs)
123 
124         if (opt.get('dict_tokenizer') == 'bpe' and
125                 opt['embedding_type'] != 'random'):
126             print('skipping preinitialization of embeddings for bpe')
127         elif not states and opt['embedding_type'] != 'random':
128             # `not states`: only set up embeddings if not loading model
129             self._copy_embeddings(self.model.decoder.lt.weight,
130                                   opt['embedding_type'])
131             if opt['lookuptable'] in ['unique', 'dec_out']:
132                 # also set encoder lt, since it's not shared
133                 self._copy_embeddings(self.model.encoder.lt.weight,
134                                       opt['embedding_type'], log=False)
135 
136         if states:
137             # set loaded states if applicable
138             self.model.load_state_dict(states['model'])
139 
140         if self.use_cuda:
141             self.model.cuda()
142 
143         if opt['embedding_type'].endswith('fixed'):
144             print('Seq2seq: fixing embedding weights.')
145             self.model.decoder.lt.weight.requires_grad = False
146             self.model.encoder.lt.weight.requires_grad = False
147             if opt['lookuptable'] in ['dec_out', 'all']:
148                 self.model.decoder.e2s.weight.requires_grad = False
149 
150         if self.use_cuda:
151             self.model.cuda()
152 
153         return self.model
154 
155     def build_criterion(self):
156         # set up criteria
157         if self.opt.get('numsoftmax', 1) > 1:
158             self.criterion = nn.NLLLoss(
159                 ignore_index=self.NULL_IDX, size_average=False)
160         else:
161             self.criterion = nn.CrossEntropyLoss(
162                 ignore_index=self.NULL_IDX, size_average=False)
163 
164         if self.use_cuda:
165             self.criterion.cuda()
166 
167     def batchify(self, *args, **kwargs):
168         """Override batchify options for seq2seq."""
169         kwargs['sort'] = True  # need sorted for pack_padded
170         return super().batchify(*args, **kwargs)
171 
172     def save(self, path=None):
173         """Save model parameters if model_file is set."""
174         path = self.opt.get('model_file', None) if path is None else path
175 
176         if path and hasattr(self, 'model'):
177             model = {}
178             if hasattr(self.model, 'module'):
179                 model['model'] = self.model.module.state_dict()
180                 model['longest_label'] = self.model.module.longest_label
181             else:
182                 model['model'] = self.model.state_dict()
183                 model['longest_label'] = self.model.longest_label
184             model['optimizer'] = self.optimizer.state_dict()
185             model['optimizer_type'] = self.opt['optimizer']
186 
187             with open(path, 'wb') as write:
188                 torch.save(model, write)
189 
190             # save opt file
191             with open(path + '.opt', 'w') as handle:
192                 # save version string
193                 self.opt['model_version'] = self.model_version()
194                 json.dump(self.opt, handle)
195 
196     def load(self, path):
197         """Return opt and model states."""
198         states = torch.load(path, map_location=lambda cpu, _: cpu)
199         # set loaded states if applicable
200         self.model.load_state_dict(states['model'])
201         if 'longest_label' in states:
202             self.model.longest_label = states['longest_label']
203         return states
204
```
--- 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()

```

diff --git a/parlai/agents/seq2seq/seq2seq.py b/parlai/agents/seq2seq/seq2seq.py
--- a/parlai/agents/seq2seq/seq2seq.py
+++ b/parlai/agents/seq2seq/seq2seq.py
@@ -5,6 +5,7 @@
 # LICENSE file in the root directory of this source tree.
 
 from parlai.core.torch_generator_agent import TorchGeneratorAgent
+from parlai.core.utils import warn_once
 from .modules import Seq2seq, opt_to_kwargs
 
 import torch
@@ -201,3 +202,22 @@
         if 'longest_label' in states:
             self.model.longest_label = states['longest_label']
         return states
+
+    def is_valid(self, obs):
+        normally_valid = super().is_valid(obs)
+        if not normally_valid:
+            # shortcut boolean evaluation
+            return normally_valid
+        contains_empties = obs['text_vec'].shape[0] == 0
+        if self.is_training and contains_empties:
+            warn_once(
+                'seq2seq got an empty input sequence (text_vec) during training. '
+                'Skipping this example, but you should check your dataset and '
+                'preprocessing.'
+            )
+        elif not self.is_training and contains_empties:
+            warn_once(
+                'seq2seq got an empty input sequence (text_vec) in an '
+                'evaluation example! This may affect your metrics!'
+            )
+        return not contains_empties

{"golden_diff": "diff --git a/parlai/agents/seq2seq/seq2seq.py b/parlai/agents/seq2seq/seq2seq.py\n--- a/parlai/agents/seq2seq/seq2seq.py\n+++ b/parlai/agents/seq2seq/seq2seq.py\n@@ -5,6 +5,7 @@\n # LICENSE file in the root directory of this source tree.\n \n from parlai.core.torch_generator_agent import TorchGeneratorAgent\n+from parlai.core.utils import warn_once\n from .modules import Seq2seq, opt_to_kwargs\n \n import torch\n@@ -201,3 +202,22 @@\n         if 'longest_label' in states:\n             self.model.longest_label = states['longest_label']\n         return states\n+\n+    def is_valid(self, obs):\n+        normally_valid = super().is_valid(obs)\n+        if not normally_valid:\n+            # shortcut boolean evaluation\n+            return normally_valid\n+        contains_empties = obs['text_vec'].shape[0] == 0\n+        if self.is_training and contains_empties:\n+            warn_once(\n+                'seq2seq got an empty input sequence (text_vec) during training. '\n+                'Skipping this example, but you should check your dataset and '\n+                'preprocessing.'\n+            )\n+        elif not self.is_training and contains_empties:\n+            warn_once(\n+                'seq2seq got an empty input sequence (text_vec) in an '\n+                'evaluation example! This may affect your metrics!'\n+            )\n+        return not contains_empties\n", "issue": "Empty training examples throwing runtime error\nI'm getting an error with the OpenSubtitles (2009 and 2018) and the Cornell Movie datasets with length 0 examples being loaded. My guess is that there are empty messages in the datasets, which could easily be removed with some preprocessing or a flag to avoid such examples. However, I'm having trouble finding such a flag and would appreciate any help you can provide. I do not have this issue arise on other datasets that I have explored so far. \r\n\r\nI'm a bit puzzled as to why others haven't seemed to run into this problem and was hoping you could help point me in the right direction, especially if I'm missing an easy fix. Thanks.\r\n\r\n**Error:**\r\n```\r\nTraceback (most recent call last):\r\n File \"examples/train_model.py\", line 16, in <module>\r\n   TrainLoop(opt).train()\r\n File \"/data/odemasi/packages/ParlAI/parlai/scripts/train_model.py\", line 523, in train\r\n   world.parley()\r\n File \"/data/odemasi/packages/ParlAI/parlai/core/worlds.py\", line 654, in parley\r\n   batch_act = self.batch_act(agent_idx, batch_observations[agent_idx])\r\n File \"/data/odemasi/packages/ParlAI/parlai/core/worlds.py\", line 627, in batch_act\r\n   batch_actions = a.batch_act(batch_observation)\r\n File \"/data/odemasi/packages/ParlAI/parlai/core/torch_agent.py\", line 1206, in batch_act\r\n   output = self.train_step(batch)\r\n File \"/data/odemasi/packages/ParlAI/parlai/core/torch_generator_agent.py\", line 478, in train_step\r\n   raise e\r\n File \"/data/odemasi/packages/ParlAI/parlai/core/torch_generator_agent.py\", line 454, in train_step\r\n   scores, preds, _ = self.model(batch.text_vec, batch.label_vec)\r\n File \"/data/odemasi/anaconda3/envs/parlai_venv/lib/python3.7/site-packages/torch/nn/modules/module.py\", line 489, in __call__\r\n   result = self.forward(*input, **kwargs)\r\n File \"/data/odemasi/packages/ParlAI/parlai/core/torch_generator_agent.py\", line 214, in forward\r\n   encoder_states = prev_enc if prev_enc is not None else self.encoder(xs)\r\n File \"/data/odemasi/anaconda3/envs/parlai_venv/lib/python3.7/site-packages/torch/nn/modules/module.py\", line 489, in __call__\r\n   result = self.forward(*input, **kwargs)\r\n File \"/data/odemasi/packages/ParlAI/parlai/agents/seq2seq/modules.py\", line 226, in forward\r\n   xes = pack_padded_sequence(xes, x_lens, batch_first=True)\r\n File \"/data/odemasi/anaconda3/envs/parlai_venv/lib/python3.7/site-packages/torch/nn/utils/rnn.py\", line 148, in pack_padded_sequence\r\n   return PackedSequence(torch._C._VariableFunctions._pack_padded_sequence(input, lengths, batch_first))\r\nRuntimeError: Length of all samples has to be greater than 0, but found an element in 'lengths' that is <= 0\r\n```\r\n\r\n\r\n**Resulted from:**\r\npython examples/train_model.py \\\r\n-t cornell_movie \\\r\n-bs 32 \\\r\n--hiddensize 1024 \\\r\n--dict-minfreq 2 \\\r\n--dict-lower True \\\r\n--dict-file cornell_dict \\\r\n-m seq2seq \\\r\n-mf cornell_seq2seq \n", "before_files": [{"content": "#!/usr/bin/env python3\n\n# Copyright (c) Facebook, Inc. and its affiliates.\n# This source code is licensed under the MIT license found in the\n# LICENSE file in the root directory of this source tree.\n\nfrom parlai.core.torch_generator_agent import TorchGeneratorAgent\nfrom .modules import Seq2seq, opt_to_kwargs\n\nimport torch\nimport torch.nn as nn\n\nimport json\n\n\nclass Seq2seqAgent(TorchGeneratorAgent):\n    \"\"\"Agent which takes an input sequence and produces an output sequence.\n\n    This model supports encoding the input and decoding the output via one of\n    several flavors of RNN. It then uses a linear layer (whose weights can\n    be shared with the embedding layer) to convert RNN output states into\n    output tokens. This model supports greedy decoding, selecting the\n    highest probability token at each time step, as well as beam\n    search.\n\n    For more information, see the following papers:\n    - Neural Machine Translation by Jointly Learning to Align and Translate\n      `(Bahdanau et al. 2014) <arxiv.org/abs/1409.0473>`_\n    - Sequence to Sequence Learning with Neural Networks\n      `(Sutskever et al. 2014) <arxiv.org/abs/1409.3215>`_\n    - Effective Approaches to Attention-based Neural Machine Translation\n      `(Luong et al. 2015) <arxiv.org/abs/1508.04025>`_\n    \"\"\"\n\n    @classmethod\n    def add_cmdline_args(cls, argparser):\n        \"\"\"Add command-line arguments specifically for this agent.\"\"\"\n        agent = argparser.add_argument_group('Seq2Seq Arguments')\n        agent.add_argument('-hs', '--hiddensize', type=int, default=128,\n                           help='size of the hidden layers')\n        agent.add_argument('-esz', '--embeddingsize', type=int, default=128,\n                           help='size of the token embeddings')\n        agent.add_argument('-nl', '--numlayers', type=int, default=2,\n                           help='number of hidden layers')\n        agent.add_argument('-dr', '--dropout', type=float, default=0.1,\n                           help='dropout rate')\n        agent.add_argument('-bi', '--bidirectional', type='bool',\n                           default=False,\n                           help='whether to encode the context with a '\n                                'bidirectional rnn')\n        agent.add_argument('-att', '--attention', default='none',\n                           choices=['none', 'concat', 'general', 'dot',\n                                    'local'],\n                           help='Choices: none, concat, general, local. '\n                                'If set local, also set attention-length. '\n                                '(see arxiv.org/abs/1508.04025)')\n        agent.add_argument('-attl', '--attention-length', default=48, type=int,\n                           help='Length of local attention.')\n        agent.add_argument('--attention-time', default='post',\n                           choices=['pre', 'post'],\n                           help='Whether to apply attention before or after '\n                                'decoding.')\n        agent.add_argument('-rnn', '--rnn-class', default='lstm',\n                           choices=Seq2seq.RNN_OPTS.keys(),\n                           help='Choose between different types of RNNs.')\n        agent.add_argument('-dec', '--decoder', default='same',\n                           choices=['same', 'shared'],\n                           help='Choose between different decoder modules. '\n                                'Default \"same\" uses same class as encoder, '\n                                'while \"shared\" also uses the same weights. '\n                                'Note that shared disabled some encoder '\n                                'options--in particular, bidirectionality.')\n        agent.add_argument('-lt', '--lookuptable', default='unique',\n                           choices=['unique', 'enc_dec', 'dec_out', 'all'],\n                           help='The encoder, decoder, and output modules can '\n                                'share weights, or not. '\n                                'Unique has independent embeddings for each. '\n                                'Enc_dec shares the embedding for the encoder '\n                                'and decoder. '\n                                'Dec_out shares decoder embedding and output '\n                                'weights. '\n                                'All shares all three weights.')\n        agent.add_argument('-soft', '--numsoftmax', default=1, type=int,\n                           help='default 1, if greater then uses mixture of '\n                                'softmax (see arxiv.org/abs/1711.03953).')\n        agent.add_argument('-idr', '--input-dropout', type=float, default=0.0,\n                           help='Probability of replacing tokens with UNK in training.')\n\n        super(Seq2seqAgent, cls).add_cmdline_args(argparser)\n        return agent\n\n    @staticmethod\n    def model_version():\n        \"\"\"Return current version of this model, counting up from 0.\n\n        Models may not be backwards-compatible with older versions.\n        Version 1 split from version 0 on Aug 29, 2018.\n        Version 2 split from version 1 on Nov 13, 2018\n        To use version 0, use --model legacy:seq2seq:0\n        To use version 1, use --model legacy:seq2seq:1\n        (legacy agent code is located in parlai/agents/legacy_agents).\n        \"\"\"\n        return 2\n\n    def __init__(self, opt, shared=None):\n        \"\"\"Set up model.\"\"\"\n        super().__init__(opt, shared)\n        self.id = 'Seq2Seq'\n\n    def build_model(self, states=None):\n        \"\"\"Initialize model, override to change model setup.\"\"\"\n        opt = self.opt\n        if not states:\n            states = {}\n\n        kwargs = opt_to_kwargs(opt)\n        self.model = Seq2seq(\n            len(self.dict), opt['embeddingsize'], opt['hiddensize'],\n            padding_idx=self.NULL_IDX, start_idx=self.START_IDX,\n            end_idx=self.END_IDX, unknown_idx=self.dict[self.dict.unk_token],\n            longest_label=states.get('longest_label', 1),\n            **kwargs)\n\n        if (opt.get('dict_tokenizer') == 'bpe' and\n                opt['embedding_type'] != 'random'):\n            print('skipping preinitialization of embeddings for bpe')\n        elif not states and opt['embedding_type'] != 'random':\n            # `not states`: only set up embeddings if not loading model\n            self._copy_embeddings(self.model.decoder.lt.weight,\n                                  opt['embedding_type'])\n            if opt['lookuptable'] in ['unique', 'dec_out']:\n                # also set encoder lt, since it's not shared\n                self._copy_embeddings(self.model.encoder.lt.weight,\n                                      opt['embedding_type'], log=False)\n\n        if states:\n            # set loaded states if applicable\n            self.model.load_state_dict(states['model'])\n\n        if self.use_cuda:\n            self.model.cuda()\n\n        if opt['embedding_type'].endswith('fixed'):\n            print('Seq2seq: fixing embedding weights.')\n            self.model.decoder.lt.weight.requires_grad = False\n            self.model.encoder.lt.weight.requires_grad = False\n            if opt['lookuptable'] in ['dec_out', 'all']:\n                self.model.decoder.e2s.weight.requires_grad = False\n\n        if self.use_cuda:\n            self.model.cuda()\n\n        return self.model\n\n    def build_criterion(self):\n        # set up criteria\n        if self.opt.get('numsoftmax', 1) > 1:\n            self.criterion = nn.NLLLoss(\n                ignore_index=self.NULL_IDX, size_average=False)\n        else:\n            self.criterion = nn.CrossEntropyLoss(\n                ignore_index=self.NULL_IDX, size_average=False)\n\n        if self.use_cuda:\n            self.criterion.cuda()\n\n    def batchify(self, *args, **kwargs):\n        \"\"\"Override batchify options for seq2seq.\"\"\"\n        kwargs['sort'] = True  # need sorted for pack_padded\n        return super().batchify(*args, **kwargs)\n\n    def save(self, path=None):\n        \"\"\"Save model parameters if model_file is set.\"\"\"\n        path = self.opt.get('model_file', None) if path is None else path\n\n        if path and hasattr(self, 'model'):\n            model = {}\n            if hasattr(self.model, 'module'):\n                model['model'] = self.model.module.state_dict()\n                model['longest_label'] = self.model.module.longest_label\n            else:\n                model['model'] = self.model.state_dict()\n                model['longest_label'] = self.model.longest_label\n            model['optimizer'] = self.optimizer.state_dict()\n            model['optimizer_type'] = self.opt['optimizer']\n\n            with open(path, 'wb') as write:\n                torch.save(model, write)\n\n            # save opt file\n            with open(path + '.opt', 'w') as handle:\n                # save version string\n                self.opt['model_version'] = self.model_version()\n                json.dump(self.opt, handle)\n\n    def load(self, path):\n        \"\"\"Return opt and model states.\"\"\"\n        states = torch.load(path, map_location=lambda cpu, _: cpu)\n        # set loaded states if applicable\n        self.model.load_state_dict(states['model'])\n        if 'longest_label' in states:\n            self.model.longest_label = states['longest_label']\n        return states\n", "path": "parlai/agents/seq2seq/seq2seq.py"}], "after_files": [{"content": "#!/usr/bin/env python3\n\n# Copyright (c) Facebook, Inc. and its affiliates.\n# This source code is licensed under the MIT license found in the\n# LICENSE file in the root directory of this source tree.\n\nfrom parlai.core.torch_generator_agent import TorchGeneratorAgent\nfrom parlai.core.utils import warn_once\nfrom .modules import Seq2seq, opt_to_kwargs\n\nimport torch\nimport torch.nn as nn\n\nimport json\n\n\nclass Seq2seqAgent(TorchGeneratorAgent):\n    \"\"\"Agent which takes an input sequence and produces an output sequence.\n\n    This model supports encoding the input and decoding the output via one of\n    several flavors of RNN. It then uses a linear layer (whose weights can\n    be shared with the embedding layer) to convert RNN output states into\n    output tokens. This model supports greedy decoding, selecting the\n    highest probability token at each time step, as well as beam\n    search.\n\n    For more information, see the following papers:\n    - Neural Machine Translation by Jointly Learning to Align and Translate\n      `(Bahdanau et al. 2014) <arxiv.org/abs/1409.0473>`_\n    - Sequence to Sequence Learning with Neural Networks\n      `(Sutskever et al. 2014) <arxiv.org/abs/1409.3215>`_\n    - Effective Approaches to Attention-based Neural Machine Translation\n      `(Luong et al. 2015) <arxiv.org/abs/1508.04025>`_\n    \"\"\"\n\n    @classmethod\n    def add_cmdline_args(cls, argparser):\n        \"\"\"Add command-line arguments specifically for this agent.\"\"\"\n        agent = argparser.add_argument_group('Seq2Seq Arguments')\n        agent.add_argument('-hs', '--hiddensize', type=int, default=128,\n                           help='size of the hidden layers')\n        agent.add_argument('-esz', '--embeddingsize', type=int, default=128,\n                           help='size of the token embeddings')\n        agent.add_argument('-nl', '--numlayers', type=int, default=2,\n                           help='number of hidden layers')\n        agent.add_argument('-dr', '--dropout', type=float, default=0.1,\n                           help='dropout rate')\n        agent.add_argument('-bi', '--bidirectional', type='bool',\n                           default=False,\n                           help='whether to encode the context with a '\n                                'bidirectional rnn')\n        agent.add_argument('-att', '--attention', default='none',\n                           choices=['none', 'concat', 'general', 'dot',\n                                    'local'],\n                           help='Choices: none, concat, general, local. '\n                                'If set local, also set attention-length. '\n                                '(see arxiv.org/abs/1508.04025)')\n        agent.add_argument('-attl', '--attention-length', default=48, type=int,\n                           help='Length of local attention.')\n        agent.add_argument('--attention-time', default='post',\n                           choices=['pre', 'post'],\n                           help='Whether to apply attention before or after '\n                                'decoding.')\n        agent.add_argument('-rnn', '--rnn-class', default='lstm',\n                           choices=Seq2seq.RNN_OPTS.keys(),\n                           help='Choose between different types of RNNs.')\n        agent.add_argument('-dec', '--decoder', default='same',\n                           choices=['same', 'shared'],\n                           help='Choose between different decoder modules. '\n                                'Default \"same\" uses same class as encoder, '\n                                'while \"shared\" also uses the same weights. '\n                                'Note that shared disabled some encoder '\n                                'options--in particular, bidirectionality.')\n        agent.add_argument('-lt', '--lookuptable', default='unique',\n                           choices=['unique', 'enc_dec', 'dec_out', 'all'],\n                           help='The encoder, decoder, and output modules can '\n                                'share weights, or not. '\n                                'Unique has independent embeddings for each. '\n                                'Enc_dec shares the embedding for the encoder '\n                                'and decoder. '\n                                'Dec_out shares decoder embedding and output '\n                                'weights. '\n                                'All shares all three weights.')\n        agent.add_argument('-soft', '--numsoftmax', default=1, type=int,\n                           help='default 1, if greater then uses mixture of '\n                                'softmax (see arxiv.org/abs/1711.03953).')\n        agent.add_argument('-idr', '--input-dropout', type=float, default=0.0,\n                           help='Probability of replacing tokens with UNK in training.')\n\n        super(Seq2seqAgent, cls).add_cmdline_args(argparser)\n        return agent\n\n    @staticmethod\n    def model_version():\n        \"\"\"Return current version of this model, counting up from 0.\n\n        Models may not be backwards-compatible with older versions.\n        Version 1 split from version 0 on Aug 29, 2018.\n        Version 2 split from version 1 on Nov 13, 2018\n        To use version 0, use --model legacy:seq2seq:0\n        To use version 1, use --model legacy:seq2seq:1\n        (legacy agent code is located in parlai/agents/legacy_agents).\n        \"\"\"\n        return 2\n\n    def __init__(self, opt, shared=None):\n        \"\"\"Set up model.\"\"\"\n        super().__init__(opt, shared)\n        self.id = 'Seq2Seq'\n\n    def build_model(self, states=None):\n        \"\"\"Initialize model, override to change model setup.\"\"\"\n        opt = self.opt\n        if not states:\n            states = {}\n\n        kwargs = opt_to_kwargs(opt)\n        self.model = Seq2seq(\n            len(self.dict), opt['embeddingsize'], opt['hiddensize'],\n            padding_idx=self.NULL_IDX, start_idx=self.START_IDX,\n            end_idx=self.END_IDX, unknown_idx=self.dict[self.dict.unk_token],\n            longest_label=states.get('longest_label', 1),\n            **kwargs)\n\n        if (opt.get('dict_tokenizer') == 'bpe' and\n                opt['embedding_type'] != 'random'):\n            print('skipping preinitialization of embeddings for bpe')\n        elif not states and opt['embedding_type'] != 'random':\n            # `not states`: only set up embeddings if not loading model\n            self._copy_embeddings(self.model.decoder.lt.weight,\n                                  opt['embedding_type'])\n            if opt['lookuptable'] in ['unique', 'dec_out']:\n                # also set encoder lt, since it's not shared\n                self._copy_embeddings(self.model.encoder.lt.weight,\n                                      opt['embedding_type'], log=False)\n\n        if states:\n            # set loaded states if applicable\n            self.model.load_state_dict(states['model'])\n\n        if self.use_cuda:\n            self.model.cuda()\n\n        if opt['embedding_type'].endswith('fixed'):\n            print('Seq2seq: fixing embedding weights.')\n            self.model.decoder.lt.weight.requires_grad = False\n            self.model.encoder.lt.weight.requires_grad = False\n            if opt['lookuptable'] in ['dec_out', 'all']:\n                self.model.decoder.e2s.weight.requires_grad = False\n\n        if self.use_cuda:\n            self.model.cuda()\n\n        return self.model\n\n    def build_criterion(self):\n        # set up criteria\n        if self.opt.get('numsoftmax', 1) > 1:\n            self.criterion = nn.NLLLoss(\n                ignore_index=self.NULL_IDX, size_average=False)\n        else:\n            self.criterion = nn.CrossEntropyLoss(\n                ignore_index=self.NULL_IDX, size_average=False)\n\n        if self.use_cuda:\n            self.criterion.cuda()\n\n    def batchify(self, *args, **kwargs):\n        \"\"\"Override batchify options for seq2seq.\"\"\"\n        kwargs['sort'] = True  # need sorted for pack_padded\n        return super().batchify(*args, **kwargs)\n\n    def save(self, path=None):\n        \"\"\"Save model parameters if model_file is set.\"\"\"\n        path = self.opt.get('model_file', None) if path is None else path\n\n        if path and hasattr(self, 'model'):\n            model = {}\n            if hasattr(self.model, 'module'):\n                model['model'] = self.model.module.state_dict()\n                model['longest_label'] = self.model.module.longest_label\n            else:\n                model['model'] = self.model.state_dict()\n                model['longest_label'] = self.model.longest_label\n            model['optimizer'] = self.optimizer.state_dict()\n            model['optimizer_type'] = self.opt['optimizer']\n\n            with open(path, 'wb') as write:\n                torch.save(model, write)\n\n            # save opt file\n            with open(path + '.opt', 'w') as handle:\n                # save version string\n                self.opt['model_version'] = self.model_version()\n                json.dump(self.opt, handle)\n\n    def load(self, path):\n        \"\"\"Return opt and model states.\"\"\"\n        states = torch.load(path, map_location=lambda cpu, _: cpu)\n        # set loaded states if applicable\n        self.model.load_state_dict(states['model'])\n        if 'longest_label' in states:\n            self.model.longest_label = states['longest_label']\n        return states\n\n    def is_valid(self, obs):\n        normally_valid = super().is_valid(obs)\n        if not normally_valid:\n            # shortcut boolean evaluation\n            return normally_valid\n        contains_empties = obs['text_vec'].shape[0] == 0\n        if self.is_training and contains_empties:\n            warn_once(\n                'seq2seq got an empty input sequence (text_vec) during training. '\n                'Skipping this example, but you should check your dataset and '\n                'preprocessing.'\n            )\n        elif not self.is_training and contains_empties:\n            warn_once(\n                'seq2seq got an empty input sequence (text_vec) in an '\n                'evaluation example! This may affect your metrics!'\n            )\n        return not contains_empties\n", "path": "parlai/agents/seq2seq/seq2seq.py"}]}