convert_v1_to_v2_weights.py 3.59 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# Copyright 2022 AlQuraishi Laboratory
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Converts OpenFold .pt checkpoints into AlphaFold .npz ones, which can then be
# used to run inference using DeepMind's JAX code.

18
import logging
19
20
21
22
23
24
import argparse
import os
import shutil
import torch

from openfold.utils.import_weights import convert_deprecated_v1_keys
25
26
27
from deepspeed.utils.zero_to_fp32 import (
    get_optim_files, parse_optim_states, get_model_state_file
)
28
29
30
31
32
33
34


def convert_v1_to_v2_weights(args):
    checkpoint_path = args.input_ckpt_path
    is_dir = os.path.isdir(checkpoint_path)
    if is_dir:
        # A DeepSpeed checkpoint
35
        logging.info(
36
            'Converting deepspeed checkpoint found at {args.input_checkpoint_path}')
37
        state_dict_key = 'module'
38
39
40
41
42
43
44
45
46
47
48
49
        latest_path = os.path.join(checkpoint_path, 'latest')
        if os.path.isfile(latest_path):
            with open(latest_path, 'r') as fd:
                tag = fd.read().strip()
        else:
            raise ValueError(f"Unable to find 'latest' file at {latest_path}")

        ds_checkpoint_dir = os.path.join(checkpoint_path, tag)
        model_output_path = os.path.join(args.output_ckpt_path, tag)
        optim_files = get_optim_files(ds_checkpoint_dir)
        zero_stage, _, _ = parse_optim_states(optim_files, ds_checkpoint_dir)
        model_file = get_model_state_file(ds_checkpoint_dir, zero_stage)
50
51
    else:
        # A Pytorch Lightning checkpoint
52
53
        logging.info(
            'Converting pytorch lightning checkpoint found at {args.input_checkpoint_path}')
54
        state_dict_key = 'state_dict'
55
        model_output_path = args.output_ckpt_path
56
57
58
        model_file = checkpoint_path

    model_dict = torch.load(model_file, map_location=torch.device('cpu'))
59
60
    model_dict[state_dict_key] = convert_deprecated_v1_keys(
        model_dict[state_dict_key])
61
62
63

    if 'ema' in model_dict:
        ema_state_dict = model_dict['ema']['params']
64
65
        model_dict['ema']['params'] = convert_deprecated_v1_keys(
            ema_state_dict)
66
67

    if is_dir:
68
69
70
71
        param_shapes = convert_deprecated_v1_keys(
            model_dict['param_shapes'][0])
        model_dict['param_shapes'] = [param_shapes]

72
        shutil.copytree(checkpoint_path, args.output_ckpt_path)
73
74
75
76
77
78
79
80
81
82
83
        out_fname = os.path.join(
            model_output_path, os.path.basename(model_file))

        for optim_file in optim_files:
            optim_dict = torch.load(optim_file)
            new_optim_dict = optim_dict.copy()
            new_optim_dict['optimizer_state_dict']['param_slice_mappings'][0] = convert_deprecated_v1_keys(
                optim_dict['optimizer_state_dict']['param_slice_mappings'][0])
            out_optim_fname = os.path.join(
                model_output_path, os.path.basename(optim_file))
            torch.save(new_optim_dict, out_optim_fname)
84
    else:
85
        out_fname = model_output_path
86
87
88
89
90
91
92
93
94
95
96

    torch.save(model_dict, out_fname)


if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("input_ckpt_path", type=str)
    parser.add_argument("output_ckpt_path", type=str)

    args = parser.parse_args()

97
    convert_v1_to_v2_weights(args)