Deadmon commited on
Commit
62d1104
·
verified ·
1 Parent(s): bb75d67

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +35 -44
app.py CHANGED
@@ -1,8 +1,7 @@
1
  import torch
2
  import spaces
3
- from diffusers import StableDiffusionPipeline, DDIMScheduler, AutoencoderKL
4
  from transformers import AutoFeatureExtractor
5
- from diffusers.pipelines.stable_diffusion.safety_checker import StableDiffusionSafetyChecker
6
  from ip_adapter.ip_adapter_faceid import IPAdapterFaceID, IPAdapterFaceIDPlus
7
  from huggingface_hub import hf_hub_download
8
  from insightface.app import FaceAnalysis
@@ -10,16 +9,10 @@ from insightface.utils import face_align
10
  import gradio as gr
11
  import cv2
12
 
13
- base_model_path = "SG161222/Realistic_Vision_V4.0_noVAE"
14
  vae_model_path = "stabilityai/sd-vae-ft-mse"
15
  image_encoder_path = "laion/CLIP-ViT-H-14-laion2B-s32B-b79K"
16
  ip_ckpt = hf_hub_download(repo_id="h94/IP-Adapter-FaceID", filename="ip-adapter-faceid_sd15.bin", repo_type="model")
17
  ip_plus_ckpt = hf_hub_download(repo_id="h94/IP-Adapter-FaceID", filename="ip-adapter-faceid-plusv2_sd15.bin", repo_type="model")
18
-
19
- safety_model_id = "CompVis/stable-diffusion-safety-checker"
20
- safety_feature_extractor = AutoFeatureExtractor.from_pretrained(safety_model_id)
21
- safety_checker = StableDiffusionSafetyChecker.from_pretrained(safety_model_id)
22
-
23
  device = "cuda"
24
 
