GeeveGeorge commited on
Commit
2ad97ea
β€’
1 Parent(s): 44dcb2b

faster inference using new diffusers update. vae tiling and cpu offloading, much faster inference on zero gpu.

Browse files
Files changed (1) hide show
  1. app.py +42 -65
app.py CHANGED
@@ -4,54 +4,47 @@ import threading
4
  import time
5
 
6
  import gradio as gr
7
- import numpy as np
8
  import torch
9
- from diffusers import CogVideoXPipeline
 
 
10
  from datetime import datetime, timedelta
11
  from openai import OpenAI
12
  import spaces
13
- import imageio
14
  import moviepy.editor as mp
15
  from typing import List, Union
16
  import PIL
17
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
  dtype = torch.float16
19
  device = "cuda" if torch.cuda.is_available() else "cpu"
20
- pipe = CogVideoXPipeline.from_pretrained("THUDM/CogVideoX-2b", torch_dtype=dtype).to(device)
 
 
 
21
 
22
  sys_prompt = """You are part of a team of bots that creates videos. You work with an assistant bot that will draw anything you say in square brackets.
23
-
24
  For example , outputting " a beautiful morning in the woods with the sun peaking through the trees " will trigger your partner bot to output an video of a forest morning , as described. You will be prompted by people looking to create detailed , amazing videos. The way to accomplish this is to take their short prompts and make them extremely detailed and descriptive.
25
  There are a few rules to follow:
26
-
27
  You will only ever output a single video description per user request.
28
-
29
  When modifications are requested , you should not simply make the description longer . You should refactor the entire description to integrate the suggestions.
30
  Other times the user will not want modifications , but instead want a new image . In this case , you should ignore your previous conversation with the user.
31
-
32
  Video descriptions must have the same num of words as examples below. Extra words will be ignored.
33
  """
34
 
35
-
36
- def export_to_video_imageio(
37
- video_frames: Union[List[np.ndarray], List[PIL.Image.Image]], output_video_path: str = None, fps: int = 8
38
- ) -> str:
39
- """
40
- Export the video frames to a video file using imageio lib to Avoid "green screen" issue (for example CogVideoX)
41
- """
42
- if output_video_path is None:
43
- output_video_path = tempfile.NamedTemporaryFile(suffix=".mp4").name
44
-
45
- if isinstance(video_frames[0], PIL.Image.Image):
46
- video_frames = [np.array(frame) for frame in video_frames]
47
-
48
- with imageio.get_writer(output_video_path, fps=fps) as writer:
49
- for frame in video_frames:
50
- writer.append_data(frame)
51
-
52
- return output_video_path
53
-
54
-
55
  def convert_prompt(prompt: str, retry_times: int = 3) -> str:
56
  if not os.environ.get("OPENAI_API_KEY"):
57
  return prompt
@@ -87,7 +80,6 @@ def convert_prompt(prompt: str, retry_times: int = 3) -> str:
87
  return response.choices[0].message.content
88
  return prompt
89
 
90
-
91
  @spaces.GPU(duration=240)
