benchmark.py 2.61 KB
Newer Older
dingchang's avatar
dingchang committed
1
# Copyright (c) OpenMMLab. All rights reserved.
wuyuefeng's avatar
wuyuefeng committed
2
3
import argparse
import time
4

wuyuefeng's avatar
wuyuefeng committed
5
import torch
6
7
8
9
from mmengine import Config
from mmengine.device import get_device
from mmengine.registry import init_default_scope
from mmengine.runner import Runner, autocast, load_checkpoint
wuyuefeng's avatar
wuyuefeng committed
10

11
from mmdet3d.registry import MODELS
Ziyi Wu's avatar
Ziyi Wu committed
12
from tools.misc.fuse_conv_bn import fuse_module
wuyuefeng's avatar
wuyuefeng committed
13
14
15
16
17
18


def parse_args():
    parser = argparse.ArgumentParser(description='MMDet benchmark a model')
    parser.add_argument('config', help='test config file path')
    parser.add_argument('checkpoint', help='checkpoint file')
wuyuefeng's avatar
wuyuefeng committed
19
    parser.add_argument('--samples', default=2000, help='samples to benchmark')
wuyuefeng's avatar
wuyuefeng committed
20
21
    parser.add_argument(
        '--log-interval', default=50, help='interval of logging')
22
23
24
25
    parser.add_argument(
        '--amp',
        action='store_true',
        help='Whether to use automatic mixed precision inference')
wuyuefeng's avatar
wuyuefeng committed
26
27
28
29
30
31
32
33
34
35
36
    parser.add_argument(
        '--fuse-conv-bn',
        action='store_true',
        help='Whether to fuse conv and bn, this will slightly increase'
        'the inference speed')
    args = parser.parse_args()
    return args


def main():
    args = parse_args()
37
    init_default_scope('mmdet3d')
wuyuefeng's avatar
wuyuefeng committed
38

39
    # build config and set cudnn_benchmark
wuyuefeng's avatar
wuyuefeng committed
40
    cfg = Config.fromfile(args.config)
41
42

    if cfg.env_cfg.get('cudnn_benchmark', False):
wuyuefeng's avatar
wuyuefeng committed
43
        torch.backends.cudnn.benchmark = True
44
45
46
47
48
49

    # build dataloader
    dataloader = Runner.build_dataloader(cfg.test_dataloader)

    # build model and load checkpoint
    model = MODELS.build(cfg.model)
wuyuefeng's avatar
wuyuefeng committed
50
51
52
    load_checkpoint(model, args.checkpoint, map_location='cpu')
    if args.fuse_conv_bn:
        model = fuse_module(model)
53
    model.to(get_device())
wuyuefeng's avatar
wuyuefeng committed
54
55
56
57
58
59
    model.eval()

    # the first several iterations may be very slow so skip them
    num_warmup = 5
    pure_inf_time = 0

wuyuefeng's avatar
wuyuefeng committed
60
    # benchmark with several samples and take the average
61
    for i, data in enumerate(dataloader):
wuyuefeng's avatar
wuyuefeng committed
62
63
64
65

        torch.cuda.synchronize()
        start_time = time.perf_counter()

66
67
        with autocast(enabled=args.amp):
            model.test_step(data)
wuyuefeng's avatar
wuyuefeng committed
68
69
70
71
72
73
74
75

        torch.cuda.synchronize()
        elapsed = time.perf_counter() - start_time

        if i >= num_warmup:
            pure_inf_time += elapsed
            if (i + 1) % args.log_interval == 0:
                fps = (i + 1 - num_warmup) / pure_inf_time
76
77
                print(f'Done sample [{i + 1:<3}/ {args.samples}], '
                      f'fps: {fps:.1f} sample / s')
wuyuefeng's avatar
wuyuefeng committed
78

wuyuefeng's avatar
wuyuefeng committed
79
        if (i + 1) == args.samples:
wuyuefeng's avatar
wuyuefeng committed
80
81
            pure_inf_time += elapsed
            fps = (i + 1 - num_warmup) / pure_inf_time
82
            print(f'Overall fps: {fps:.1f} sample / s')
wuyuefeng's avatar
wuyuefeng committed
83
84
85
86
87
            break


if __name__ == '__main__':
    main()