We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
lr scheduler not optimizing params
`svi.step()` is not updating parameters with each optimizer.  see #1241

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `pyro/optim/optim.py`
Content:
```
1 from __future__ import absolute_import, division, print_function
2 
3 import torch
4 
5 import pyro
6 from pyro.optim.adagrad_rmsprop import AdagradRMSProp as pt_AdagradRMSProp
7 from pyro.optim.clipped_adam import ClippedAdam as pt_ClippedAdam
8 from pyro.params import module_from_param_with_module_name, user_param_name
9 
10 
11 class PyroOptim(object):
12     """
13     A wrapper for torch.optim.Optimizer objects that helps with managing dynamically generated parameters.
14 
15     :param optim_constructor: a torch.optim.Optimizer
16     :param optim_args: a dictionary of learning arguments for the optimizer or a callable that returns
17         such dictionaries
18     """
19     def __init__(self, optim_constructor, optim_args):
20         self.pt_optim_constructor = optim_constructor
21 
22         # must be callable or dict
23         assert callable(optim_args) or isinstance(
24             optim_args, dict), "optim_args must be function that returns defaults or a defaults dictionary"
25 
26         # hold our args to be called/used
27         self.pt_optim_args = optim_args
28 
29         # holds the torch optimizer objects
30         self.optim_objs = {}
31 
32         # holds the current epoch
33         self.epoch = None
34 
35         # any optimizer state that's waiting to be consumed (because that parameter hasn't been seen before)
36         self._state_waiting_to_be_consumed = {}
37 
38     def __call__(self, params,  *args, **kwargs):
39         """
40         :param params: a list of parameters
41         :type params: an iterable of strings
42 
43         Do an optimization step for each param in params. If a given param has never been seen before,
44         initialize an optimizer for it.
45         """
46         for p in params:
47             # if we have not seen this param before, we instantiate and optim object to deal with it
48             if p not in self.optim_objs:
49                 # create a single optim object for that param
50                 self.optim_objs[p] = self._get_optim(p)
51                 # set state from _state_waiting_to_be_consumed if present
52                 param_name = pyro.get_param_store().param_name(p)
53                 if param_name in self._state_waiting_to_be_consumed:
54                     state = self._state_waiting_to_be_consumed.pop(param_name)
55                     self.optim_objs[p].load_state_dict(state)
56 
57             # actually perform the step for the optim object
58             self.optim_objs[p].step(*args, **kwargs)
59 
60     def get_state(self):
61         """
62         Get state associated with all the optimizers in the form of a dictionary with
63         key-value pairs (parameter name, optim state dicts)
64         """
65         state_dict = {}
66         for param in self.optim_objs:
67             param_name = pyro.get_param_store().param_name(param)
68             state_dict[param_name] = self.optim_objs[param].state_dict()
69         return state_dict
70 
71     def set_state(self, state_dict):
72         """
73         Set the state associated with all the optimizers using the state obtained
74         from a previous call to get_state()
75         """
76         self._state_waiting_to_be_consumed = state_dict
77 
78     def save(self, filename):
79         """
80         :param filename: file name to save to
81         :type name: str
82 
83         Save optimizer state to disk
84         """
85         with open(filename, "wb") as output_file:
86             torch.save(self.get_state(), output_file)
87 
88     def load(self, filename):
89         """
90         :param filename: file name to load from
91         :type name: str
92 
93         Load optimizer state from disk
94         """
95         with open(filename, "rb") as input_file:
96             state = torch.load(input_file)
97         self.set_state(state)
98 
99     def _get_optim(self, param):
100         return self.pt_optim_constructor([param], **self._get_optim_args(param))
101 
102     # helper to fetch the optim args if callable (only used internally)
103     def _get_optim_args(self, param):
104         # if we were passed a fct, we call fct with param info
105         # arguments are (module name, param name) e.g. ('mymodule', 'bias')
106         if callable(self.pt_optim_args):
107 
108             # get param name
109             param_name = pyro.get_param_store().param_name(param)
110             module_name = module_from_param_with_module_name(param_name)
111             stripped_param_name = user_param_name(param_name)
112 
113             # invoke the user-provided callable
114             opt_dict = self.pt_optim_args(module_name, stripped_param_name)
115 
116             # must be dictionary
117             assert isinstance(opt_dict, dict), "per-param optim arg must return defaults dictionary"
118             return opt_dict
119         else:
120             return self.pt_optim_args
121 
122 
123 def AdagradRMSProp(optim_args):
124     """
125     A wrapper for an optimizer that is a mash-up of
126     :class:`~torch.optim.Adagrad` and :class:`~torch.optim.RMSprop`.
127     """
128     return PyroOptim(pt_AdagradRMSProp, optim_args)
129 
130 
131 def ClippedAdam(optim_args):
132     """
133     A wrapper for a modification of the :class:`~torch.optim.Adam`
134     optimization algorithm that supports gradient clipping.
135     """
136     return PyroOptim(pt_ClippedAdam, optim_args)
137
```

