def save_model(self, output_model_path: str, replacements: list[tuple[nn.Module, Callable]] = None):
        """Save the model to the output_model_path with the specified replacements.

        :param output_model_path: Path to save the model.
        :param replacements: List of replacements to apply before saving the model. Each replacement is a tuple of
            (submodule_type, replacement_fn). The replacement_fn should take the submodule as input and return the
            replacement module.
        """
        replacements = replacements or []
        # unpack qkv before saving
        replacements.append([UnpackedQKV, lambda module: module.create_packed()])

        for submodule_type, replacement_fn in replacements:
            logger.debug("Replacing %s with %s", submodule_type, replacement_fn)
            replace_submodules(self.model, submodule_type, replacement_fn)

        self.model.save_pretrained(output_model_path)
Save the model to the output_model_path with the specified replacements.

        :param output_model_path: Path to save the model.
        :param replacements: List of replacements to apply before saving the model. Each replacement is a tuple of
            (submodule_type, replacement_fn). The replacement_fn should take the submodule as input and return the
            replacement module.
        
olive/common/hf/wrapper.py