We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
advanced profiler description fails for python 3.6
## 🐛 Bug

Python 3.6 doesn't have the `pstats.SortKey.CUMULATIVE` enum so the profiler description breaks.

### To Reproduce

Steps to reproduce the behavior:

Use Python 3.6, pass in the AdvancedProfiler, get report at end of a training run. 

```
profiler = AdvancedProfiler(line_count_restriction=10)
trainer = Trainer(profiler=profiler)
trainer.fit(model)
```

Stack trace:
```
    164         for action_name, pr in self.profiled_actions.items():
    165             s = io.StringIO()
--> 166             sortby = pstats.SortKey.CUMULATIVE
    167             ps = pstats.Stats(pr, stream=s).strip_dirs().sort_stats(sortby)
    168             ps.print_stats(self.line_count_restriction)

AttributeError: module 'pstats' has no attribute 'SortKey'
```


#### Code sample

```
from pytorch_lightning import Trainer
from pytorch_lightning.profiler import AdvancedProfiler
from argparse import Namespace
from pl_examples.basic_examples.lightning_module_template import LightningTemplateModel


# define model
hparams = {
    "batch_size": 128,
    "in_features": 784,
    "hidden_dim": 512,
    "drop_prob": 0.0,
    "out_features": 10,
    "learning_rate": 5e-3,
    "data_root": "data"
}
hparams = Namespace(**hparams)
model = LightningTemplateModel(hparams)

# overfit on small batch
profiler = AdvancedProfiler(line_count_restriction=10)
trainer = Trainer(profiler=profiler, overfit_pct=0.05, min_epochs=10)
trainer.fit(model)
```

### Expected behavior

<!-- A clear and concise description of what you expected to happen. -->

### Environment

Collecting environment information...
PyTorch version: 1.4.0
Is debug build: No
CUDA used to build PyTorch: 10.1

