tuandunghcmut's picture
Add files using upload-large-folder tool
f0384a9 verified
Raw
History Blame Contribute Delete
3.02 kB
# Copyright (c) Meta Platforms, Inc. and affiliates.
# All rights reserved.
#
# This source code is licensed under the BSD-style license found in the
# LICENSE file in the root directory of this source tree.
import copy
import hashlib
import os
from typing import Optional
import torch
from torch import nn
def store_model_weights(
model: nn.Module,
checkpoint_path: str,
checkpoint_key: Optional[str] = None,
strict=True,
):
"""
This method can be used to prepare weights files for new models. It receives as
input a model architecture and a checkpoint from the training script and produces
a file with the weights ready for release.
Code reference:
https://github.com/pytorch/vision/blob/main/references/classification/utils.py
Args:
model (nn.Module): The model on which the weights will be loaded for validation purposes.
checkpoint_path (str): The path of the checkpoint we will load.
checkpoint_key (str, optional): The key of the checkpoint where the model weights are stored.
For example, ``model`` is a common key used by many.
If ``None``, the checkpoint file is treated as model weights file. Default: ``None``.
strict (bool): whether to strictly enforce that the keys
in :attr:`state_dict` match the keys returned by this module's
:meth:`~torch.nn.Module.state_dict` function. Default: ``True``
Returns:
output_path (str): The location where the weights are saved.
"""
# Store the new model next to the checkpoint_path
checkpoint_path = os.path.abspath(checkpoint_path)
output_dir = os.path.dirname(checkpoint_path)
# Deep copy to avoid side-effects on the model object.
model = copy.deepcopy(model)
checkpoint = torch.load(checkpoint_path, map_location="cpu")
# Load the weights to the model to validate that everything works
# and remove unnecessary weights (such as auxiliaries, etc)
# If no checkpoint_key is provided, the checkpoint_path is treated
# as the model weights file
if checkpoint_key is None:
model.load_state_dict(checkpoint, strict=strict)
else:
if checkpoint_key == "model_ema":
del checkpoint[checkpoint_key]["n_averaged"]
nn.modules.utils.consume_prefix_in_state_dict_if_present(
checkpoint[checkpoint_key], "module."
)
model.load_state_dict(checkpoint[checkpoint_key], strict=strict)
tmp_path = os.path.join(output_dir, str(model.__hash__()))
torch.save(model.state_dict(), tmp_path)
sha256_hash = hashlib.sha256()
with open(tmp_path, "rb") as f:
# Read and update hash string value in blocks of 4K
for byte_block in iter(lambda: f.read(4096), b""):
sha256_hash.update(byte_block)
hh = sha256_hash.hexdigest()
output_path = os.path.join(output_dir, "weights-" + str(hh[:8]) + ".pth")
os.replace(tmp_path, output_path)
return output_path