We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Unexpected behaviour `by_epoch` DvcliveLoggerHook/AnyLogger
Thanks for reporting the unexpected results and we appreciate it a lot.

See also the DVClive issue: https://github.com/iterative/dvclive/issues/267

**Describe the Issue**

I was using the `dvclive` hook for mmcv and expected the `by_epoch` variable to mean something else then it is doing right now. I expected to get a result per epoch. However, it seems to have no (or not the expected) effect. 

**Reproduction**

1. What command, code, or script did you run? I added the following to my config.

```bash
log_config = dict(
    hooks=[
        dict(
            type="DvcliveLoggerHook",
            path="{{ fileDirname }}/../live",
            interval=1,
            by_epoch=True,
        ),
    ],
)
```

2. Did you make any modifications on the code? Did you understand what you have modified?

I did not modify the code.

**Environment**

1. Please run `python -c "from mmcv.utils import collect_env; print(collect_env())"` to collect necessary environment information and paste it here.

<details><summary>Output</summary>

```none
{   
    'sys.platform': 'linux', 
    'Python': '3.8.8 (default, Feb 24 2021, 21: 46: 12) [GCC 7.3.0]',
    'CUDA available': True,
    'GPU 0, 1, 2, 3': 'NVIDIA TITAN RTX',
    'CUDA_HOME': '/usr/local/cuda',
    'NVCC': 'Cuda compilation tools, 
    release 11.2, V11.2.142',
    'GCC': 'gcc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0',
    'PyTorch': '1.9.0a0+df837d0', 
    'PyTorch compiling details': 'PyTorch built with:\n  - GCC 9.3\n  - C++ Version: 201402\n  - Intel(R) Math Kernel Library Version 2019.0.4 Product Build 20190411 for Intel(R) 64 architecture applications\n  - Intel(R) MKL-DNN v1.7.0 (Git Hash N/A)\n  - OpenMP 201511 (a.k.a. OpenMP 4.5)\n  - NNPACK is enabled\n  - CPU capability usage: AVX2\n  - CUDA Runtime 11.2\n  - NVCC architecture flags: -gencode;arch=compute_52,
    code=sm_52;-gencode;arch=compute_60,code=sm_60;-gencode;arch=compute_61,
    code=sm_61;-gencode;arch=compute_70,code=sm_70;-gencode;arch=compute_75,
    code=sm_75;-gencode;arch=compute_80,code=sm_80;-gencode;arch=compute_86,
    code=sm_86;-gencode;arch=compute_86,code=compute_86\n  - CuDNN 8.1.1\n  - Magma 2.5.2\n  - Build settings: BLAS_INFO=mkl,
    BUILD_TYPE=Release,
    CUDA_VERSION=11.2,
    CUDNN_VERSION=8.1.1,
    CXX_COMPILER=/usr/bin/c++,
    CXX_FLAGS= -fvisibility-inlines-hidden -DUSE_PTHREADPOOL -fopenmp -DNDEBUG -DUSE_FBGEMM -DUSE_QNNPACK -DUSE_PYTORCH_QNNPACK -DUSE_XNNPACK -O2 -fPIC -Wno-narrowing -Wall -Wextra -Werror=return-type -Wno-missing-field-initializers -Wno-type-limits -Wno-array-bounds -Wno-unknown-pragmas -Wno-sign-compare -Wno-unused-parameter -Wno-unused-variable -Wno-unused-function -Wno-unused-result -Wno-unused-local-typedefs -Wno-strict-overflow -Wno-strict-aliasing -Wno-error=deprecated-declarations -Wno-stringop-overflow -Wno-psabi -Wno-error=pedantic -Wno-error=redundant-decls -Wno-error=old-style-cast -fdiagnostics-color=always -faligned-new -Wno-unused-but-set-variable -Wno-maybe-uninitialized -fno-math-errno -fno-trapping-math -Werror=format -Werror=cast-function-type -Wno-stringop-overflow,
    FORCE_FALLBACK_CUDA_MPI=1,
    LAPACK_INFO=mkl,
    PERF_WITH_AVX=1,
    PERF_WITH_AVX2=1,
    PERF_WITH_AVX512=1,
    TORCH_VERSION=1.9.0,
    USE_CUDA=ON,
    USE_CUDNN=ON,
    USE_EXCEPTION_PTR=1,
    USE_GFLAGS=OFF,
    USE_GLOG=OFF,
    USE_MKL=ON,
    USE_MKLDNN=ON,
    USE_MPI=ON,
    USE_NCCL=ON,
    USE_NNPACK=ON,
    USE_OPENMP=ON,
    \n',
    'TorchVision': '0.9.0a0',
    'OpenCV': '3.4.11',
    'MMCV': '1.5.0',
    'MMCV Compiler': 'GCC 9.3',
    'MMCV CUDA Compiler': '11.2'
}
```