92
  def infer(
93
  prompt: str,
@@ -95,34 +87,25 @@ def infer(
95
  guidance_scale: float,
96
  progress=gr.Progress(track_tqdm=True)
97
  ):
98
- torch.cuda.empty_cache()
99
-
100
- prompt_embeds, _ = pipe.encode_prompt(
101
- prompt=prompt,
102
- negative_prompt=None,
103
- do_classifier_free_guidance=True,
104
- num_videos_per_prompt=1,
105
- max_sequence_length=226,
106
- device=device,
107
- dtype=dtype,
108
- )
109
-
110
- video = pipe(
111
- num_inference_steps=num_inference_steps,
112
- guidance_scale=guidance_scale,
113
- prompt_embeds=prompt_embeds,
114
- negative_prompt_embeds=torch.zeros_like(prompt_embeds),
115
- ).frames[0]
116
-
117
-
118
  return video
119
 
120
-
121
  def save_video(tensor):
122
  timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
123
  video_path = f"./output/{timestamp}.mp4"
124
  os.makedirs(os.path.dirname(video_path), exist_ok=True)
125
- export_to_video_imageio(tensor[1:], video_path)
126
  return video_path
127
 
128
  def convert_to_gif(video_path):
@@ -133,7 +116,6 @@ def convert_to_gif(video_path):
133
  clip.write_gif(gif_path, fps=8)
134
  return gif_path
135
 
136
-
137
  def delete_old_files():
138
  while True:
139
  now = datetime.now()
@@ -147,7 +129,6 @@ def delete_old_files():
147
  os.remove(file_path)
148
  time.sleep(600) # Sleep for 10 minutes
149
 
150
-
151
  threading.Thread(target=delete_old_files, daemon=True).start()
152
 
153
  with gr.Blocks() as demo:
@@ -160,7 +141,6 @@ with gr.Blocks() as demo:
160
  <a href="https://github.com/THUDM/CogVideo">🌐 Github</a> |
161
  <a href="https://arxiv.org/pdf/2408.06072">πŸ“œ arxiv </a>
162
  </div>
163
-
164
  <div style="text-align: center; font-size: 15px; font-weight: bold; color: red; margin-bottom: 20px;">
165
  ⚠️ This demo is for academic research and experiential use only.
166
  Users should strictly adhere to local laws and ethics.
@@ -177,9 +157,9 @@ with gr.Blocks() as demo:
177
  with gr.Column():
178
  gr.Markdown("**Optional Parameters** (default values are recommended)<br>"
179
  "Turn Inference Steps larger if you want more detailed video, but it will be slower.<br>"
180
- "50 steps are recommended for most cases. will cause 120 seconds for inference.<br>")
181
  with gr.Row():
182
- num_inference_steps = gr.Number(label="Inference Steps", value=50)
183
  guidance_scale = gr.Number(label="Guidance Scale", value=6.0)
184
  generate_button = gr.Button("🎬 Generate Video")
185
 
@@ -200,31 +180,30 @@ with gr.Blocks() as demo:
200
  <tr>
201
  <td>A detailed wooden toy ship with intricately carved masts and sails is seen gliding smoothly over a plush, blue carpet that mimics the waves of the sea. The ship's hull is painted a rich brown, with tiny windows. The carpet, soft and textured, provides a perfect backdrop, resembling an oceanic expanse. Surrounding the ship are various other toys and children's items, hinting at a playful environment. The scene captures the innocence and imagination of childhood, with the toy ship's journey symbolizing endless adventures in a whimsical, indoor setting.</td>
202
  <td><a href="https://github.com/THUDM/CogVideo/raw/main/resources/videos/1.mp4">Video 1</a></td>
203
- <td>50</td>
204
  <td>6</td>
205
  </tr>
206
  <tr>
207
- <td>The camera follows behind a white vintage SUV with a black roof rack as it speeds up a steep dirt road surrounded by pine trees on a steep mountain slope, dust kicks up from it’s tires, the sunlight shines on the SUV as it speeds along the dirt road, casting a warm glow over the scene. The dirt road curves gently into the distance, with no other cars or vehicles in sight. The trees on either side of the road are redwoods, with patches of greenery scattered throughout. The car is seen from the rear following the curve with ease, making it seem as if it is on a rugged drive through the rugged terrain. The dirt road itself is surrounded by steep hills and mountains, with a clear blue sky above with wispy clouds.</td>
208
  <td><a href="https://github.com/THUDM/CogVideo/raw/main/resources/videos/2.mp4">Video 2</a></td>
209
- <td>50</td>
210
  <td>6</td>
211
  </tr>
212
  <tr>
213
  <td>A street artist, clad in a worn-out denim jacket and a colorful bandana, stands before a vast concrete wall in the heart, holding a can of spray paint, spray-painting a colorful bird on a mottled wall.</td>
214
  <td><a href="https://github.com/THUDM/CogVideo/raw/main/resources/videos/3.mp4">Video 3</a></td>
215
- <td>50</td>
216
  <td>6</td>
217
  </tr>
218
  <tr>
219
  <td>In the haunting backdrop of a war-torn city, where ruins and crumbled walls tell a story of devastation, a poignant close-up frames a young girl. Her face is smudged with ash, a silent testament to the chaos around her. Her eyes glistening with a mix of sorrow and resilience, capturing the raw emotion of a world that has lost its innocence to the ravages of conflict.</td>
220
  <td><a href="https://github.com/THUDM/CogVideo/raw/main/resources/videos/4.mp4">Video 4</a></td>
221
- <td>50</td>
222
  <td>6</td>
223
  </tr>
224
  </table>
225
  """)
226
 
227
-
228
  def generate(prompt, num_inference_steps, guidance_scale, progress=gr.Progress(track_tqdm=True)):
229
  tensor = infer(prompt, num_inference_steps, guidance_scale, progress=progress)
230
  video_path = save_video(tensor)
@@ -234,11 +213,9 @@ with gr.Blocks() as demo:
234
 
235
  return video_path, video_update, gif_update
236
 
237
-
238
  def enhance_prompt_func(prompt):
239
  return convert_prompt(prompt, retry_times=1)
240
 
241
-
242
  generate_button.click(
243
  generate,
244
  inputs=[prompt, num_inference_steps, guidance_scale],
@@ -252,4 +229,4 @@ with gr.Blocks() as demo:
252
  )
253
 
254
  if __name__ == "__main__":
255
- demo.launch()
 
4
  import time
5
 
6
  import gradio as gr
 
7
  import torch
8
+ import gc
9
+ from diffusers import CogVideoXPipeline, CogVideoXDDIMScheduler
10
+ from diffusers.utils import export_to_video
11
  from datetime import datetime, timedelta
12
  from openai import OpenAI
13
  import spaces
 
14
  import moviepy.editor as mp
15
  from typing import List, Union
16
  import PIL
17
 
18
+ def reset_memory():
19
+ gc.collect()
20
+ torch.cuda.empty_cache()
21
+ torch.cuda.reset_accumulated_memory_stats()
22
+ torch.cuda.reset_peak_memory_stats()
23
+
24
+ def print_memory():
25
+ memory = round(torch.cuda.memory_allocated() / 1024**3, 2)
26
+ max_memory = round(torch.cuda.max_memory_allocated() / 1024**3, 2)
27
+ max_reserved = round(torch.cuda.max_memory_reserved() / 1024**3, 2)
28
+ print(f"{memory=} GB")
29
+ print(f"{max_memory=} GB")
30
+ print(f"{max_reserved=} GB")
31
+
32
  dtype = torch.float16
33
  device = "cuda" if torch.cuda.is_available() else "cpu"
34
+ pipe = CogVideoXPipeline.from_pretrained("THUDM/CogVideoX-2b", torch_dtype=dtype)
35
+ pipe.scheduler = CogVideoXDDIMScheduler.from_config(pipe.scheduler.config, timestep_spacing="trailing")
36
+ pipe.enable_sequential_cpu_offload()
37
+ pipe.vae.enable_tiling()
38
 
39
  sys_prompt = """You are part of a team of bots that creates videos. You work with an assistant bot that will draw anything you say in square brackets.
 
40
  For example , outputting " a beautiful morning in the woods with the sun peaking through the trees " will trigger your partner bot to output an video of a forest morning , as described. You will be prompted by people looking to create detailed , amazing videos. The way to accomplish this is to take their short prompts and make them extremely detailed and descriptive.
41
  There are a few rules to follow:
 
42
  You will only ever output a single video description per user request.
 
43
  When modifications are requested , you should not simply make the description longer . You should refactor the entire description to integrate the suggestions.
44
  Other times the user will not want modifications , but instead want a new image . In this case , you should ignore your previous conversation with the user.
 
45
  Video descriptions must have the same num of words as examples below. Extra words will be ignored.
46
  """
47
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
  def convert_prompt(prompt: str, retry_times: int = 3) -> str:
49
  if not os.environ.get("OPENAI_API_KEY"):
50
  return prompt
 
80
  return response.choices[0].message.content
81
  return prompt
82
 
 
83
  @spaces.GPU(duration=240)
84
  def infer(
85
  prompt: str,
 
87
  guidance_scale: float,
88
  progress=gr.Progress(track_tqdm=True)
89
  ):
90
+ reset_memory()
91
+
92
+ with torch.cuda.amp.autocast():
93
+ video = pipe(
94
+ prompt=prompt,
95
+ num_frames=48,
96
+ guidance_scale=guidance_scale,
97
+ num_inference_steps=num_inference_steps,
98
+ generator=torch.Generator().manual_seed(42)
99
+ ).frames[0]
100
+
101
+ print_memory()
 
 
 
 
 
 
 
 
102
  return video
103
 
 
104
  def save_video(tensor):
105
  timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
106
  video_path = f"./output/{timestamp}.mp4"
107
  os.makedirs(os.path.dirname(video_path), exist_ok=True)
108
+ export_to_video(tensor, video_path, fps=8)
109
  return video_path
110
 
111
  def convert_to_gif(video_path):
 
116
  clip.write_gif(gif_path, fps=8)
117
  return gif_path
118
 
 
119
  def delete_old_files():
120
  while True:
121
  now = datetime.now()
 
129
  os.remove(file_path)
130
  time.sleep(600) # Sleep for 10 minutes
131
 
 
132
  threading.Thread(target=delete_old_files, daemon=True).start()
133
 
134
  with gr.Blocks() as demo:
 
141
  <a href="https://github.com/THUDM/CogVideo">🌐 Github</a> |
142
  <a href="https://arxiv.org/pdf/2408.06072">πŸ“œ arxiv </a>
143
  </div>
 
144
  <div style="text-align: center; font-size: 15px; font-weight: bold; color: red; margin-bottom: 20px;">
145
  ⚠️ This demo is for academic research and experiential use only.
146
  Users should strictly adhere to local laws and ethics.
 
157
  with gr.Column():
158
  gr.Markdown("**Optional Parameters** (default values are recommended)<br>"
159
  "Turn Inference Steps larger if you want more detailed video, but it will be slower.<br>"
160
+ "30 steps are recommended for most cases. will cause about 60 seconds for inference.<br>")
161
  with gr.Row():
162
+ num_inference_steps = gr.Number(label="Inference Steps", value=30)
163
  guidance_scale = gr.Number(label="Guidance Scale", value=6.0)
164
  generate_button = gr.Button("🎬 Generate Video")
165
 
 
180
  <tr>
181
  <td>A detailed wooden toy ship with intricately carved masts and sails is seen gliding smoothly over a plush, blue carpet that mimics the waves of the sea. The ship's hull is painted a rich brown, with tiny windows. The carpet, soft and textured, provides a perfect backdrop, resembling an oceanic expanse. Surrounding the ship are various other toys and children's items, hinting at a playful environment. The scene captures the innocence and imagination of childhood, with the toy ship's journey symbolizing endless adventures in a whimsical, indoor setting.</td>
182
  <td><a href="https://github.com/THUDM/CogVideo/raw/main/resources/videos/1.mp4">Video 1</a></td>
183
+ <td>30</td>
184
  <td>6</td>
185
  </tr>
186
  <tr>
187
+ <td>The camera follows behind a white vintage SUV with a black roof rack as it speeds up a steep dirt road surrounded by pine trees on a steep mountain slope, dust kicks up from it's tires, the sunlight shines on the SUV as it speeds along the dirt road, casting a warm glow over the scene. The dirt road curves gently into the distance, with no other cars or vehicles in sight. The trees on either side of the road are redwoods, with patches of greenery scattered throughout. The car is seen from the rear following the curve with ease, making it seem as if it is on a rugged drive through the rugged terrain. The dirt road itself is surrounded by steep hills and mountains, with a clear blue sky above with wispy clouds.</td>
188
  <td><a href="https://github.com/THUDM/CogVideo/raw/main/resources/videos/2.mp4">Video 2</a></td>
189
+ <td>30</td>
190
  <td>6</td>
191
  </tr>
192
  <tr>
193
  <td>A street artist, clad in a worn-out denim jacket and a colorful bandana, stands before a vast concrete wall in the heart, holding a can of spray paint, spray-painting a colorful bird on a mottled wall.</td>
194
  <td><a href="https://github.com/THUDM/CogVideo/raw/main/resources/videos/3.mp4">Video 3</a></td>
195
+ <td>30</td>
196
  <td>6</td>
197
  </tr>
198
  <tr>
199
  <td>In the haunting backdrop of a war-torn city, where ruins and crumbled walls tell a story of devastation, a poignant close-up frames a young girl. Her face is smudged with ash, a silent testament to the chaos around her. Her eyes glistening with a mix of sorrow and resilience, capturing the raw emotion of a world that has lost its innocence to the ravages of conflict.</td>
200
  <td><a href="https://github.com/THUDM/CogVideo/raw/main/resources/videos/4.mp4">Video 4</a></td>
201
+ <td>30</td>
202
  <td>6</td>
203
  </tr>
204
  </table>
205
  """)
206
 
 
207
  def generate(prompt, num_inference_steps, guidance_scale, progress=gr.Progress(track_tqdm=True)):
208
  tensor = infer(prompt, num_inference_steps, guidance_scale, progress=progress)
209
  video_path = save_video(tensor)
 
213
 
214
  return video_path, video_update, gif_update
215
 
 
216
  def enhance_prompt_func(prompt):
217
  return convert_prompt(prompt, retry_times=1)
218
 
 
219
  generate_button.click(
220
  generate,
221
  inputs=[prompt, num_inference_steps, guidance_scale],
 
229
  )
230
 
231
  if __name__ == "__main__":
232
+ demo.launch()