def save_model(
        self, model_id: str, output_dir: str = None, overwrite: bool = False, only_cache_files: bool = False
    ):
        """Save a model from the cache to a given path."""
        output_dir = Path(output_dir) if output_dir else Path.cwd()
        output_dir.mkdir(parents=True, exist_ok=True)
        model_json = self.load_model(model_id)
        if model_json["type"].lower() == "compositemodel":
            model_json_config = model_json["config"]
            copied_components = []
            saved_external_files = {}
            for component_name, component in zip(
                model_json_config["model_component_names"], model_json_config["model_components"]
            ):
                if component["type"].lower() != "onnxmodel":
                    # save each component with a prefix
                    # e.g. "component_1" -> "component_1_{resource_name}"
                    copied_components.append(
                        self._save_model(
                            component,
                            output_dir=output_dir,
                            overwrite=overwrite,
                            only_cache_files=only_cache_files,
                            path_prefix=component_name,
                        )
                    )
                else:
                    # save all onnx files into the same directory
                    component_model_json, component_local_resource_names = self._replace_with_local_resources(
                        component, only_cache_files=only_cache_files
                    )

                    for resource_name in component_local_resource_names:
                        if resource_name != "model_path":
                            # this case does not exist in the current code
                            # but we need to handle it for future use
                            component_model_json["config"][resource_name] = component_model_json["config"][
                                resource_name
                            ].save_to_dir(output_dir, resource_name, overwrite)
                        else:
                            from olive.passes.onnx.common import resave_model

                            resave_model(
                                ModelConfig.parse_obj(component_model_json).create_model().model_path,
                                output_dir / "model" / f"{component_name}.onnx",
                                saved_external_files=saved_external_files,
                            )
                            component_model_json["config"][resource_name] = str(output_dir / "model")
                            component_model_json["config"]["onnx_file_name"] = f"{component_name}.onnx"

                    copied_components.append(component_model_json)

            model_json_config["model_components"] = copied_components
            # save additional files
            model_json = self._save_additional_files(model_json, output_dir / "model")
        else:
            model_json = self._save_model(model_json, output_dir, overwrite)

        # save model json
        with (output_dir / "model_config.json").open("w") as f:
            json.dump(model_json, f, indent=4)
        return model_json
Save a model from the cache to a given path.
olive/cache.py