


import itertools
from dataclasses import dataclass
from typing import List, Optional

import pyarrow as pa
import pyarrow.parquet as pq

import datasets
from datasets.table import table_cast


snake_case__			 =						datasets.utils.logging.get_logger(__name__)


@dataclass
class 					lowerCAmelCase_ (       datasets.BuilderConfig):
						lowerCamelCase_         =     10_000
						lowerCamelCase_         =     None
						lowerCamelCase_         =     None






class 					lowerCAmelCase_ (       datasets.ArrowBasedBuilder):
						lowerCamelCase_         =     ParquetConfig




						def  _snake_case					(	self						:   Union[str, Any]						)      ->int:






									"""simple docstring"""






									return datasets.DatasetInfo(features=self.config.features						)




						def  _snake_case					(	self						:   List[Any]   ,     __A						:   List[str]						)      ->Dict:






									"""simple docstring"""






									if not self.config.data_files:
												raise ValueError(F'''At least one data file must be specified, but got data_files={self.config.data_files}'''						)
									a__ :str						  =    dl_manager.download_and_extract(self.config.data_files						)
									if isinstance(__A   ,     (str, list, tuple)						):
												a__ :Dict						  =    data_files
												if isinstance(__A   ,     __A						):
															a__ :Optional[Any]						  =    [files]
												# Use `dl_manager.iter_files` to skip hidden files in an extracted archive
												a__ :int						  =    [dl_manager.iter_files(__A						) for file in files]
												return [datasets.SplitGenerator(name=datasets.Split.TRAIN   ,     gen_kwargs={"files": files}						)]
									a__ :List[str]						  =    []
									for split_name, files in data_files.items():
												if isinstance(__A   ,     __A						):
															a__ :Dict						  =    [files]
												# Use `dl_manager.iter_files` to skip hidden files in an extracted archive
												a__ :Any						  =    [dl_manager.iter_files(__A						) for file in files]
												# Infer features is they are stoed in the arrow schema
												if self.info.features is None:
															for file in itertools.chain.from_iterable(__A						):
																		with open(__A   ,     "rb"						) as f:
																					a__ :Optional[Any]						  =    datasets.Features.from_arrow_schema(pq.read_schema(__A						)						)
																		break
												splits.append(datasets.SplitGenerator(name=__A   ,     gen_kwargs={"files": files}						)						)
									return splits




						def  _snake_case					(	self						:   Union[str, Any]   ,     __A						:   pa.Table						)      ->pa.Table:






									"""simple docstring"""






									if self.info.features is not None:
												# more expensive cast to support nested features with keys in a different order
												# allows str <-> int/float or str to Audio for example
												a__ :str						  =    table_cast(__A   ,     self.info.features.arrow_schema						)
									return pa_table






						def  _snake_case					(	self						:   Optional[Any]   ,     __A						:   Any						)      ->List[str]:






									"""simple docstring"""






									a__ :Optional[int]						  =    self.info.features.arrow_schema if self.info.features is not None else None
									if self.info.features is not None and self.config.columns is not None:
												if sorted(field.name for field in schema						) != sorted(self.config.columns						):
															raise ValueError(
															    F'''Tried to load parquet data with columns \'{self.config.columns}\' with mismatching features \'{self.info.features}\''''						)
									for file_idx, file in enumerate(itertools.chain.from_iterable(__A						)						):
												with open(__A   ,     "rb"						) as f:
															a__ :int						  =    pq.ParquetFile(__A						)
															try:
																		for batch_idx, record_batch in enumerate(
																		    parquet_file.iter_batches(batch_size=self.config.batch_size   ,     columns=self.config.columns						)						):
																					a__ :Union[str, Any]						  =    pa.Table.from_batches([record_batch]						)
																					# Uncomment for debugging (will print the Arrow table size and elements)
																					# logger.warning(f"pa_table: {pa_table} num rows: {pa_table.num_rows}")
																					# logger.warning('\n'.join(str(pa_table.slice(i, 1).to_pydict()) for i in range(pa_table.num_rows)))
																					yield F'''{file_idx}_{batch_idx}''', self._cast_table(__A						)
															except ValueError as e:
																		logger.error(F'''Failed to read file \'{file}\' with error {type(__A						)}: {e}'''						)
																		raise






import argparse

import torch

from diffusers.pipelines.stable_diffusion.convert_from_ckpt import download_from_original_stable_diffusion_ckpt


