comdoleger commited on
Commit
26d32c4
·
verified ·
1 Parent(s): 038609d

Upload jobs/process/GenerateProcess.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. jobs/process/GenerateProcess.py +173 -0
jobs/process/GenerateProcess.py ADDED
@@ -0,0 +1,173 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gc
2
+ import os
3
+ from collections import OrderedDict
4
+ from typing import ForwardRef, List, Optional, Union
5
+
6
+ import torch
7
+ from safetensors.torch import save_file, load_file
8
+
9
+ from jobs.process.BaseProcess import BaseProcess
10
+ from toolkit.config_modules import ModelConfig, GenerateImageConfig
11
+ from toolkit.metadata import get_meta_for_safetensors, load_metadata_from_safetensors, add_model_hash_to_meta, \
12
+ add_base_model_info_to_meta
13
+ from toolkit.sampler import get_sampler
14
+ from toolkit.stable_diffusion_model import StableDiffusion
15
+ from toolkit.train_tools import get_torch_dtype
16
+ import random
17
+
18
+ from toolkit.util.get_model import get_model_class
19
+
20
+
21
+ class GenerateConfig:
22
+
23
+ def __init__(self, **kwargs):
24
+ self.prompts: List[str]
25
+ self.sampler = kwargs.get('sampler', 'ddpm')
26
+ self.width = kwargs.get('width', 512)
27
+ self.height = kwargs.get('height', 512)
28
+ self.size_list: Union[List[int], None] = kwargs.get('size_list', None)
29
+ self.neg = kwargs.get('neg', '')
30
+ self.seed = kwargs.get('seed', -1)
31
+ self.guidance_scale = kwargs.get('guidance_scale', 7)
32
+ self.sample_steps = kwargs.get('sample_steps', 20)
33
+ self.prompt_2 = kwargs.get('prompt_2', None)
34
+ self.neg_2 = kwargs.get('neg_2', None)
35
+ self.prompts = kwargs.get('prompts', None)
36
+ self.guidance_rescale = kwargs.get('guidance_rescale', 0.0)
37
+ self.compile = kwargs.get('compile', False)
38
+ self.ext = kwargs.get('ext', 'png')
39
+ self.prompt_file = kwargs.get('prompt_file', False)
40
+ self.num_repeats = kwargs.get('num_repeats', 1)
41
+ self.prompts_in_file = self.prompts
42
+ if self.prompts is None:
43
+ raise ValueError("Prompts must be set")
44
+ if isinstance(self.prompts, str):
45
+ if os.path.exists(self.prompts):
46
+ with open(self.prompts, 'r', encoding='utf-8') as f:
47
+ self.prompts_in_file = f.read().splitlines()
48
+ self.prompts_in_file = [p.strip() for p in self.prompts_in_file if len(p.strip()) > 0]
49
+ else:
50
+ raise ValueError("Prompts file does not exist, put in list if you want to use a list of prompts")
51
+
52
+ self.random_prompts = kwargs.get('random_prompts', False)
53
+ self.max_random_per_prompt = kwargs.get('max_random_per_prompt', 1)
54
+ self.max_images = kwargs.get('max_images', 10000)
55
+
56
+ if self.random_prompts:
57
+ self.prompts = []
58
+ for i in range(self.max_images):
59
+ num_prompts = random.randint(1, self.max_random_per_prompt)
60
+ prompt_list = [random.choice(self.prompts_in_file) for _ in range(num_prompts)]
61
+ self.prompts.append(", ".join(prompt_list))
62
+ else:
63
+ self.prompts = self.prompts_in_file
64
+
65
+ if kwargs.get('shuffle', False):
66
+ # shuffle the prompts
67
+ random.shuffle(self.prompts)
68
+
69
+
70
+ class GenerateProcess(BaseProcess):
71
+ process_id: int
72
+ config: OrderedDict
73
+ progress_bar: ForwardRef('tqdm') = None
74
+ sd: StableDiffusion
75
+
76
+ def __init__(
77
+ self,
78
+ process_id: int,
79
+ job,
80
+ config: OrderedDict
81
+ ):
82
+ super().__init__(process_id, job, config)
83
+ self.output_folder = self.get_conf('output_folder', required=True)
84
+ self.model_config = ModelConfig(**self.get_conf('model', required=True))
85
+ self.device = self.get_conf('device', self.job.device)
86
+ self.generate_config = GenerateConfig(**self.get_conf('generate', required=True))
87
+ self.torch_dtype = get_torch_dtype(self.get_conf('dtype', 'float16'))
88
+
89
+ self.progress_bar = None
90
+
91
+ ModelClass = get_model_class(self.model_config)
92
+ # if the model class has get_train_scheduler static method
93
+ if hasattr(ModelClass, 'get_train_scheduler'):
94
+ sampler = ModelClass.get_train_scheduler()
95
+ else:
96
+ # get the noise scheduler
97
+ arch = 'sd'
98
+ if self.model_config.is_pixart:
99
+ arch = 'pixart'
100
+ if self.model_config.is_flux:
101
+ arch = 'flux'
102
+ if self.model_config.is_lumina2:
103
+ arch = 'lumina2'
104
+ sampler = get_sampler(
105
+ self.train_config.noise_scheduler,
106
+ {
107
+ "prediction_type": "v_prediction" if self.model_config.is_v_pred else "epsilon",
108
+ },
109
+ arch=arch,
110
+ )
111
+ self.sd = ModelClass(
112
+ device=self.device,
113
+ model_config=self.model_config,
114
+ dtype=self.model_config.dtype,
115
+ noise_scheduler=sampler,
116
+ )
117
+
118
+ print(f"Using device {self.device}")
119
+
120
+ def clean_prompt(self, prompt: str):
121
+ # remove any non alpha numeric characters or ,'" from prompt
122
+ return ''.join(e for e in prompt if e.isalnum() or e in ", '\"")
123
+
124
+ def run(self):
125
+ with torch.no_grad():
126
+ super().run()
127
+ print("Loading model...")
128
+ self.sd.load_model()
129
+ self.sd.pipeline.to(self.device, self.torch_dtype)
130
+
131
+ print("Compiling model...")
132
+ # self.sd.unet = torch.compile(self.sd.unet, mode="reduce-overhead", fullgraph=True)
133
+ if self.generate_config.compile:
134
+ self.sd.unet = torch.compile(self.sd.unet, mode="reduce-overhead")
135
+
136
+ print(f"Generating {len(self.generate_config.prompts)} images")
137
+ # build prompt image configs
138
+ prompt_image_configs = []
139
+ for _ in range(self.generate_config.num_repeats):
140
+ for prompt in self.generate_config.prompts:
141
+ # remove --
142
+ prompt = prompt.replace('--', '').strip()
143
+ width = self.generate_config.width
144
+ height = self.generate_config.height
145
+ # prompt = self.clean_prompt(prompt)
146
+
147
+ if self.generate_config.size_list is not None:
148
+ # randomly select a size
149
+ width, height = random.choice(self.generate_config.size_list)
150
+
151
+ prompt_image_configs.append(GenerateImageConfig(
152
+ prompt=prompt,
153
+ prompt_2=self.generate_config.prompt_2,
154
+ width=width,
155
+ height=height,
156
+ num_inference_steps=self.generate_config.sample_steps,
157
+ guidance_scale=self.generate_config.guidance_scale,
158
+ negative_prompt=self.generate_config.neg,
159
+ negative_prompt_2=self.generate_config.neg_2,
160
+ seed=self.generate_config.seed,
161
+ guidance_rescale=self.generate_config.guidance_rescale,
162
+ output_ext=self.generate_config.ext,
163
+ output_folder=self.output_folder,
164
+ add_prompt_file=self.generate_config.prompt_file
165
+ ))
166
+ # generate images
167
+ self.sd.generate_images(prompt_image_configs, sampler=self.generate_config.sampler)
168
+
169
+ print("Done generating images")
170
+ # cleanup
171
+ del self.sd
172
+ gc.collect()
173
+ torch.cuda.empty_cache()