</details>


2. You may add addition that may be helpful for locating the problem, such as
   - How you installed PyTorch \[e.g., pip, conda, source\]
   - Other environment variables that may be related (such as `$PATH`, `$LD_LIBRARY_PATH`, `$PYTHONPATH`, etc.)


**Error traceback**
If applicable, paste the error traceback here.

n/a

**Bug fix**
If you have already identified the reason, you can provide the information here. If you are willing to create a PR to fix it, please also leave a comment here and that would be much appreciated!

n/a


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `mmcv/runner/hooks/logger/dvclive.py`
Content:
```
1 # Copyright (c) OpenMMLab. All rights reserved.
2 from pathlib import Path
3 from typing import Optional
4 
5 from ...dist_utils import master_only
6 from ..hook import HOOKS
7 from .base import LoggerHook
8 
9 
10 @HOOKS.register_module()
11 class DvcliveLoggerHook(LoggerHook):
12     """Class to log metrics with dvclive.
13 
14     It requires `dvclive`_ to be installed.
15 
16     Args:
17         model_file (str): Default None. If not None, after each epoch the
18             model will be saved to {model_file}.
19         interval (int): Logging interval (every k iterations). Default 10.
20         ignore_last (bool): Ignore the log of last iterations in each epoch
21             if less than `interval`. Default: True.
22         reset_flag (bool): Whether to clear the output buffer after logging.
23             Default: False.
24         by_epoch (bool): Whether EpochBasedRunner is used. Default: True.
25         dvclive (Live, optional): An instance of the `Live`_ logger to use
26             instead of initializing a new one internally. Defaults to None.
27         kwargs: Arguments for instantiating `Live`_ (ignored if `dvclive` is
28             provided).
29 
30     .. _dvclive:
31         https://dvc.org/doc/dvclive
32 
33     .. _Live:
34         https://dvc.org/doc/dvclive/api-reference/live#parameters
35     """
36 
37     def __init__(self,
38                  model_file: Optional[str] = None,
39                  interval: int = 10,
40                  ignore_last: bool = True,
41                  reset_flag: bool = False,
42                  by_epoch: bool = True,
43                  dvclive=None,
44                  **kwargs):
45         super().__init__(interval, ignore_last, reset_flag, by_epoch)
46         self.model_file = model_file
47         self._import_dvclive(dvclive, **kwargs)
48 
49     def _import_dvclive(self, dvclive=None, **kwargs) -> None:
50         try:
51             from dvclive import Live
52         except ImportError:
53             raise ImportError(
54                 'Please run "pip install dvclive" to install dvclive')
55         self.dvclive = dvclive if dvclive is not None else Live(**kwargs)
56 
57     @master_only
58     def log(self, runner) -> None:
59         tags = self.get_loggable_tags(runner)
60         if tags:
61             self.dvclive.set_step(self.get_iter(runner))
62             for k, v in tags.items():
63                 self.dvclive.log(k, v)
64 
65     @master_only
66     def after_train_epoch(self, runner) -> None:
67         super().after_train_epoch(runner)
68         if self.model_file is not None:
69             runner.save_checkpoint(
70                 Path(self.model_file).parent,
71                 filename_tmpl=Path(self.model_file).name,
72                 create_symlink=False,
73             )
74
```
--- 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/mmcv/runner/hooks/logger/dvclive.py b/mmcv/runner/hooks/logger/dvclive.py
--- a/mmcv/runner/hooks/logger/dvclive.py
+++ b/mmcv/runner/hooks/logger/dvclive.py
@@ -21,7 +21,10 @@
             if less than `interval`. Default: True.
         reset_flag (bool): Whether to clear the output buffer after logging.
             Default: False.
