mvaloatto ysharma HF staff commited on
Commit
8448e25
0 Parent(s):

Duplicate from ysharma/InstructPix2Pix_Chatbot

Browse files

Co-authored-by: yuvraj sharma <ysharma@users.noreply.huggingface.co>

Files changed (5) hide show
  1. .gitattributes +34 -0
  2. README.md +14 -0
  3. app.py +241 -0
  4. requirements.txt +6 -0
  5. style.css +36 -0
.gitattributes ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ *.7z filter=lfs diff=lfs merge=lfs -text
2
+ *.arrow filter=lfs diff=lfs merge=lfs -text
3
+ *.bin filter=lfs diff=lfs merge=lfs -text
4
+ *.bz2 filter=lfs diff=lfs merge=lfs -text
5
+ *.ckpt filter=lfs diff=lfs merge=lfs -text
6
+ *.ftz filter=lfs diff=lfs merge=lfs -text
7
+ *.gz filter=lfs diff=lfs merge=lfs -text
8
+ *.h5 filter=lfs diff=lfs merge=lfs -text
9
+ *.joblib filter=lfs diff=lfs merge=lfs -text
10
+ *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
+ *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
+ *.model filter=lfs diff=lfs merge=lfs -text
13
+ *.msgpack filter=lfs diff=lfs merge=lfs -text
14
+ *.npy filter=lfs diff=lfs merge=lfs -text
15
+ *.npz filter=lfs diff=lfs merge=lfs -text
16
+ *.onnx filter=lfs diff=lfs merge=lfs -text
17
+ *.ot filter=lfs diff=lfs merge=lfs -text
18
+ *.parquet filter=lfs diff=lfs merge=lfs -text
19
+ *.pb filter=lfs diff=lfs merge=lfs -text
20
+ *.pickle filter=lfs diff=lfs merge=lfs -text
21
+ *.pkl filter=lfs diff=lfs merge=lfs -text
22
+ *.pt filter=lfs diff=lfs merge=lfs -text
23
+ *.pth filter=lfs diff=lfs merge=lfs -text
24
+ *.rar filter=lfs diff=lfs merge=lfs -text
25
+ *.safetensors filter=lfs diff=lfs merge=lfs -text
26
+ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
+ *.tar.* filter=lfs diff=lfs merge=lfs -text
28
+ *.tflite filter=lfs diff=lfs merge=lfs -text
29
+ *.tgz filter=lfs diff=lfs merge=lfs -text
30
+ *.wasm filter=lfs diff=lfs merge=lfs -text
31
+ *.xz filter=lfs diff=lfs merge=lfs -text
32
+ *.zip filter=lfs diff=lfs merge=lfs -text
33
+ *.zst filter=lfs diff=lfs merge=lfs -text
34
+ *tfevents* filter=lfs diff=lfs merge=lfs -text
README.md ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: InstructPix2Pix Chatbot
3
+ emoji: ⚡
4
+ colorFrom: blue
5
+ colorTo: purple
6
+ sdk: gradio
7
+ sdk_version: 3.16.2
8
+ app_file: app.py
9
+ pinned: false
10
+ license: mit
11
+ duplicated_from: ysharma/InstructPix2Pix_Chatbot
12
+ ---
13
+
14
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
app.py ADDED
@@ -0,0 +1,241 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import PIL
2
+ import requests
3
+ import torch
4
+ import gradio as gr
5
+ import random
6
+ from PIL import Image
7
+ import os
8
+ import time
9
+ from diffusers import StableDiffusionInstructPix2PixPipeline, EulerAncestralDiscreteScheduler
10
+
11
+ #Loading from Diffusers Library
12
+ model_id = "timbrooks/instruct-pix2pix"
13
+ pipe = StableDiffusionInstructPix2PixPipeline.from_pretrained(model_id, torch_dtype=torch.float16, revision="fp16") #, safety_checker=None)
14
+ pipe.to("cuda")
15
+ #pipe.enable_attention_slicing()
16
+ pipe.enable_xformers_memory_efficient_attention()
17
+ pipe.unet.to(memory_format=torch.channels_last)
18
+
19
+
20
+ help_text = """
21
+ **Note: Please be advised that a safety checker has been implemented in this public space.
22
+ Any attempts to generate inappropriate or NSFW images will result in the display of a black screen
23
+ as a precautionary measure to protect all users. We appreciate your cooperation in
24
+ maintaining a safe and appropriate environment for all members of our community.**
25
+
26
+ New features and bug-fixes:
27
+
28
+ 1. Chat style interface
29
+ 2. Now use **'reverse'** as prompt to get back the previous image after an unwanted edit
30
+ 3. Use **'restart'** as prompt to get back to original image and start over!
31
+ 4. Now you can load larger image files (~5 mb) as well
32
+
33
+ Some notes from the official [instruct-pix2pix](https://huggingface.co/spaces/timbrooks/instruct-pix2pix) Space by the authors and from the official [Diffusers docs](https://huggingface.co/docs/diffusers/main/en/api/pipelines/stable_diffusion/pix2pix) -
34
+
35
+ If you're not getting what you want, there may be a few reasons:
36
+ 1. Is the image not changing enough? Your guidance_scale may be too low. It should be >1. Higher guidance scale encourages to generate images
37
+ that are closely linked to the text `prompt`, usually at the expense of lower image quality. This value dictates how similar the output should
38
+ be to the input. This pipeline requires a value of at least `1`. It's possible your edit requires larger changes from the original image.
39
+
40
+ 2. Alternatively, you can toggle image_guidance_scale. Image guidance scale is to push the generated image towards the inital image. Image guidance
41
+ scale is enabled by setting `image_guidance_scale > 1`. Higher image guidance scale encourages to generate images that are closely
42
+ linked to the source image `image`, usually at the expense of lower image quality.
43
+ 3. I have observed that rephrasing the instruction sometimes improves results (e.g., "turn him into a dog" vs. "make him a dog" vs. "as a dog").
44
+ 4. Increasing the number of steps sometimes improves results.
45
+ 5. Do faces look weird? The Stable Diffusion autoencoder has a hard time with faces that are small in the image. Try:
46
+ * Cropping the image so the face takes up a larger portion of the frame.
47
+ """
48
+
49
+ css = """
50
+ #col-container {max-width: 580px; margin-left: auto; margin-right: auto;}
51
+ a {text-decoration-line: underline; font-weight: 600;}
52
+ .footer {
53
+ margin-bottom: 45px;
54
+ margin-top: 10px;
55
+ text-align: center;
56
+ border-bottom: 1px solid #e5e5e5;
57
+ }
58
+ .footer>p {
59
+ font-size: .8rem;
60
+ display: inline-block;
61
+ padding: 0 10px;
62
+ transform: translateY(10px);
63
+ background: white;
64
+ }
65
+ .dark .footer {
66
+ border-color: #303030;
67
+ }
68
+ .dark .footer>p {
69
+ background: #0b0f19;
70
+ }
71
+ .animate-spin {
72
+ animation: spin 1s linear infinite;
73
+ }
74
+ @keyframes spin {
75
+ from {
76
+ transform: rotate(0deg);
77
+ }
78
+ to {
79
+ transform: rotate(360deg);
80
+ }
81
+ }
82
+ """
83
+
84
+
85
+ def previous(image):
86
+ return image
87
+
88
+ def upload_image(file):
89
+ return Image.open(file)
90
+
91
+ def upload_button_config():
92
+ return gr.update(visible=False)
93
+
94
+ def upload_textbox_config(text_in):
95
+ return gr.update(visible=True)
96
+
97
+ def chat(btn_upload, image_in, in_steps, in_guidance_scale, in_img_guidance_scale, image_hid, img_name, counter_out, image_oneup, prompt, history, progress=gr.Progress(track_tqdm=True)):
98
+ progress(0, desc="Starting...")
99
+ if prompt != '' and prompt.lower() == 'reverse' : #--to add revert functionality later
100
+ history = history or []
101
+ temp_img_name = img_name[:-4]+str(int(time.time()))+'.png'
102
+ image_oneup.save(temp_img_name)
103
+ response = 'Reverted to the last image ' + '<img src="/file=' + temp_img_name + '">'
104
+ history.append((prompt, response))
105
+ return history, history, image_oneup, temp_img_name, counter_out
106
+ if prompt != '' and prompt.lower() == 'restart' : #--to add revert functionality later
107
+ history = history or []
108
+ temp_img_name = img_name[:-4]+str(int(time.time()))+'.png'
109
+ #Resizing the image
110
+ basewidth = 512
111
+ wpercent = (basewidth/float(image_in.size[0]))
112
+ hsize = int((float(image_in.size[1])*float(wpercent)))
113
+ image_in = image_in.resize((basewidth,hsize), Image.Resampling.LANCZOS)
114
+ image_in.save(temp_img_name)
115
+ response = 'Reverted to the last image ' + '<img src="/file=' + temp_img_name + '">'
116
+ history.append((prompt, response))
117
+ return history, history, image_in, temp_img_name, counter_out
118
+ #adding supportive sample text
119
+ add_text_list = ["There you go", "Enjoy your image!", "Nice work! Wonder what you gonna do next!", "Way to go!", "Does this work for you?", "Something like this?"]
120
+ if counter_out == 0:
121
+ t1 = time.time()
122
+ print(f"Time at start = {t1}")
123
+ #convert file object to image
124
+ image_in = Image.open(btn_upload)
125
+
126
+ #Resizing the image
127
+ basewidth = 512
128
+ wpercent = (basewidth/float(image_in.size[0]))
129
+ hsize = int((float(image_in.size[1])*float(wpercent)))
130
+ image_in = image_in.resize((basewidth,hsize), Image.Resampling.LANCZOS)
131
+
132
+ # Save the image to the file-like object
133
+ seed = random.randint(0, 1000000)
134
+ img_name = f"./edited_image_{seed}.png"
135
+ image_in.save(img_name)
136
+
137
+ #add state
138
+ history = history or []
139
+ response = '<img src="/file=' + img_name + '">'
140
+ history.append((prompt, response))
141
+ counter_out += 1
142
+
143
+ t2 = time.time()
144
+ print(f"Time at end = {t2}")
145
+ time_diff = t2-t1
146
+ print(f"Time taken = {time_diff}")
147
+ return history, history, image_in, img_name, counter_out
148
+
149
+ elif counter_out == 1:
150
+ #instruct-pix2pix inference
151
+ edited_image = pipe(prompt, image=image_in, num_inference_steps=int(in_steps), guidance_scale=float(in_guidance_scale), image_guidance_scale=float(in_img_guidance_scale)).images[0]
152
+ if os.path.exists(img_name):
153
+ os.remove(img_name)
154
+ temp_img_name = img_name[:-4]+str(int(time.time()))[-4:] +'.png'
155
+ with open(temp_img_name, "wb") as fp:
156
+ # Save the image to the file-like object
157
+ edited_image.save(fp)
158
+ #Get the name of the saved image
159
+ saved_image_name1 = fp.name
160
+ history = history or []
161
+ response = random.choice(add_text_list) + '<img src="/file=' + saved_image_name1 + '">' #IMG_NAME
162
+ history.append((prompt, response))
163
+ counter_out += 1
164
+ return history, history, edited_image, temp_img_name, counter_out
165
+
166
+ elif counter_out > 1:
167
+ edited_image = pipe(prompt, image=image_hid, num_inference_steps=int(in_steps), guidance_scale=float(in_guidance_scale), image_guidance_scale=float(in_img_guidance_scale)).images[0]
168
+ if os.path.exists(img_name):
169
+ os.remove(img_name)
170
+ temp_img_name = img_name[:-4]+str(int(time.time()))[-4:]+'.png'
171
+ # Create a file-like object
172
+ with open(temp_img_name, "wb") as fp:
173
+ # Save the image to the file-like object
174
+ edited_image.save(fp)
175
+ #Get the name of the saved image
176
+ saved_image_name2 = fp.name
177
+ #edited_image.save(temp_img_name) #, overwrite=True)
178
+ history = history or []
179
+ response = random.choice(add_text_list) + '<img src="/file=' + saved_image_name2 + '">'
180
+ history.append((prompt, response))
181
+ counter_out += 1
182
+ return history, history, edited_image, temp_img_name, counter_out
183
+
184
+
185
+ #Blocks layout
186
+ with gr.Blocks(css="style.css") as demo:
187
+ with gr.Column(elem_id="col-container"):
188
+ gr.HTML("""<div style="text-align: center; max-width: 700px; margin: 0 auto;">
189
+ <div
190
+ style="
191
+ display: inline-flex;
192
+ align-items: center;
193
+ gap: 0.8rem;
194
+ font-size: 1.75rem;
195
+ "
196
+ >
197
+ <h1 style="font-weight: 900; margin-bottom: 7px; margin-top: 5px;">
198
+ ChatPix2Pix: Image Editing by Instructions
199
+ </h1>
200
+ </div>
201
+ <p style="margin-bottom: 10px; font-size: 94%">
202
+ Hi, I'm a photoshop expert bot, start by uploading your image using the upload button, and then tell me what changes you want to make to it.<br>
203
+ <a href="https://huggingface.co/spaces/ysharma/InstructPix2Pix_Chatbot?duplicate=true"><img src="https://bit.ly/3gLdBN6" alt="Duplicate Space"></a>Duplicate Space with GPU Upgrade for fast Inference & no queue<br>
204
+ Based on <a href="https://huggingface.co/timbrooks/instruct-pix2pix" target="_blank">Diffusers implementation</a> of InstructPix2Pix.
205
+ </p>
206
+ </div>""")
207
+ with gr.Accordion("Advance settings for Training and Inference", open=False):
208
+ image_in = gr.Image(visible=False,type='pil', label="Original Image")
209
+ gr.Markdown("Advance settings for - Number of Inference steps, Guidanace scale, and Image guidance scale.")
210
+ in_steps = gr.Number(label="Enter the number of Inference steps", value = 20)
211
+ in_guidance_scale = gr.Slider(1,10, step=0.5, label="Set Guidance scale", value=7.5)
212
+ in_img_guidance_scale = gr.Slider(1,10, step=0.5, label="Set Image Guidance scale", value=1.5)
213
+ image_hid = gr.Image(type='pil', visible=False)
214
+ image_oneup = gr.Image(type='pil', visible=False)
215
+ img_name_temp_out = gr.Textbox(visible=False)
216
+ counter_out = gr.Number(visible=False, value=0, precision=0)
217
+
218
+ #with gr.Row():
219
+ text_in = gr.Textbox(value='', placeholder="Type your instructions here and press enter", elem_id = "input_prompt", visible=False, label='Great! Now you can edit your image with Instructions')
220
+ btn_upload = gr.UploadButton("Upload image to start editing", file_types=["image"], file_count="single", elem_id="upload_button")
221
+
222
+ chatbot = gr.Chatbot(elem_id = 'chatbot-component', label='Conversational editing for Images')
223
+ state_in = gr.State()
224
+
225
+ #Using Event Listeners
226
+ btn_upload.upload(chat,
227
+ [btn_upload, image_in, in_steps, in_guidance_scale, in_img_guidance_scale, image_hid, img_name_temp_out,counter_out, image_oneup, text_in, state_in],
228
+ [chatbot, state_in, image_in, img_name_temp_out, counter_out])
229
+ btn_upload.upload(fn = upload_textbox_config, inputs=text_in, outputs = text_in)
230
+
231
+ text_in.submit(chat,[btn_upload, image_in, in_steps, in_guidance_scale, in_img_guidance_scale, image_hid, img_name_temp_out,counter_out, image_oneup, text_in, state_in], [chatbot, state_in, image_hid, img_name_temp_out, counter_out])
232
+ text_in.submit(previous, [image_hid], [image_oneup])
233
+
234
+ chatbot.change(fn = upload_button_config, outputs=btn_upload) #, scroll_to_output = True)
235
+ text_in.submit(None, [], [], _js = "() => document.getElementById('#chatbot-component').scrollTop = document.getElementById('#chatbot-component').scrollHeight")
236
+
237
+ #with gr.Accordion("Release Notes", open=False):
238
+ gr.Markdown(help_text)
239
+
240
+ demo.queue(concurrency_count=10)
241
+ demo.launch(debug=True, width="80%", height=2000)
requirements.txt ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ git+https://github.com/huggingface/diffusers.git
2
+ transformers
3
+ accelerate
4
+ safetensors
5
+ --pre
6
+ xformers
style.css ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #col-container {max-width: 700px; margin-left: auto; margin-right: auto;}
2
+ a {text-decoration-line: underline; font-weight: 600;}
3
+ .footer {
4
+ margin-bottom: 45px;
5
+ margin-top: 10px;
6
+ text-align: center;
7
+ border-bottom: 1px solid #e5e5e5;
8
+ }
9
+ .footer>p {
10
+ font-size: .8rem;
11
+ display: inline-block;
12
+ padding: 0 10px;
13
+ transform: translateY(10px);
14
+ background: white;
15
+ }
16
+ .dark .footer {
17
+ border-color: #303030;
18
+ }
19
+ .dark .footer>p {
20
+ background: #0b0f19;
21
+ }
22
+ .animate-spin {
23
+ animation: spin 1s linear infinite;
24
+ }
25
+ @keyframes spin {
26
+ from {
27
+ transform: rotate(0deg);
28
+ }
29
+ to {
30
+ transform: rotate(360deg);
31
+ }
32
+ }
33
+ #upload_button {
34
+ background-color: black;
35
+ color: white;
36
+ }