if __name__ == "__main__":
		snake_case__			 =						argparse.ArgumentParser()

		parser.add_argument(
		    '''--checkpoint_path''', default=None, type=str, required=True, help='''Path to the checkpoint to convert.'''
		)
		# !wget https://raw.githubusercontent.com/CompVis/stable-diffusion/main/configs/stable-diffusion/v1-inference.yaml
		parser.add_argument(
		    '''--original_config_file''',
		    default=None,
		    type=str,
		    help='''The YAML config file corresponding to the original architecture.''',
		)
		parser.add_argument(
		    '''--num_in_channels''',
		    default=None,
		    type=int,
		    help='''The number of input channels. If `None` number of input channels will be automatically inferred.''',
		)
		parser.add_argument(
		    '''--scheduler_type''',
		    default='''pndm''',
		    type=str,
		    help='''Type of scheduler to use. Should be one of [\'pndm\', \'lms\', \'ddim\', \'euler\', \'euler-ancestral\', \'dpm\']''',
		)
		parser.add_argument(
		    '''--pipeline_type''',
		    default=None,
		    type=str,
		    help=(
		        '''The pipeline type. One of \'FrozenOpenCLIPEmbedder\', \'FrozenCLIPEmbedder\', \'PaintByExample\''''
		        '''. If `None` pipeline will be automatically inferred.'''
		    ),
		)
		parser.add_argument(
		    '''--image_size''',
		    default=None,
		    type=int,
		    help=(
		        '''The image size that the model was trained on. Use 512 for Stable Diffusion v1.X and Stable Siffusion v2'''
		        ''' Base. Use 768 for Stable Diffusion v2.'''
		    ),
		)
		parser.add_argument(
		    '''--prediction_type''',
		    default=None,
		    type=str,
		    help=(
		        '''The prediction type that the model was trained on. Use \'epsilon\' for Stable Diffusion v1.X and Stable'''
		        ''' Diffusion v2 Base. Use \'v_prediction\' for Stable Diffusion v2.'''
		    ),
		)
		parser.add_argument(
		    '''--extract_ema''',
		    action='''store_true''',
		    help=(
		        '''Only relevant for checkpoints that have both EMA and non-EMA weights. Whether to extract the EMA weights'''
		        ''' or not. Defaults to `False`. Add `--extract_ema` to extract the EMA weights. EMA weights usually yield'''
		        ''' higher quality images for inference. Non-EMA weights are usually better to continue fine-tuning.'''
		    ),
		)
		parser.add_argument(
		    '''--upcast_attention''',
		    action='''store_true''',
		    help=(
		        '''Whether the attention computation should always be upcasted. This is necessary when running stable'''
		        ''' diffusion 2.1.'''
		    ),
		)
		parser.add_argument(
		    '''--from_safetensors''',
		    action='''store_true''',
		    help='''If `--checkpoint_path` is in `safetensors` format, load checkpoint with safetensors instead of PyTorch.''',
		)
		parser.add_argument(
		    '''--to_safetensors''',
		    action='''store_true''',
		    help='''Whether to store pipeline in safetensors format or not.''',
		)
		parser.add_argument('''--dump_path''', default=None, type=str, required=True, help='''Path to the output model.''')
		parser.add_argument('''--device''', type=str, help='''Device to use (e.g. cpu, cuda:0, cuda:1, etc.)''')
		parser.add_argument(
		    '''--stable_unclip''',
		    type=str,
		    default=None,
		    required=False,
		    help='''Set if this is a stable unCLIP model. One of \'txt2img\' or \'img2img\'.''',
		)
		parser.add_argument(
		    '''--stable_unclip_prior''',
		    type=str,
		    default=None,
		    required=False,
		    help='''Set if this is a stable unCLIP txt2img model. Selects which prior to use. If `--stable_unclip` is set to `txt2img`, the karlo prior (https://huggingface.co/kakaobrain/karlo-v1-alpha/tree/main/prior) is selected by default.''',
		)
		parser.add_argument(
		    '''--clip_stats_path''',
		    type=str,
		    help='''Path to the clip stats file. Only required if the stable unclip model\'s config specifies `model.params.noise_aug_config.params.clip_stats_path`.''',
		    required=False,
		)
		parser.add_argument(
		    '''--controlnet''', action='''store_true''', default=None, help='''Set flag if this is a controlnet checkpoint.'''
		)
		parser.add_argument('''--half''', action='''store_true''', help='''Save weights in half precision.''')
		parser.add_argument(
		    '''--vae_path''',
		    type=str,
		    default=None,
		    required=False,
		    help='''Set to a path, hub id to an already converted vae to not convert it again.''',
		)
		snake_case__			 =						parser.parse_args()

		snake_case__			 =						download_from_original_stable_diffusion_ckpt(
		    checkpoint_path=args.checkpoint_path,
		    original_config_file=args.original_config_file,
		    image_size=args.image_size,
		    prediction_type=args.prediction_type,
		    model_type=args.pipeline_type,
		    extract_ema=args.extract_ema,
		    scheduler_type=args.scheduler_type,
		    num_in_channels=args.num_in_channels,
		    upcast_attention=args.upcast_attention,
		    from_safetensors=args.from_safetensors,
		    device=args.device,
		    stable_unclip=args.stable_unclip,
		    stable_unclip_prior=args.stable_unclip_prior,
		    clip_stats_path=args.clip_stats_path,
		    controlnet=args.controlnet,
		    vae_path=args.vae_path,
		)

		if args.half:
				pipe.to(torch_dtype=torch.floataa)

		if args.controlnet:
				# only save the controlnet model
				pipe.controlnet.save_pretrained(args.dump_path, safe_serialization=args.to_safetensors)
		else:
				pipe.save_pretrained(args.dump_path, safe_serialization=args.to_safetensors)