Path: `pyro/optim/lr_scheduler.py`
Content:
```
1 from __future__ import absolute_import, division, print_function
2 
3 from pyro.optim.optim import PyroOptim
4 
5 
6 class PyroLRScheduler(PyroOptim):
7     """
8     A wrapper for torch.optim.lr_scheduler objects that adjust learning rates
9     for dynamically generated parameters.
10 
11     :param optim_constructor: a torch.optim.lr_scheduler
12     :param optim_args: a dictionary of learning arguments for the optimizer or a callable that returns
13         such dictionaries. must contain the key 'optimizer' with pytorch optimizer value
14 
15     Example::
16 
17         optimizer = torch.optim.SGD
18         pyro_scheduler = pyro.optim.ExponentialLR({'optimizer': optimizer, 'optim_args': {'lr': 0.01}, 'gamma': 0.1})
19     """
20     def __init__(self, scheduler_constructor, optim_args):
21         # pytorch scheduler
22         self.pt_scheduler_constructor = scheduler_constructor
23         # torch optimizer
24         pt_optim_constructor = optim_args.pop('optimizer')
25         # kwargs for the torch optimizer
26         optim_kwargs = optim_args.pop('optim_args')
27         self.kwargs = optim_args
28         # current epoch
29         self.epoch = None
30         super(PyroLRScheduler, self).__init__(pt_optim_constructor, optim_kwargs)
31 
32     def __call__(self, params, *args, **kwargs):
33         kwargs['epoch'] = self.epoch
34         super(PyroLRScheduler, self).__call__(params, *args, **kwargs)
35 
36     def _get_optim(self, params):
37         optim = super(PyroLRScheduler, self)._get_optim(params)
38         return self.pt_scheduler_constructor(optim, **self.kwargs)
39 
40     def set_epoch(self, epoch):
41         self.epoch = epoch
42
```
--- 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/pyro/optim/lr_scheduler.py b/pyro/optim/lr_scheduler.py
--- a/pyro/optim/lr_scheduler.py
+++ b/pyro/optim/lr_scheduler.py
@@ -16,6 +16,8 @@
 
         optimizer = torch.optim.SGD
         pyro_scheduler = pyro.optim.ExponentialLR({'optimizer': optimizer, 'optim_args': {'lr': 0.01}, 'gamma': 0.1})
+        svi = SVI(model, guide, pyro_scheduler, loss=TraceGraph_ELBO())
+        svi.step()
     """
     def __init__(self, scheduler_constructor, optim_args):
         # pytorch scheduler
diff --git a/pyro/optim/optim.py b/pyro/optim/optim.py
--- a/pyro/optim/optim.py
+++ b/pyro/optim/optim.py
@@ -57,6 +57,12 @@
             # actually perform the step for the optim object
             self.optim_objs[p].step(*args, **kwargs)
 
+            # if optim object was a scheduler, perform an actual optim step
+            if isinstance(self.optim_objs[p], torch.optim.lr_scheduler._LRScheduler):
+                optim_kwargs = kwargs.copy()
+                optim_kwargs.pop('epoch', None)
+                self.optim_objs[p].optimizer.step(*args, **optim_kwargs)
+
     def get_state(self):
         """
         Get state associated with all the optimizers in the form of a dictionary with

