Repository: open-mmlab/mmyolo (language: python)

Issue:
[Docs] Fix useful_tools.md
1.Add voc2012 instruction in download_dataset
2.Modify model_converters folder path


Discussion / hints:

Fix patch:
diff --git a/README.md b/README.md
index 87786a608..358afebbd 100644
--- a/README.md
+++ b/README.md
@@ -62,13 +62,20 @@ The master branch works with **PyTorch 1.6+**.
 
   MMYOLO decomposes the framework into different components where users can easily customize a model by combining different modules with various training and testing strategies.
 
-<img src="https://user-images.githubusercontent.com/27466624/190986949-01414a91-baae-4228-8828-c59db58dcf36.jpg" alt="BaseModule"/>
-  The figure is contributed by RangeKing@GitHub, thank you very much!
+<img src="https://user-images.githubusercontent.com/27466624/199999337-0544a4cb-3cbd-4f3e-be26-bcd9e74db7ff.jpg" alt="BaseModule-P5"/>
+  The figure above is contributed by RangeKing@GitHub, thank you very much!
+
+And the figure of P6 model is in [model_design.md](docs/en/algorithm_descriptions/model_design.md).
 
 </details>
 
 ## What's New
 
+💎 **v0.1.3** was released on 10/11/2022:
+
+1. Fix training failure when saving best weights based on mmengine 0.3.1
+2. Fix `add_dump_metric` error based on mmdet 3.0.0rc3
+
 💎 **v0.1.2** was released on 3/11/2022:
 
 1. Support [YOLOv5/YOLOv6/YOLOX/RTMDet deployments](https://github.com/open-mmlab/mmyolo/blob/main/configs/deploy) for ONNXRuntime and TensorRT
@@ -88,9 +95,9 @@ MMYOLO relies on PyTorch, MMCV, MMEngine, and MMDetection. Below are quick steps
 conda create -n open-mmlab python=3.8 pytorch==1.10.1 torchvision==0.11.2 cudatoolkit=11.3 -c pytorch -y
 conda activate open-mmlab
 pip install openmim
-mim install "mmengine>=0.3.0"
+mim install "mmengine>=0.3.1"
 mim install "mmcv>=2.0.0rc1,<2.1.0"
-mim install "mmdet>=3.0.0rc2,<3.1.0"
+mim install "mmdet>=3.0.0rc3,<3.1.0"
 git clone https://github.com/open-mmlab/mmyolo.git
 cd mmyolo
 # Install albumentations
@@ -135,6 +142,7 @@ For different parts from MMDetection, we have also prepared user guides and adva
 
   - [Data flow](docs/en/advanced_guides/data_flow.md)
   - [How to](docs/en/advanced_guides/how_to.md)
+  - [Plugins](docs/en/advanced_guides/plugins.md)
 
 ## Overview of Benchmark and Model Zoo
 
diff --git a/README_zh-CN.md b/README_zh-CN.md
index 5b2a82f4a..252713729 100644
--- a/README_zh-CN.md
+++ b/README_zh-CN.md
@@ -62,13 +62,20 @@ MMYOLO 是一个基于 PyTorch 和 MMDetection 的 YOLO 系列算法开源工具
 
   MMYOLO 将框架解耦成不同的模块组件，通过组合不同的模块和训练测试策略，用户可以便捷地构建自定义模型。
 
-<img src="https://user-images.githubusercontent.com/27466624/190986949-01414a91-baae-4228-8828-c59db58dcf36.jpg" alt="基类"/>
+<img src="https://user-images.githubusercontent.com/27466624/199999337-0544a4cb-3cbd-4f3e-be26-bcd9e74db7ff.jpg" alt="基类-P5"/>
   图为 RangeKing@GitHub 提供，非常感谢！
 
+P6 模型图详见 [model_design.md](docs/zh_CN/algorithm_descriptions/model_design.md)。
+
 </details>
 
 ## 最新进展
 
+💎 **v0.1.3** 版本已经在 2022.11.10 发布：
+
+1. 基于 mmengine 0.3.1 修复保存最好权重时训练失败问题
+2. 基于 mmdet 3.0.0rc3 修复 `add_dump_metric` 报错 (#253)
+
 💎 **v0.1.2** 版本已经在 2022.11.3 发布：
 
 1. 支持 ONNXRuntime 和 TensorRT 的 [YOLOv5/YOLOv6/YOLOX/RTMDet 部署](https://github.com/open-mmlab/mmyolo/blob/main/configs/deploy)
@@ -97,9 +104,9 @@ MMYOLO 依赖 PyTorch, MMCV, MMEngine 和 MMDetection，以下是安装的简要
 conda create -n open-mmlab python=3.8 pytorch==1.10.1 torchvision==0.11.2 cudatoolkit=11.3 -c pytorch -y
 conda activate open-mmlab
 pip install openmim
-mim install "mmengine>=0.3.0"
+mim install "mmengine>=0.3.1"
 mim install "mmcv>=2.0.0rc1,<2.1.0"
-mim install "mmdet>=3.0.0rc2,<3.1.0"
+mim install "mmdet>=3.0.0rc3,<3.1.0"
 git clone https://github.com/open-mmlab/mmyolo.git
 cd mmyolo
 # Install albumentations
@@ -145,6 +152,7 @@ MMYOLO 用法和 MMDetection 几乎一致，所有教程都是通用的，你也
 
   - [数据流](docs/zh_cn/advanced_guides/data_flow.md)
   - [How to](docs/zh_cn/advanced_guides/how_to.md)
+  - [插件](docs/zh_cn/advanced_guides/plugins.md)
 
 - [解读文章和资源汇总](docs/zh_cn/article.md)
 
diff --git a/configs/rtmdet/README.md b/configs/rtmdet/README.md
index 652401c5e..e909d3f34 100644
--- a/configs/rtmdet/README.md
+++ b/configs/rtmdet/README.md
@@ -12,13 +12,13 @@ Our tech-report will be released soon.
 
 ## Results and Models
 
-|  Backbone   | size | SyncBN | ox AP | Params(M) | FLOPS(G) | TRT-FP16-Latency(ms) |                      Config                       |                                                                                                                                                   Download                                                                                                                                                    |
-| :---------: | :--: | :----: | ----: | :-------: | :------: | :------------------: | :-----------------------------------------------: | :-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
-| RTMDet-tiny | 640  |  Yes   |  40.9 |    4.8    |   8.1    |         0.98         | [config](./rtmdet_tiny_syncbn_8xb32-300e_coco.py) | [model](https://download.openmmlab.com/mmyolo/v0/rtmdet/rtmdet_tiny_syncbn_8xb32-300e_coco/rtmdet_tiny_syncbn_8xb32-300e_coco_20220902_112414-259f3241.pth) \| [log](https://download.openmmlab.com/mmdetection/v3.0/rtmdet/rtmdet_tiny_8xb32-300e_coco/rtmdet_tiny_8xb32-300e_coco_20220902_112414.log.json) |
-|  RTMDet-s   | 640  |  Yes   |  44.5 |   8.89    |   14.8   |         1.22         |  [config](./rtmdet_s_syncbn_8xb32-300e_coco.py)   |       [model](https://download.openmmlab.com/mmyolo/v0/rtmdet/rtmdet_s_syncbn_8xb32-300e_coco/rtmdet_s_syncbn_8xb32-300e_coco_20220905_161602-fd1cacb9.pth) \| [log](https://download.openmmlab.com/mmdetection/v3.0/rtmdet/rtmdet_s_8xb32-300e_coco/rtmdet_s_8xb32-300e_coco_20220905_161602.log.json)       |
-|  RTMDet-m   | 640  |  Yes   |  49.1 |   24.71   |  39.27   |         1.62         |  [config](./rtmdet_m_syncbn_8xb32-300e_coco.py)   |       [model](https://download.openmmlab.com/mmyolo/v0/rtmdet/rtmdet_m_syncbn_8xb32-300e_coco/rtmdet_m_syncbn_8xb32-300e_coco_20220924_132959-d9f2e90d.pth) \| [log](https://download.openmmlab.com/mmdetection/v3.0/rtmdet/rtmdet_m_8xb32-300e_coco/rtmdet_m_8xb32-300e_coco_20220924_132959.log.json)       |
-|  RTMDet-l   | 640  |  Yes   |  51.3 |   52.3    |  80.23   |         2.44         |  [config](./rtmdet_l_syncbn_8xb32-300e_coco.py)   |       [model](https://download.openmmlab.com/mmyolo/v0/rtmdet/rtmdet_l_syncbn_8xb32-300e_coco/rtmdet_l_syncbn_8xb32-300e_coco_20220926_150401-40c754b5.pth) \| [log](https://download.openmmlab.com/mmdetection/v3.0/rtmdet/rtmdet_l_8xb32-300e_coco/rtmdet_l_8xb32-300e_coco_20220926_150401.log.json)       |
-|  RTMDet-x   | 640  |  Yes   |  52.6 |   94.86   |  141.67  |         3.10         |  [config](./rtmdet_x_syncbn_8xb32-300e_coco.py)   |                                                                                                                                           [model](<>) \| [log](<>)                                                                                                                                            |
+|  Backbone   | size | SyncBN | box AP | Params(M) | FLOPS(G) | TRT-FP16-Latency(ms) |                      Config                       |                                                                                                                                                   Download                                                                                                                                                    |
+| :---------: | :--: | :----: | -----: | :-------: | :------: | :------------------: | :-----------------------------------------------: | :-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
+| RTMDet-tiny | 640  |  Yes   |   40.9 |    4.8    |   8.1    |         0.98         | [config](./rtmdet_tiny_syncbn_8xb32-300e_coco.py) | [model](https://download.openmmlab.com/mmyolo/v0/rtmdet/rtmdet_tiny_syncbn_8xb32-300e_coco/rtmdet_tiny_syncbn_8xb32-300e_coco_20220902_112414-259f3241.pth) \| [log](https://download.openmmlab.com/mmdetection/v3.0/rtmdet/rtmdet_tiny_8xb32-300e_coco/rtmdet_tiny_8xb32-300e_coco_20220902_112414.log.json) |
+|  RTMDet-s   | 640  |  Yes   |   44.5 |   8.89    |   14.8   |         1.22         |  [config](./rtmdet_s_syncbn_8xb32-300e_coco.py)   |       [model](https://download.openmmlab.com/mmyolo/v0/rtmdet/rtmdet_s_syncbn_8xb32-300e_coco/rtmdet_s_syncbn_8xb32-300e_coco_20220905_161602-fd1cacb9.pth) \| [log](https://download.openmmlab.com/mmdetection/v3.0/rtmdet/rtmdet_s_8xb32-300e_coco/rtmdet_s_8xb32-300e_coco_20220905_161602.log.json)       |
+|  RTMDet-m   | 640  |  Yes   |   49.1 |   24.71   |  39.27   |         1.62         |  [config](./rtmdet_m_syncbn_8xb32-300e_coco.py)   |       [model](https://download.openmmlab.com/mmyolo/v0/rtmdet/rtmdet_m_syncbn_8xb32-300e_coco/rtmdet_m_syncbn_8xb32-300e_coco_20220924_132959-d9f2e90d.pth) \| [log](https://download.openmmlab.com/mmdetection/v3.0/rtmdet/rtmdet_m_8xb32-300e_coco/rtmdet_m_8xb32-300e_coco_20220924_132959.log.json)       |
+|  RTMDet-l   | 640  |  Yes   |   51.3 |   52.3    |  80.23   |         2.44         |  [config](./rtmdet_l_syncbn_8xb32-300e_coco.py)   |       [model](https://download.openmmlab.com/mmyolo/v0/rtmdet/rtmdet_l_syncbn_8xb32-300e_coco/rtmdet_l_syncbn_8xb32-300e_coco_20220926_150401-40c754b5.pth) \| [log](https://download.openmmlab.com/mmdetection/v3.0/rtmdet/rtmdet_l_8xb32-300e_coco/rtmdet_l_8xb32-300e_coco_20220926_150401.log.json)       |
+|  RTMDet-x   | 640  |  Yes   |   52.6 |   94.86   |  141.67  |         3.10         |  [config](./rtmdet_x_syncbn_8xb32-300e_coco.py)   |                                                                                                                                           [model](<>) \| [log](<>)                                                                                                                                            |
 
 **Note**:
 
diff --git a/demo/featmap_vis_demo.py b/demo/featmap_vis_demo.py
index f8eb3b2a6..c9fb8eda5 100644
--- a/demo/featmap_vis_demo.py
+++ b/demo/featmap_vis_demo.py
@@ -1,39 +1,45 @@
 # Copyright (c) OpenMMLab. All rights reserved.
 import argparse
+import os
 from typing import Sequence
 
 import mmcv
-import numpy as np
 from mmdet.apis import inference_detector, init_detector
 from mmengine import Config, DictAction
+from mmengine.utils import ProgressBar
 
 from mmyolo.registry import VISUALIZERS
 from mmyolo.utils import register_all_modules
+from mmyolo.utils.misc import auto_arrange_images, get_file_list
 
 
 # TODO: Refine
 def parse_args():
-    parser = argparse.ArgumentParser(description='Visualize Featmaps')
-    parser.add_argument('img', help='Image file')
+    parser = argparse.ArgumentParser(description='Visualize feature map')
+    parser.add_argument(
+        'img', help='Image path, include image file, dir and URL.')
     parser.add_argument('config', help='Config file')
     parser.add_argument('checkpoint', help='Checkpoint file')
+    parser.add_argument(
+        '--out-dir', default='./output', help='Path to output file')
     parser.add_argument(
         '--target-layers',
         default=['backbone'],
         nargs='+',
         type=str,
-        help='The target layers to get featmap, if not set, the tool will '
+        help='The target layers to get feature map, if not set, the tool will '
         'specify the backbone')
     parser.add_argument(
         '--preview-model',
         default=False,
         action='store_true',
         help='To preview all the model layers')
-    parser.add_argument('--out-file', default=None, help='Path to output file')
     parser.add_argument(
         '--device', default='cuda:0', help='Device used for inference')
     parser.add_argument(
         '--score-thr', type=float, default=0.3, help='Bbox score threshold')
+    parser.add_argument(
+        '--show', action='store_true', help='Show the featmap results')
     parser.add_argument(
         '--channel-reduction',
         default='select_max',
@@ -88,28 +94,9 @@ def release(self):
             handle.remove()
 
 
-def auto_arrange_imgs(imgs):
-    len_img = len(imgs)
-    col = 2
-    if len_img <= col:
-        imgs = np.concatenate(imgs, axis=1)
-    else:
-        row = len_img // col + 1
-        fill_img_list = [np.ones(imgs[0].shape, dtype=np.uint8) * 255] * (
-            row * col - len_img)
-        imgs.extend(fill_img_list)
-        merge_imgs_col = []
-        for i in range(row):
-            start = col * i
-            end = col * (i + 1)
-            merge_col = np.hstack(imgs[start:end])
-            merge_imgs_col.append(merge_col)
-
-        imgs = np.vstack(merge_imgs_col)
-    return imgs
-
-
-def main(args):
+def main():
+    args = parse_args()
+
     # register all modules in mmdet into the registries
     register_all_modules()
 
@@ -124,9 +111,13 @@ def main(args):
 
     model = init_detector(args.config, args.checkpoint, device=args.device)
 
+    if not os.path.exists(args.out_dir) and not args.show:
+        os.mkdir(args.out_dir)
+
     if args.preview_model:
         print(model)
-        print('\n Please remove `--preview-model` to get the AM.')
+        print('\n This flag is only show model, if you want to continue, '
+              'please remove `--preview-model` to get the feature map.')
         return
 
     target_layers = []
@@ -143,11 +134,11 @@ def main(args):
     visualizer = VISUALIZERS.build(model.cfg.visualizer)
     visualizer.dataset_meta = model.dataset_meta
 
-    images = args.img
-    if not isinstance(images, list):
-        images = [images]
+    # get file list
+    image_list, source_type = get_file_list(args.img)
 
-    for image_path in images:
+    progress_bar = ProgressBar(len(image_list))
+    for image_path in image_list:
         result, featmaps = activations_wrapper(image_path)
         if not isinstance(featmaps, Sequence):
             featmaps = [featmaps]
@@ -159,10 +150,16 @@ def main(args):
             else:
                 flatten_featmaps.append(featmap)
 
-        # show the results
-        img = mmcv.imread(args.img)
+        img = mmcv.imread(image_path)
         img = mmcv.imconvert(img, 'bgr', 'rgb')
 
+        if source_type['is_dir']:
+            filename = os.path.relpath(image_path, args.img).replace('/', '_')
+        else:
+            filename = os.path.basename(image_path)
+        out_file = None if args.show else os.path.join(args.out_dir, filename)
+
+        # show the results
         shown_imgs = []
         visualizer.add_datasample(
             'result',
@@ -184,16 +181,20 @@ def main(args):
                 arrangement=args.arrangement)
             shown_imgs.append(shown_img)
 
-        shown_imgs = auto_arrange_imgs(shown_imgs)
+        shown_imgs = auto_arrange_images(shown_imgs)
 
-        if args.out_file is not None:
-            mmcv.imwrite(shown_imgs[..., ::-1], args.out_file)
-        else:
+        progress_bar.update()
+        if out_file:
+            mmcv.imwrite(shown_imgs[..., ::-1], out_file)
+
+        if args.show:
             visualizer.show(shown_imgs)
 
+    print(f'All done!'
+          f'\nResults have been saved at {os.path.abspath(args.out_dir)}')
+
 
 # Please refer to the usage tutorial:
 # https://github.com/open-mmlab/mmyolo/blob/main/docs/zh_cn/user_guides/visualization.md # noqa
 if __name__ == '__main__':
-    args = parse_args()
-    main(args)
+    main()
diff --git a/demo/image_demo.py b/demo/image_demo.py
index d2827ebf8..5ccc7aefe 100644
--- a/demo/image_demo.py
+++ b/demo/image_demo.py
@@ -1,20 +1,15 @@
 # Copyright (c) OpenMMLab. All rights reserved.
-import logging
 import os
-import urllib
 from argparse import ArgumentParser
 
 import mmcv
-import torch
 from mmdet.apis import inference_detector, init_detector
 from mmengine.logging import print_log
-from mmengine.utils import ProgressBar, scandir
+from mmengine.utils import ProgressBar
 
 from mmyolo.registry import VISUALIZERS
 from mmyolo.utils import register_all_modules, switch_to_deploy
-
-IMG_EXTENSIONS = ('.jpg', '.jpeg', '.png', '.ppm', '.bmp', '.pgm', '.tif',
-                  '.tiff', '.webp')
+from mmyolo.utils.misc import get_file_list
 
 
 def parse_args():
@@ -39,7 +34,9 @@ def parse_args():
     return args
 
 
-def main(args):
+def main():
+    args = parse_args()
+
     # register all modules in mmdet into the registries
     register_all_modules()
 
@@ -49,45 +46,32 @@ def main(args):
     if args.deploy:
         switch_to_deploy(model)
 
+    if not os.path.exists(args.out_dir) and not args.show:
+        os.mkdir(args.out_dir)
+
     # init visualizer
     visualizer = VISUALIZERS.build(model.cfg.visualizer)
     visualizer.dataset_meta = model.dataset_meta
 
-    is_dir = os.path.isdir(args.img)
-    is_url = args.img.startswith(('http:/', 'https:/'))
-    is_file = os.path.splitext(args.img)[-1] in (IMG_EXTENSIONS)
-
-    files = []
-    if is_dir:
-        # when input source is dir
-        for file in scandir(args.img, IMG_EXTENSIONS, recursive=True):
-            files.append(os.path.join(args.img, file))
-    elif is_url:
-        # when input source is url
-        filename = os.path.basename(
-            urllib.parse.unquote(args.img).split('?')[0])
-        torch.hub.download_url_to_file(args.img, filename)
-        files = [os.path.join(os.getcwd(), filename)]
-    elif is_file:
-        # when input source is single image
-        files = [args.img]
-    else:
-        print_log(
-            'Cannot find image file.', logger='current', level=logging.WARNING)
+    # get file list
+    files, source_type = get_file_list(args.img)
 
     # start detector inference
     progress_bar = ProgressBar(len(files))
     for file in files:
         result = inference_detector(model, file)
+
         img = mmcv.imread(file)
         img = mmcv.imconvert(img, 'bgr', 'rgb')
-        if is_dir:
+
+        if source_type['is_dir']:
             filename = os.path.relpath(file, args.img).replace('/', '_')
         else:
             filename = os.path.basename(file)
         out_file = None if args.show else os.path.join(args.out_dir, filename)
+
         visualizer.add_datasample(
-            filename,
+            os.path.basename(out_file),
             img,
             data_sample=result,
             draw_gt=False,
@@ -96,11 +80,11 @@ def main(args):
             out_file=out_file,
             pred_score_thr=args.score_thr)
         progress_bar.update()
+
     if not args.show:
         print_log(
             f'\nResults have been saved at {os.path.abspath(args.out_dir)}')
 
 
 if __name__ == '__main__':
-    args = parse_args()
-    main(args)
+    main()
diff --git a/docker/Dockerfile b/docker/Dockerfile
index 93959e600..191273c10 100644
--- a/docker/Dockerfile
+++ b/docker/Dockerfile
@@ -26,7 +26,7 @@ RUN apt-get update \
 
 # Install MMEngine , MMCV and MMDet
 RUN pip install --no-cache-dir openmim && \
-    mim install --no-cache-dir "mmengine>=0.3.0" "mmcv>=2.0.0rc1,<2.1.0" "mmdet>=3.0.0rc2,<3.1.0"
+    mim install --no-cache-dir "mmengine>=0.3.1" "mmcv>=2.0.0rc1,<2.1.0" "mmdet>=3.0.0rc3,<3.1.0"
 
 # Install MMYOLO
 RUN git clone https://github.com/open-mmlab/mmyolo.git /mmyolo && \
diff --git a/docker/Dockerfile_deployment b/docker/Dockerfile_deployment
index 644c590e3..7326cafab 100644
--- a/docker/Dockerfile_deployment
+++ b/docker/Dockerfile_deployment
@@ -28,9 +28,16 @@ RUN wget -q https://github.com/microsoft/onnxruntime/releases/download/v${ONNXRU
     && pip install pycuda
 
 
-# Install OPENMIM MMENGINE MMCV MMDET
+# Install OPENMIM MMENGINE MMDET
 RUN pip install --no-cache-dir openmim \
-    && mim install --no-cache-dir "mmengine>=0.3.0" "mmcv>=2.0.0rc1,<2.1.0" "mmdet>=3.0.0rc2,<3.1.0"
+    && mim install --no-cache-dir "mmengine>=0.3.1" "mmdet>=3.0.0rc3,<3.1.0" \
+    && mim install --no-cache-dir opencv-python==4.5.5.64 opencv-python-headless==4.5.5.64
+
+RUN git clone https://github.com/open-mmlab/mmcv.git -b 2.x mmcv \
+    && cd mmcv \
+    && mim install --no-cache-dir -r requirements/optional.txt \
+    && MMCV_WITH_OPS=1 mim install --no-cache-dir -e . -v \
+    && cd ..
 
 # Install MMYOLO
 RUN git clone https://github.com/open-mmlab/mmyolo.git -b dev mmyolo \
@@ -41,9 +48,7 @@ RUN git clone https://github.com/open-mmlab/mmyolo.git -b dev mmyolo \
 # Install MMDEPLOY
 ENV ONNXRUNTIME_DIR=/openmmlab/onnxruntime-linux-x64-${ONNXRUNTIME_VERSION} \
     TENSORRT_DIR=/usr/lib/x86_64-linux-gnu \
-    CUDNN_DIR=/usr/lib/x86_64-linux-gnu \
-    BACKUP_LD_LIBRARY_PATH=$LD_LIBRARY_PATH \
-    LD_LIBRARY_PATH=$ONNXRUNTIME_DIR/lib:$TENSORRT_DIR/lib:$CUDNN_DIR/lib64:$BACKUP_LD_LIBRARY_PATH
+    CUDNN_DIR=/usr/lib/x86_64-linux-gnu
 
 RUN git clone https://github.com/open-mmlab/mmdeploy -b dev-1.x mmdeploy \
     && cd mmdeploy \
@@ -57,4 +62,4 @@ RUN git clone https://github.com/open-mmlab/mmdeploy -b dev-1.x mmdeploy \
     && mim install --no-cache-dir -e .
 
 # Fix undefined symbol bug
-RUN echo -e "\nldconfig" > /root/.bashrc
+    RUN echo -e "\nexport LD_LIBRARY_PATH=${ONNXRUNTIME_DIR}/lib:${TENSORRT_DIR}/lib:${CUDNN_DIR}/lib64:${LD_LIBRARY_PATH}\nldconfig" >> /root/.bashrc
diff --git a/docs/en/advanced_guides/index.rst b/docs/en/advanced_guides/index.rst
index 06827c1a0..bd72cd2e4 100644
--- a/docs/en/advanced_guides/index.rst
+++ b/docs/en/advanced_guides/index.rst
@@ -14,3 +14,12 @@ How to
    :maxdepth: 1
 
    how_to.md
+
+
+Plugins
+************************
+
+.. toctree::
+   :maxdepth: 1
+
+   plugins.md
diff --git a/docs/en/advanced_guides/plugins.md b/docs/en/advanced_guides/plugins.md
new file mode 100644
index 000000000..779d515c6
--- /dev/null
+++ b/docs/en/advanced_guides/plugins.md
@@ -0,0 +1,1 @@
+# Plugins
diff --git a/docs/en/algorithm_descriptions/model_design.md b/docs/en/algorithm_descriptions/model_design.md
index f7fb35772..e1fc5b822 100644
--- a/docs/en/algorithm_descriptions/model_design.md
+++ b/docs/en/algorithm_descriptions/model_design.md
@@ -2,13 +2,19 @@
 
 ## YOLO series model basic class
 
-The structural graph is provided by RangeKing@GitHub. Thank you RangeKing！
+The structural figure is provided by RangeKing@GitHub. Thank you RangeKing！
 
 <div align=center>
-<img src="https://user-images.githubusercontent.com/27466624/190986949-01414a91-baae-4228-8828-c59db58dcf36.jpg" width=800 alt="base class">
+<img src="https://user-images.githubusercontent.com/27466624/199999337-0544a4cb-3cbd-4f3e-be26-bcd9e74db7ff.jpg" alt="BaseModule-P5">
+Figure 1: P5 model structure
 </div>
 
-Most YOLO series algorithms adopt a unified algorithm-building structure, typically as Darknet + PAFPN. In order to let users quickly understand the YOLO series algorithm architecture, we deliberately designed the `BaseBackbone` + `BaseYOLONeck` structure, as shown in the above graph.
+<div align=center>
+<img src="https://user-images.githubusercontent.com/27466624/200850066-0c434173-2d40-4c12-8de3-eda473ff172f.jpg" alt="BaseModule-P6">
+Figure 2: P6 model structure
+</div>
+
+Most YOLO series algorithms adopt a unified algorithm-building structure, typically as Darknet + PAFPN. In order to let users quickly understand the YOLO series algorithm architecture, we deliberately designed the `BaseBackbone` + `BaseYOLONeck` structure, as shown in the above figure.
 
 The benefits of the abstract `BaseBackbone` include:
 
@@ -20,7 +26,9 @@ The benefits of the abstract `BaseBackbone` include:
 
 ### BaseBackbone
 
-We can see in the above graph, as for P5, `BaseBackbone` includes 1 stem layer and 4 stage layers which are similar to the basic structure of ResNet. Different backbone network algorithms inherit the `BaseBackbone`. Users can build each layer of the whole network by implementing customized basic modules through the internal `build_xx` method.
+- As shown in Figure 1, for P5, `BaseBackbone` includes 1 stem layer and 4 stage layers which are similar to the basic structure of ResNet.
+- As shown in Figure 2, for P6, `BaseBackbone` includes 1 stem layer and 5 stage layers.
+  Different backbone network algorithms inherit the `BaseBackbone`. Users can build each layer of the whole network by implementing customized basic modules through the internal `build_xx` method.
 
 ### BaseYOLONeck
 
diff --git a/docs/en/algorithm_descriptions/yolov5_description.md b/docs/en/algorithm_descriptions/yolov5_description.md
index a244056f7..e22eef64b 100644
--- a/docs/en/algorithm_descriptions/yolov5_description.md
+++ b/docs/en/algorithm_descriptions/yolov5_description.md
@@ -3,7 +3,13 @@
 ## 0 Introduction
 
 <div align=center >
-<img alt="YOLOv5_structure_v3.3" src="https://user-images.githubusercontent.com/27466624/192134657-a8d0286d-640c-445f-89bd-fda751094a4a.jpg"/>
+<img alt="YOLOv5-P5_structure_v3.4" src="https://user-images.githubusercontent.com/27466624/200000324-70ae078f-cea7-4189-8baa-440656797dad.jpg"/>
+Figure 1: YOLOv5-P5 model structure
+</div>
+
+<div align=center >
+<img alt="YOLOv5-P6_structure_v1.0" src="https://user-images.githubusercontent.com/27466624/200845705-c9f3300f-9847-4933-b79d-0efcf0286e16.jpg"/>
+Figure 2: YOLOv5-P6 model structure
 </div>
 
 RangeKing@github provides the graph above. Thanks, RangeKing!
@@ -15,7 +21,11 @@ In short, the main features of YOLOv5 are:
 2. **Fast training speed**: the training time in the case of 300 epochs is similar to most of the one-stage and two-stage algorithms under 12 epochs, such as RetinaNet, ATSS, and Faster R-CNN.
 3. **Abundant optimization for corner cases**: YOLOv5 has implemented many optimizations. The functions and documentation are richer as well.
 
-This article will start with the principle of the YOLOv5 algorithm and then focus on analyzing the implementation in MMYOLO. The follow-up part includes the guide and speed benchmark of YOLOv5.
+Figures 1 and 2 show that the main differences between the P5 and P6 versions of YOLOv5 are the network structure and the image input resolution. Other differences, such as the number of anchors and loss weights, can be found in the [configuration file](https://github.com/open-mmlab/mmyolo/blob/main/configs/yolov5/yolov5_s-p6-v62_syncbn_fast_8xb16-300e_coco.py). This article will start with the principle of the YOLOv5 algorithm and then focus on analyzing the implementation in MMYOLO. The follow-up part includes the guide and speed benchmark of YOLOv5.
+
+```{hint}
+Unless specified, the P5 model is described by default in this documentation.
+```
 
 We hope this article becomes your core document to start and master YOLOv5. Since YOLOv5 is still constantly updated, we will also keep updating this document. So please always catch up with the latest version.
 
@@ -52,7 +62,7 @@ Many data augmentation methods are used in YOLOv5, including:
 - **Mosaic**
 - **RandomAffine**
 - **MixUp**
-- **Image blue and other transformations using Albu**
+- **Image blur and other transformations using Albu**
 - **HSV color space enhancement**
 - **Random horizontal flips**
 
@@ -121,7 +131,7 @@ Note: **In YOLOv5's implementation of MixUP, the other random image must be proc
 
 The rest of the augmentations are:
 
-- **Image blue and other transformations using Albu**
+- **Image blur and other transformations using Albu**
 - **HSV color space enhancement**
 - **Random horizontal flips**
 
@@ -245,20 +255,25 @@ This section was written by RangeKing@github. Thanks a lot!
 
 The YOLOv5 network structure is the standard `CSPDarknet` + `PAFPN` + `non-decoupled Head`.
 
-The size of the YOLOv5 network structure is determined by the `deepen_factor` and `widen_factor` parameters. `deepen_factor` controls the depth of the network structure, that is, the number of stacks of `DarknetBottleneck` modules in `CSPLayer`. `widen_factor` controls the width of the network structure, that is, the number of channels of the module output feature map. Take YOLOv5-l as an example. Its `deepen_factor = widen_factor = 1.0` , the overall structure is shown in the graph above.
+The size of the YOLOv5 network structure is determined by the `deepen_factor` and `widen_factor` parameters. `deepen_factor` controls the depth of the network structure, that is, the number of stacks of `DarknetBottleneck` modules in `CSPLayer`. `widen_factor` controls the width of the network structure, that is, the number of channels of the module output feature map. Take YOLOv5-l as an example. Its `deepen_factor = widen_factor = 1.0`. the overall structure is shown in the graph above.
 
 The upper part of the figure is an overview of the model; the lower part is the specific network structure, in which the modules are marked with numbers in serial, which is convenient for users to correspond to the configuration files of the YOLOv5 official repository. The middle part is the detailed composition of each sub-module.
 
-If you want to use **netron** to visualize the details of the network structure, just open the ONNX file format exported by MMDeploy in netron.
+If you want to use **netron** to visualize the details of the network structure, open the ONNX file format exported by MMDeploy in netron.
+
+```{hint}
+The shapes of the feature map in Section 1.2 are (B, C, H, W) by default.
+```
 
 #### 1.2.1 Backbone
 
 `CSPDarknet` in MMYOLO inherits from `BaseBackbone`. The overall structure is similar to `ResNet` with a total of 5 layers of design, including one `Stem Layer` and four `Stage Layer`:
 
 - `Stem Layer` is a `ConvModule` whose kernel size is 6x6. It is more efficient than the `Focus` module used before v6.1.
-- Each of the first three `Stage Layer` consists of one `ConvModule` and one `CSPLayer`, as shown in the Details part in the graph above. `ConvModule` is a 3x3 `Conv2d` + `BatchNorm` + `SiLU activation function` module. `CSPLayer` is the C3 module in the official YOLOv5 repository, consisting of three `ConvModule` + n `DarknetBottleneck` with residual connections.
-- The 4th `Stage Layer` adds an `SPPF` module at the end. The `SPPF` module is to serialize the input through multiple 5x5 `MaxPool2d` layers, which has the same effect as the `SPP` module but is faster.
-- The P5 model passes the corresponding results from the second to the fourth `Stage Layer` to the `Neck` structure and extracts three output feature maps. Take a 640x640 input image as an example. The output features are (B, 256, 80, 80), (B,512,40,40), and (B,1024,20,20), the corresponding stride is 8/16/32.
+- Except for the last `Stage Layer`, each `Stage Layer` consists of one `ConvModule` and one `CSPLayer`, as shown in the Details part in the graph above. `ConvModule` is a 3x3 `Conv2d` + `BatchNorm` + `SiLU activation function` module. `CSPLayer` is the C3 module in the official YOLOv5 repository, consisting of three `ConvModule` + n `DarknetBottleneck` with residual connections.
+- The last `Stage Layer` adds an `SPPF` module at the end. The `SPPF` module is to serialize the input through multiple 5x5 `MaxPool2d` layers, which has the same effect as the `SPP` module but is faster.
+- The P5 model passes the corresponding results from the second to the fourth `Stage Layer` to the `Neck` structure and extracts three output feature maps. Take a 640x640 input image as an example. The output features are (B, 256, 80, 80), (B,512,40,40), and (B,1024,20,20). The corresponding stride is 8/16/32.
+- The P6 model passes the corresponding results from the second to the fifth `Stage Layer` to the `Neck` structure and extracts three output feature maps. Take a 1280x1280 input image as an example. The output features are (B, 256, 160, 160), (B,512,80,80), (B,768,40,40), and (B,1024,20,20). The corresponding stride is 8/16/32/64.
 
 #### 1.2.2 Neck
 
@@ -266,7 +281,7 @@ There is no **Neck** part in the official YOLOv5. However, to facilitate users t
 
 Based on the `BaseYOLONeck` structure, YOLOv5's `Neck` also follows the same build process. However, for non-existed modules, we use `nn.Identity` instead.
 
-The feature maps output by the Neck module are the same as the Backbone, which is (B,256,80,80), (B,512,40,40), and (B,1024,20,20).
+The feature maps output by the Neck module is the same as the Backbone. The P5 model is (B,256,80,80), (B,512,40,40) and (B,1024,20,20); the P6 model is (B,256,160,160), (B,512,80,80), (B,768,40,40) and (B,1024,20,20).
 
 #### 1.2.3 Head
 
@@ -274,7 +289,13 @@ The `Head` structure of YOLOv5 is the same as YOLOv3, which is a `non-decoupled
 
 The `PAFPN` outputs three feature maps of different scales, whose shapes are (B,256,80,80), (B,512,40,40), and (B,1024,20,20) accordingly.
 
-Since YOLOv5 has a non-decoupled output, that is, classification and bbox detection results are all in different channels of the same convolution module. Taking the COCO dataset as an example, when the input is 640x640 resolution, the output shapes of the Head module are `(B, 3x(4+1+80),80,80)`, `(B, 3x(4+1+80),40,40)` and `(B, 3x(4+1+80),20,20)`. `3` represents three anchors, `4` represents the bbox prediction branch, `1` represents the obj prediction branch, and `80` represents the class prediction branch of the COCO dataset.
+Since YOLOv5 has a non-decoupled output, that is, classification and bbox detection results are all in different channels of the same convolution module. Taking the COCO dataset as an example:
+
+- When the input of P5 model is 640x640 resolution, the output shapes of the Head module are `(B, 3x(4+1+80),80,80)`, `(B, 3x(4+1+80),40,40)` and `(B, 3x(4+1+80),20,20)`.
+
+- When the input of P6 model is 1280x1280 resolution, the output shapes of the Head module are  `(B, 3x(4+1+80),160,160)`, `(B, 3x(4+1+80),80,80)`, `(B, 3x(4+1+80),40,40)` and `(B, 3x(4+1+80),20,20)`.
+
+  `3` represents three anchors, `4` represents the bbox prediction branch, `1` represents the obj prediction branch, and `80` represents the class prediction branch of the COCO dataset.
 
 ### 1.3 Positive and negative sample assignment strategy
 
diff --git a/docs/en/get_started.md b/docs/en/get_started.md
index fae36dd23..dd1028ace 100644
--- a/docs/en/get_started.md
+++ b/docs/en/get_started.md
@@ -6,7 +6,8 @@ Compatible MMEngine, MMCV and MMDetection versions are shown as below. Please in
 
 | MMYOLO version |   MMDetection version    |     MMEngine version     |      MMCV version       |
 | :------------: | :----------------------: | :----------------------: | :---------------------: |
-|      main      | mmdet>=3.0.0rc2, \<3.1.0 | mmengine>=0.3.0, \<1.0.0 | mmcv>=2.0.0rc0, \<2.1.0 |
+|      main      | mmdet>=3.0.0rc3, \<3.1.0 | mmengine>=0.3.1, \<1.0.0 | mmcv>=2.0.0rc0, \<2.1.0 |
+|     0.1.3      | mmdet>=3.0.0rc3, \<3.1.0 | mmengine>=0.3.1, \<1.0.0 | mmcv>=2.0.0rc0, \<2.1.0 |
 |     0.1.2      | mmdet>=3.0.0rc2, \<3.1.0 | mmengine>=0.3.0, \<1.0.0 | mmcv>=2.0.0rc0, \<2.1.0 |
 |     0.1.1      |     mmdet==3.0.0rc1      | mmengine>=0.1.0, \<0.2.0 | mmcv>=2.0.0rc0, \<2.1.0 |
 |     0.1.0      |     mmdet==3.0.0rc0      | mmengine>=0.1.0, \<0.2.0 | mmcv>=2.0.0rc0, \<2.1.0 |
@@ -50,9 +51,9 @@ conda install pytorch torchvision cpuonly -c pytorch
 
 ```shell
 pip install -U openmim
-mim install "mmengine>=0.3.0"
+mim install "mmengine>=0.3.1"
 mim install "mmcv>=2.0.0rc1,<2.1.0"
-mim install "mmdet>=3.0.0rc2,<3.1.0"
+mim install "mmdet>=3.0.0rc3,<3.1.0"
 ```
 
 **Note:**
@@ -156,7 +157,7 @@ To install MMEngine with pip instead of MIM, please follow \[MMEngine installati
 For example, you can install MMEngine by the following command.
 
 ```shell
-pip install "mmengine>=0.3.0"
+pip install "mmengine>=0.3.1"
 ```
 
 #### Install MMCV without MIM
diff --git a/docs/en/notes/changelog.md b/docs/en/notes/changelog.md
index 218b9c4fb..90175b7b1 100644
--- a/docs/en/notes/changelog.md
+++ b/docs/en/notes/changelog.md
@@ -1,5 +1,30 @@
 # Changelog
 
+## v0.1.3（10/11/2022)
+
+### New Features
+
+1. Support CBAM plug-in and provide plug-in documentation (#246)
+2. Add YOLOv5 P6 model structure diagram and related descriptions (#273)
+
+### Bug Fixes
+
+1. Fix training failure when saving best weights based on mmengine 0.3.1
+2. Fix `add_dump_metric` error based on mmdet 3.0.0rc3 (#253)
+3. Fix backbone does not support `init_cfg` issue (#272)
+4. Change typing import method based on mmdet 3.0.0rc3 (#261)
+
+### Improvements
+
+1. `featmap_vis_demo` support for folder and url input (#248)
+2. Deploy docker file refinement (#242)
+
+#### Contributors
+
+A total of 10 developers contributed to this release.
+
+Thank @kitecats, @triple-Mu, @RangeKing, @PeterH0323, @Zheng-LinXiao, @tkhe, @weikai520, @zytx121, @wanghonglie, @hhaAndroid
+
 ## v0.1.2（3/11/2022)
 
 ### Highlights
diff --git a/docs/en/overview.md b/docs/en/overview.md
index 6927c21c8..339bcfa32 100644
--- a/docs/en/overview.md
+++ b/docs/en/overview.md
@@ -53,3 +53,4 @@ The detailed instruction of MMYOLO is as follows.
 
    - [Data flow](https://mmyolo.readthedocs.io/en/latest/advanced_guides/index.html#data-flow)
    - [How to](https://mmyolo.readthedocs.io/en/latest/advanced_guides/index.html#how-to)
+   - [Plugins](https://mmyolo.readthedocs.io/en/latest/advanced_guides/index.html#plugins)
diff --git a/docs/en/user_guides/useful_tools.md b/docs/en/user_guides/useful_tools.md
index a52743bdc..a1ec5dfca 100644
--- a/docs/en/user_guides/useful_tools.md
+++ b/docs/en/user_guides/useful_tools.md
@@ -115,23 +115,23 @@ Description of the script's functions:
 The data required by each sub function is obtained through the data preparation of `main()`.
 Function 1: Generated by the sub function `show_bbox_num` to display the distribution of categories and bbox instances.
 
-<img src="https://user-images.githubusercontent.com/90811472/196891728-4c2f1ab3-01cb-445f-a6b8-39752387c40f.jpg"/>
+<img src="https://user-images.githubusercontent.com/90811472/200314770-4fb21626-72f2-4a4c-be5d-bf860ad830ec.jpg"/>
 
 Function 2: Generated by the sub function `show_bbox_wh` to display the width and height distribution of categories and bbox instances.
 
-<img src="https://user-images.githubusercontent.com/90811472/199019573-650b9652-eb14-4bc0-a5e8-650dfc578fc8.jpg"/>
+<img src="https://user-images.githubusercontent.com/90811472/200315007-96e8e795-992a-4c72-90fa-f6bc00b3f2c7.jpg"/>
 
 Function 3: Generated by the sub function `show_bbox_wh_ratio` to display the width to height ratio distribution of categories and bbox instances.
 
-<img src="https://user-images.githubusercontent.com/90811472/199019593-0f810a21-18d2-41ac-b4fa-baa8288bcb23.jpg"/>
+<img src="https://user-images.githubusercontent.com/90811472/200315044-4bdedcf6-087a-418e-8fe8-c2d3240ceba8.jpg"/>
 
 Function 3: Generated by the sub function `show_bbox_area` to display the distribution map of category and bbox instance area based on area rules.
 
-<img src="https://user-images.githubusercontent.com/90811472/199022991-5388db47-d0f3-4201-9eee-13c5fab6bca9.jpg"/>
+<img src="https://user-images.githubusercontent.com/90811472/200315075-71680fe2-db6f-4981-963e-a035c1281fc1.jpg"/>
 
-Print List: Generated by the sub function `show_class_list` and `show_data_lis`.
+Print List: Generated by the sub function `show_class_list` and `show_data_list`.
 
-<img src="https://user-images.githubusercontent.com/90811472/199090989-15109bbf-f035-477d-8566-e2a28de0935d.jpg"/>
+<img src="https://user-images.githubusercontent.com/90811472/200315152-9d6df91c-f2d2-4bba-9f95-b790fac37b62.jpg"/>
 
 ```shell
 python tools/analysis_tools/dataset_analysis.py ${CONFIG} \
@@ -145,44 +145,44 @@ python tools/analysis_tools/dataset_analysis.py ${CONFIG} \
 
 E,g：
 
-1.Use `config` file `configs/yolov5/yolov5_s-v61_syncbn_8xb16-300e_coco.py` analyze the dataset, By default,the data loadingt type is `train_dataset`, the area rule is `[0,32,96,1e5]`, generate a result graph containing all functions and save the graph to the current running directory `./dataset_analysis` folder:
+1.Use `config` file `configs/yolov5/voc/yolov5_s-v61_fast_1xb64-50e_voc.py` analyze the dataset, By default,the data loadingt type is `train_dataset`, the area rule is `[0,32,96,1e5]`, generate a result graph containing all functions and save the graph to the current running directory `./dataset_analysis` folder:
 
 ```shell
-python tools/analysis_tools/dataset_analysis.py configs/yolov5/yolov5_s-v61_syncbn_8xb16-300e_coco.py
+python tools/analysis_tools/dataset_analysis.py configs/yolov5/voc/yolov5_s-v61_fast_1xb64-50e_voc.py
 ```
 
-2.Use `config` file `configs/yolov5/yolov5_s-v61_syncbn_8xb16-300e_coco.py` analyze the dataset, change the data loading type from the default `train_dataset` to `val_dataset` through the `--val-dataset` setting:
+2.Use `config` file `configs/yolov5/voc/yolov5_s-v61_fast_1xb64-50e_voc.py` analyze the dataset, change the data loading type from the default `train_dataset` to `val_dataset` through the `--val-dataset` setting:
 
 ```shell
-python tools/analysis_tools/dataset_analysis.py configs/yolov5/yolov5_s-v61_syncbn_8xb16-300e_coco.py \
+python tools/analysis_tools/dataset_analysis.py configs/yolov5/voc/yolov5_s-v61_fast_1xb64-50e_voc.py \
                                                --val-dataset
 ```
 
-3.Use `config` file `configs/yolov5/yolov5_s-v61_syncbn_8xb16-300e_coco.py` analyze the dataset, change the display of all generated classes to specific classes. Take the display of `person` classes as an example:
+3.Use `config` file `configs/yolov5/voc/yolov5_s-v61_fast_1xb64-50e_voc.py` analyze the dataset, change the display of all generated classes to specific classes. Take the display of `person` classes as an example:
 
 ```shell
-python tools/analysis_tools/dataset_analysis.py configs/yolov5/yolov5_s-v61_syncbn_8xb16-300e_coco.py \
+python tools/analysis_tools/dataset_analysis.py configs/yolov5/voc/yolov5_s-v61_fast_1xb64-50e_voc.py \
                                                --class-name person
 ```
 
-4.Use `config` file `configs/yolov5/yolov5_s-v61_syncbn_8xb16-300e_coco.py` analyze the dataset, redefine the area rule through `--area-rule` . Take `30 70 125` as an example, the area rule becomes `[0,30,70,125,1e5]`：
+4.Use `config` file `configs/yolov5/voc/yolov5_s-v61_fast_1xb64-50e_voc.py` analyze the dataset, redefine the area rule through `--area-rule` . Take `30 70 125` as an example, the area rule becomes `[0,30,70,125,1e5]`：
 
 ```shell
-python tools/analysis_tools/dataset_analysis.py configs/yolov5/yolov5_s-v61_syncbn_8xb16-300e_coco.py \
-                                               --area-rule 30 70 120
+python tools/analysis_tools/dataset_analysis.py configs/yolov5/voc/yolov5_s-v61_fast_1xb64-50e_voc.py \
+                                               --area-rule 30 70 125
 ```
 
-5.Use `config` file `configs/yolov5/yolov5_s-v61_syncbn_8xb16-300e_coco.py` analyze the dataset, change the display of four function renderings to only display `Function 1` as an example:
+5.Use `config` file `configs/yolov5/voc/yolov5_s-v61_fast_1xb64-50e_voc.py` analyze the dataset, change the display of four function renderings to only display `Function 1` as an example:
 
 ```shell
-python tools/analysis_tools/dataset_analysis.py configs/yolov5/yolov5_s-v61_syncbn_8xb16-300e_coco.py \
+python tools/analysis_tools/dataset_analysis.py configs/yolov5/voc/yolov5_s-v61_fast_1xb64-50e_voc.py \
                                                --func show_bbox_num
 ```
 
-6.Use `config` file `configs/yolov5/yolov5_s-v61_syncbn_8xb16-300e_coco.py` analyze the dataset, modify the picture saving address to `work_ir/dataset_analysis`:
+6.Use `config` file `configs/yolov5/voc/yolov5_s-v61_fast_1xb64-50e_voc.py` analyze the dataset, modify the picture saving address to `work_ir/dataset_analysis`:
 
 ```shell
-python tools/analysis_tools/dataset_analysis.py configs/yolov5/yolov5_s-v61_syncbn_8xb16-300e_coco.py \
+python tools/analysis_tools/dataset_analysis.py configs/yolov5/voc/yolov5_s-v61_fast_1xb64-50e_voc.py \
                                                --output-dir work_dir/dataset_analysis
 ```
 
@@ -251,13 +251,14 @@ Instructions:
 ```shell
 python tools/misc/download_dataset.py --dataset-name coco2017
 python tools/misc/download_dataset.py --dataset-name voc2007
+python tools/misc/download_dataset.py --dataset-name voc2012
 python tools/misc/download_dataset.py --dataset-name lvis
 python tools/misc/download_dataset.py --dataset-name balloon [--save-dir ${SAVE_DIR}] [--unzip]
 ```
 
 ## Convert Model
 
-The three scripts under the `tools/` directory can help users convert the keys in the official pre-trained model of YOLO to the format of MMYOLO, and use MMYOLO to fine-tune the model.
+The six scripts under the `tools/model_converters` directory can help users convert the keys in the official pre-trained model of YOLO to the format of MMYOLO, and use MMYOLO to fine-tune the model.
 
 ### YOLOv5
 
diff --git a/docs/en/user_guides/yolov5_tutorial.md b/docs/en/user_guides/yolov5_tutorial.md
index 2d453ff36..492c145db 100644
--- a/docs/en/user_guides/yolov5_tutorial.md
+++ b/docs/en/user_guides/yolov5_tutorial.md
@@ -10,9 +10,9 @@ conda activate open-mmlab
 conda install pytorch torchvision -c pytorch
 # conda install pytorch torchvision cpuonly -c pytorch
 pip install -U openmim
-mim install "mmengine>=0.3.0"
+mim install "mmengine>=0.3.1"
 mim install "mmcv>=2.0.0rc1,<2.1.0"
-mim install "mmdet>=3.0.0rc2,<3.1.0"
+mim install "mmdet>=3.0.0rc3,<3.1.0"
 git clone https://github.com/open-mmlab/mmyolo.git
 cd mmyolo
 # Install albumentations
diff --git a/docs/zh_cn/advanced_guides/how_to.md b/docs/zh_cn/advanced_guides/how_to.md
index b0834020b..00bd82465 100644
--- a/docs/zh_cn/advanced_guides/how_to.md
+++ b/docs/zh_cn/advanced_guides/how_to.md
@@ -4,30 +4,12 @@
 
 ## 给主干网络增加插件
 
-MMYOLO 支持在 Backbone 的不同 Stage 后增加如 `none_local`、`dropblock` 等插件，用户可以直接通过修改 config 文件中 `backbone` 的 `plugins` 参数来实现对插件的管理。例如为 `YOLOv5` 增加 `GeneralizedAttention` 插件，其配置文件如下：
-
-```python
-_base_ = './yolov5_s-v61_syncbn_8xb16-300e_coco.py'
-
-model = dict(
-    backbone=dict(
-        plugins=[
-            dict(
-                cfg=dict(
-                    type='mmdet.GeneralizedAttention',
-                    spatial_range=-1,
-                    num_heads=8,
-                    attention_type='0011',
-                    kv_stride=2),
-                stages=(False, False, True, True)),
-        ], ))
-```
-
-`cfg` 参数表示插件的具体配置， `stages` 参数表示是否在 backbone 对应的 stage 后面增加插件，长度需要和 backbone 的 stage 数量相同。
+[更多的插件使用](plugins.md)
 
 ## 应用多个 Neck
 
-如果你想堆叠多个 Neck，可以直接在配置文件中的 Neck 参数，MMYOLO 支持以 `List` 形式拼接多个 Neck 配置，你需要保证上一个 Neck 的输出通道与下一个 Neck 的输入通道相匹配。如需要调整通道，可以插入 `mmdet.ChannelMapper` 模块用来对齐多个 Neck 之间的通道数量。具体配置如下：
+如果你想堆叠多个 Neck，可以直接在配置文件中的 Neck 参数，MMYOLO 支持以 `List` 形式拼接多个 Neck 配置，你需要保证上一个 Neck 的输出通道与下一个 Neck
+的输入通道相匹配。如需要调整通道，可以插入 `mmdet.ChannelMapper` 模块用来对齐多个 Neck 之间的通道数量。具体配置如下：
 
 ```python
 _base_ = './yolov5_s-v61_syncbn_8xb16-300e_coco.py'
@@ -42,7 +24,8 @@ model = dict(
             deepen_factor=deepen_factor,
             widen_factor=widen_factor,
             in_channels=[256, 512, 1024],
-            out_channels=[256, 512, 1024], # 因为 out_channels 由 widen_factor 控制，YOLOv5PAFPN 的 out_channels = out_channels * widen_factor
+            out_channels=[256, 512, 1024],
+            # 因为 out_channels 由 widen_factor 控制，YOLOv5PAFPN 的 out_channels = out_channels * widen_factor
             num_csp_blocks=3,
             norm_cfg=dict(type='BN', momentum=0.03, eps=0.001),
             act_cfg=dict(type='SiLU', inplace=True)),
@@ -58,14 +41,16 @@ model = dict(
             num_blocks=2,
             # disable zero_init_offset to follow official implementation
             zero_init_offset=False)
-    ]
-    bbox_head=dict(head_module=dict(in_channels=[512,512,512])) # 因为 out_channels 由 widen_factor 控制，YOLOv5HeadModuled 的 in_channels * widen_factor 才会等于最后一个 neck 的 out_channels
+    ],
+    bbox_head=dict(head_module=dict(in_channels=[512, 512, 512]))
+    # 因为 out_channels 由 widen_factor 控制，YOLOv5HeadModuled 的 in_channels * widen_factor 才会等于最后一个 neck 的 out_channels
 )
 ```
 
 ## 跨库使用主干网络
 
-OpenMMLab 2.0 体系中 MMYOLO、MMDetection、MMClassification、MMSegmentation 中的模型注册表都继承自 MMEngine 中的根注册表，允许这些 OpenMMLab 开源库直接使用彼此已经实现的模块。 因此用户可以在 MMYOLO 中使用来自 MMDetection、MMClassification 的主干网络，而无需重新实现。
+OpenMMLab 2.0 体系中 MMYOLO、MMDetection、MMClassification、MMSegmentation 中的模型注册表都继承自 MMEngine 中的根注册表，允许这些 OpenMMLab
+开源库直接使用彼此已经实现的模块。 因此用户可以在 MMYOLO 中使用来自 MMDetection、MMClassification 的主干网络，而无需重新实现。
 
 ```{note}
 1. 使用其他主干网络时，你需要保证主干网络的输出通道与 Neck 的输入通道相匹配。
@@ -235,7 +220,8 @@ OpenMMLab 2.0 体系中 MMYOLO、MMDetection、MMClassification、MMSegmentation
 
 ### 通过 MMClassification 使用 `timm` 中实现的主干网络
 
-由于 MMClassification 提供了 Py**T**orch **Im**age **M**odels (`timm`) 主干网络的封装，用户也可以通过 MMClassification 直接使用 `timm` 中的主干网络。假设想将 `EfficientNet-B1`作为 `YOLOv5` 的主干网络，则配置文件如下：
+由于 MMClassification 提供了 Py**T**orch **Im**age **M**odels (`timm`) 主干网络的封装，用户也可以通过 MMClassification 直接使用 `timm`
+中的主干网络。假设想将 `EfficientNet-B1`作为 `YOLOv5` 的主干网络，则配置文件如下：
 
 ```python
 _base_ = './yolov5_s-v61_syncbn_8xb16-300e_coco.py'
@@ -251,9 +237,9 @@ channels = [40, 112, 320]
 
 model = dict(
     backbone=dict(
-        _delete_=True, # 将 _base_ 中关于 backbone 的字段删除
-        type='mmcls.TIMMBackbone', # 使用 mmcls 中的 timm 主干网络
-        model_name='efficientnet_b1', # 使用 TIMM 中的 efficientnet_b1
+        _delete_=True,  # 将 _base_ 中关于 backbone 的字段删除
+        type='mmcls.TIMMBackbone',  # 使用 mmcls 中的 timm 主干网络
+        model_name='efficientnet_b1',  # 使用 TIMM 中的 efficientnet_b1
         features_only=True,
         pretrained=True,
         out_indices=(2, 3, 4)),
@@ -261,13 +247,13 @@ model = dict(
         type='YOLOv5PAFPN',
         deepen_factor=deepen_factor,
         widen_factor=widen_factor,
-        in_channels=channels, # 注意：EfficientNet-B1 输出的3个通道是 [40, 112, 320]，和原先的 yolov5-s neck 不匹配，需要更改
+        in_channels=channels,  # 注意：EfficientNet-B1 输出的3个通道是 [40, 112, 320]，和原先的 yolov5-s neck 不匹配，需要更改
         out_channels=channels),
     bbox_head=dict(
         type='YOLOv5Head',
         head_module=dict(
             type='YOLOv5HeadModule',
-            in_channels=channels, # head 部分输入通道也要做相应更改
+            in_channels=channels,  # head 部分输入通道也要做相应更改
             widen_factor=widen_factor))
 )
 ```
diff --git a/docs/zh_cn/advanced_guides/index.rst b/docs/zh_cn/advanced_guides/index.rst
index 10553f845..81810a88c 100644
--- a/docs/zh_cn/advanced_guides/index.rst
+++ b/docs/zh_cn/advanced_guides/index.rst
@@ -14,3 +14,12 @@ How to
    :maxdepth: 1
 
    how_to.md
+
+
+插件
+************************
+
+.. toctree::
+   :maxdepth: 1
+
+   plugins.md
diff --git a/docs/zh_cn/advanced_guides/plugins.md b/docs/zh_cn/advanced_guides/plugins.md
new file mode 100644
index 000000000..338d280f8
--- /dev/null
+++ b/docs/zh_cn/advanced_guides/plugins.md
@@ -0,0 +1,35 @@
+# 更多的插件使用
+
+MMYOLO 支持在 Backbone 的不同 Stage 后增加如 `none_local`、`dropblock` 等插件，用户可以直接通过修改 config 文件中 `backbone` 的 `plugins`
+参数来实现对插件的管理。例如为 `YOLOv5` 增加 `GeneralizedAttention` 插件，其配置文件如下：
+
+```python
+_base_ = './yolov5_s-v61_syncbn_8xb16-300e_coco.py'
+
+model = dict(
+    backbone=dict(
+        plugins=[
+            dict(
+                cfg=dict(
+                    type='GeneralizedAttention',
+                    spatial_range=-1,
+                    num_heads=8,
+                    attention_type='0011',
+                    kv_stride=2),
+                stages=(False, False, True, True))
+        ]))
+```
+
+`cfg` 参数表示插件的具体配置， `stages` 参数表示是否在 backbone 对应的 stage 后面增加插件，长度需要和 backbone 的 stage 数量相同。
+
+目前 `MMYOLO` 支持了如下插件：
+
+<details open>
+<summary><b>支持的插件</b></summary>
+
+- [x] [CBAM](https://github.com/open-mmlab/mmyolo/blob/dev/mmyolo/models/plugins/cbam.py#L84)
+- [x] [GeneralizedAttention](https://github.com/open-mmlab/mmcv/blob/2.x/mmcv/cnn/bricks/generalized_attention.py#L13)
+- [x] [NonLocal2d](https://github.com/open-mmlab/mmcv/blob/2.x/mmcv/cnn/bricks/non_local.py#L250)
+- [x] [ContextBlock](https://github.com/open-mmlab/mmcv/blob/2.x/mmcv/cnn/bricks/context_block.py#L18)
+
+</details>
diff --git a/docs/zh_cn/algorithm_descriptions/model_design.md b/docs/zh_cn/algorithm_descriptions/model_design.md
index 1dc893541..92b8f2c43 100644
--- a/docs/zh_cn/algorithm_descriptions/model_design.md
+++ b/docs/zh_cn/algorithm_descriptions/model_design.md
@@ -5,7 +5,13 @@
 下图为 RangeKing@GitHub 提供，非常感谢！
 
 <div align=center>
-<img src="https://user-images.githubusercontent.com/27466624/190986949-01414a91-baae-4228-8828-c59db58dcf36.jpg" alt="基类">
+<img src="https://user-images.githubusercontent.com/27466624/199999337-0544a4cb-3cbd-4f3e-be26-bcd9e74db7ff.jpg" alt="基类 P5">
+图 1：P5 模型结构
+</div>
+
+<div align=center>
+<img src="https://user-images.githubusercontent.com/27466624/200850066-0c434173-2d40-4c12-8de3-eda473ff172f.jpg" alt="基类 P6">
+图 2：P6 模型结构
 </div>
 
 YOLO 系列算法大部分采用了统一的算法搭建结构，典型的如 Darknet + PAFPN。为了让用户快速理解 YOLO 系列算法架构，我们特意设计了如上图中的 BaseBackbone + BaseYOLONeck 结构。
@@ -20,7 +26,10 @@ YOLO 系列算法大部分采用了统一的算法搭建结构，典型的如 Da
 
 ### BaseBackbone
 
-如上图所示，对于 P5 而言，BaseBackbone 包括 1 个 stem 层 + 4 个 stage 层的类似 ResNet 的基础结构，不同算法的主干网络继承 BaseBackbone，用户可以通过实现内部的 `build_xx` 方法，使用自定义的基础模块来构建每一层的内部结构。
+- 如图 1 所示，对于 P5 而言，BaseBackbone 为包含 1 个 stem 层 + 4 个 stage 层的类似 ResNet 的基础结构。
+- 如图 2 所示，对于 P6 而言，BaseBackbone 为包含 1 个 stem 层 + 5 个 stage 层的结构。
+
+不同算法的主干网络继承 BaseBackbone，用户可以通过实现内部的 `build_xx` 方法，使用自定义的基础模块来构建每一层的内部结构。
 
 ### BaseYOLONeck
 
diff --git a/docs/zh_cn/algorithm_descriptions/rtmdet_description.md b/docs/zh_cn/algorithm_descriptions/rtmdet_description.md
index 84f5a4a6e..164a83a1c 100644
--- a/docs/zh_cn/algorithm_descriptions/rtmdet_description.md
+++ b/docs/zh_cn/algorithm_descriptions/rtmdet_description.md
@@ -5,7 +5,7 @@
 高性能，低延时的单阶段目标检测器
 
 <div align=center>
-<img alt="RTMDet_structure_v1.0" src="https://user-images.githubusercontent.com/27466624/192954055-e044fe8a-53e6-4a08-8af2-f29c73e4b54b.jpg"/>
+<img alt="RTMDet_structure_v1.2" src="https://user-images.githubusercontent.com/27466624/200001002-008ac696-e74d-4da1-9c6d-07149e2ad752.jpg"/>
 </div>
 
 以上结构图由 RangeKing@github 绘制。
diff --git a/docs/zh_cn/algorithm_descriptions/yolov5_description.md b/docs/zh_cn/algorithm_descriptions/yolov5_description.md
index c1bdfa237..61db0a0d5 100644
--- a/docs/zh_cn/algorithm_descriptions/yolov5_description.md
+++ b/docs/zh_cn/algorithm_descriptions/yolov5_description.md
@@ -3,7 +3,13 @@
 ## 0 简介
 
 <div align=center >
-<img alt="YOLOv5_structure_v3.3" src="https://user-images.githubusercontent.com/27466624/192134657-a8d0286d-640c-445f-89bd-fda751094a4a.jpg"/>
+<img alt="YOLOv5-P5_structure_v3.4" src="https://user-images.githubusercontent.com/27466624/200000324-70ae078f-cea7-4189-8baa-440656797dad.jpg"/>
+图 1：YOLOv5-P5 模型结构
+</div>
+
+<div align=center >
+<img alt="YOLOv5-P6_structure_v1.0" src="https://user-images.githubusercontent.com/27466624/200845705-c9f3300f-9847-4933-b79d-0efcf0286e16.jpg"/>
+图 2：YOLOv5-P6 模型结构
 </div>
 
 以上结构图由 RangeKing@github 绘制。
@@ -14,7 +20,11 @@ YOLOv5 是一个面向实时工业应用而开源的目标检测算法，受到
 2. **算法训练速度极快**，在 300 epoch 情况下训练时长和大部分 one-stage 算法如 RetinaNet、ATSS 和 two-stage 算法如 Faster R-CNN 在 12 epoch 的训练时间接近
 3. 框架进行了**非常多的 corner case 优化**，功能和文档也比较丰富
 
-本文将从 YOLOv5 算法本身原理讲起，然后重点分析 MMYOLO 中的实现。关于 YOLOv5 的使用指南和速度等对比请阅读本文的后续内容。
+如图 1 和 2 所示，YOLOv5 的 P5 和 P6 版本主要差异在于网络结构和图片输入分辨率。其他区别，如 anchors 个数和 loss 权重可详见[配置文件](https://github.com/open-mmlab/mmyolo/blob/main/configs/yolov5/yolov5_s-p6-v62_syncbn_fast_8xb16-300e_coco.py)。本文将从 YOLOv5 算法本身原理讲起，然后重点分析 MMYOLO 中的实现。关于 YOLOv5 的使用指南和速度等对比请阅读本文的后续内容。
+
+```{hint}
+没有特殊说明情况下，本文默认描述的是 P5 模型。
+```
 
 希望本文能够成为你入门和掌握 YOLOv5 的核心文档。由于 YOLOv5 本身也在不断迭代更新，我们也会不断的更新本文档。请注意阅读最新版本。
 
@@ -245,21 +255,26 @@ train_pipeline = [
 
 YOLOv5 网络结构是标准的 `CSPDarknet` + `PAFPN` + `非解耦 Head`。
 
-YOLOv5 网络结构大小由 `deepen_factor` 和 `widen_factor` 两个参数决定。其中 `deepen_factor` 控制网络结构深度，即 `CSPLayer` 中 `DarknetBottleneck` 模块堆叠的数量；`widen_factor` 控制网络结构宽度，即模块输出特征图的通道数。以 YOLOv5-l 为例，其 `deepen_factor = widen_factor = 1.0` ，整体结构图如上所示。
+YOLOv5 网络结构大小由 `deepen_factor` 和 `widen_factor` 两个参数决定。其中 `deepen_factor` 控制网络结构深度，即 `CSPLayer` 中 `DarknetBottleneck` 模块堆叠的数量；`widen_factor` 控制网络结构宽度，即模块输出特征图的通道数。以 YOLOv5-l 为例，其 `deepen_factor = widen_factor = 1.0` 。P5 和 P6 的模型整体结构分别如图 1 和图 2 所示。
 
 图的上半部分为模型总览；下半部分为具体网络结构，其中的模块均标有序号，方便用户与 YOLOv5 官方仓库的配置文件对应；中间部分为各子模块的具体构成。
 
 如果想使用 netron 可视化网络结构图细节，可以直接在 netron 中将 MMDeploy 导出的 ONNX 文件格式文件打开。
 
+```{hint}
+1.2 小节涉及的特征维度（shape）都为 (B, C, H, W)。
+```
+
 #### 1.2.1 Backbone
 
-在 MMYOLO 中 `CSPDarknet` 继承自 `BaseBackbone`，整体结构和 `ResNet` 类似，共 5 层结构，包含 1 个 `Stem Layer` 和 4 个 `Stage Layer`：
+在 MMYOLO 中 `CSPDarknet` 继承自 `BaseBackbone`，整体结构和 `ResNet` 类似。P5 模型共 5 层结构，包含 1 个 `Stem Layer` 和 4 个 `Stage Layer`：
 
 - `Stem Layer` 是 1 个 6x6 kernel 的 `ConvModule`，相较于 v6.1 版本之前的 `Focus` 模块更加高效。
-- 前 3 个 `Stage Layer` 均由 1 个 `ConvModule` 和 1 个 `CSPLayer` 组成。如上图 Details 部分所示。
+- 除了最后一个 `Stage Layer`，其他均由 1 个 `ConvModule` 和 1 个 `CSPLayer` 组成。如上图 Details 部分所示。
   其中 `ConvModule` 为 3x3的 `Conv2d` + `BatchNorm` + `SiLU 激活函数`。`CSPLayer` 即 YOLOv5 官方仓库中的 C3 模块，由 3 个 `ConvModule` + n 个 `DarknetBottleneck`(带残差连接) 组成。
-- 第 4 个 `Stage Layer` 在最后增加了 `SPPF` 模块。`SPPF` 模块是将输入串行通过多个 5x5 大小的 `MaxPool2d` 层，与 `SPP`  模块效果相同，但速度更快。
-- P5 模型结构会在 `Stage Layer` 2-4 之后分别输出一个特征图进入 `Neck` 结构。以 640x640 输入图片为例，其输出特征为 (B,256,80,80)、 (B,512,40,40) 和 (B,1024,20,20)，对应的 stride 分别为 8/16/32。
+- 最后一个 `Stage Layer` 在最后增加了 `SPPF` 模块。`SPPF` 模块是将输入串行通过多个 5x5 大小的 `MaxPool2d` 层，与 `SPP` 模块效果相同，但速度更快。
+- P5 模型会在 `Stage Layer` 2-4 之后分别输出一个特征图进入 `Neck` 结构。以 640x640 输入图片为例，其输出特征为 (B,256,80,80)、(B,512,40,40) 和 (B,1024,20,20)，对应的 stride 分别为 8/16/32。
+- P6 模型会在 `Stage Layer` 2-5 之后分别输出一个特征图进入 `Neck` 结构。以 1280x1280 输入图片为例，其输出特征为 (B,256,160,160)、(B,512,80,80)、(B,768,40,40) 和 (B,1024,20,20)，对应的 stride 分别为 8/16/32/64。
 
 #### 1.2.2 Neck
 
@@ -267,14 +282,18 @@ YOLOv5 官方仓库的配置文件中并没有 Neck 部分，为方便用户与
 
 基于 `BaseYOLONeck` 结构，YOLOv5 `Neck` 也是遵循同一套构建流程，对于不存在的模块，我们采用 `nn.Identity` 代替。
 
-Neck 模块输出的特征图和 Backbone 完全一致即为 (B,256,80,80)、 (B,512,40,40) 和  (B,1024,20,20)。
+Neck 模块输出的特征图和 Backbone 完全一致。即 P5 模型为 (B,256,80,80)、 (B,512,40,40) 和 (B,1024,20,20)；P6 模型为 (B,256,160,160)、(B,512,80,80)、(B,768,40,40) 和 (B,1024,20,20)。
 
 #### 1.2.3 Head
 
 YOLOv5 Head 结构和 YOLOv3 完全一样，为 `非解耦 Head`。Head 模块只包括 3 个不共享权重的卷积，用于将输入特征图进行变换而已。
 
 前面的 PAFPN 依然是输出 3 个不同尺度的特征图，shape 为 (B,256,80,80)、 (B,512,40,40) 和 (B,1024,20,20)。
-由于 YOLOv5 是非解耦输出，即分类和 bbox 检测等都是在同一个卷积的不同通道中完成。以 COCO 80 类为例，在输入为 640x640 分辨率情况下，其 Head 模块输出的 shape 分别为 (B, 3x(4+1+80),80,80), (B, 3x(4+1+80),40,40) 和 (B, 3x(4+1+80),20,20)。其中 3 表示 3 个 anchor，4 表示 bbox 预测分支，1 表示 obj 预测分支，80 表示 COCO 数据集类别预测分支。
+由于 YOLOv5 是非解耦输出，即分类和 bbox 检测等都是在同一个卷积的不同通道中完成。以 COCO 80 类为例：
+
+- P5 模型在输入为 640x640 分辨率情况下，其 Head 模块输出的 shape 分别为 `(B, 3x(4+1+80),80,80)`, `(B, 3x(4+1+80),40,40)` 和 `(B, 3x(4+1+80),20,20)`。
+- P6 模型在输入为 1280x1280 分辨率情况下，其 Head 模块输出的 shape 分别为 `(B, 3x(4+1+80),160,160)`, `(B, 3x(4+1+80),80,80)`, `(B, 3x(4+1+80),40,40)` 和 `(B, 3x(4+1+80),20,20)`。
+  其中 3 表示 3 个 anchor，4 表示 bbox 预测分支，1 表示 obj 预测分支，80 表示 COCO 数据集类别预测分支。
 
 ### 1.3 正负样本匹配策略
 
diff --git a/docs/zh_cn/deploy/yolov5_deployment.md b/docs/zh_cn/deploy/yolov5_deployment.md
index a0800bfef..2cf652427 100644
--- a/docs/zh_cn/deploy/yolov5_deployment.md
+++ b/docs/zh_cn/deploy/yolov5_deployment.md
@@ -419,10 +419,10 @@ python3 ${MMDEPLOY_DIR}/tools/profiler.py \
 
 ```shell
 python3 ${MMDEPLOY_DIR}/tools/profiler.py \
-  configs/deploy/detection_tensorrt_static-640x640.py \
+  configs/deploy/detection_onnxruntime_static.py \
   configs/deploy/model/yolov5_s-static.py \
   data/coco/val2017 \
-  --model work_dir_trt/end2end.engine \
+  --model work_dir_ort/end2end.onnx \
   --device cpu
 ```
 
diff --git a/docs/zh_cn/get_started.md b/docs/zh_cn/get_started.md
index 59d92f8c5..db8ae0fff 100644
--- a/docs/zh_cn/get_started.md
+++ b/docs/zh_cn/get_started.md
@@ -6,7 +6,8 @@
 
 | MMYOLO version |   MMDetection version    |     MMEngine version     |      MMCV version       |
 | :------------: | :----------------------: | :----------------------: | :---------------------: |
-|      main      | mmdet>=3.0.0rc2, \<3.1.0 | mmengine>=0.3.0, \<1.0.0 | mmcv>=2.0.0rc0, \<2.1.0 |
+|      main      | mmdet>=3.0.0rc3, \<3.1.0 | mmengine>=0.3.1, \<1.0.0 | mmcv>=2.0.0rc0, \<2.1.0 |
+|     0.1.3      | mmdet>=3.0.0rc3, \<3.1.0 | mmengine>=0.3.1, \<1.0.0 | mmcv>=2.0.0rc0, \<2.1.0 |
 |     0.1.2      | mmdet>=3.0.0rc2, \<3.1.0 | mmengine>=0.3.0, \<1.0.0 | mmcv>=2.0.0rc0, \<2.1.0 |
 |     0.1.1      |     mmdet==3.0.0rc1      | mmengine>=0.1.0, \<0.2.0 | mmcv>=2.0.0rc0, \<2.1.0 |
 |     0.1.0      |     mmdet==3.0.0rc0      | mmengine>=0.1.0, \<0.2.0 | mmcv>=2.0.0rc0, \<2.1.0 |
@@ -50,9 +51,9 @@ conda install pytorch torchvision cpuonly -c pytorch
 
 ```shell
 pip install -U openmim
-mim install "mmengine>=0.3.0"
+mim install "mmengine>=0.3.1"
 mim install "mmcv>=2.0.0rc1,<2.1.0"
-mim install "mmdet>=3.0.0rc1,<3.1.0"
+mim install "mmdet>=3.0.0rc3,<3.1.0"
 ```
 
 **注意：**
@@ -158,7 +159,7 @@ inference_detector(model, 'demo/demo.jpg')
 例如，你可以通过以下命令安装 MMEngine：
 
 ```shell
-pip install "mmengine>=0.3.0"
+pip install "mmengine>=0.3.1"
 ```
 
 #### 不使用 MIM 安装 MMCV
diff --git a/docs/zh_cn/notes/changelog.md b/docs/zh_cn/notes/changelog.md
index a1ceb35e2..2aac408c5 100644
--- a/docs/zh_cn/notes/changelog.md
+++ b/docs/zh_cn/notes/changelog.md
@@ -1,5 +1,30 @@
 # 更新日志
 
+## v0.1.3（10/11/2022)
+
+### 新特性
+
+1. 支持 CBAM 插件并提供插件文档 (#246)
+2. 新增 YOLOv5 P6 模型结构图和相关说明 (#273)
+
+### Bug 修复
+
+1. 基于 mmengine 0.3.1 修复保存最好权重时训练失败问题
+2. 基于 mmdet 3.0.0rc3 修复 `add_dump_metric` 报错 (#253)
+3. 修复 backbone 不支持 `init_cfg` 问题 (#272)
+4. 基于 mmdet 3.0.0rc3 改变 typing 导入方式 (#261)
+
+### 完善
+
+1. `featmap_vis_demo` 支持文件夹和 url 输入 (#248)
+2. 部署 docker 文件完善 (#242)
+
+### 贡献者
+
+总共 10 位开发者参与了本次版本
+
+谢谢 @kitecats, @triple-Mu, @RangeKing, @PeterH0323, @Zheng-LinXiao, @tkhe, @weikai520, @zytx121, @wanghonglie, @hhaAndroid
+
 ## v0.1.2（3/11/2022)
 
 ### 亮点
diff --git a/docs/zh_cn/overview.md b/docs/zh_cn/overview.md
index 37bdab910..1515b038b 100644
--- a/docs/zh_cn/overview.md
+++ b/docs/zh_cn/overview.md
@@ -53,5 +53,6 @@ MMYOLO 文件结构和 MMDetection 完全一致。为了能够充分复用 MMDet
 
    - [数据流](https://mmyolo.readthedocs.io/zh_CN/latest/advanced_guides/index.html#id1)
    - [How to](https://mmyolo.readthedocs.io/zh_CN/latest/advanced_guides/index.html#how-to)
+   - [插件](https://mmyolo.readthedocs.io/zh_CN/latest/advanced_guides/index.html#id3)
 
 6. [解读文章和资源汇总](article.md)
diff --git a/docs/zh_cn/user_guides/useful_tools.md b/docs/zh_cn/user_guides/useful_tools.md
index 4e324d0f7..84cb52c19 100644
--- a/docs/zh_cn/user_guides/useful_tools.md
+++ b/docs/zh_cn/user_guides/useful_tools.md
@@ -108,30 +108,30 @@ python tools/analysis_tools/browse_dataset.py 'configs/yolov5/yolov5_s-v61_syncb
                                                --not-show
 ```
 
-### 可视化数据集分
+### 可视化数据集分析
 
 脚本 `tools/analysis_tools/dataset_analysis.py` 能够帮助用户得到四种功能的结果图，并将图片保存到当前运行目录下的 `dataset_analysis` 文件夹中。
 关于该脚本的功能的说明：
 通过 `main()` 的数据准备，得到每个子函数所需要的数据。
 功能一：显示类别和 bbox 实例个数的分布图，通过子函数 `show_bbox_num` 生成。
 
-<img src="https://user-images.githubusercontent.com/90811472/196891728-4c2f1ab3-01cb-445f-a6b8-39752387c40f.jpg"/>
+<img src="https://user-images.githubusercontent.com/90811472/200314770-4fb21626-72f2-4a4c-be5d-bf860ad830ec.jpg"/>
 
 功能二：显示类别和 bbox 实例宽、高的分布图，通过子函数 `show_bbox_wh` 生成。
 
-<img src="https://user-images.githubusercontent.com/90811472/199019573-650b9652-eb14-4bc0-a5e8-650dfc578fc8.jpg"/>
+<img src="https://user-images.githubusercontent.com/90811472/200315007-96e8e795-992a-4c72-90fa-f6bc00b3f2c7.jpg"/>
 
 功能三：显示类别和 bbox 实例宽/高比例的分布图，通过子函数 `show_bbox_wh_ratio` 生成。
 
-<img src="https://user-images.githubusercontent.com/90811472/199019593-0f810a21-18d2-41ac-b4fa-baa8288bcb23.jpg"/>
+<img src="https://user-images.githubusercontent.com/90811472/200315044-4bdedcf6-087a-418e-8fe8-c2d3240ceba8.jpg"/>
 
 功能四：基于面积规则下，显示类别和 bbox 实例面积的分布图，通过子函数 `show_bbox_area` 生成。
 
-<img src="https://user-images.githubusercontent.com/90811472/199022991-5388db47-d0f3-4201-9eee-13c5fab6bca9.jpg"/>
+<img src="https://user-images.githubusercontent.com/90811472/200315075-71680fe2-db6f-4981-963e-a035c1281fc1.jpg"/>
 
-打印列表显示，通过脚本中子函数 `show_class_list` 和 `show_data_lis` 生成。
+打印列表显示，通过脚本中子函数 `show_class_list` 和 `show_data_list` 生成。
 
-<img src="https://user-images.githubusercontent.com/90811472/199090989-15109bbf-f035-477d-8566-e2a28de0935d.jpg"/>
+<img src="https://user-images.githubusercontent.com/90811472/200315152-9d6df91c-f2d2-4bba-9f95-b790fac37b62.jpg"/>
 
 ```shell
 python tools/analysis_tools/dataset_analysis.py ${CONFIG} \
@@ -145,44 +145,44 @@ python tools/analysis_tools/dataset_analysis.py ${CONFIG} \
 
 例子：
 
-1.使用 `config` 文件 `configs/yolov5/yolov5_s-v61_syncbn_8xb16-300e_coco.py` 分析数据集，其中默认设置:数据加载类型为 `train_dataset` ，面积规则设置为 `[0,32,96,1e5]` ,生成包含所有类的结果图并将图片保存到当前运行目录下 `./dataset_analysis` 文件夹中：
+1.使用 `config` 文件 `configs/yolov5/voc/yolov5_s-v61_fast_1xb64-50e_voc.py` 分析数据集，其中默认设置:数据加载类型为 `train_dataset` ，面积规则设置为 `[0,32,96,1e5]` ,生成包含所有类的结果图并将图片保存到当前运行目录下 `./dataset_analysis` 文件夹中：
 
 ```shell
-python tools/analysis_tools/dataset_analysis.py configs/yolov5/yolov5_s-v61_syncbn_8xb16-300e_coco.py
+python tools/analysis_tools/dataset_analysis.py configs/yolov5/voc/yolov5_s-v61_fast_1xb64-50e_voc.py
 ```
 
-2.使用 `config` 文件 `configs/yolov5/yolov5_s-v61_syncbn_8xb16-300e_coco.py` 分析数据集，通过 `--val-dataset` 设置将数据加载类型由默认的 `train_dataset` 改为 `val_dataset`：
+2.使用 `config` 文件 `configs/yolov5/voc/yolov5_s-v61_fast_1xb64-50e_voc.py` 分析数据集，通过 `--val-dataset` 设置将数据加载类型由默认的 `train_dataset` 改为 `val_dataset`：
 
 ```shell
-python tools/analysis_tools/dataset_analysis.py configs/yolov5/yolov5_s-v61_syncbn_8xb16-300e_coco.py \
+python tools/analysis_tools/dataset_analysis.py configs/yolov5/voc/yolov5_s-v61_fast_1xb64-50e_voc.py \
                                                --val-dataset
 ```
 
-3.使用 `config` 文件 `configs/yolov5/yolov5_s-v61_syncbn_8xb16-300e_coco.py` 分析数据集，通过 `--class-name` 设置将生成所有类改为特定类显示，以显示 `person` 为例：
+3.使用 `config` 文件 `configs/yolov5/voc/yolov5_s-v61_fast_1xb64-50e_voc.py` 分析数据集，通过 `--class-name` 设置将生成所有类改为特定类显示，以显示 `person` 为例：
 
 ```shell
-python tools/analysis_tools/dataset_analysis.py configs/yolov5/yolov5_s-v61_syncbn_8xb16-300e_coco.py \
+python tools/analysis_tools/dataset_analysis.py configs/yolov5/voc/yolov5_s-v61_fast_1xb64-50e_voc.py \
                                                --class-name person
 ```
 
-4.使用 `config` 文件 `configs/yolov5/yolov5_s-v61_syncbn_8xb16-300e_coco.py` 分析数据集，通过 `--area-rule` 重新定义面积规则，以 `30 70 125` 为例,面积规则变为 `[0,30,70,125,1e5]`：
+4.使用 `config` 文件 `configs/yolov5/voc/yolov5_s-v61_fast_1xb64-50e_voc.py` 分析数据集，通过 `--area-rule` 重新定义面积规则，以 `30 70 125` 为例,面积规则变为 `[0,30,70,125,1e5]`：
 
 ```shell
-python tools/analysis_tools/dataset_analysis.py configs/yolov5/yolov5_s-v61_syncbn_8xb16-300e_coco.py \
+python tools/analysis_tools/dataset_analysis.py configs/yolov5/voc/yolov5_s-v61_fast_1xb64-50e_voc.py \
                                                --area-rule 30 70 125
 ```
 
-5.使用 `config` 文件 `configs/yolov5/yolov5_s-v61_syncbn_8xb16-300e_coco.py` 分析数据集，通过 `--func` 设置，将显示四个功能效果图改为只显示 `功能一` 为例：
+5.使用 `config` 文件 `configs/yolov5/voc/yolov5_s-v61_fast_1xb64-50e_voc.py` 分析数据集，通过 `--func` 设置，将显示四个功能效果图改为只显示 `功能一` 为例：
 
 ```shell
-python tools/analysis_tools/dataset_analysis.py configs/yolov5/yolov5_s-v61_syncbn_8xb16-300e_coco.py \
+python tools/analysis_tools/dataset_analysis.py configs/yolov5/voc/yolov5_s-v61_fast_1xb64-50e_voc.py \
                                                --func show_bbox_num
 ```
 
-6.使用 `config` 文件 `configs/yolov5/yolov5_s-v61_syncbn_8xb16-300e_coco.py` 分析数据集，通过 `--output-dir` 设置修改图片保存地址，以 `work_ir/dataset_analysis` 地址为例：
+6.使用 `config` 文件 `configs/yolov5/voc/yolov5_s-v61_fast_1xb64-50e_voc.py` 分析数据集，通过 `--output-dir` 设置修改图片保存地址，以 `work_ir/dataset_analysis` 地址为例：
 
 ```shell
-python tools/analysis_tools/dataset_analysis.py configs/yolov5/yolov5_s-v61_syncbn_8xb16-300e_coco.py \
+python tools/analysis_tools/dataset_analysis.py configs/yolov5/voc/yolov5_s-v61_fast_1xb64-50e_voc.py \
                                                --output-dir work_dir/dataset_analysis
 ```
 
@@ -252,13 +252,14 @@ python tools/dataset_converters/yolo2coco.py /path/to/the/root/dir/of/your_datas
 ```shell
 python tools/misc/download_dataset.py --dataset-name coco2017
 python tools/misc/download_dataset.py --dataset-name voc2007
+python tools/misc/download_dataset.py --dataset-name voc2012
 python tools/misc/download_dataset.py --dataset-name lvis
 python tools/misc/download_dataset.py --dataset-name balloon [--save-dir ${SAVE_DIR}] [--unzip]
 ```
 
 ## 模型转换
 
-文件夹 `tools/analysis_tools/` 下的三个脚本能够帮助用户将对应YOLO官方的预训练模型中的键转换成 `MMYOLO` 格式，并使用 `MMYOLO` 对模型进行微调。
+文件夹 `tools/model_converters/` 下的六个脚本能够帮助用户将对应YOLO官方的预训练模型中的键转换成 `MMYOLO` 格式，并使用 `MMYOLO` 对模型进行微调。
 
 ### YOLOv5
 
diff --git a/docs/zh_cn/user_guides/yolov5_tutorial.md b/docs/zh_cn/user_guides/yolov5_tutorial.md
index 8f300c804..2cd7ccf68 100644
--- a/docs/zh_cn/user_guides/yolov5_tutorial.md
+++ b/docs/zh_cn/user_guides/yolov5_tutorial.md
@@ -10,9 +10,9 @@ conda activate open-mmlab
 conda install pytorch torchvision -c pytorch
 # conda install pytorch torchvision cpuonly -c pytorch
 pip install -U openmim
-mim install "mmengine>=0.3.0"
+mim install "mmengine>=0.3.1"
 mim install "mmcv>=2.0.0rc1,<2.1.0"
-mim install "mmdet>=3.0.0rc2,<3.1.0"
+mim install "mmdet>=3.0.0rc3,<3.1.0"
 git clone https://github.com/open-mmlab/mmyolo.git
 cd mmyolo
 # Install albumentations
diff --git a/mmyolo/__init__.py b/mmyolo/__init__.py
index b3f75ce3c..67367292c 100644
--- a/mmyolo/__init__.py
+++ b/mmyolo/__init__.py
@@ -10,11 +10,11 @@
 mmcv_maximum_version = '2.1.0'
 mmcv_version = digit_version(mmcv.__version__)
 
-mmengine_minimum_version = '0.3.0'
+mmengine_minimum_version = '0.3.1'
 mmengine_maximum_version = '1.0.0'
 mmengine_version = digit_version(mmengine.__version__)
 
-mmdet_minimum_version = '3.0.0rc2'
+mmdet_minimum_version = '3.0.0rc3'
 mmdet_maximum_version = '3.1.0'
 mmdet_version = digit_version(mmdet.__version__)
 
diff --git a/mmyolo/models/__init__.py b/mmyolo/models/__init__.py
index b290017aa..51c37f043 100644
--- a/mmyolo/models/__init__.py
+++ b/mmyolo/models/__init__.py
@@ -6,4 +6,5 @@
 from .layers import *  # noqa: F401,F403
 from .losses import *  # noqa: F401,F403
 from .necks import *  # noqa: F401,F403
+from .plugins import *  # noqa: F401,F403
 from .task_modules import *  # noqa: F401,F403
diff --git a/mmyolo/models/backbones/csp_darknet.py b/mmyolo/models/backbones/csp_darknet.py
index 7aba54458..88d99c79d 100644
--- a/mmyolo/models/backbones/csp_darknet.py
+++ b/mmyolo/models/backbones/csp_darknet.py
@@ -146,12 +146,15 @@ def build_stage_layer(self, stage_idx: int, setting: list) -> list:
         return stage
 
     def init_weights(self):
-        """Initialize the parameters."""
-        for m in self.modules():
-            if isinstance(m, torch.nn.Conv2d):
-                # In order to be consistent with the source code,
-                # reset the Conv2d initialization parameters
-                m.reset_parameters()
+        if self.init_cfg is None:
+            """Initialize the parameters."""
+            for m in self.modules():
+                if isinstance(m, torch.nn.Conv2d):
+                    # In order to be consistent with the source code,
+                    # reset the Conv2d initialization parameters
+                    m.reset_parameters()
+        else:
+            super().init_weights()
 
 
 @MODELS.register_module()
diff --git a/mmyolo/models/backbones/cspnext.py b/mmyolo/models/backbones/cspnext.py
index 26dc67db9..adca9dd9d 100644
--- a/mmyolo/models/backbones/cspnext.py
+++ b/mmyolo/models/backbones/cspnext.py
@@ -5,7 +5,7 @@
 import torch.nn as nn
 from mmcv.cnn import ConvModule, DepthwiseSeparableConvModule
 from mmdet.models.backbones.csp_darknet import CSPLayer
-from mmdet.utils.typing import ConfigType, OptConfigType, OptMultiConfig
+from mmdet.utils import ConfigType, OptConfigType, OptMultiConfig
 
 from mmyolo.registry import MODELS
 from ..layers import SPPFBottleneck
diff --git a/mmyolo/models/backbones/efficient_rep.py b/mmyolo/models/backbones/efficient_rep.py
index b9ff74ea4..9ac1b81be 100644
--- a/mmyolo/models/backbones/efficient_rep.py
+++ b/mmyolo/models/backbones/efficient_rep.py
@@ -143,9 +143,12 @@ def build_stage_layer(self, stage_idx: int, setting: list) -> list:
         return stage
 
     def init_weights(self):
-        """Initialize the parameters."""
-        for m in self.modules():
-            if isinstance(m, torch.nn.Conv2d):
-                # In order to be consistent with the source code,
-                # reset the Conv2d initialization parameters
-                m.reset_parameters()
+        if self.init_cfg is None:
+            """Initialize the parameters."""
+            for m in self.modules():
+                if isinstance(m, torch.nn.Conv2d):
+                    # In order to be consistent with the source code,
+                    # reset the Conv2d initialization parameters
+                    m.reset_parameters()
+        else:
+            super().init_weights()
diff --git a/mmyolo/models/necks/base_yolo_neck.py b/mmyolo/models/necks/base_yolo_neck.py
index bf1bee73a..89d0ccf05 100644
--- a/mmyolo/models/necks/base_yolo_neck.py
+++ b/mmyolo/models/necks/base_yolo_neck.py
@@ -18,96 +18,97 @@ class BaseYOLONeck(BaseModule, metaclass=ABCMeta):
     .. code:: text
 
      P5 neck model structure diagram
-                                      +-----------+    +-------+
-                                      | bottom_up |--->|  out  |---> output2
-                                      |  layer1   |    | layer2|
-     stride=32                        +-----------+    +-------+
-     idx=2  +------+                        ^
-     -----> |reduce|                  +-----------+
-            |layer2|--------+-------->|    cat    |
-            +------+        |         +-----------+
-                            v               ^
+                        +--------+                     +-------+
+                        |top_down|----------+--------->|  out  |---> output0
+                        | layer1 |          |          | layer0|
+                        +--------+          |          +-------+
+     stride=8                ^              |
+     idx=0  +------+    +--------+          |
+     -----> |reduce|--->|   cat  |          |
+            |layer0|    +--------+          |
+            +------+         ^              v
                         +--------+    +-----------+
                         |upsample|    |downsample |
-                        | layer2 |    |  layer1   |
+                        | layer1 |    |  layer0   |
                         +--------+    +-----------+
-     stride=16               v              ^
-     idx=1  +------+    +--------+    +-----------+    +-------+
-     -----> |reduce|--->|   cat  |    | bottom_up |--->|  out  |---> output1
-            |layer1|    +--------+    |   layer0  |    | layer1|
-            +------+         v        +-----------+    +-------+
-                        +--------+          ^
+                             ^              |
+                        +--------+          v
                         |top_down|    +-----------+
                         | layer2 |--->|    cat    |
                         +--------+    +-----------+
-                             v              ^
+     stride=16               ^              v
+     idx=1  +------+    +--------+    +-----------+    +-------+
+     -----> |reduce|--->|   cat  |    | bottom_up |--->|  out  |---> output1
+            |layer1|    +--------+    |   layer0  |    | layer1|
+            +------+         ^        +-----------+    +-------+
+                             |              v
                         +--------+    +-----------+
                         |upsample|    |downsample |
-                        | layer1 |    |  layer0   |
-                        +--------+    +-----------+
-     stride=8                v              ^
+                        | layer2 |    |  layer1   |
+     stride=32          +--------+    +-----------+
+     idx=2  +------+         ^              v
+     -----> |reduce|         |        +-----------+
+            |layer2|---------+------->|    cat    |
+            +------+                  +-----------+
+                                            v
+                                      +-----------+    +-------+
+                                      | bottom_up |--->|  out  |---> output2
+                                      |  layer1   |    | layer2|
+                                      +-----------+    +-------+
+    ------------------------------------------------------------------------
+     P6 neck model structure diagram
+                        +--------+                     +-------+
+                        |top_down|----------+--------->|  out  |---> output0
+                        | layer1 |          |          | layer0|
+                        +--------+          |          +-------+
+     stride=8                ^              |
      idx=0  +------+    +--------+          |
      -----> |reduce|--->|   cat  |          |
             |layer0|    +--------+          |
-            +------+         v              |
-                        +--------+          |          +-------+
-                        |top_down|----------+--------->|  out  |---> output0
-                        | layer1 |                     | layer0|
-                        +--------+                     +-------+
-
-
-     P6 neck model structure diagram
-                                      +-----------+    +-------+
-                                      | bottom_up |--->|  out  |---> output3
-                                      |  layer2   |    | layer3|
-     stride=64                        +-----------+    +-------+
-     idx=3  +------+                        ^
-     -----> |reduce|                  +-----------+
-            |layer3|---------+------->|    cat    |
-            +------+         |        +-----------+
-                             v              ^
+            +------+         ^              v
                         +--------+    +-----------+
                         |upsample|    |downsample |
-                        | layer3 |    |  layer2   |
+                        | layer1 |    |  layer0   |
                         +--------+    +-----------+
-     stride=32               v              ^
-     idx=2  +------+    +--------+    +-----------+    +-------+
-     -----> |reduce|--->|   cat  |    | bottom_up |--->|  out  |---> output2
-            |layer2|    +--------+    |   layer1  |    | layer2|
-            +------+         v        +-----------+    +-------+
-                        +--------+          ^
+                             ^              |
+                        +--------+          v
                         |top_down|    +-----------+
-                        | layer3 |--->|    cat    |
+                        | layer2 |--->|    cat    |
                         +--------+    +-----------+
-                             v              ^
+     stride=16               ^              v
+     idx=1  +------+    +--------+    +-----------+    +-------+
+     -----> |reduce|--->|   cat  |    | bottom_up |--->|  out  |---> output1
+            |layer1|    +--------+    |   layer0  |    | layer1|
+            +------+         ^        +-----------+    +-------+
+                             |              v
                         +--------+    +-----------+
                         |upsample|    |downsample |
                         | layer2 |    |  layer1   |
                         +--------+    +-----------+
-     stride=16               v              ^
-     idx=1  +------+    +--------+    +-----------+    +-------+
-     -----> |reduce|--->|   cat  |    | bottom_up |--->|  out  |---> output1
-            |layer1|    +--------+    |   layer0  |    | layer1|
-            +------+         v        +-----------+    +-------+
-                        +--------+          ^
+                             ^              |
+                        +--------+          v
                         |top_down|    +-----------+
-                        | layer2 |--->|    cat    |
+                        | layer3 |--->|    cat    |
                         +--------+    +-----------+
-                             v              ^
+     stride=32               ^              v
+     idx=2  +------+    +--------+    +-----------+    +-------+
+     -----> |reduce|--->|   cat  |    | bottom_up |--->|  out  |---> output2
+            |layer2|    +--------+    |   layer1  |    | layer2|
+            +------+         ^        +-----------+    +-------+
+                             |              v
                         +--------+    +-----------+
                         |upsample|    |downsample |
-                        | layer1 |    |  layer0   |
+                        | layer3 |    |  layer2   |
                         +--------+    +-----------+
-     stride=8                v              ^
-     idx=0  +------+    +--------+          |
-     -----> |reduce|--->|   cat  |          |
-            |layer0|    +--------+          |
-            +------+         v              |
-                        +--------+          |          +-------+
-                        |top_down|----------+--------->|  out  |---> output0
-                        | layer1 |                     | layer0|
-                        +--------+                     +-------+
-
+     stride=64               ^              v
+     idx=3  +------+         |        +-----------+
+     -----> |reduce|---------+------->|    cat    |
+            |layer3|                  +-----------+
+            +------+                        v
+                                      +-----------+    +-------+
+                                      | bottom_up |--->|  out  |---> output3
+                                      |  layer2   |    | layer3|
+                                      +-----------+    +-------+
     Args:
         in_channels (List[int]): Number of input channels per scale.
         out_channels (int): Number of output channels (used at each scale)
diff --git a/mmyolo/models/plugins/__init__.py b/mmyolo/models/plugins/__init__.py
new file mode 100644
index 000000000..497233ac2
--- /dev/null
+++ b/mmyolo/models/plugins/__init__.py
@@ -0,0 +1,4 @@
+# Copyright (c) OpenMMLab. All rights reserved.
+from .cbam import CBAM
+
+__all__ = ['CBAM']
diff --git a/mmyolo/models/plugins/cbam.py b/mmyolo/models/plugins/cbam.py
new file mode 100644
index 000000000..0741fe9f2
--- /dev/null
+++ b/mmyolo/models/plugins/cbam.py
@@ -0,0 +1,116 @@
+# Copyright (c) OpenMMLab. All rights reserved.
+
+import torch
+import torch.nn as nn
+from mmcv.cnn import ConvModule
+from mmdet.utils import OptMultiConfig
+from mmengine.model import BaseModule
+
+from mmyolo.registry import MODELS
+
+
+class ChannelAttention(BaseModule):
+    """ChannelAttention.
+
+    Args:
+        channels (int): The input (and output) channels of the
+            ChannelAttention.
+        reduce_ratio (int): Squeeze ratio in ChannelAttention, the intermediate
+            channel will be ``int(channels/ratio)``. Defaults to 16.
+        act_cfg (dict): Config dict for activation layer
+            Defaults to dict(type='ReLU').
+    """
+
+    def __init__(self,
+                 channels: int,
+                 reduce_ratio: int = 16,
+                 act_cfg: dict = dict(type='ReLU')):
+        super().__init__()
+
+        self.avg_pool = nn.AdaptiveAvgPool2d(1)
+        self.max_pool = nn.AdaptiveMaxPool2d(1)
+
+        self.fc = nn.Sequential(
+            ConvModule(
+                in_channels=channels,
+                out_channels=int(channels / reduce_ratio),
+                kernel_size=1,
+                stride=1,
+                conv_cfg=None,
+                act_cfg=act_cfg),
+            ConvModule(
+                in_channels=int(channels / reduce_ratio),
+                out_channels=channels,
+                kernel_size=1,
+                stride=1,
+                conv_cfg=None,
+                act_cfg=None))
+        self.sigmoid = nn.Sigmoid()
+
+    def forward(self, x: torch.Tensor) -> torch.Tensor:
+        avgpool_out = self.fc(self.avg_pool(x))
+        maxpool_out = self.fc(self.max_pool(x))
+        out = self.sigmoid(avgpool_out + maxpool_out)
+        return out
+
+
+class SpatialAttention(BaseModule):
+    """SpatialAttention
+    Args:
+         kernel_size (int): The size of the convolution kernel in
+            SpatialAttention. Defaults to 7.
+    """
+
+    def __init__(self, kernel_size: int = 7):
+        super().__init__()
+
+        self.conv = ConvModule(
+            in_channels=2,
+            out_channels=1,
+            kernel_size=kernel_size,
+            stride=1,
+            padding=kernel_size // 2,
+            conv_cfg=None,
+            act_cfg=dict(type='Sigmoid'))
+
+    def forward(self, x: torch.Tensor) -> torch.Tensor:
+        avg_out = torch.mean(x, dim=1, keepdim=True)
+        max_out, _ = torch.max(x, dim=1, keepdim=True)
+        out = torch.cat([avg_out, max_out], dim=1)
+        out = self.conv(out)
+        return out
+
+
+@MODELS.register_module()
+class CBAM(BaseModule):
+    """Convolutional Block Attention Module. arxiv link:
+    https://arxiv.org/abs/1807.06521v2.
+
+    Args:
+        in_channels (int): The input (and output) channels of the CBAM.
+        reduce_ratio (int): Squeeze ratio in ChannelAttention, the intermediate
+            channel will be ``int(channels/ratio)``. Defaults to 16.
+        kernel_size (int): The size of the convolution kernel in
+            SpatialAttention. Defaults to 7.
+        act_cfg (dict): Config dict for activation layer in ChannelAttention
+            Defaults to dict(type='ReLU').
+        init_cfg (dict or list[dict], optional): Initialization config dict.
+            Defaults to None.
+    """
+
+    def __init__(self,
+                 in_channels: int,
+                 reduce_ratio: int = 16,
+                 kernel_size: int = 7,
+                 act_cfg: dict = dict(type='ReLU'),
+                 init_cfg: OptMultiConfig = None):
+        super().__init__(init_cfg)
+        self.channel_attention = ChannelAttention(
+            channels=in_channels, reduce_ratio=reduce_ratio, act_cfg=act_cfg)
+
+        self.spatial_attention = SpatialAttention(kernel_size)
+
+    def forward(self, x: torch.Tensor) -> torch.Tensor:
+        out = self.channel_attention(x) * x
+        out = self.spatial_attention(out) * out
+        return out
diff --git a/mmyolo/utils/misc.py b/mmyolo/utils/misc.py
index 1ba9495c1..dbc2a62e7 100644
--- a/mmyolo/utils/misc.py
+++ b/mmyolo/utils/misc.py
@@ -1,6 +1,16 @@
 # Copyright (c) OpenMMLab. All rights reserved.
+import os
+import urllib
+
+import numpy as np
+import torch
+from mmengine.utils import scandir
+
 from mmyolo.models import RepVGGBlock
 
+IMG_EXTENSIONS = ('.jpg', '.jpeg', '.png', '.ppm', '.bmp', '.pgm', '.tif',
+                  '.tiff', '.webp')
+
 
 def switch_to_deploy(model):
     """Model switch to deploy status."""
@@ -9,3 +19,74 @@ def switch_to_deploy(model):
             layer.switch_to_deploy()
 
     print('Switch model to deploy modality.')
+
+
+def auto_arrange_images(image_list: list, image_column: int = 2) -> np.ndarray:
+    """Auto arrange image to image_column x N row.
+
+    Args:
+        image_list (list): cv2 image list.
+        image_column (int): Arrange to N column. Default: 2.
+    Return:
+        (np.ndarray): image_column x N row merge image
+    """
+    img_count = len(image_list)
+    if img_count <= image_column:
+        # no need to arrange
+        image_show = np.concatenate(image_list, axis=1)
+    else:
+        # arrange image according to image_column
+        image_row = round(img_count / image_column)
+        fill_img_list = [np.ones(image_list[0].shape, dtype=np.uint8) * 255
+                         ] * (
+                             image_row * image_column - img_count)
+        image_list.extend(fill_img_list)
+        merge_imgs_col = []
+        for i in range(image_row):
+            start_col = image_column * i
+            end_col = image_column * (i + 1)
+            merge_col = np.hstack(image_list[start_col:end_col])
+            merge_imgs_col.append(merge_col)
+
+        # merge to one image
+        image_show = np.vstack(merge_imgs_col)
+
+    return image_show
+
+
+def get_file_list(source_root: str) -> [list, dict]:
+    """Get file list.
+
+    Args:
+        source_root (str): image or video source path
+
+    Return:
+        source_file_path_list (list): A list for all source file.
+        source_type (dict): Source type: file or url or dir.
+    """
+    is_dir = os.path.isdir(source_root)
+    is_url = source_root.startswith(('http:/', 'https:/'))
+    is_file = os.path.splitext(source_root)[-1].lower() in IMG_EXTENSIONS
+
+    source_file_path_list = []
+    if is_dir:
+        # when input source is dir
+        for file in scandir(source_root, IMG_EXTENSIONS, recursive=True):
+            source_file_path_list.append(os.path.join(source_root, file))
+    elif is_url:
+        # when input source is url
+        filename = os.path.basename(
+            urllib.parse.unquote(source_root).split('?')[0])
+        file_save_path = os.path.join(os.getcwd(), filename)
+        print(f'Downloading source file to {file_save_path}')
+        torch.hub.download_url_to_file(source_root, file_save_path)
+        source_file_path_list = [file_save_path]
+    elif is_file:
+        # when input source is single image
+        source_file_path_list = [source_root]
+    else:
+        print('Cannot find image file.')
+
+    source_type = dict(is_dir=is_dir, is_url=is_url, is_file=is_file)
+
+    return source_file_path_list, source_type
diff --git a/mmyolo/version.py b/mmyolo/version.py
index dd6b2919d..3d43f2dfe 100644
--- a/mmyolo/version.py
+++ b/mmyolo/version.py
@@ -1,6 +1,6 @@
 # Copyright (c) OpenMMLab. All rights reserved.
 
-__version__ = '0.1.2'
+__version__ = '0.1.3'
 
 from typing import Tuple
 
diff --git a/requirements/mminstall.txt b/requirements/mminstall.txt
index e28911afc..4b8c41aac 100644
--- a/requirements/mminstall.txt
+++ b/requirements/mminstall.txt
@@ -1,3 +1,3 @@
 mmcv>=2.0.0rc1,<2.1.0
-mmdet>=3.0.0rc2
-mmengine>=0.3.0
+mmdet>=3.0.0rc3
+mmengine>=0.3.1
diff --git a/requirements/readthedocs.txt b/requirements/readthedocs.txt
index 774625e84..563d93f9d 100644
--- a/requirements/readthedocs.txt
+++ b/requirements/readthedocs.txt
@@ -1,5 +1,5 @@
 mmcv>=2.0.0rc1,<2.1.0
-mmdet>=3.0.0rc2
-mmengine>=0.3.0
+mmdet>=3.0.0rc3
+mmengine>=0.3.1
 torch
 torchvision
diff --git a/setup.cfg b/setup.cfg
index d44cba0e9..c62d88cce 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -3,7 +3,7 @@ line_length = 79
 multi_line_output = 0
 extra_standard_library = setuptools
 known_first_party = mmyolo
-known_third_party = PIL,asynctest,cityscapesscripts,cv2,gather_models,matplotlib,mmcv,numpy,onnx,onnxruntime,pycocotools,pytest,parameterized,pytorch_sphinx_theme,requests,scipy,seaborn,six,terminaltables,torch,ts,yaml,mmengine,mmdet
+known_third_party = PIL,asynctest,cityscapesscripts,cv2,gather_models,matplotlib,mmcv,numpy,onnx,onnxruntime,pycocotools,pytest,parameterized,pytorch_sphinx_theme,requests,scipy,seaborn,six,terminaltables,torch,ts,yaml,mmengine,mmdet,mmdeploy
 no_lines_before = STDLIB,LOCALFOLDER
 default_section = THIRDPARTY
 
diff --git a/tools/analysis_tools/dataset_analysis.py b/tools/analysis_tools/dataset_analysis.py
index 3cb7ccd6a..ae0bd1144 100644
--- a/tools/analysis_tools/dataset_analysis.py
+++ b/tools/analysis_tools/dataset_analysis.py
@@ -7,6 +7,7 @@
 import matplotlib.pyplot as plt
 import numpy as np
 from mmengine.config import Config
+from mmengine.dataset.dataset_wrapper import ConcatDataset
 from mmengine.utils import ProgressBar
 from prettytable import PrettyTable
 
@@ -61,12 +62,12 @@ def show_bbox_num(cfg, args, fig_set, class_name, class_num):
     print('\n\nDrawing bbox_num figure:')
     # Draw designs
     fig = plt.figure(
-        figsize=(fig_set['figsize'][0], fig_set['figsize'][1]), dpi=600)
+        figsize=(fig_set['figsize'][0], fig_set['figsize'][1]), dpi=300)
     plt.bar(class_name, class_num, align='center')
 
     # Draw titles, labels and so on
     for x, y in enumerate(class_num):
-        plt.text(x, y, '%s' % y, ha='center', fontsize=fig_set['fontsize'])
+        plt.text(x, y, '%s' % y, ha='center', fontsize=fig_set['fontsize'] + 3)
     plt.xticks(rotation=fig_set['xticks_angle'])
     plt.xlabel('Category Name')
     plt.ylabel('Num of instances')
@@ -77,7 +78,10 @@ def show_bbox_num(cfg, args, fig_set, class_name, class_num):
     if not os.path.exists(out_dir):
         os.makedirs(out_dir)
     out_name = fig_set['out_name']
-    fig.savefig(f'{out_dir}/{out_name}_bbox_num.jpg')  # Save Image
+    fig.savefig(
+        f'{out_dir}/{out_name}_bbox_num.jpg',
+        bbox_inches='tight',
+        pad_inches=0.1)  # Save Image
     plt.close()
     print(f'End and save in {out_dir}/{out_name}_bbox_num.jpg')
 
@@ -88,7 +92,7 @@ def show_bbox_wh(args, fig_set, class_bbox_w, class_bbox_h, class_name):
     print('\n\nDrawing bbox_wh figure:')
     # Draw designs
     fig, ax = plt.subplots(
-        figsize=(fig_set['figsize'][0], fig_set['figsize'][1]), dpi=600)
+        figsize=(fig_set['figsize'][0], fig_set['figsize'][1]), dpi=300)
 
     # Set the position of the map and label on the x-axis
     positions_w = list(range(0, 12 * len(class_name), 12))
@@ -165,7 +169,10 @@ def show_bbox_wh(args, fig_set, class_bbox_w, class_bbox_h, class_name):
     if not os.path.exists(out_dir):
         os.makedirs(out_dir)
     out_name = fig_set['out_name']
-    fig.savefig(f'{out_dir}/{out_name}_bbox_wh.jpg')  # Save Image
+    fig.savefig(
+        f'{out_dir}/{out_name}_bbox_wh.jpg',
+        bbox_inches='tight',
+        pad_inches=0.1)  # Save Image
     plt.close()
     print(f'End and save in {out_dir}/{out_name}_bbox_wh.jpg')
 
@@ -176,7 +183,7 @@ def show_bbox_wh_ratio(args, fig_set, class_name, class_bbox_ratio):
     print('\n\nDrawing bbox_wh_ratio figure:')
     # Draw designs
     fig, ax = plt.subplots(
-        figsize=(fig_set['figsize'][0], fig_set['figsize'][1]), dpi=600)
+        figsize=(fig_set['figsize'][0], fig_set['figsize'][1]), dpi=300)
 
     # Set the position of the map and label on the x-axis
     positions = list(range(0, 6 * len(class_name), 6))
@@ -222,7 +229,10 @@ def show_bbox_wh_ratio(args, fig_set, class_name, class_bbox_ratio):
     if not os.path.exists(out_dir):
         os.makedirs(out_dir)
     out_name = fig_set['out_name']
-    fig.savefig(f'{out_dir}/{out_name}_bbox_ratio.jpg')  # Save Image
+    fig.savefig(
+        f'{out_dir}/{out_name}_bbox_ratio.jpg',
+        bbox_inches='tight',
+        pad_inches=0.1)  # Save Image
     plt.close()
     print(f'End and save in {out_dir}/{out_name}_bbox_ratio.jpg')
 
@@ -240,7 +250,7 @@ def show_bbox_area(args, fig_set, area_rule, class_name, bbox_area_num):
 
     # Draw designs
     fig = plt.figure(
-        figsize=(fig_set['figsize'][0], fig_set['figsize'][1]), dpi=600)
+        figsize=(fig_set['figsize'][0], fig_set['figsize'][1]), dpi=300)
     for i in range(len(area_rule) - 1):
         area_num = [bbox_area_num[idx][i] for idx in range(len(class_name))]
         plt.bar(
@@ -251,7 +261,11 @@ def show_bbox_area(args, fig_set, area_rule, class_name, bbox_area_num):
             color=colors[i])
         for idx, (x, y) in enumerate(zip(positions.tolist(), area_num)):
             plt.text(
-                x + width * i, y, y, ha='center', fontsize=fig_set['fontsize'])
+                x + width * i,
+                y,
+                y,
+                ha='center',
+                fontsize=fig_set['fontsize'] - 1)
 
     # Draw titles, labels and so on
     plt.xticks(rotation=fig_set['xticks_angle'])
@@ -276,7 +290,10 @@ def show_bbox_area(args, fig_set, area_rule, class_name, bbox_area_num):
     if not os.path.exists(out_dir):
         os.makedirs(out_dir)
     out_name = fig_set['out_name']
-    fig.savefig(f'{out_dir}/{out_name}_bbox_area.jpg')  # Save Image
+    fig.savefig(
+        f'{out_dir}/{out_name}_bbox_area.jpg',
+        bbox_inches='tight',
+        pad_inches=0.1)  # Save Image
     plt.close()
     print(f'End and save in {out_dir}/{out_name}_bbox_area.jpg')
 
@@ -331,19 +348,19 @@ def show_data_list(args, area_rule):
     print(data_info)
 
 
-def show_dataset_classes(dataset_classes):
+def show_data_classes(data_classes):
     """When printing an error, all class names of the dataset."""
     print('\n\nThe name of the class contained in the dataset:')
     data_classes_info = PrettyTable()
     data_classes_info.title = 'Information of dataset class'
     # List Print Settings
     # If the quantity is too large, 25 rows will be displayed in each column
-    if len(dataset_classes) < 25:
-        data_classes_info.add_column('Class name', dataset_classes)
-    elif len(dataset_classes) % 25 != 0 and len(dataset_classes) > 25:
-        col_num = int(len(dataset_classes) / 25) + 1
-        data_name_list = list(dataset_classes)
-        for i in range(0, (col_num * 25) - len(dataset_classes)):
+    if len(data_classes) < 25:
+        data_classes_info.add_column('Class name', data_classes)
+    elif len(data_classes) % 25 != 0 and len(data_classes) > 25:
+        col_num = int(len(data_classes) / 25) + 1
+        data_name_list = list(data_classes)
+        for i in range(0, (col_num * 25) - len(data_classes)):
             data_name_list.append('')
         for i in range(0, len(data_name_list), 25):
             data_classes_info.add_column('Class name',
@@ -367,12 +384,21 @@ def main():
     elif args.val_dataset is True:
         dataset = DATASETS.build(cfg.val_dataloader.dataset)
 
-    data_list = dataset.load_data_list()
+    # Determine whether the dataset is ConcatDataset
+    if isinstance(dataset, ConcatDataset):
+        datasets = dataset.datasets
+        data_list = []
+        for idx in range(len(datasets)):
+            datasets_list = datasets[idx].load_data_list()
+            data_list += datasets_list
+    else:
+        data_list = dataset.load_data_list()
+
     # 2.Prepare data
     # Drawing settings
     fig_all_set = {
-        'figsize': [45, 18],
-        'fontsize': 4,
+        'figsize': [35, 18],
+        'fontsize': int(10 - 0.08 * len(dataset.metainfo['CLASSES'])),
         'xticks_angle': 70,
         'out_name': cfg.dataset_type
     }
@@ -393,8 +419,8 @@ def main():
         classes_idx = [dataset.metainfo['CLASSES'].index(args.class_name)]
         fig_set = fig_one_set
     else:
-        dataset_classes = dataset.metainfo['CLASSES']
-        show_dataset_classes(dataset_classes)
+        data_classes = dataset.metainfo['CLASSES']
+        show_data_classes(data_classes)
         raise RuntimeError(f'Expected args.class_name to be one of the list,'
                            f'but got "{args.class_name}"')
 
diff --git a/tools/misc/download_dataset.py b/tools/misc/download_dataset.py
index 44853762e..5d4776b09 100644
--- a/tools/misc/download_dataset.py
+++ b/tools/misc/download_dataset.py
@@ -85,6 +85,9 @@ def main():
             'http://host.robots.ox.ac.uk/pascal/VOC/voc2007/VOCtest_06-Nov-2007.tar',  # noqa
             'http://host.robots.ox.ac.uk/pascal/VOC/voc2007/VOCdevkit_08-Jun-2007.tar',  # noqa
         ],
+        voc2012=[
+            'http://host.robots.ox.ac.uk/pascal/VOC/voc2012/VOCtrainval_11-May-2012.tar',  # noqa
+        ],
         balloon=[
             # src link: https://github.com/matterport/Mask_RCNN/releases/download/v2.1/balloon_dataset.zip # noqa
             'https://download.openmmlab.com/mmyolo/data/balloon_dataset.zip'


Test patch:
diff --git a/.circleci/test.yml b/.circleci/test.yml
index ee909b980..5f5b68f63 100644
--- a/.circleci/test.yml
+++ b/.circleci/test.yml
@@ -66,7 +66,7 @@ jobs:
           name: Install mmyolo dependencies
           command: |
             pip install -U openmim
-            mim install 'mmengine >= 0.3.0'
+            mim install 'mmengine >= 0.3.1'
             mim install 'mmcv >= 2.0.0rc1'
             pip install git+https://github.com/open-mmlab/mmdetection.git@dev-3.x
             pip install -r requirements/albu.txt
@@ -124,7 +124,7 @@ jobs:
           name: Install mmyolo dependencies
           command: |
             docker exec mmyolo pip install -U openmim
-            docker exec mmyolo mim install 'mmengine >= 0.3.0'
+            docker exec mmyolo mim install 'mmengine >= 0.3.1'
             docker exec mmyolo mim install 'mmcv >= 2.0.0rc1'
             docker exec mmyolo pip install -e /mmdetection
             docker exec mmyolo pip install -r requirements/albu.txt
diff --git a/tests/test_models/test_plugins/__init__.py b/tests/test_models/test_plugins/__init__.py
new file mode 100644
index 000000000..ef101fec6
--- /dev/null
+++ b/tests/test_models/test_plugins/__init__.py
@@ -0,0 +1,1 @@
+# Copyright (c) OpenMMLab. All rights reserved.
diff --git a/tests/test_models/test_plugins/test_cbam.py b/tests/test_models/test_plugins/test_cbam.py
new file mode 100644
index 000000000..4af547c05
--- /dev/null
+++ b/tests/test_models/test_plugins/test_cbam.py
@@ -0,0 +1,31 @@
+# Copyright (c) OpenMMLab. All rights reserved.
+
+from unittest import TestCase
+
+import torch
+
+from mmyolo.models.plugins import CBAM
+from mmyolo.utils import register_all_modules
+
+register_all_modules()
+
+
+class TestCBAM(TestCase):
+
+    def test_forward(self):
+        tensor_shape = (2, 16, 20, 20)
+
+        images = torch.randn(*tensor_shape)
+        cbam = CBAM(16)
+        out = cbam(images)
+        self.assertEqual(out.shape, tensor_shape)
+
+        # test other ratio
+        cbam = CBAM(16, reduce_ratio=8)
+        out = cbam(images)
+        self.assertEqual(out.shape, tensor_shape)
+
+        # test other act_cfg in ChannelAttention
+        cbam = CBAM(in_channels=16, act_cfg=dict(type='Sigmoid'))
+        out = cbam(images)
+        self.assertEqual(out.shape, tensor_shape)
diff --git a/tools/test.py b/tools/test.py
index 23347f6ab..fc80c887a 100644
--- a/tools/test.py
+++ b/tools/test.py
@@ -4,8 +4,8 @@
 import os.path as osp
 
 from mmdet.engine.hooks.utils import trigger_visualization_hook
-from mmdet.utils import add_dump_metric
 from mmengine.config import Config, DictAction
+from mmengine.evaluator import DumpResults
 from mmengine.runner import Runner
 
 from mmyolo.registry import RUNNERS
@@ -92,12 +92,6 @@ def main():
     if args.deploy:
         cfg.custom_hooks.append(dict(type='SwitchToDeployHook'))
 
-    # Dump predictions
-    if args.out is not None:
-        assert args.out.endswith(('.pkl', '.pickle')), \
-            'The dump file must be a pkl file.'
-        add_dump_metric(args, cfg)
-
     # build the runner from config
     if 'runner_type' not in cfg:
         # build the default runner
@@ -107,6 +101,13 @@ def main():
         # if 'runner_type' is set in the cfg
         runner = RUNNERS.build(cfg)
 
+    # add `DumpResults` dummy metric
+    if args.out is not None:
+        assert args.out.endswith(('.pkl', '.pickle')), \
+            'The dump file must be a pkl file.'
+        runner.test_evaluator.metrics.append(
+            DumpResults(out_file_path=args.out))
+
     # start testing
     runner.test()