-        by_epoch (bool): Whether EpochBasedRunner is used. Default: True.
+        by_epoch (bool): Whether EpochBasedRunner is used.
+            Determines whether `log` is called `after_train_iter` or
+            `after_train_epoch`.
+            Default: True.
         dvclive (Live, optional): An instance of the `Live`_ logger to use
             instead of initializing a new one internally. Defaults to None.
         kwargs: Arguments for instantiating `Live`_ (ignored if `dvclive` is
@@ -58,16 +61,23 @@
     def log(self, runner) -> None:
         tags = self.get_loggable_tags(runner)
         if tags:
-            self.dvclive.set_step(self.get_iter(runner))
+            step = self.get_epoch(runner) if self.by_epoch else self.get_iter(
+                runner)
+            self.dvclive.set_step(step)
+
             for k, v in tags.items():
                 self.dvclive.log(k, v)
 
-    @master_only
     def after_train_epoch(self, runner) -> None:
-        super().after_train_epoch(runner)
         if self.model_file is not None:
             runner.save_checkpoint(
                 Path(self.model_file).parent,
                 filename_tmpl=Path(self.model_file).name,
                 create_symlink=False,
             )
+        if self.by_epoch:
+            super().after_train_epoch(runner)
+
+    def after_train_iter(self, runner) -> None:
+        if not self.by_epoch:
+            super().after_train_iter(runner)

{"golden_diff": "diff --git a/mmcv/runner/hooks/logger/dvclive.py b/mmcv/runner/hooks/logger/dvclive.py\n--- a/mmcv/runner/hooks/logger/dvclive.py\n+++ b/mmcv/runner/hooks/logger/dvclive.py\n@@ -21,7 +21,10 @@\n             if less than `interval`. Default: True.\n         reset_flag (bool): Whether to clear the output buffer after logging.\n             Default: False.\n-        by_epoch (bool): Whether EpochBasedRunner is used. Default: True.\n+        by_epoch (bool): Whether EpochBasedRunner is used.\n+            Determines whether `log` is called `after_train_iter` or\n+            `after_train_epoch`.\n+            Default: True.\n         dvclive (Live, optional): An instance of the `Live`_ logger to use\n             instead of initializing a new one internally. Defaults to None.\n         kwargs: Arguments for instantiating `Live`_ (ignored if `dvclive` is\n@@ -58,16 +61,23 @@\n     def log(self, runner) -> None:\n         tags = self.get_loggable_tags(runner)\n         if tags:\n-            self.dvclive.set_step(self.get_iter(runner))\n+            step = self.get_epoch(runner) if self.by_epoch else self.get_iter(\n+                runner)\n+            self.dvclive.set_step(step)\n+\n             for k, v in tags.items():\n                 self.dvclive.log(k, v)\n \n-    @master_only\n     def after_train_epoch(self, runner) -> None:\n-        super().after_train_epoch(runner)\n         if self.model_file is not None:\n             runner.save_checkpoint(\n                 Path(self.model_file).parent,\n                 filename_tmpl=Path(self.model_file).name,\n                 create_symlink=False,\n             )\n+        if self.by_epoch:\n+            super().after_train_epoch(runner)\n+\n+    def after_train_iter(self, runner) -> None:\n+        if not self.by_epoch:\n+            super().after_train_iter(runner)\n", "issue": "Unexpected behaviour `by_epoch` DvcliveLoggerHook/AnyLogger\nThanks for reporting the unexpected results and we appreciate it a lot.\r\n\r\nSee also the DVClive issue: https://github.com/iterative/dvclive/issues/267\r\n\r\n**Describe the Issue**\r\n\r\nI was using the `dvclive` hook for mmcv and expected the `by_epoch` variable to mean something else then it is doing right now. I expected to get a result per epoch. However, it seems to have no (or not the expected) effect. \r\n\r\n**Reproduction**\r\n\r\n1. What command, code, or script did you run? I added the following to my config.\r\n\r\n```bash\r\nlog_config = dict(\r\n    hooks=[\r\n        dict(\r\n            type=\"DvcliveLoggerHook\",\r\n            path=\"{{ fileDirname }}/../live\",\r\n            interval=1,\r\n            by_epoch=True,\r\n        ),\r\n    ],\r\n)\r\n```\r\n\r\n2. Did you make any modifications on the code? Did you understand what you have modified?\r\n\r\nI did not modify the code.\r\n\r\n**Environment**\r\n\r\n1. Please run `python -c \"from mmcv.utils import collect_env; print(collect_env())\"` to collect necessary environment information and paste it here.\r\n\r\n<details><summary>Output</summary>\r\n\r\n```none\r\n{   \r\n    'sys.platform': 'linux', \r\n    'Python': '3.8.8 (default, Feb 24 2021, 21: 46: 12) [GCC 7.3.0]',\r\n    'CUDA available': True,\r\n    'GPU 0, 1, 2, 3': 'NVIDIA TITAN RTX',\r\n    'CUDA_HOME': '/usr/local/cuda',\r\n    'NVCC': 'Cuda compilation tools, \r\n    release 11.2, V11.2.142',\r\n    'GCC': 'gcc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0',\r\n    'PyTorch': '1.9.0a0+df837d0', \r\n    'PyTorch compiling details': 'PyTorch built with:\\n  - GCC 9.3\\n  - C++ Version: 201402\\n  - Intel(R) Math Kernel Library Version 2019.0.4 Product Build 20190411 for Intel(R) 64 architecture applications\\n  - Intel(R) MKL-DNN v1.7.0 (Git Hash N/A)\\n  - OpenMP 201511 (a.k.a. OpenMP 4.5)\\n  - NNPACK is enabled\\n  - CPU capability usage: AVX2\\n  - CUDA Runtime 11.2\\n  - NVCC architecture flags: -gencode;arch=compute_52,\r\n    code=sm_52;-gencode;arch=compute_60,code=sm_60;-gencode;arch=compute_61,\r\n    code=sm_61;-gencode;arch=compute_70,code=sm_70;-gencode;arch=compute_75,\r\n    code=sm_75;-gencode;arch=compute_80,code=sm_80;-gencode;arch=compute_86,\r\n    code=sm_86;-gencode;arch=compute_86,code=compute_86\\n  - CuDNN 8.1.1\\n  - Magma 2.5.2\\n  - Build settings: BLAS_INFO=mkl,\r\n    BUILD_TYPE=Release,\r\n    CUDA_VERSION=11.2,\r\n    CUDNN_VERSION=8.1.1,\r\n    CXX_COMPILER=/usr/bin/c++,\r\n    CXX_FLAGS= -fvisibility-inlines-hidden -DUSE_PTHREADPOOL -fopenmp -DNDEBUG -DUSE_FBGEMM -DUSE_QNNPACK -DUSE_PYTORCH_QNNPACK -DUSE_XNNPACK -O2 -fPIC -Wno-narrowing -Wall -Wextra -Werror=return-type -Wno-missing-field-initializers -Wno-type-limits -Wno-array-bounds -Wno-unknown-pragmas -Wno-sign-compare -Wno-unused-parameter -Wno-unused-variable -Wno-unused-function -Wno-unused-result -Wno-unused-local-typedefs -Wno-strict-overflow -Wno-strict-aliasing -Wno-error=deprecated-declarations -Wno-stringop-overflow -Wno-psabi -Wno-error=pedantic -Wno-error=redundant-decls -Wno-error=old-style-cast -fdiagnostics-color=always -faligned-new -Wno-unused-but-set-variable -Wno-maybe-uninitialized -fno-math-errno -fno-trapping-math -Werror=format -Werror=cast-function-type -Wno-stringop-overflow,\r\n    FORCE_FALLBACK_CUDA_MPI=1,\r\n    LAPACK_INFO=mkl,\r\n    PERF_WITH_AVX=1,\r\n    PERF_WITH_AVX2=1,\r\n    PERF_WITH_AVX512=1,\r\n    TORCH_VERSION=1.9.0,\r\n    USE_CUDA=ON,\r\n    USE_CUDNN=ON,\r\n    USE_EXCEPTION_PTR=1,\r\n    USE_GFLAGS=OFF,\r\n    USE_GLOG=OFF,\r\n    USE_MKL=ON,\r\n    USE_MKLDNN=ON,\r\n    USE_MPI=ON,\r\n    USE_NCCL=ON,\r\n    USE_NNPACK=ON,\r\n    USE_OPENMP=ON,\r\n    \\n',\r\n    'TorchVision': '0.9.0a0',\r\n    'OpenCV': '3.4.11',\r\n    'MMCV': '1.5.0',\r\n    'MMCV Compiler': 'GCC 9.3',\r\n    'MMCV CUDA Compiler': '11.2'\r\n}\r\n```\r\n\r\n</details>\r\n\r\n\r\n2. You may add addition that may be helpful for locating the problem, such as\r\n   - How you installed PyTorch \\[e.g., pip, conda, source\\]\r\n   - Other environment variables that may be related (such as `$PATH`, `$LD_LIBRARY_PATH`, `$PYTHONPATH`, etc.)\r\n\r\n\r\n**Error traceback**\r\nIf applicable, paste the error traceback here.\r\n\r\nn/a\r\n\r\n**Bug fix**\r\nIf you have already identified the reason, you can provide the information here. If you are willing to create a PR to fix it, please also leave a comment here and that would be much appreciated!\r\n\r\nn/a\r\n\n", "before_files": [{"content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom pathlib import Path\nfrom typing import Optional\n\nfrom ...dist_utils import master_only\nfrom ..hook import HOOKS\nfrom .base import LoggerHook\n\n\n@HOOKS.register_module()\nclass DvcliveLoggerHook(LoggerHook):\n    \"\"\"Class to log metrics with dvclive.\n\n    It requires `dvclive`_ to be installed.\n\n    Args:\n        model_file (str): Default None. If not None, after each epoch the\n            model will be saved to {model_file}.\n        interval (int): Logging interval (every k iterations). Default 10.\n        ignore_last (bool): Ignore the log of last iterations in each epoch\n            if less than `interval`. Default: True.\n        reset_flag (bool): Whether to clear the output buffer after logging.\n            Default: False.\n        by_epoch (bool): Whether EpochBasedRunner is used. Default: True.\n        dvclive (Live, optional): An instance of the `Live`_ logger to use\n            instead of initializing a new one internally. Defaults to None.\n        kwargs: Arguments for instantiating `Live`_ (ignored if `dvclive` is\n            provided).\n\n    .. _dvclive:\n        https://dvc.org/doc/dvclive\n\n    .. _Live:\n        https://dvc.org/doc/dvclive/api-reference/live#parameters\n    \"\"\"\n\n    def __init__(self,\n                 model_file: Optional[str] = None,\n                 interval: int = 10,\n                 ignore_last: bool = True,\n                 reset_flag: bool = False,\n                 by_epoch: bool = True,\n                 dvclive=None,\n                 **kwargs):\n        super().__init__(interval, ignore_last, reset_flag, by_epoch)\n        self.model_file = model_file\n        self._import_dvclive(dvclive, **kwargs)\n\n    def _import_dvclive(self, dvclive=None, **kwargs) -> None:\n        try:\n            from dvclive import Live\n        except ImportError:\n            raise ImportError(\n                'Please run \"pip install dvclive\" to install dvclive')\n        self.dvclive = dvclive if dvclive is not None else Live(**kwargs)\n\n    @master_only\n    def log(self, runner) -> None:\n        tags = self.get_loggable_tags(runner)\n        if tags:\n            self.dvclive.set_step(self.get_iter(runner))\n            for k, v in tags.items():\n                self.dvclive.log(k, v)\n\n    @master_only\n    def after_train_epoch(self, runner) -> None:\n        super().after_train_epoch(runner)\n        if self.model_file is not None:\n            runner.save_checkpoint(\n                Path(self.model_file).parent,\n                filename_tmpl=Path(self.model_file).name,\n                create_symlink=False,\n            )\n", "path": "mmcv/runner/hooks/logger/dvclive.py"}], "after_files": [{"content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom pathlib import Path\nfrom typing import Optional\n\nfrom ...dist_utils import master_only\nfrom ..hook import HOOKS\nfrom .base import LoggerHook\n\n\n@HOOKS.register_module()\nclass DvcliveLoggerHook(LoggerHook):\n    \"\"\"Class to log metrics with dvclive.\n\n    It requires `dvclive`_ to be installed.\n\n    Args:\n        model_file (str): Default None. If not None, after each epoch the\n            model will be saved to {model_file}.\n        interval (int): Logging interval (every k iterations). Default 10.\n        ignore_last (bool): Ignore the log of last iterations in each epoch\n            if less than `interval`. Default: True.\n        reset_flag (bool): Whether to clear the output buffer after logging.\n            Default: False.\n        by_epoch (bool): Whether EpochBasedRunner is used.\n            Determines whether `log` is called `after_train_iter` or\n            `after_train_epoch`.\n            Default: True.\n        dvclive (Live, optional): An instance of the `Live`_ logger to use\n            instead of initializing a new one internally. Defaults to None.\n        kwargs: Arguments for instantiating `Live`_ (ignored if `dvclive` is\n            provided).\n\n    .. _dvclive:\n        https://dvc.org/doc/dvclive\n\n    .. _Live:\n        https://dvc.org/doc/dvclive/api-reference/live#parameters\n    \"\"\"\n\n    def __init__(self,\n                 model_file: Optional[str] = None,\n                 interval: int = 10,\n                 ignore_last: bool = True,\n                 reset_flag: bool = False,\n                 by_epoch: bool = True,\n                 dvclive=None,\n                 **kwargs):\n        super().__init__(interval, ignore_last, reset_flag, by_epoch)\n        self.model_file = model_file\n        self._import_dvclive(dvclive, **kwargs)\n\n    def _import_dvclive(self, dvclive=None, **kwargs) -> None:\n        try:\n            from dvclive import Live\n        except ImportError:\n            raise ImportError(\n                'Please run \"pip install dvclive\" to install dvclive')\n        self.dvclive = dvclive if dvclive is not None else Live(**kwargs)\n\n    @master_only\n    def log(self, runner) -> None:\n        tags = self.get_loggable_tags(runner)\n        if tags:\n            step = self.get_epoch(runner) if self.by_epoch else self.get_iter(\n                runner)\n            self.dvclive.set_step(step)\n\n            for k, v in tags.items():\n                self.dvclive.log(k, v)\n\n    def after_train_epoch(self, runner) -> None:\n        if self.model_file is not None:\n            runner.save_checkpoint(\n                Path(self.model_file).parent,\n                filename_tmpl=Path(self.model_file).name,\n                create_symlink=False,\n            )\n        if self.by_epoch:\n            super().after_train_epoch(runner)\n\n    def after_train_iter(self, runner) -> None:\n        if not self.by_epoch:\n            super().after_train_iter(runner)\n", "path": "mmcv/runner/hooks/logger/dvclive.py"}]}