25
  noise_scheduler = DDIMScheduler(
@@ -31,25 +24,18 @@ noise_scheduler = DDIMScheduler(
31
  set_alpha_to_one=False,
32
  steps_offset=1,
33
  )
 
34
  vae = AutoencoderKL.from_pretrained(vae_model_path).to(dtype=torch.float16)
35
- pipe = StableDiffusionPipeline.from_pretrained(
36
- base_model_path,
37
- torch_dtype=torch.float16,
38
- scheduler=noise_scheduler,
39
- vae=vae,
40
- feature_extractor=safety_feature_extractor,
41
- safety_checker=safety_checker
42
- ).to(device)
43
 
44
- #pipe.load_lora_weights("h94/IP-Adapter-FaceID", weight_name="ip-adapter-faceid-plusv2_sd15_lora.safetensors")
45
- #pipe.fuse_lora()
 
46
 
47
  ip_model = IPAdapterFaceID(pipe, ip_ckpt, device)
48
  ip_model_plus = IPAdapterFaceIDPlus(pipe, image_encoder_path, ip_plus_ckpt, device)
49
 
50
  app = FaceAnalysis(name="buffalo_l", providers=['CPUExecutionProvider'])
51
  app.prepare(ctx_id=0, det_size=(640, 640))
52
-
53
  cv2.setNumThreads(1)
54
 
55
  @spaces.GPU(enable_queue=True)
@@ -62,24 +48,34 @@ def generate_image(images, prompt, negative_prompt, preserve_face_structure, fac
62
  faceid_embed = torch.from_numpy(faces[0].normed_embedding).unsqueeze(0)
63
  faceid_all_embeds.append(faceid_embed)
64
  if(first_iteration and preserve_face_structure):
65
- face_image = face_align.norm_crop(face, landmark=faces[0].kps, image_size=224) # you can also segment the face
66
  first_iteration = False
67
-
68
  average_embedding = torch.mean(torch.stack(faceid_all_embeds, dim=0), dim=0)
69
-
70
  total_negative_prompt = f"{negative_prompt} {nfaa_negative_prompt}"
71
-
72
  if(not preserve_face_structure):
73
  print("Generating normal")
74
  image = ip_model.generate(
75
- prompt=prompt, negative_prompt=total_negative_prompt, faceid_embeds=average_embedding,
76
- scale=likeness_strength, width=512, height=512, num_inference_steps=30
 
 
 
 
 
77
  )
78
  else:
79
  print("Generating plus")
80
  image = ip_model_plus.generate(
81
- prompt=prompt, negative_prompt=total_negative_prompt, faceid_embeds=average_embedding,
82
- scale=likeness_strength, face_image=face_image, shortcut=True, s_scale=face_strength, width=512, height=512, num_inference_steps=30
 
 
 
 
 
 
 
 
83
  )
84
  print(image)
85
  return image
@@ -95,24 +91,24 @@ def swap_to_gallery(images):
95
 
96
  def remove_back_to_files():
97
  return gr.update(visible=False), gr.update(visible=False), gr.update(visible=True)
 
98
  css = '''
99
  h1{margin-bottom: 0 !important}
100
  '''
 
101
  with gr.Blocks(css=css) as demo:
102
  gr.Markdown("# IP-Adapter-FaceID Plus demo")
103
  gr.Markdown("Demo for the [h94/IP-Adapter-FaceID model](https://huggingface.co/h94/IP-Adapter-FaceID) - Generate AI images with your own face - Non-commercial license")
104
  with gr.Row():
105
  with gr.Column():
106
  files = gr.Files(
107
- label="Drag 1 or more photos of your face",
108
- file_types=["image"]
109
- )
110
  uploaded_files = gr.Gallery(label="Your images", visible=False, columns=5, rows=1, height=125)
111
  with gr.Column(visible=False) as clear_button:
112
  remove_and_reupload = gr.ClearButton(value="Remove and upload new ones", components=files, size="sm")
113
- prompt = gr.Textbox(label="Prompt",
114
- info="Try something like 'a photo of a man/woman/person'",
115
- placeholder="A photo of a [man/woman/person]...")
116
  negative_prompt = gr.Textbox(label="Negative Prompt", placeholder="low quality")
117
  style = gr.Radio(label="Generation type", info="For stylized try prompts like 'a watercolor painting of a woman'", choices=["Photorealistic", "Stylized"], value="Photorealistic")
118
  submit = gr.Button("Submit")
@@ -120,18 +116,13 @@ with gr.Blocks(css=css) as demo:
120
  preserve = gr.Checkbox(label="Preserve Face Structure", info="Higher quality, less versatility (the face structure of your first photo will be preserved). Unchecking this will use the v1 model.", value=True)
121
  face_strength = gr.Slider(label="Face Structure strength", info="Only applied if preserve face structure is checked", value=1.3, step=0.1, minimum=0, maximum=3)
122
  likeness_strength = gr.Slider(label="Face Embed strength", value=1.0, step=0.1, minimum=0, maximum=5)
123
- nfaa_negative_prompts = gr.Textbox(label="Appended Negative Prompts", info="Negative prompts to steer generations towards safe for all audiences outputs", value="naked, bikini, skimpy, scanty, bare skin, lingerie, swimsuit, exposed, see-through")
124
  with gr.Column():
125
  gallery = gr.Gallery(label="Generated Images")
126
- style.change(fn=change_style,
127
- inputs=style,
128
- outputs=[preserve, face_strength, likeness_strength])
129
- files.upload(fn=swap_to_gallery, inputs=files, outputs=[uploaded_files, clear_button, files])
130
- remove_and_reupload.click(fn=remove_back_to_files, outputs=[uploaded_files, clear_button, files])
131
- submit.click(fn=generate_image,
132
- inputs=[files,prompt,negative_prompt,preserve, face_strength, likeness_strength, nfaa_negative_prompts],
133
- outputs=gallery)
134
-
135
  gr.Markdown("This demo includes extra features to mitigate the implicit bias of the model and prevent explicit usage of it to generate content with faces of people, including third parties, that is not safe for all audiences, including naked or semi-naked people.")
136
-
137
  demo.launch()
 
1
  import torch
2
  import spaces
3
+ from diffusers import StableDiffusionPipeline, DDIMScheduler, AutoencoderKL, DiffusionPipeline
4
  from transformers import AutoFeatureExtractor
 
5
  from ip_adapter.ip_adapter_faceid import IPAdapterFaceID, IPAdapterFaceIDPlus
6
  from huggingface_hub import hf_hub_download
7
  from insightface.app import FaceAnalysis
 
9
  import gradio as gr
10
  import cv2
11
 
 
12
  vae_model_path = "stabilityai/sd-vae-ft-mse"
13
  image_encoder_path = "laion/CLIP-ViT-H-14-laion2B-s32B-b79K"
14
  ip_ckpt = hf_hub_download(repo_id="h94/IP-Adapter-FaceID", filename="ip-adapter-faceid_sd15.bin", repo_type="model")
15
  ip_plus_ckpt = hf_hub_download(repo_id="h94/IP-Adapter-FaceID", filename="ip-adapter-faceid-plusv2_sd15.bin", repo_type="model")
 
 
 
 
 
16
  device = "cuda"
17
 
18
  noise_scheduler = DDIMScheduler(
 
24
  set_alpha_to_one=False,
25
  steps_offset=1,
26
  )
27
+
28
  vae = AutoencoderKL.from_pretrained(vae_model_path).to(dtype=torch.float16)
 
 
 
 
 
 
 
 
29
 
30
+ pipeline = DiffusionPipeline.from_pretrained("fluently/Fluently-XL-v2")
31
+ pipeline.load_lora_weights("ehristoforu/dalle-3-xl-v2")
32
+ pipe = pipeline.to(device)
33
 
34
  ip_model = IPAdapterFaceID(pipe, ip_ckpt, device)
35
  ip_model_plus = IPAdapterFaceIDPlus(pipe, image_encoder_path, ip_plus_ckpt, device)
36
 
37
  app = FaceAnalysis(name="buffalo_l", providers=['CPUExecutionProvider'])
38
  app.prepare(ctx_id=0, det_size=(640, 640))
 
39
  cv2.setNumThreads(1)
40
 
41
  @spaces.GPU(enable_queue=True)
 
48
  faceid_embed = torch.from_numpy(faces[0].normed_embedding).unsqueeze(0)
49
  faceid_all_embeds.append(faceid_embed)
50
  if(first_iteration and preserve_face_structure):
51
+ face_image = face_align.norm_crop(face, landmark=faces[0].kps, image_size=224)
52
  first_iteration = False
 
53
  average_embedding = torch.mean(torch.stack(faceid_all_embeds, dim=0), dim=0)
 
54
  total_negative_prompt = f"{negative_prompt} {nfaa_negative_prompt}"
 
55
  if(not preserve_face_structure):
56
  print("Generating normal")
57
  image = ip_model.generate(
58
+ prompt=prompt,
59
+ negative_prompt=total_negative_prompt,
60
+ faceid_embeds=average_embedding,
61
+ scale=likeness_strength,
62
+ width=512,
63
+ height=512,
64
+ num_inference_steps=30
65
  )
66
  else:
67
  print("Generating plus")
68
  image = ip_model_plus.generate(
69
+ prompt=prompt,
70
+ negative_prompt=total_negative_prompt,
71
+ faceid_embeds=average_embedding,
72
+ scale=likeness_strength,
73
+ face_image=face_image,
74
+ shortcut=True,
75
+ s_scale=face_strength,
76
+ width=512,
77
+ height=512,
78
+ num_inference_steps=30
79
  )
80
  print(image)
81
  return image
 
91
 
92
  def remove_back_to_files():
93
  return gr.update(visible=False), gr.update(visible=False), gr.update(visible=True)
94
+
95
  css = '''
96
  h1{margin-bottom: 0 !important}
97
  '''
98
+
99
  with gr.Blocks(css=css) as demo:
100
  gr.Markdown("# IP-Adapter-FaceID Plus demo")
101
  gr.Markdown("Demo for the [h94/IP-Adapter-FaceID model](https://huggingface.co/h94/IP-Adapter-FaceID) - Generate AI images with your own face - Non-commercial license")
102
  with gr.Row():
103
  with gr.Column():
104
  files = gr.Files(
105
+ label="Drag 1 or more photos of your face",
106
+ file_types=["image"]
107
+ )
108
  uploaded_files = gr.Gallery(label="Your images", visible=False, columns=5, rows=1, height=125)
109
  with gr.Column(visible=False) as clear_button:
110
  remove_and_reupload = gr.ClearButton(value="Remove and upload new ones", components=files, size="sm")
111
+ prompt = gr.Textbox(label="Prompt", info="Try something like 'a photo of a man/woman/person'", placeholder="A photo of a [man/woman/person]...")
 
 
112
  negative_prompt = gr.Textbox(label="Negative Prompt", placeholder="low quality")
113
  style = gr.Radio(label="Generation type", info="For stylized try prompts like 'a watercolor painting of a woman'", choices=["Photorealistic", "Stylized"], value="Photorealistic")
114
  submit = gr.Button("Submit")
 
116
  preserve = gr.Checkbox(label="Preserve Face Structure", info="Higher quality, less versatility (the face structure of your first photo will be preserved). Unchecking this will use the v1 model.", value=True)
117
  face_strength = gr.Slider(label="Face Structure strength", info="Only applied if preserve face structure is checked", value=1.3, step=0.1, minimum=0, maximum=3)
118
  likeness_strength = gr.Slider(label="Face Embed strength", value=1.0, step=0.1, minimum=0, maximum=5)
119
+ nfaa_negative_prompts = gr.Textbox(label="Appended Negative Prompts", info="Negative prompts to steer generations towards safe for all audiences outputs", value="naked, bikini, skimpy, scanty, bare skin, lingerie, swimsuit, exposed, see-through")
120
  with gr.Column():
121
  gallery = gr.Gallery(label="Generated Images")
122
+ style.change(fn=change_style, inputs=style, outputs=[preserve, face_strength, likeness_strength])
123
+ files.upload(fn=swap_to_gallery, inputs=files, outputs=[uploaded_files, clear_button, files])
124
+ remove_and_reupload.click(fn=remove_back_to_files, outputs=[uploaded_files, clear_button, files])
125
+ submit.click(fn=generate_image, inputs=[files,prompt,negative_prompt,preserve, face_strength, likeness_strength, nfaa_negative_prompts], outputs=gallery)
 
 
 
 
 
126
  gr.Markdown("This demo includes extra features to mitigate the implicit bias of the model and prevent explicit usage of it to generate content with faces of people, including third parties, that is not safe for all audiences, including naked or semi-naked people.")
127
+
128
  demo.launch()