def save_metadata(self, output_dir: str, exclude_load_keys: Optional[list[str]] = None, **kwargs) -> list[str]:
        """Save model metadata files to the output directory.

        :param output_dir: output directory to save metadata files
        :param exclude_load_keys: list of keys to exclude from load_kwargs
        :param kwargs: additional keyword arguments to pass to `save_pretrained` method
        :return: list of file paths
        """
        output_dir = Path(output_dir)
        if not output_dir.exists():
            output_dir.mkdir(parents=True)
        elif not output_dir.is_dir():
            raise ValueError("Expecting a directory as input.")

        saved_filepaths = []

        # save config and module files
        # load already saved config, could be saved by loaded_model.save_pretrained
        # don't want to override it with the current model config
        config_file_path = output_dir / "config.json"
        config = (
            get_model_config(output_dir, trust_remote_code=self.get_load_kwargs().get("trust_remote"))
            if config_file_path.exists()
            else self.get_hf_model_config(exclude_load_keys=exclude_load_keys)
        )
        if getattr(config, "auto_map", None):
            # needs model_name_or_path to find module files
            # conditional since model_name_or_path might trigger preprocessing for some mlflow models
            config, module_files = save_module_files(
                config,
                self.model_name_or_path,
                str(output_dir),
                **self.get_load_kwargs(exclude_load_keys=exclude_load_keys),
            )
            saved_filepaths.extend(module_files)
        save_model_config(config, output_dir, **kwargs)
        saved_filepaths.append(str(config_file_path))

        # save model generation config, skip if it already exists
        # non-generative models won't have generation config
        generation_config_file_path = output_dir / "generation_config.json"
        if not generation_config_file_path.exists() and (
            generation_config := self.get_hf_generation_config(exclude_load_keys=exclude_load_keys)
        ):
            save_model_config(generation_config, output_dir, **kwargs)
            saved_filepaths.append(str(generation_config_file_path))

        # save tokenizer, skip if it already exists
        try:
            get_tokenizer(output_dir)
        except (OSError, TypeError):
            # there is no tokenizer in the output_dir, save the tokenizer
            # "TypeError: not a string" happens with transformers 4.52+
            tokenizer_filepaths = save_tokenizer(self.get_hf_tokenizer(), output_dir, **kwargs)
            saved_filepaths.extend([fp for fp in tokenizer_filepaths if Path(fp).exists()])

        logger.debug("Save metadata files to %s: %s", output_dir, saved_filepaths)

        return saved_filepaths
Save model metadata files to the output directory.

        :param output_dir: output directory to save metadata files
        :param exclude_load_keys: list of keys to exclude from load_kwargs
        :param kwargs: additional keyword arguments to pass to `save_pretrained` method
        :return: list of file paths
        
olive/model/handler/mixin/hf.py