"convert/vscode:/vscode.git/clone" did not exist on "5e9db9fb0bcefbe599734b02dd030f4a347ce576"
prediction_merger.py 3.37 KB
Newer Older
1
2
3
import argparse
import copy
import json
Fengzhe Zhou's avatar
Fengzhe Zhou committed
4
import os
5
6
7
8
9
10
11
12

import mmengine
from mmengine.config import Config, ConfigDict

from opencompass.utils import build_dataset_from_cfg, get_infer_output_path


def parse_args():
13
14
    parser = argparse.ArgumentParser(
        description='Merge patitioned predictions')
15
    parser.add_argument('config', help='Train config file path')
Fengzhe Zhou's avatar
Fengzhe Zhou committed
16
17
18
    parser.add_argument('-w', '--work-dir', default=None, type=str)
    parser.add_argument('-r', '--reuse', default='latest', type=str)
    parser.add_argument('-c', '--clean', action='store_true')
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
    args = parser.parse_args()
    return args


class PredictionMerger:

    def __init__(self, cfg: ConfigDict) -> None:
        self.cfg = cfg
        self.model_cfg = copy.deepcopy(self.cfg['model'])
        self.dataset_cfg = copy.deepcopy(self.cfg['dataset'])
        self.work_dir = self.cfg.get('work_dir')

    def run(self):
        filename = get_infer_output_path(
            self.model_cfg, self.dataset_cfg,
Fengzhe Zhou's avatar
Fengzhe Zhou committed
34
35
            os.path.join(self.work_dir, 'predictions'))
        root, ext = os.path.splitext(filename)
36
37
        partial_filename = root + '_0' + ext

Fengzhe Zhou's avatar
Fengzhe Zhou committed
38
        if os.path.exists(os.path.realpath(filename)):
39
40
            return

Fengzhe Zhou's avatar
Fengzhe Zhou committed
41
        if not os.path.exists(os.path.realpath(partial_filename)):
42
43
44
45
46
            print(f'{filename} not found')
            return

        # Load predictions
        partial_filenames = []
Fengzhe Zhou's avatar
Fengzhe Zhou committed
47
48
49
50
51
52
53
54
55
56
        preds, offset = {}, 0
        i = 1
        while os.path.exists(os.path.realpath(partial_filename)):
            partial_filenames.append(os.path.realpath(partial_filename))
            _preds = mmengine.load(partial_filename)
            partial_filename = root + f'_{i}' + ext
            i += 1
            for _o in range(len(_preds)):
                preds[str(offset)] = _preds[str(_o)]
                offset += 1
57
58
59
60
61
62
63
64
65
66

        dataset = build_dataset_from_cfg(self.dataset_cfg)
        if len(preds) != len(dataset.test):
            print('length mismatch')
            return

        print(f'Merge {partial_filenames} to {filename}')
        with open(filename, 'w', encoding='utf-8') as f:
            json.dump(preds, f, indent=4, ensure_ascii=False)

Fengzhe Zhou's avatar
Fengzhe Zhou committed
67
68
69
70
71
        if self.cfg['clean']:
            for partial_filename in partial_filenames:
                print(f'Remove {partial_filename}')
                os.remove(partial_filename)

72
73
74
75
76
77
78

def dispatch_tasks(cfg):
    for model in cfg['models']:
        for dataset in cfg['datasets']:
            PredictionMerger({
                'model': model,
                'dataset': dataset,
Fengzhe Zhou's avatar
Fengzhe Zhou committed
79
80
                'work_dir': cfg['work_dir'],
                'clean': cfg['clean']
81
82
83
84
85
86
87
88
89
90
91
            }).run()


def main():
    args = parse_args()
    cfg = Config.fromfile(args.config)
    # set work_dir
    if args.work_dir is not None:
        cfg['work_dir'] = args.work_dir
    else:
        cfg.setdefault('work_dir', './outputs/default')
Fengzhe Zhou's avatar
Fengzhe Zhou committed
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107

    if args.reuse:
        if args.reuse == 'latest':
            if not os.path.exists(cfg.work_dir) or not os.listdir(
                    cfg.work_dir):
                print('No previous results to reuse!')
                return
            else:
                dirs = os.listdir(cfg.work_dir)
                dir_time_str = sorted(dirs)[-1]
        else:
            dir_time_str = args.reuse
    cfg['work_dir'] = os.path.join(cfg.work_dir, dir_time_str)

    cfg['clean'] = args.clean

108
109
110
111
112
    dispatch_tasks(cfg)


if __name__ == '__main__':
    main()