{"golden_diff": "diff --git a/pyro/optim/lr_scheduler.py b/pyro/optim/lr_scheduler.py\n--- a/pyro/optim/lr_scheduler.py\n+++ b/pyro/optim/lr_scheduler.py\n@@ -16,6 +16,8 @@\n \n         optimizer = torch.optim.SGD\n         pyro_scheduler = pyro.optim.ExponentialLR({'optimizer': optimizer, 'optim_args': {'lr': 0.01}, 'gamma': 0.1})\n+        svi = SVI(model, guide, pyro_scheduler, loss=TraceGraph_ELBO())\n+        svi.step()\n     \"\"\"\n     def __init__(self, scheduler_constructor, optim_args):\n         # pytorch scheduler\ndiff --git a/pyro/optim/optim.py b/pyro/optim/optim.py\n--- a/pyro/optim/optim.py\n+++ b/pyro/optim/optim.py\n@@ -57,6 +57,12 @@\n             # actually perform the step for the optim object\n             self.optim_objs[p].step(*args, **kwargs)\n \n+            # if optim object was a scheduler, perform an actual optim step\n+            if isinstance(self.optim_objs[p], torch.optim.lr_scheduler._LRScheduler):\n+                optim_kwargs = kwargs.copy()\n+                optim_kwargs.pop('epoch', None)\n+                self.optim_objs[p].optimizer.step(*args, **optim_kwargs)\n+\n     def get_state(self):\n         \"\"\"\n         Get state associated with all the optimizers in the form of a dictionary with\n", "issue": "lr scheduler not optimizing params\n`svi.step()` is not updating parameters with each optimizer.  see #1241\n", "before_files": [{"content": "from __future__ import absolute_import, division, print_function\n\nimport torch\n\nimport pyro\nfrom pyro.optim.adagrad_rmsprop import AdagradRMSProp as pt_AdagradRMSProp\nfrom pyro.optim.clipped_adam import ClippedAdam as pt_ClippedAdam\nfrom pyro.params import module_from_param_with_module_name, user_param_name\n\n\nclass PyroOptim(object):\n    \"\"\"\n    A wrapper for torch.optim.Optimizer objects that helps with managing dynamically generated parameters.\n\n    :param optim_constructor: a torch.optim.Optimizer\n    :param optim_args: a dictionary of learning arguments for the optimizer or a callable that returns\n        such dictionaries\n    \"\"\"\n    def __init__(self, optim_constructor, optim_args):\n        self.pt_optim_constructor = optim_constructor\n\n        # must be callable or dict\n        assert callable(optim_args) or isinstance(\n            optim_args, dict), \"optim_args must be function that returns defaults or a defaults dictionary\"\n\n        # hold our args to be called/used\n        self.pt_optim_args = optim_args\n\n        # holds the torch optimizer objects\n        self.optim_objs = {}\n\n        # holds the current epoch\n        self.epoch = None\n\n        # any optimizer state that's waiting to be consumed (because that parameter hasn't been seen before)\n        self._state_waiting_to_be_consumed = {}\n\n    def __call__(self, params,  *args, **kwargs):\n        \"\"\"\n        :param params: a list of parameters\n        :type params: an iterable of strings\n\n        Do an optimization step for each param in params. If a given param has never been seen before,\n        initialize an optimizer for it.\n        \"\"\"\n        for p in params:\n            # if we have not seen this param before, we instantiate and optim object to deal with it\n            if p not in self.optim_objs:\n                # create a single optim object for that param\n                self.optim_objs[p] = self._get_optim(p)\n                # set state from _state_waiting_to_be_consumed if present\n                param_name = pyro.get_param_store().param_name(p)\n                if param_name in self._state_waiting_to_be_consumed:\n                    state = self._state_waiting_to_be_consumed.pop(param_name)\n                    self.optim_objs[p].load_state_dict(state)\n\n            # actually perform the step for the optim object\n            self.optim_objs[p].step(*args, **kwargs)\n\n    def get_state(self):\n        \"\"\"\n        Get state associated with all the optimizers in the form of a dictionary with\n        key-value pairs (parameter name, optim state dicts)\n        \"\"\"\n        state_dict = {}\n        for param in self.optim_objs:\n            param_name = pyro.get_param_store().param_name(param)\n            state_dict[param_name] = self.optim_objs[param].state_dict()\n        return state_dict\n\n    def set_state(self, state_dict):\n        \"\"\"\n        Set the state associated with all the optimizers using the state obtained\n        from a previous call to get_state()\n        \"\"\"\n        self._state_waiting_to_be_consumed = state_dict\n\n    def save(self, filename):\n        \"\"\"\n        :param filename: file name to save to\n        :type name: str\n\n        Save optimizer state to disk\n        \"\"\"\n        with open(filename, \"wb\") as output_file:\n            torch.save(self.get_state(), output_file)\n\n    def load(self, filename):\n        \"\"\"\n        :param filename: file name to load from\n        :type name: str\n\n        Load optimizer state from disk\n        \"\"\"\n        with open(filename, \"rb\") as input_file:\n            state = torch.load(input_file)\n        self.set_state(state)\n\n    def _get_optim(self, param):\n        return self.pt_optim_constructor([param], **self._get_optim_args(param))\n\n    # helper to fetch the optim args if callable (only used internally)\n    def _get_optim_args(self, param):\n        # if we were passed a fct, we call fct with param info\n        # arguments are (module name, param name) e.g. ('mymodule', 'bias')\n        if callable(self.pt_optim_args):\n\n            # get param name\n            param_name = pyro.get_param_store().param_name(param)\n            module_name = module_from_param_with_module_name(param_name)\n            stripped_param_name = user_param_name(param_name)\n\n            # invoke the user-provided callable\n            opt_dict = self.pt_optim_args(module_name, stripped_param_name)\n\n            # must be dictionary\n            assert isinstance(opt_dict, dict), \"per-param optim arg must return defaults dictionary\"\n            return opt_dict\n        else:\n            return self.pt_optim_args\n\n\ndef AdagradRMSProp(optim_args):\n    \"\"\"\n    A wrapper for an optimizer that is a mash-up of\n    :class:`~torch.optim.Adagrad` and :class:`~torch.optim.RMSprop`.\n    \"\"\"\n    return PyroOptim(pt_AdagradRMSProp, optim_args)\n\n\ndef ClippedAdam(optim_args):\n    \"\"\"\n    A wrapper for a modification of the :class:`~torch.optim.Adam`\n    optimization algorithm that supports gradient clipping.\n    \"\"\"\n    return PyroOptim(pt_ClippedAdam, optim_args)\n", "path": "pyro/optim/optim.py"}, {"content": "from __future__ import absolute_import, division, print_function\n\nfrom pyro.optim.optim import PyroOptim\n\n\nclass PyroLRScheduler(PyroOptim):\n    \"\"\"\n    A wrapper for torch.optim.lr_scheduler objects that adjust learning rates\n    for dynamically generated parameters.\n\n    :param optim_constructor: a torch.optim.lr_scheduler\n    :param optim_args: a dictionary of learning arguments for the optimizer or a callable that returns\n        such dictionaries. must contain the key 'optimizer' with pytorch optimizer value\n\n    Example::\n\n        optimizer = torch.optim.SGD\n        pyro_scheduler = pyro.optim.ExponentialLR({'optimizer': optimizer, 'optim_args': {'lr': 0.01}, 'gamma': 0.1})\n    \"\"\"\n    def __init__(self, scheduler_constructor, optim_args):\n        # pytorch scheduler\n        self.pt_scheduler_constructor = scheduler_constructor\n        # torch optimizer\n        pt_optim_constructor = optim_args.pop('optimizer')\n        # kwargs for the torch optimizer\n        optim_kwargs = optim_args.pop('optim_args')\n        self.kwargs = optim_args\n        # current epoch\n        self.epoch = None\n        super(PyroLRScheduler, self).__init__(pt_optim_constructor, optim_kwargs)\n\n    def __call__(self, params, *args, **kwargs):\n        kwargs['epoch'] = self.epoch\n        super(PyroLRScheduler, self).__call__(params, *args, **kwargs)\n\n    def _get_optim(self, params):\n        optim = super(PyroLRScheduler, self)._get_optim(params)\n        return self.pt_scheduler_constructor(optim, **self.kwargs)\n\n    def set_epoch(self, epoch):\n        self.epoch = epoch\n", "path": "pyro/optim/lr_scheduler.py"}], "after_files": [{"content": "from __future__ import absolute_import, division, print_function\n\nimport torch\n\nimport pyro\nfrom pyro.optim.adagrad_rmsprop import AdagradRMSProp as pt_AdagradRMSProp\nfrom pyro.optim.clipped_adam import ClippedAdam as pt_ClippedAdam\nfrom pyro.params import module_from_param_with_module_name, user_param_name\n\n\nclass PyroOptim(object):\n    \"\"\"\n    A wrapper for torch.optim.Optimizer objects that helps with managing dynamically generated parameters.\n\n    :param optim_constructor: a torch.optim.Optimizer\n    :param optim_args: a dictionary of learning arguments for the optimizer or a callable that returns\n        such dictionaries\n    \"\"\"\n    def __init__(self, optim_constructor, optim_args):\n        self.pt_optim_constructor = optim_constructor\n\n        # must be callable or dict\n        assert callable(optim_args) or isinstance(\n            optim_args, dict), \"optim_args must be function that returns defaults or a defaults dictionary\"\n\n        # hold our args to be called/used\n        self.pt_optim_args = optim_args\n\n        # holds the torch optimizer objects\n        self.optim_objs = {}\n\n        # holds the current epoch\n        self.epoch = None\n\n        # any optimizer state that's waiting to be consumed (because that parameter hasn't been seen before)\n        self._state_waiting_to_be_consumed = {}\n\n    def __call__(self, params,  *args, **kwargs):\n        \"\"\"\n        :param params: a list of parameters\n        :type params: an iterable of strings\n\n        Do an optimization step for each param in params. If a given param has never been seen before,\n        initialize an optimizer for it.\n        \"\"\"\n        for p in params:\n            # if we have not seen this param before, we instantiate and optim object to deal with it\n            if p not in self.optim_objs:\n                # create a single optim object for that param\n                self.optim_objs[p] = self._get_optim(p)\n                # set state from _state_waiting_to_be_consumed if present\n                param_name = pyro.get_param_store().param_name(p)\n                if param_name in self._state_waiting_to_be_consumed:\n                    state = self._state_waiting_to_be_consumed.pop(param_name)\n                    self.optim_objs[p].load_state_dict(state)\n\n            # actually perform the step for the optim object\n            self.optim_objs[p].step(*args, **kwargs)\n\n            # if optim object was a scheduler, perform an actual optim step\n            if isinstance(self.optim_objs[p], torch.optim.lr_scheduler._LRScheduler):\n                optim_kwargs = kwargs.copy()\n                optim_kwargs.pop('epoch', None)\n                self.optim_objs[p].optimizer.step(*args, **optim_kwargs)\n\n    def get_state(self):\n        \"\"\"\n        Get state associated with all the optimizers in the form of a dictionary with\n        key-value pairs (parameter name, optim state dicts)\n        \"\"\"\n        state_dict = {}\n        for param in self.optim_objs:\n            param_name = pyro.get_param_store().param_name(param)\n            state_dict[param_name] = self.optim_objs[param].state_dict()\n        return state_dict\n\n    def set_state(self, state_dict):\n        \"\"\"\n        Set the state associated with all the optimizers using the state obtained\n        from a previous call to get_state()\n        \"\"\"\n        self._state_waiting_to_be_consumed = state_dict\n\n    def save(self, filename):\n        \"\"\"\n        :param filename: file name to save to\n        :type name: str\n\n        Save optimizer state to disk\n        \"\"\"\n        with open(filename, \"wb\") as output_file:\n            torch.save(self.get_state(), output_file)\n\n    def load(self, filename):\n        \"\"\"\n        :param filename: file name to load from\n        :type name: str\n\n        Load optimizer state from disk\n        \"\"\"\n        with open(filename, \"rb\") as input_file:\n            state = torch.load(input_file)\n        self.set_state(state)\n\n    def _get_optim(self, param):\n        return self.pt_optim_constructor([param], **self._get_optim_args(param))\n\n    # helper to fetch the optim args if callable (only used internally)\n    def _get_optim_args(self, param):\n        # if we were passed a fct, we call fct with param info\n        # arguments are (module name, param name) e.g. ('mymodule', 'bias')\n        if callable(self.pt_optim_args):\n\n            # get param name\n            param_name = pyro.get_param_store().param_name(param)\n            module_name = module_from_param_with_module_name(param_name)\n            stripped_param_name = user_param_name(param_name)\n\n            # invoke the user-provided callable\n            opt_dict = self.pt_optim_args(module_name, stripped_param_name)\n\n            # must be dictionary\n            assert isinstance(opt_dict, dict), \"per-param optim arg must return defaults dictionary\"\n            return opt_dict\n        else:\n            return self.pt_optim_args\n\n\ndef AdagradRMSProp(optim_args):\n    \"\"\"\n    A wrapper for an optimizer that is a mash-up of\n    :class:`~torch.optim.Adagrad` and :class:`~torch.optim.RMSprop`.\n    \"\"\"\n    return PyroOptim(pt_AdagradRMSProp, optim_args)\n\n\ndef ClippedAdam(optim_args):\n    \"\"\"\n    A wrapper for a modification of the :class:`~torch.optim.Adam`\n    optimization algorithm that supports gradient clipping.\n    \"\"\"\n    return PyroOptim(pt_ClippedAdam, optim_args)\n", "path": "pyro/optim/optim.py"}, {"content": "from __future__ import absolute_import, division, print_function\n\nfrom pyro.optim.optim import PyroOptim\n\n\nclass PyroLRScheduler(PyroOptim):\n    \"\"\"\n    A wrapper for torch.optim.lr_scheduler objects that adjust learning rates\n    for dynamically generated parameters.\n\n    :param optim_constructor: a torch.optim.lr_scheduler\n    :param optim_args: a dictionary of learning arguments for the optimizer or a callable that returns\n        such dictionaries. must contain the key 'optimizer' with pytorch optimizer value\n\n    Example::\n\n        optimizer = torch.optim.SGD\n        pyro_scheduler = pyro.optim.ExponentialLR({'optimizer': optimizer, 'optim_args': {'lr': 0.01}, 'gamma': 0.1})\n        svi = SVI(model, guide, pyro_scheduler, loss=TraceGraph_ELBO())\n        svi.step()\n    \"\"\"\n    def __init__(self, scheduler_constructor, optim_args):\n        # pytorch scheduler\n        self.pt_scheduler_constructor = scheduler_constructor\n        # torch optimizer\n        pt_optim_constructor = optim_args.pop('optimizer')\n        # kwargs for the torch optimizer\n        optim_kwargs = optim_args.pop('optim_args')\n        self.kwargs = optim_args\n        # current epoch\n        self.epoch = None\n        super(PyroLRScheduler, self).__init__(pt_optim_constructor, optim_kwargs)\n\n    def __call__(self, params, *args, **kwargs):\n        kwargs['epoch'] = self.epoch\n        super(PyroLRScheduler, self).__call__(params, *args, **kwargs)\n\n    def _get_optim(self, params):\n        optim = super(PyroLRScheduler, self)._get_optim(params)\n        return self.pt_scheduler_constructor(optim, **self.kwargs)\n\n    def set_epoch(self, epoch):\n        self.epoch = epoch\n", "path": "pyro/optim/lr_scheduler.py"}]}