multimodalart HF Staff commited on
Commit
8b8c48f
·
verified ·
1 Parent(s): f468e0f

[Admin maintenance] Support new ZeroGPU hardware

Browse files

Thank you so much for having shared this Space with the community on this demo. We have upgraded the ZeroGPU infra-structure to run on modern blackwell architecture.
For that, we need to upgrade your demo to support that. This PR fixes your demo to work with the new architecture. As this is something we broke on our end, we may merge this PR autonomously. If this breaks unexpectedly or brings unintended consequences, feel free to revert, modify or otherwise. Any issues you can email apolinario@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