RashiAgarwal commited on
Commit
6cb857a
1 Parent(s): 9d99be0

Upload 10 files

Browse files
app.py ADDED
@@ -0,0 +1,337 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ #!pip install -q --upgrade transformers diffusers ftfy
3
+ !pip install -q --upgrade transformers==4.25.1 diffusers ftfy
4
+ !pip install accelerate -q
5
+
6
+ from base64 import b64encode
7
+
8
+ import numpy
9
+ import torch
10
+ from diffusers import AutoencoderKL, LMSDiscreteScheduler, UNet2DConditionModel
11
+ from huggingface_hub import notebook_login
12
+
13
+ # For video display:
14
+ from IPython.display import HTML
15
+ from matplotlib import pyplot as plt
16
+ from pathlib import Path
17
+ from PIL import Image
18
+ from torch import autocast
19
+ from torchvision import transforms as tfms
20
+ from tqdm.auto import tqdm
21
+ from transformers import CLIPTextModel, CLIPTokenizer, logging
22
+
23
+ torch.manual_seed(1)
24
+ #if not (Path.home()/'.huggingface'/'token').exists(): notebook_login()
25
+
26
+ # Supress some unnecessary warnings when loading the CLIPTextModel
27
+ logging.set_verbosity_error()
28
+
29
+ # Set device
30
+ torch_device = "cuda" if torch.cuda.is_available() else "cpu"
31
+
32
+ import os
33
+ MY_TOKEN=os.environ.get('HF_TOKEN_SD')
34
+
35
+
36
+ # Load the autoencoder model which will be used to decode the latents into image space.
37
+ vae = AutoencoderKL.from_pretrained("CompVis/stable-diffusion-v1-4", subfolder="vae",use_auth_token=MY_TOKEN)
38
+
39
+ # Load the tokenizer and text encoder to tokenize and encode the text.
40
+ tokenizer = CLIPTokenizer.from_pretrained("openai/clip-vit-large-patch14")
41
+ text_encoder = CLIPTextModel.from_pretrained("openai/clip-vit-large-patch14")
42
+
43
+ # The UNet model for generating the latents.
44
+ unet = UNet2DConditionModel.from_pretrained("CompVis/stable-diffusion-v1-4", subfolder="unet")
45
+
46
+ # The noise scheduler
47
+ scheduler = LMSDiscreteScheduler(beta_start=0.00085, beta_end=0.012, beta_schedule="scaled_linear", num_train_timesteps=1000)
48
+
49
+ # To the GPU we go!
50
+ vae = vae.to(torch_device)
51
+ text_encoder = text_encoder.to(torch_device)
52
+ unet = unet.to(torch_device)
53
+
54
+ """Functions"""
55
+
56
+ def pil_to_latent(input_im):
57
+ # Single image -> single latent in a batch (so size 1, 4, 64, 64)
58
+ with torch.no_grad():
59
+ latent = vae.encode(tfms.ToTensor()(input_im).unsqueeze(0).to(torch_device)*2-1) # Note scaling
60
+ return 0.18215 * latent.latent_dist.sample()
61
+
62
+ def latents_to_pil(latents):
63
+ # bath of latents -> list of images
64
+ latents = (1 / 0.18215) * latents
65
+ with torch.no_grad():
66
+ image = vae.decode(latents).sample
67
+ image = (image / 2 + 0.5).clamp(0, 1)
68
+ image = image.detach().cpu().permute(0, 2, 3, 1).numpy()
69
+ images = (image * 255).round().astype("uint8")
70
+ pil_images = [Image.fromarray(image) for image in images]
71
+ return pil_images
72
+
73
+
74
+ def get_output_embeds(input_embeddings):
75
+ # CLIP's text model uses causal mask, so we prepare it here:
76
+ bsz, seq_len = input_embeddings.shape[:2]
77
+ causal_attention_mask = text_encoder.text_model._build_causal_attention_mask(bsz, seq_len, dtype=input_embeddings.dtype)
78
+
79
+ # Getting the output embeddings involves calling the model with passing output_hidden_states=True
80
+ # so that it doesn't just return the pooled final predictions:
81
+ encoder_outputs = text_encoder.text_model.encoder(
82
+ inputs_embeds=input_embeddings,
83
+ attention_mask=None, # We aren't using an attention mask so that can be None
84
+ causal_attention_mask=causal_attention_mask.to(torch_device),
85
+ output_attentions=None,
86
+ output_hidden_states=True, # We want the output embs not the final output
87
+ return_dict=None,
88
+ )
89
+
90
+ # We're interested in the output hidden state only
91
+ output = encoder_outputs[0]
92
+
93
+ # There is a final layer norm we need to pass these through
94
+ output = text_encoder.text_model.final_layer_norm(output)
95
+
96
+ # And now they're ready!
97
+ return output
98
+
99
+ #Generating an image with these modified embeddings
100
+
101
+ def generate_with_embs(text_embeddings, text_input):
102
+ height = 512 # default height of Stable Diffusion
103
+ width = 512 # default width of Stable Diffusion
104
+ num_inference_steps = 10 # Number of denoising steps
105
+ guidance_scale = 7.5 # Scale for classifier-free guidance
106
+ generator = torch.manual_seed(64) # Seed generator to create the inital latent noise
107
+ batch_size = 1
108
+
109
+ max_length = text_input.input_ids.shape[-1]
110
+ uncond_input = tokenizer(
111
+ [""] * batch_size, padding="max_length", max_length=max_length, return_tensors="pt"
112
+ )
113
+ with torch.no_grad():
114
+ uncond_embeddings = text_encoder(uncond_input.input_ids.to(torch_device))[0]
115
+ text_embeddings = torch.cat([uncond_embeddings, text_embeddings])
116
+
117
+ # Prep Scheduler
118
+ scheduler.set_timesteps(num_inference_steps)
119
+
120
+ # Prep latents
121
+ latents = torch.randn(
122
+ (batch_size, unet.config.in_channels, height // 8, width // 8),
123
+ generator=generator,
124
+ )
125
+ latents = latents.to(torch_device)
126
+ latents = latents * scheduler.init_noise_sigma
127
+
128
+ # Loop
129
+ for i, t in tqdm(enumerate(scheduler.timesteps)):
130
+ # expand the latents if we are doing classifier-free guidance to avoid doing two forward passes.
131
+ latent_model_input = torch.cat([latents] * 2)
132
+ sigma = scheduler.sigmas[i]
133
+ latent_model_input = scheduler.scale_model_input(latent_model_input, t)
134
+
135
+ # predict the noise residual
136
+ with torch.no_grad():
137
+ noise_pred = unet(latent_model_input, t, encoder_hidden_states=text_embeddings)["sample"]
138
+
139
+ # perform guidance
140
+ noise_pred_uncond, noise_pred_text = noise_pred.chunk(2)
141
+ noise_pred = noise_pred_uncond + guidance_scale * (noise_pred_text - noise_pred_uncond)
142
+
143
+ # compute the previous noisy sample x_t -> x_t-1
144
+ latents = scheduler.step(noise_pred, t, latents).prev_sample
145
+
146
+ return latents_to_pil(latents)[0]
147
+
148
+ def ref_loss(images,ref_image):
149
+ # Reference image
150
+ error = torch.abs(images - ref_image).mean()
151
+ return error
152
+
153
+ def inference(prompt, style_index):
154
+
155
+ styles = ['<midjourney-style>', '<hitokomoru-style>','<birb-style>','<summie-style>','<illustration-style>','<m-geo>']
156
+ embed = ['learned_embeds_m.bin','learned_embeds_h.bin', 'learned_embeds.bin', 'learned_embeds_s.bin','learned_embeds_i.bin','learned_embeds_mg.bin']
157
+
158
+
159
+ # Tokenize
160
+ text_input = tokenizer(prompt+" .", padding="max_length", max_length=tokenizer.model_max_length, truncation=True, return_tensors="pt")
161
+ # Access the embedding layer
162
+ token_emb_layer = text_encoder.text_model.embeddings.token_embedding
163
+ token_embeddings = token_emb_layer(text_input.input_ids.to(torch_device))
164
+ pos_emb_layer = text_encoder.text_model.embeddings.position_embedding
165
+
166
+ position_ids = text_encoder.text_model.embeddings.position_ids[:, :77]
167
+ position_embeddings = pos_emb_layer(position_ids)
168
+
169
+ ## Without any Textual Inversion
170
+ input_ids = text_input.input_ids.to(torch_device)
171
+
172
+ # Get token embeddings
173
+ token_embeddings = token_emb_layer(input_ids)
174
+
175
+ # Combine with pos embs
176
+ input_embeddings = token_embeddings + position_embeddings
177
+
178
+ # Feed through to get final output embs
179
+ modified_output_embeddings = get_output_embeds(input_embeddings)
180
+
181
+ # And generate an image with this:
182
+ image1 = generate_with_embs(modified_output_embeddings,text_input)
183
+
184
+ replace_id=269 #replaced dot with Textual Inversion
185
+
186
+ ## midjourney-style
187
+ style = styles[style_index]
188
+ emb = embed[style_index]
189
+
190
+ x_embed = torch.load(emb)
191
+
192
+ # The new embedding - our special birb word
193
+ replacement_token_embedding = x_embed[style].to(torch_device)
194
+
195
+ # Insert this into the token embeddings
196
+ token_embeddings[0, torch.where(input_ids[0]==replace_id)] = replacement_token_embedding.to(torch_device)
197
+
198
+ # Combine with pos embs
199
+ input_embeddings = token_embeddings + position_embeddings
200
+
201
+ # Feed through to get final output embs
202
+ modified_output_embeddings = get_output_embeds(input_embeddings)
203
+
204
+ # And generate an image with this:
205
+ image2 = generate_with_embs(modified_output_embeddings,text_input)
206
+
207
+ prompt1 = 'rainbow'
208
+
209
+ # Tokenize
210
+ text_input1 = tokenizer(prompt1, padding="max_length", max_length=tokenizer.model_max_length, truncation=True, return_tensors="pt")
211
+
212
+ # Access the embedding layer
213
+ token_emb_layer = text_encoder.text_model.embeddings.token_embedding
214
+
215
+ pos_emb_layer = text_encoder.text_model.embeddings.position_embedding
216
+ position_ids = text_encoder.text_model.embeddings.position_ids[:, :77]
217
+ position_embeddings1 = pos_emb_layer(position_ids)
218
+
219
+ input_ids1 = text_input1.input_ids.to(torch_device)
220
+
221
+ # Get token embeddings
222
+ token_embeddings1 = token_emb_layer(input_ids1)
223
+
224
+ # Combine with pos embs
225
+ input_embeddings1 = token_embeddings1 + position_embeddings1
226
+
227
+ # Feed through to get final output embs
228
+ modified_output_embeddings1 = get_output_embeds(input_embeddings1)
229
+
230
+ # And generate an image with this:
231
+ ref_image = generate_with_embs(modified_output_embeddings1, text_input1)
232
+
233
+ ref_latent = pil_to_latent(ref_image)
234
+
235
+ height = 512 # default height of Stable Diffusion
236
+ width = 512 # default width of Stable Diffusion
237
+ num_inference_steps = 10 # # Number of denoising steps
238
+ guidance_scale = 8 # # Scale for classifier-free guidance
239
+ generator = torch.manual_seed(64) # Seed generator to create the inital latent noise
240
+ batch_size = 1
241
+ blue_loss_scale = 200 #
242
+
243
+ # Prep text
244
+ text_input = tokenizer([prompt], padding="max_length", max_length=tokenizer.model_max_length, truncation=True, return_tensors="pt")
245
+ with torch.no_grad():
246
+ text_embeddings = text_encoder(text_input.input_ids.to(torch_device))[0]
247
+
248
+ # And the uncond. input as before:
249
+ max_length = text_input.input_ids.shape[-1]
250
+ uncond_input = tokenizer(
251
+ [""] * batch_size, padding="max_length", max_length=max_length, return_tensors="pt"
252
+ )
253
+ with torch.no_grad():
254
+ uncond_embeddings = text_encoder(uncond_input.input_ids.to(torch_device))[0]
255
+ text_embeddings = torch.cat([uncond_embeddings, text_embeddings])
256
+
257
+ # Prep Scheduler
258
+ scheduler.set_timesteps(num_inference_steps)
259
+
260
+ # Prep latents
261
+ latents = torch.randn(
262
+ (batch_size, unet.config.in_channels, height // 8, width // 8),
263
+ generator=generator,
264
+ )
265
+ latents = latents.to(torch_device)
266
+ latents = latents * scheduler.init_noise_sigma
267
+
268
+ # Loop
269
+ for i, t in tqdm(enumerate(scheduler.timesteps)):
270
+ # expand the latents if we are doing classifier-free guidance to avoid doing two forward passes.
271
+ latent_model_input = torch.cat([latents] * 2)
272
+ sigma = scheduler.sigmas[i]
273
+ latent_model_input = scheduler.scale_model_input(latent_model_input, t)
274
+
275
+ # predict the noise residual
276
+ with torch.no_grad():
277
+ noise_pred = unet(latent_model_input, t, encoder_hidden_states=text_embeddings)["sample"]
278
+
279
+ # perform CFG
280
+ noise_pred_uncond, noise_pred_text = noise_pred.chunk(2)
281
+ noise_pred = noise_pred_uncond + guidance_scale * (noise_pred_text - noise_pred_uncond)
282
+
283
+ #### ADDITIONAL GUIDANCE ###
284
+ if i%5 == 0:
285
+ # Requires grad on the latents
286
+ latents = latents.detach().requires_grad_()
287
+
288
+ # Get the predicted x0:
289
+ # latents_x0 = latents - sigma * noise_pred
290
+ latents_x0 = scheduler.step(noise_pred, t, latents).pred_original_sample
291
+
292
+ # Decode to image space
293
+ denoised_images = vae.decode((1 / 0.18215) * latents_x0).sample / 2 + 0.5 # range (0, 1)
294
+
295
+ #ref image
296
+ with torch.no_grad():
297
+ ref_images = vae.decode((1 / 0.18215) * ref_latent).sample / 2 + 0.5 # range (0, 1)
298
+
299
+ # Calculate loss
300
+ loss = ref_loss(denoised_images,ref_images) * blue_loss_scale
301
+
302
+ # Occasionally print it out
303
+ # if i%10==0:
304
+ # print(i, 'loss:', loss.item())
305
+
306
+ # Get gradient
307
+ cond_grad = torch.autograd.grad(loss, latents)[0]
308
+
309
+ # Modify the latents based on this gradient
310
+ latents = latents.detach() - cond_grad * sigma**2
311
+ scheduler._step_index = scheduler._step_index - 1
312
+
313
+
314
+ # Now step with scheduler
315
+ latents = scheduler.step(noise_pred, t, latents).prev_sample
316
+ #latents = scheduler.step(noise_pred, t, latents).pred_original_sample
317
+
318
+
319
+ image3 = latents_to_pil(latents)[0]
320
+
321
+ return (image1, 'Original Image'), (image2, 'Styled Image'), (image3, 'After Textual Inversion')
322
+
323
+ # Gradio App with num_inference_steps=10
324
+
325
+ title="Textual Inversion in Stable Diffusion"
326
+ description="<p style='text-align: center;'>Textual Inversion in Stable Diffusion.</b></p>"
327
+ gallery = gr.Gallery(label="Generated images", show_label=True, elem_id="gallery", columns=3).style(grid=[2], height="auto")
328
+
329
+ gr.Interface(fn=inference, inputs=["text",
330
+
331
+ gr.Radio([('<midjourney-style>',0), ('<hitokomoru-style>',1),('<birb-style>',2),
332
+ ('<summie-style>',3),('<illustration-style>',4),('<m-geo>',5)] , value = 0, label = 'Styles')],
333
+ outputs = gallery, title = title,
334
+ examples = [['a girl playing in snow',0],
335
+ ['an oil painting of a goddess',1],
336
+ ['a rabbit on the moon', 5 ]], ).launch(debug=True)
337
+
learned_embeds.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:f2e23a8f2d3628ed77acb8151751ecd4efc4017e8da86bc29af10f855ca308d9
3
+ size 3819
learned_embeds_b.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:879da7c2e8287ab071af22a81dc978e5140905d0d802671750112ff47ba391c6
3
+ size 4864
learned_embeds_c.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:fbdcc3699f3ad8b464e63e1360d5acdd0d5fdf97f74c06962dbb08e60fb576ff
3
+ size 3840
learned_embeds_c1.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:278197c4384b90db9faca3b1aef796fa2e305c9b5eb8840289207a71a8f4129c
3
+ size 3819
learned_embeds_h.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:f81a9c575e329e08a24e08f47ae73c5b50dec4bcb557974552549b45e2d1b0d4
3
+ size 3819
learned_embeds_i.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:44d65046c071e37f75f31a7a81a34c50a96080e8a3aedc7cda1094dae5d385f0
3
+ size 3819
learned_embeds_m.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:4865a5d2ecd012985940748023fd80e4fd299837f1dccedb85ee83be5bb1f957
3
+ size 3819
learned_embeds_mg.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:48f9968e6236292263f84f83cc730fe0c37d797415649b2941c0a9a0ca6c2c51
3
+ size 3819
learned_embeds_s.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:bf60867553500a6822e9752ed6ee4f816299069623fc6aa428da9ff81ad3bfec
3
+ size 3819