OS: Ubuntu 18.04.3 LTS
GCC version: (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0
CMake version: version 3.12.0

Python version: 3.6
Is CUDA available: Yes
CUDA runtime version: 10.0.130
GPU models and configuration: GPU 0: Tesla P100-PCIE-16GB
Nvidia driver version: 418.67
cuDNN version: /usr/lib/x86_64-linux-gnu/libcudnn.so.7.6.5

Versions of relevant libraries:
[pip3] numpy==1.17.5
[pip3] pytorch-lightning==0.6.1.dev0
[pip3] torch==1.4.0
[pip3] torchsummary==1.5.1
[pip3] torchtext==0.3.1
[pip3] torchvision==0.5.0
[conda] Could not collect




--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `pytorch_lightning/profiler/profiler.py`
Content:
```
1 from contextlib import contextmanager
2 from collections import defaultdict
3 import time
4 import numpy as np
5 import cProfile
6 import pstats
7 import io
8 from abc import ABC, abstractmethod
9 import logging
10 
11 logger = logging.getLogger(__name__)
12 
13 
14 class BaseProfiler(ABC):
15     """
16     If you wish to write a custom profiler, you should inhereit from this class.
17     """
18 
19     @abstractmethod
20     def start(self, action_name):
21         """
22         Defines how to start recording an action.
23         """
24         pass
25 
26     @abstractmethod
27     def stop(self, action_name):
28         """
29         Defines how to record the duration once an action is complete.
30         """
31         pass
32 
33     @contextmanager
34     def profile(self, action_name):
35         """
36         Yields a context manager to encapsulate the scope of a profiled action.
37 
38         Example::
39 
40             with self.profile('load training data'):
41                 # load training data code
42 
43         The profiler will start once you've entered the context and will automatically
44         stop once you exit the code block.
45         """
46         try:
47             self.start(action_name)
48             yield action_name
49         finally:
50             self.stop(action_name)
51 
52     def profile_iterable(self, iterable, action_name):
53         iterator = iter(iterable)
54         while True:
55             try:
56                 self.start(action_name)
57                 value = next(iterator)
58                 self.stop(action_name)
59                 yield value
60             except StopIteration:
61                 self.stop(action_name)
62                 break
63 
64     def describe(self):
65         """
66         Logs a profile report after the conclusion of the training run.
67         """
68         pass
69 
70 
71 class PassThroughProfiler(BaseProfiler):
72     """
73     This class should be used when you don't want the (small) overhead of profiling.
74     The Trainer uses this class by default.
75     """
76 
77     def __init__(self):
78         pass
79 
80     def start(self, action_name):
81         pass
82 
83     def stop(self, action_name):
84         pass
85 
86 
87 class Profiler(BaseProfiler):
88     """
89     This profiler simply records the duration of actions (in seconds) and reports
90     the mean duration of each action and the total time spent over the entire training run.
91     """
92 
93     def __init__(self):
94         self.current_actions = {}
95         self.recorded_durations = defaultdict(list)
96 
97     def start(self, action_name):
98         if action_name in self.current_actions:
99             raise ValueError(
100                 f"Attempted to start {action_name} which has already started."
101             )
102         self.current_actions[action_name] = time.monotonic()
103 
104     def stop(self, action_name):
105         end_time = time.monotonic()
106         if action_name not in self.current_actions:
107             raise ValueError(
108                 f"Attempting to stop recording an action ({action_name}) which was never started."
109             )
110         start_time = self.current_actions.pop(action_name)
111         duration = end_time - start_time
112         self.recorded_durations[action_name].append(duration)
113 
114     def describe(self):
115         output_string = "\n\nProfiler Report\n"
116 
117         def log_row(action, mean, total):
118             return f"\n{action:<20s}\t|  {mean:<15}\t|  {total:<15}"
119 
120         output_string += log_row("Action", "Mean duration (s)", "Total time (s)")
121         output_string += f"\n{'-' * 65}"
122         for action, durations in self.recorded_durations.items():
123             output_string += log_row(
124                 action, f"{np.mean(durations):.5}", f"{np.sum(durations):.5}",
125             )
126         output_string += "\n"
127         logger.info(output_string)
128 
129 
130 class AdvancedProfiler(BaseProfiler):
131     """
132     This profiler uses Python's cProfiler to record more detailed information about
133     time spent in each function call recorded during a given action. The output is quite
134     verbose and you should only use this if you want very detailed reports.
135     """
136 
137     def __init__(self, output_filename=None, line_count_restriction=1.0):
138         """
139         :param output_filename (str): optionally save profile results to file instead of printing
140             to std out when training is finished.
141         :param line_count_restriction (int|float): this can be used to limit the number of functions
142             reported for each action. either an integer (to select a count of lines),
143             or a decimal fraction between 0.0 and 1.0 inclusive (to select a percentage of lines)
144         """
145         self.profiled_actions = {}
146         self.output_filename = output_filename
147         self.line_count_restriction = line_count_restriction
148 
149     def start(self, action_name):
150         if action_name not in self.profiled_actions:
151             self.profiled_actions[action_name] = cProfile.Profile()
152         self.profiled_actions[action_name].enable()
153 
154     def stop(self, action_name):
155         pr = self.profiled_actions.get(action_name)
156         if pr is None:
157             raise ValueError(
158                 f"Attempting to stop recording an action ({action_name}) which was never started."
159             )
160         pr.disable()
161 
162     def describe(self):
163         self.recorded_stats = {}
164         for action_name, pr in self.profiled_actions.items():
165             s = io.StringIO()
166             sortby = pstats.SortKey.CUMULATIVE
167             ps = pstats.Stats(pr, stream=s).strip_dirs().sort_stats(sortby)
168             ps.print_stats(self.line_count_restriction)
169             self.recorded_stats[action_name] = s.getvalue()
170         if self.output_filename is not None:
171             # save to file
172             with open(self.output_filename, "w") as f:
173                 for action, stats in self.recorded_stats.items():
174                     f.write(f"Profile stats for: {action}")
175                     f.write(stats)
176         else:
177             # log to standard out
178             output_string = "\nProfiler Report\n"
179             for action, stats in self.recorded_stats.items():
180                 output_string += f"\nProfile stats for: {action}\n{stats}"
181             logger.info(output_string)
182
```
--- 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/pytorch_lightning/profiler/profiler.py b/pytorch_lightning/profiler/profiler.py
--- a/pytorch_lightning/profiler/profiler.py
+++ b/pytorch_lightning/profiler/profiler.py
@@ -163,8 +163,7 @@
         self.recorded_stats = {}
         for action_name, pr in self.profiled_actions.items():
             s = io.StringIO()
-            sortby = pstats.SortKey.CUMULATIVE
-            ps = pstats.Stats(pr, stream=s).strip_dirs().sort_stats(sortby)
+            ps = pstats.Stats(pr, stream=s).strip_dirs().sort_stats('cumulative')
             ps.print_stats(self.line_count_restriction)
             self.recorded_stats[action_name] = s.getvalue()
         if self.output_filename is not None:

{"golden_diff": "diff --git a/pytorch_lightning/profiler/profiler.py b/pytorch_lightning/profiler/profiler.py\n--- a/pytorch_lightning/profiler/profiler.py\n+++ b/pytorch_lightning/profiler/profiler.py\n@@ -163,8 +163,7 @@\n         self.recorded_stats = {}\n         for action_name, pr in self.profiled_actions.items():\n             s = io.StringIO()\n-            sortby = pstats.SortKey.CUMULATIVE\n-            ps = pstats.Stats(pr, stream=s).strip_dirs().sort_stats(sortby)\n+            ps = pstats.Stats(pr, stream=s).strip_dirs().sort_stats('cumulative')\n             ps.print_stats(self.line_count_restriction)\n             self.recorded_stats[action_name] = s.getvalue()\n         if self.output_filename is not None:\n", "issue": "advanced profiler description fails for python 3.6\n## \ud83d\udc1b Bug\r\n\r\nPython 3.6 doesn't have the `pstats.SortKey.CUMULATIVE` enum so the profiler description breaks.\r\n\r\n### To Reproduce\r\n\r\nSteps to reproduce the behavior:\r\n\r\nUse Python 3.6, pass in the AdvancedProfiler, get report at end of a training run. \r\n\r\n```\r\nprofiler = AdvancedProfiler(line_count_restriction=10)\r\ntrainer = Trainer(profiler=profiler)\r\ntrainer.fit(model)\r\n```\r\n\r\nStack trace:\r\n```\r\n    164         for action_name, pr in self.profiled_actions.items():\r\n    165             s = io.StringIO()\r\n--> 166             sortby = pstats.SortKey.CUMULATIVE\r\n    167             ps = pstats.Stats(pr, stream=s).strip_dirs().sort_stats(sortby)\r\n    168             ps.print_stats(self.line_count_restriction)\r\n\r\nAttributeError: module 'pstats' has no attribute 'SortKey'\r\n```\r\n\r\n\r\n#### Code sample\r\n\r\n```\r\nfrom pytorch_lightning import Trainer\r\nfrom pytorch_lightning.profiler import AdvancedProfiler\r\nfrom argparse import Namespace\r\nfrom pl_examples.basic_examples.lightning_module_template import LightningTemplateModel\r\n\r\n\r\n# define model\r\nhparams = {\r\n    \"batch_size\": 128,\r\n    \"in_features\": 784,\r\n    \"hidden_dim\": 512,\r\n    \"drop_prob\": 0.0,\r\n    \"out_features\": 10,\r\n    \"learning_rate\": 5e-3,\r\n    \"data_root\": \"data\"\r\n}\r\nhparams = Namespace(**hparams)\r\nmodel = LightningTemplateModel(hparams)\r\n\r\n# overfit on small batch\r\nprofiler = AdvancedProfiler(line_count_restriction=10)\r\ntrainer = Trainer(profiler=profiler, overfit_pct=0.05, min_epochs=10)\r\ntrainer.fit(model)\r\n```\r\n\r\n### Expected behavior\r\n\r\n<!-- A clear and concise description of what you expected to happen. -->\r\n\r\n### Environment\r\n\r\nCollecting environment information...\r\nPyTorch version: 1.4.0\r\nIs debug build: No\r\nCUDA used to build PyTorch: 10.1\r\n\r\nOS: Ubuntu 18.04.3 LTS\r\nGCC version: (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0\r\nCMake version: version 3.12.0\r\n\r\nPython version: 3.6\r\nIs CUDA available: Yes\r\nCUDA runtime version: 10.0.130\r\nGPU models and configuration: GPU 0: Tesla P100-PCIE-16GB\r\nNvidia driver version: 418.67\r\ncuDNN version: /usr/lib/x86_64-linux-gnu/libcudnn.so.7.6.5\r\n\r\nVersions of relevant libraries:\r\n[pip3] numpy==1.17.5\r\n[pip3] pytorch-lightning==0.6.1.dev0\r\n[pip3] torch==1.4.0\r\n[pip3] torchsummary==1.5.1\r\n[pip3] torchtext==0.3.1\r\n[pip3] torchvision==0.5.0\r\n[conda] Could not collect\r\n\r\n\r\n\n", "before_files": [{"content": "from contextlib import contextmanager\nfrom collections import defaultdict\nimport time\nimport numpy as np\nimport cProfile\nimport pstats\nimport io\nfrom abc import ABC, abstractmethod\nimport logging\n\nlogger = logging.getLogger(__name__)\n\n\nclass BaseProfiler(ABC):\n    \"\"\"\n    If you wish to write a custom profiler, you should inhereit from this class.\n    \"\"\"\n\n    @abstractmethod\n    def start(self, action_name):\n        \"\"\"\n        Defines how to start recording an action.\n        \"\"\"\n        pass\n\n    @abstractmethod\n    def stop(self, action_name):\n        \"\"\"\n        Defines how to record the duration once an action is complete.\n        \"\"\"\n        pass\n\n    @contextmanager\n    def profile(self, action_name):\n        \"\"\"\n        Yields a context manager to encapsulate the scope of a profiled action.\n\n        Example::\n\n            with self.profile('load training data'):\n                # load training data code\n\n        The profiler will start once you've entered the context and will automatically\n        stop once you exit the code block.\n        \"\"\"\n        try:\n            self.start(action_name)\n            yield action_name\n        finally:\n            self.stop(action_name)\n\n    def profile_iterable(self, iterable, action_name):\n        iterator = iter(iterable)\n        while True:\n            try:\n                self.start(action_name)\n                value = next(iterator)\n                self.stop(action_name)\n                yield value\n            except StopIteration:\n                self.stop(action_name)\n                break\n\n    def describe(self):\n        \"\"\"\n        Logs a profile report after the conclusion of the training run.\n        \"\"\"\n        pass\n\n\nclass PassThroughProfiler(BaseProfiler):\n    \"\"\"\n    This class should be used when you don't want the (small) overhead of profiling.\n    The Trainer uses this class by default.\n    \"\"\"\n\n    def __init__(self):\n        pass\n\n    def start(self, action_name):\n        pass\n\n    def stop(self, action_name):\n        pass\n\n\nclass Profiler(BaseProfiler):\n    \"\"\"\n    This profiler simply records the duration of actions (in seconds) and reports\n    the mean duration of each action and the total time spent over the entire training run.\n    \"\"\"\n\n    def __init__(self):\n        self.current_actions = {}\n        self.recorded_durations = defaultdict(list)\n\n    def start(self, action_name):\n        if action_name in self.current_actions:\n            raise ValueError(\n                f\"Attempted to start {action_name} which has already started.\"\n            )\n        self.current_actions[action_name] = time.monotonic()\n\n    def stop(self, action_name):\n        end_time = time.monotonic()\n        if action_name not in self.current_actions:\n            raise ValueError(\n                f\"Attempting to stop recording an action ({action_name}) which was never started.\"\n            )\n        start_time = self.current_actions.pop(action_name)\n        duration = end_time - start_time\n        self.recorded_durations[action_name].append(duration)\n\n    def describe(self):\n        output_string = \"\\n\\nProfiler Report\\n\"\n\n        def log_row(action, mean, total):\n            return f\"\\n{action:<20s}\\t|  {mean:<15}\\t|  {total:<15}\"\n\n        output_string += log_row(\"Action\", \"Mean duration (s)\", \"Total time (s)\")\n        output_string += f\"\\n{'-' * 65}\"\n        for action, durations in self.recorded_durations.items():\n            output_string += log_row(\n                action, f\"{np.mean(durations):.5}\", f\"{np.sum(durations):.5}\",\n            )\n        output_string += \"\\n\"\n        logger.info(output_string)\n\n\nclass AdvancedProfiler(BaseProfiler):\n    \"\"\"\n    This profiler uses Python's cProfiler to record more detailed information about\n    time spent in each function call recorded during a given action. The output is quite\n    verbose and you should only use this if you want very detailed reports.\n    \"\"\"\n\n    def __init__(self, output_filename=None, line_count_restriction=1.0):\n        \"\"\"\n        :param output_filename (str): optionally save profile results to file instead of printing\n            to std out when training is finished.\n        :param line_count_restriction (int|float): this can be used to limit the number of functions\n            reported for each action. either an integer (to select a count of lines),\n            or a decimal fraction between 0.0 and 1.0 inclusive (to select a percentage of lines)\n        \"\"\"\n        self.profiled_actions = {}\n        self.output_filename = output_filename\n        self.line_count_restriction = line_count_restriction\n\n    def start(self, action_name):\n        if action_name not in self.profiled_actions:\n            self.profiled_actions[action_name] = cProfile.Profile()\n        self.profiled_actions[action_name].enable()\n\n    def stop(self, action_name):\n        pr = self.profiled_actions.get(action_name)\n        if pr is None:\n            raise ValueError(\n                f\"Attempting to stop recording an action ({action_name}) which was never started.\"\n            )\n        pr.disable()\n\n    def describe(self):\n        self.recorded_stats = {}\n        for action_name, pr in self.profiled_actions.items():\n            s = io.StringIO()\n            sortby = pstats.SortKey.CUMULATIVE\n            ps = pstats.Stats(pr, stream=s).strip_dirs().sort_stats(sortby)\n            ps.print_stats(self.line_count_restriction)\n            self.recorded_stats[action_name] = s.getvalue()\n        if self.output_filename is not None:\n            # save to file\n            with open(self.output_filename, \"w\") as f:\n                for action, stats in self.recorded_stats.items():\n                    f.write(f\"Profile stats for: {action}\")\n                    f.write(stats)\n        else:\n            # log to standard out\n            output_string = \"\\nProfiler Report\\n\"\n            for action, stats in self.recorded_stats.items():\n                output_string += f\"\\nProfile stats for: {action}\\n{stats}\"\n            logger.info(output_string)\n", "path": "pytorch_lightning/profiler/profiler.py"}], "after_files": [{"content": "from contextlib import contextmanager\nfrom collections import defaultdict\nimport time\nimport numpy as np\nimport cProfile\nimport pstats\nimport io\nfrom abc import ABC, abstractmethod\nimport logging\n\nlogger = logging.getLogger(__name__)\n\n\nclass BaseProfiler(ABC):\n    \"\"\"\n    If you wish to write a custom profiler, you should inhereit from this class.\n    \"\"\"\n\n    @abstractmethod\n    def start(self, action_name):\n        \"\"\"\n        Defines how to start recording an action.\n        \"\"\"\n        pass\n\n    @abstractmethod\n    def stop(self, action_name):\n        \"\"\"\n        Defines how to record the duration once an action is complete.\n        \"\"\"\n        pass\n\n    @contextmanager\n    def profile(self, action_name):\n        \"\"\"\n        Yields a context manager to encapsulate the scope of a profiled action.\n\n        Example::\n\n            with self.profile('load training data'):\n                # load training data code\n\n        The profiler will start once you've entered the context and will automatically\n        stop once you exit the code block.\n        \"\"\"\n        try:\n            self.start(action_name)\n            yield action_name\n        finally:\n            self.stop(action_name)\n\n    def profile_iterable(self, iterable, action_name):\n        iterator = iter(iterable)\n        while True:\n            try:\n                self.start(action_name)\n                value = next(iterator)\n                self.stop(action_name)\n                yield value\n            except StopIteration:\n                self.stop(action_name)\n                break\n\n    def describe(self):\n        \"\"\"\n        Logs a profile report after the conclusion of the training run.\n        \"\"\"\n        pass\n\n\nclass PassThroughProfiler(BaseProfiler):\n    \"\"\"\n    This class should be used when you don't want the (small) overhead of profiling.\n    The Trainer uses this class by default.\n    \"\"\"\n\n    def __init__(self):\n        pass\n\n    def start(self, action_name):\n        pass\n\n    def stop(self, action_name):\n        pass\n\n\nclass Profiler(BaseProfiler):\n    \"\"\"\n    This profiler simply records the duration of actions (in seconds) and reports\n    the mean duration of each action and the total time spent over the entire training run.\n    \"\"\"\n\n    def __init__(self):\n        self.current_actions = {}\n        self.recorded_durations = defaultdict(list)\n\n    def start(self, action_name):\n        if action_name in self.current_actions:\n            raise ValueError(\n                f\"Attempted to start {action_name} which has already started.\"\n            )\n        self.current_actions[action_name] = time.monotonic()\n\n    def stop(self, action_name):\n        end_time = time.monotonic()\n        if action_name not in self.current_actions:\n            raise ValueError(\n                f\"Attempting to stop recording an action ({action_name}) which was never started.\"\n            )\n        start_time = self.current_actions.pop(action_name)\n        duration = end_time - start_time\n        self.recorded_durations[action_name].append(duration)\n\n    def describe(self):\n        output_string = \"\\n\\nProfiler Report\\n\"\n\n        def log_row(action, mean, total):\n            return f\"\\n{action:<20s}\\t|  {mean:<15}\\t|  {total:<15}\"\n\n        output_string += log_row(\"Action\", \"Mean duration (s)\", \"Total time (s)\")\n        output_string += f\"\\n{'-' * 65}\"\n        for action, durations in self.recorded_durations.items():\n            output_string += log_row(\n                action, f\"{np.mean(durations):.5}\", f\"{np.sum(durations):.5}\",\n            )\n        output_string += \"\\n\"\n        logger.info(output_string)\n\n\nclass AdvancedProfiler(BaseProfiler):\n    \"\"\"\n    This profiler uses Python's cProfiler to record more detailed information about\n    time spent in each function call recorded during a given action. The output is quite\n    verbose and you should only use this if you want very detailed reports.\n    \"\"\"\n\n    def __init__(self, output_filename=None, line_count_restriction=1.0):\n        \"\"\"\n        :param output_filename (str): optionally save profile results to file instead of printing\n            to std out when training is finished.\n        :param line_count_restriction (int|float): this can be used to limit the number of functions\n            reported for each action. either an integer (to select a count of lines),\n            or a decimal fraction between 0.0 and 1.0 inclusive (to select a percentage of lines)\n        \"\"\"\n        self.profiled_actions = {}\n        self.output_filename = output_filename\n        self.line_count_restriction = line_count_restriction\n\n    def start(self, action_name):\n        if action_name not in self.profiled_actions:\n            self.profiled_actions[action_name] = cProfile.Profile()\n        self.profiled_actions[action_name].enable()\n\n    def stop(self, action_name):\n        pr = self.profiled_actions.get(action_name)\n        if pr is None:\n            raise ValueError(\n                f\"Attempting to stop recording an action ({action_name}) which was never started.\"\n            )\n        pr.disable()\n\n    def describe(self):\n        self.recorded_stats = {}\n        for action_name, pr in self.profiled_actions.items():\n            s = io.StringIO()\n            ps = pstats.Stats(pr, stream=s).strip_dirs().sort_stats('cumulative')\n            ps.print_stats(self.line_count_restriction)\n            self.recorded_stats[action_name] = s.getvalue()\n        if self.output_filename is not None:\n            # save to file\n            with open(self.output_filename, \"w\") as f:\n                for action, stats in self.recorded_stats.items():\n                    f.write(f\"Profile stats for: {action}\")\n                    f.write(stats)\n        else:\n            # log to standard out\n            output_string = \"\\nProfiler Report\\n\"\n            for action, stats in self.recorded_stats.items():\n                output_string += f\"\\nProfile stats for: {action}\\n{stats}\"\n            logger.info(output_string)\n", "path": "pytorch_lightning/profiler/profiler.py"}]}