BestWishYsh multimodalart HF Staff commited on
Commit
eef5aca
·
1 Parent(s): f468e0f

[Admin maintenance] Support new ZeroGPU hardware (#5)

Browse files

- [Admin maintenance] Support new ZeroGPU hardware (8b8c48f79ac89d1c80bf6a94634ef1917f2f5ed9)


Co-authored-by: Apolinário from multimodal AI art <multimodalart@users.noreply.huggingface.co>

Files changed (2) hide show
  1. app.py +78 -55
  2. requirements.txt +4 -11
app.py CHANGED
@@ -166,7 +166,6 @@ class MagicTimeController:
166
  _, unexpected = self.unet_model.load_state_dict(motion_module_state_dict, strict=False)
167
  assert len(unexpected) == 0
168
 
169
- @spaces.GPU(duration=120)
170
  def magictime(
171
  self,
172
  dreambooth_dropdown,
@@ -177,66 +176,90 @@ class MagicTimeController:
177
  height_slider,
178
  seed_textbox,
179
  ):
180
- torch.cuda.empty_cache()
181
- time.sleep(1)
 
 
 
 
 
 
 
 
 
 
 
182
 
183
- if self.selected_motion_module != motion_module_dropdown: self.update_motion_module(motion_module_dropdown)
184
- if self.selected_motion_module != motion_module_dropdown: self.update_motion_module_2(motion_module_dropdown)
185
- if self.selected_dreambooth != dreambooth_dropdown: self.update_dreambooth(dreambooth_dropdown)
186
-
187
- while self.text_encoder is None or self.unet is None:
188
- self.update_dreambooth(dreambooth_dropdown, motion_module_dropdown)
189
 
190
- if is_xformers_available(): self.unet.enable_xformers_memory_efficient_attention()
191
 
192
- pipeline = MagicTimePipeline(
193
- vae=self.vae, text_encoder=self.text_encoder, tokenizer=self.tokenizer, unet=self.unet,
194
- scheduler=DDIMScheduler(**OmegaConf.to_container(self.inference_config.noise_scheduler_kwargs))
195
- ).to(device)
 
 
 
 
 
 
 
 
 
 
196
 
197
- if int(seed_textbox) > 0: seed = int(seed_textbox)
198
- else: seed = int(random_seed())
199
- torch.manual_seed(seed)
200
-
201
- assert seed == torch.initial_seed()
202
- print(f"### seed: {seed}")
203
-
204
- generator = torch.Generator(device=device)
205
- generator.manual_seed(seed)
206
-
207
- sample = pipeline(
208
- prompt_textbox,
209
- negative_prompt = negative_prompt_textbox,
210
- num_inference_steps = 25,
211
- guidance_scale = 8.,
212
- width = width_slider,
213
- height = height_slider,
214
- video_length = 16,
215
- generator = generator,
216
- ).videos
217
-
218
- save_sample_path = os.path.join(self.savedir, f"sample.mp4")
219
- save_videos_grid(sample, save_sample_path)
220
-
221
- json_config = {
222
- "prompt": prompt_textbox,
223
- "n_prompt": negative_prompt_textbox,
224
- "width": width_slider,
225
- "height": height_slider,
226
- "seed": seed,
227
- "dreambooth": dreambooth_dropdown,
228
- }
229
-
230
- # 修复:将字典序列化为 JSON 字符串
231
- json_config_str = json.dumps(json_config, indent=4)
232
 
233
- torch.cuda.empty_cache()
234
- time.sleep(1)
235
-
236
- # 修复:直接返回字符串以配合 gr.Code 组件
237
- return save_sample_path, json_config_str
238
 
239
- controller = MagicTimeController()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
240
 
241
  def ui():
242
  with gr.Blocks(css=css) as demo:
 
166
  _, unexpected = self.unet_model.load_state_dict(motion_module_state_dict, strict=False)
167
  assert len(unexpected) == 0
168
 
 
169
  def magictime(
170
  self,
171
  dreambooth_dropdown,
 
176
  height_slider,
177
  seed_textbox,
178
  ):
179
+ # Delegate to a module-level @spaces.GPU function so `self` (the
180
+ # controller, which contains Swift-modified nn.Modules with unpicklable
181
+ # local `device_hook` closures on Linear) is NOT pickled into the
182
+ # ZeroGPU worker. All GPU work happens via the global `controller`.
183
+ return _magictime_gpu(
184
+ dreambooth_dropdown,
185
+ motion_module_dropdown,
186
+ prompt_textbox,
187
+ negative_prompt_textbox,
188
+ int(width_slider),
189
+ int(height_slider),
190
+ str(seed_textbox),
191
+ )
192
 
193
+ controller = MagicTimeController()
 
 
 
 
 
194
 
 
195
 
196
+ @spaces.GPU(duration=120)
197
+ def _magictime_gpu(
198
+ dreambooth_dropdown,
199
+ motion_module_dropdown,
200
+ prompt_textbox,
201
+ negative_prompt_textbox,
202
+ width_slider,
203
+ height_slider,
204
+ seed_textbox,
205
+ ):
206
+ # Use the module-level `controller` global so we don't pickle `self`.
207
+ if controller.selected_motion_module != motion_module_dropdown: controller.update_motion_module(motion_module_dropdown)
208
+ if controller.selected_motion_module != motion_module_dropdown: controller.update_motion_module_2(motion_module_dropdown)
209
+ if controller.selected_dreambooth != dreambooth_dropdown: controller.update_dreambooth(dreambooth_dropdown)
210
 
211
+ while controller.text_encoder is None or controller.unet is None:
212
+ controller.update_dreambooth(dreambooth_dropdown, motion_module_dropdown)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
213
 
214
+ torch.cuda.empty_cache()
215
+ time.sleep(1)
 
 
 
216
 
217
+ if is_xformers_available(): controller.unet.enable_xformers_memory_efficient_attention()
218
+
219
+ pipeline = MagicTimePipeline(
220
+ vae=controller.vae, text_encoder=controller.text_encoder, tokenizer=controller.tokenizer, unet=controller.unet,
221
+ scheduler=DDIMScheduler(**OmegaConf.to_container(controller.inference_config.noise_scheduler_kwargs))
222
+ ).to(device)
223
+
224
+ if int(seed_textbox) > 0: seed = int(seed_textbox)
225
+ else: seed = int(random_seed())
226
+ torch.manual_seed(seed)
227
+
228
+ assert seed == torch.initial_seed()
229
+ print(f"### seed: {seed}")
230
+
231
+ generator = torch.Generator(device=device)
232
+ generator.manual_seed(seed)
233
+
234
+ sample = pipeline(
235
+ prompt_textbox,
236
+ negative_prompt = negative_prompt_textbox,
237
+ num_inference_steps = 25,
238
+ guidance_scale = 8.,
239
+ width = width_slider,
240
+ height = height_slider,
241
+ video_length = 16,
242
+ generator = generator,
243
+ ).videos
244
+
245
+ save_sample_path = os.path.join(controller.savedir, f"sample.mp4")
246
+ save_videos_grid(sample, save_sample_path)
247
+
248
+ json_config = {
249
+ "prompt": prompt_textbox,
250
+ "n_prompt": negative_prompt_textbox,
251
+ "width": width_slider,
252
+ "height": height_slider,
253
+ "seed": seed,
254
+ "dreambooth": dreambooth_dropdown,
255
+ }
256
+
257
+ json_config_str = json.dumps(json_config, indent=4)
258
+
259
+ torch.cuda.empty_cache()
260
+ time.sleep(1)
261
+
262
+ return save_sample_path, json_config_str
263
 
264
  def ui():
265
  with gr.Blocks(css=css) as demo:
requirements.txt CHANGED
@@ -1,10 +1,6 @@
1
- # torch==2.2.2
2
- # torchvision==0.17.2
3
- # torchaudio==2.2.2
4
- # xformers==0.0.25.post1
5
- torch==2.7.1
6
- torchvision==0.22.1
7
- torchaudio==2.7.1
8
  imageio==2.27.0
9
  imageio[ffmpeg]
10
  imageio[pyav]
@@ -15,11 +11,8 @@ accelerate==0.28.0
15
  diffusers==0.11.1
16
  transformers==4.38.2
17
  huggingface_hub==0.25.2
18
- # huggingface_hub==0.33.5
19
- gradio>=3.50.2
20
  gdown
21
- triton
22
  einops
23
  omegaconf
24
  safetensors
25
- spaces
 
1
+ torch==2.8.0
2
+ torchvision==0.23.0
3
+ torchaudio==2.8.0
 
 
 
 
4
  imageio==2.27.0
5
  imageio[ffmpeg]
6
  imageio[pyav]
 
11
  diffusers==0.11.1
12
  transformers==4.38.2
13
  huggingface_hub==0.25.2
 
 
14
  gdown
 
15
  einops
16
  omegaconf
17
  safetensors
18
+ spaces