Opera8 commited on
Commit
fa9370d
·
verified ·
1 Parent(s): 7a4c91f

Update acestep/inference.py

Browse files
Files changed (1) hide show
  1. acestep/inference.py +12 -71
acestep/inference.py CHANGED
@@ -11,10 +11,8 @@ from loguru import logger
11
  import torch
12
  from acestep.audio_utils import AudioSaver, generate_uuid_from_params
13
 
14
- # HuggingFace Space environment detection
15
  IS_HUGGINGFACE_SPACE = os.environ.get("SPACE_ID") is not None
16
 
17
- # تعریف کلاس اختصاصی برای خروج امن قبل از اتمام محدودیت ۱۲۰ ثانیه‌ای
18
  class TimeoutSavedException(Exception):
19
  def __init__(self, task_id: str, step: int):
20
  self.task_id = task_id
@@ -23,31 +21,19 @@ class TimeoutSavedException(Exception):
23
 
24
  @dataclass
25
  class GenerationParams:
26
- """Configuration for music generation parameters."""
27
- # Required Inputs
28
  task_type: str = "text2music"
29
  instruction: str = "Fill the audio semantic mask based on the given conditions:"
30
-
31
- # Audio Uploads
32
  reference_audio: Optional[str] = None
33
  src_audio: Optional[str] = None
34
-
35
- # LM Codes Hints
36
  audio_codes: str = ""
37
-
38
- # Text Inputs
39
  caption: str = ""
40
  lyrics: str = ""
41
  instrumental: bool = False
42
-
43
- # Metadata
44
  vocal_language: str = "unknown"
45
  bpm: Optional[int] = None
46
  keyscale: str = ""
47
  timesignature: str = ""
48
  duration: float = -1.0
49
-
50
- # Advanced Settings
51
  inference_steps: int = 8
52
  seed: int = -1
53
  guidance_scale: float = 7.0
@@ -55,14 +41,11 @@ class GenerationParams:
55
  cfg_interval_start: float = 0.0
56
  cfg_interval_end: float = 1.0
57
  shift: float = 1.0
58
- infer_method: str = "ode" # "ode" or "sde" - diffusion inference method
59
  timesteps: Optional[List[float]] = None
60
-
61
  repainting_start: float = 0.0
62
  repainting_end: float = -1
63
  audio_cover_strength: float = 1.0
64
-
65
- # 5Hz Language Model Parameters
66
  thinking: bool = True
67
  lm_temperature: float = 0.85
68
  lm_cfg_scale: float = 2.0
@@ -71,10 +54,9 @@ class GenerationParams:
71
  lm_negative_prompt: str = "NO USER INPUT"
72
  use_cot_metas: bool = True
73
  use_cot_caption: bool = True
74
- use_cot_lyrics: bool = False # TODO: not used yet
75
  use_cot_language: bool = True
76
  use_constrained_decoding: bool = True
77
-
78
  cot_bpm: Optional[int] = None
79
  cot_keyscale: str = ""
80
  cot_timesignature: str = ""
@@ -82,34 +64,26 @@ class GenerationParams:
82
  cot_vocal_language: str = "unknown"
83
  cot_caption: str = ""
84
  cot_lyrics: str = ""
85
-
86
- # شناسه ذخیره و احیا
87
  task_id: Optional[str] = None
88
 
89
  def to_dict(self) -> Dict[str, Any]:
90
- """Convert config to dictionary for JSON serialization."""
91
  return asdict(self)
92
 
93
-
94
  @dataclass
95
  class GenerationConfig:
96
- """Configuration for music generation."""
97
  batch_size: int = 2
98
  allow_lm_batch: bool = False
99
  use_random_seed: bool = True
100
  seeds: Optional[List[int]] = None
101
  lm_batch_chunk_size: int = 8
102
  constrained_decoding_debug: bool = False
103
- audio_format: str = "flac" # Default to FLAC for fast saving
104
 
105
  def to_dict(self) -> Dict[str, Any]:
106
- """Convert config to dictionary for JSON serialization."""
107
  return asdict(self)
108
 
109
-
110
  @dataclass
111
  class GenerationResult:
112
- """Result of music generation."""
113
  audios: List[Dict[str, Any]] = field(default_factory=list)
114
  status_message: str = ""
115
  extra_outputs: Dict[str, Any] = field(default_factory=dict)
@@ -117,13 +91,10 @@ class GenerationResult:
117
  error: Optional[str] = None
118
 
119
  def to_dict(self) -> Dict[str, Any]:
120
- """Convert result to dictionary for JSON serialization."""
121
  return asdict(self)
122
 
123
-
124
  @dataclass
125
  class UnderstandResult:
126
- """Result of music understanding from audio codes."""
127
  caption: str = ""
128
  lyrics: str = ""
129
  bpm: Optional[int] = None
@@ -136,13 +107,10 @@ class UnderstandResult:
136
  error: Optional[str] = None
137
 
138
  def to_dict(self) -> Dict[str, Any]:
139
- """Convert result to dictionary for JSON serialization."""
140
  return asdict(self)
141
 
142
-
143
  @dataclass
144
  class CreateSampleResult:
145
- """Result of creating a music sample from a natural language query."""
146
  caption: str = ""
147
  lyrics: str = ""
148
  bpm: Optional[int] = None
@@ -156,13 +124,10 @@ class CreateSampleResult:
156
  error: Optional[str] = None
157
 
158
  def to_dict(self) -> Dict[str, Any]:
159
- """Convert result to dictionary for JSON serialization."""
160
  return asdict(self)
161
 
162
-
163
  @dataclass
164
  class FormatSampleResult:
165
- """Result of formatting user-provided caption and lyrics."""
166
  caption: str = ""
167
  lyrics: str = ""
168
  bpm: Optional[int] = None
@@ -175,10 +140,8 @@ class FormatSampleResult:
175
  error: Optional[str] = None
176
 
177
  def to_dict(self) -> Dict[str, Any]:
178
- """Convert result to dictionary for JSON serialization."""
179
  return asdict(self)
180
 
181
-
182
  def _update_metadata_from_lm(
183
  metadata: Dict[str, Any],
184
  bpm: Optional[int],
@@ -189,7 +152,6 @@ def _update_metadata_from_lm(
189
  caption: str,
190
  lyrics: str,
191
  ) -> Tuple[Optional[int], str, str, Optional[float], str, str, str]:
192
- """Update metadata fields from LM output if not provided by user."""
193
  if bpm is None and metadata.get('bpm'):
194
  bpm_value = metadata.get('bpm')
195
  if bpm_value not in ["N/A", ""]:
@@ -224,7 +186,6 @@ def _update_metadata_from_lm(
224
  lyrics = metadata.get('lyrics')
225
  return bpm, key_scale, time_signature, audio_duration, vocal_language, caption, lyrics
226
 
227
-
228
  def generate_music(
229
  dit_handler,
230
  llm_handler,
@@ -233,7 +194,6 @@ def generate_music(
233
  save_dir: Optional[str] = None,
234
  progress=None,
235
  ) -> GenerationResult:
236
- """Generate music using ACE-Step model with optional LM reasoning."""
237
  try:
238
  audio_code_string_to_use = params.audio_codes
239
  lm_generated_metadata = None
@@ -244,7 +204,6 @@ def generate_music(
244
  "total_time": 0.0,
245
  }
246
 
247
- # Extract mutable copies of metadata
248
  bpm = params.bpm
249
  key_scale = params.keyscale
250
  time_signature = params.timesignature
@@ -257,42 +216,37 @@ def generate_music(
257
  need_audio_codes = not user_provided_audio_codes
258
  actual_batch_size = config.batch_size if config.batch_size is not None else 1
259
 
260
- # تعیین روت دایرکتوری پایدار برای ذخیره لیتنت‌ها
261
  storage_root = "/data" if os.path.exists("/data") else tempfile.gettempdir()
262
  resume_dir = os.path.join(storage_root, "resume_tasks")
263
  os.makedirs(resume_dir, exist_ok=True)
264
 
265
- # بررسی هوشمند فیلد Seed برای استخراج شناسه احیا (Tracking ID)
266
  active_task_id = params.task_id
267
  is_resumed_run = False
268
 
269
- # اگر کاربر شناسه احیا را به جای Seed وارد کرده باشد (غیر عددی بودن سید)
270
  if isinstance(params.seed, str) and params.seed.strip():
271
  cleaned_seed = params.seed.strip()
272
  if not cleaned_seed.replace("-", "").replace(",", "").isdigit():
273
  active_task_id = cleaned_seed
274
  is_resumed_run = True
275
- logger.info(f"🟢 [Save & Resume] Resuming request from Seed-Input Tracking ID: {active_task_id}")
276
 
277
  if not active_task_id or not active_task_id.strip():
278
  active_task_id = str(uuid.uuid4())[:8]
279
 
280
  params.task_id = active_task_id
281
 
282
- # بررسی فیزیکی وجود وضعیت ذخیره شده بر روی دیسک
283
  resume_path = os.path.join(resume_dir, f"{active_task_id}_latents.pt")
284
  meta_path = os.path.join(resume_dir, f"{active_task_id}_meta.json")
285
 
286
  if os.path.exists(resume_path) and os.path.exists(meta_path):
287
  is_resumed_run = True
288
- logger.info(f"🟢 [Save & Resume] Valid saved state files found for Task {active_task_id}")
289
 
290
  seed_for_generation = ""
291
  if config.seeds is not None and len(config.seeds) > 0:
292
  if isinstance(config.seeds, list):
293
  seed_for_generation = ",".join(str(s) for s in config.seeds)
294
 
295
- # اگر در حالت احیا هستیم، از ساخت سیدهای تصادفی جدید عبور می‌کنیم تا شرایط ثابت بماند
296
  if is_resumed_run:
297
  config.use_random_seed = False
298
  if os.path.exists(meta_path):
@@ -308,7 +262,6 @@ def generate_music(
308
 
309
  actual_seed_list, _ = dit_handler.prepare_seeds(actual_batch_size, seed_for_generation, config.use_random_seed)
310
 
311
- # ذخیره سیدها در ابتدای فاز یک برای بازیابی‌های احتمالی بعدی در فاز دو
312
  if not is_resumed_run:
313
  temp_meta_save = os.path.join(resume_dir, f"{active_task_id}_meta.json")
314
  try:
@@ -317,7 +270,6 @@ def generate_music(
317
  except Exception as e:
318
  logger.error(f"Failed to pre-save meta seeds: {e}")
319
 
320
- # بارگذاری مجدد دیتای متادیتا در فاز یک در صورت احیا شدن
321
  if is_resumed_run and os.path.exists(meta_path):
322
  try:
323
  with open(meta_path, 'r', encoding='utf-8') as f:
@@ -325,7 +277,7 @@ def generate_music(
325
  saved_lm_metadata = meta_data.get("lm_metadata")
326
  if saved_lm_metadata:
327
  lm_generated_metadata = saved_lm_metadata
328
- logger.info(f"🟢 [Save & Resume] Restored CoT Metadata for Task {active_task_id}")
329
  except Exception as e:
330
  logger.error(f"Failed to restore metadata from meta file: {e}")
331
 
@@ -473,7 +425,6 @@ def generate_music(
473
  if params.use_cot_language:
474
  dit_input_vocal_language = lm_generated_metadata.get("vocal_language", dit_input_vocal_language)
475
 
476
- # ذخیره کردن وضعیت متا برای ب��زیابی در فاز دو
477
  temp_meta_save = os.path.join(resume_dir, f"{active_task_id}_meta.json")
478
  try:
479
  with open(temp_meta_save, 'w', encoding='utf-8') as f:
@@ -486,14 +437,13 @@ def generate_music(
486
  except Exception as e:
487
  logger.error(f"Failed to save temporary CoT meta: {e}")
488
 
489
- # دزدیدن متد هندلر دیفیوشن برای رصد زمان و لیتنت‌ها
490
  decoder = dit_handler.model.decoder
491
  original_forward = decoder.forward
492
  current_step = 0
493
- timeout_limit = 95.0 # ثانیه - محدودیت زمانی امن جهت خروج قبل از اتمام تایم اوت هاگینگ فیس
494
  fsm_start_time = time.time()
495
 
496
- # بازیابی لیتنت‌های ذخیره شده قبلی و همگام‌سازی گام شروع
497
  is_resumed_run_active = False
498
  resume_step_idx = 0
499
  saved_latents_tensor = None
@@ -505,35 +455,29 @@ def generate_music(
505
  resume_step_idx = meta_data.get("resume_step", 0)
506
  saved_latents_tensor = torch.load(resume_path, map_location='cpu')
507
  is_resumed_run_active = True
508
- logger.info(f"🟢 [Dynamic Monkeypatch] State active. Will inject saved VRAM at step {resume_step_idx}")
509
  except Exception as e:
510
- logger.error(f"Monkeypatch state restore failed: {e}")
511
  is_resumed_run_active = False
512
 
513
  def patched_forward(self_decoder, hidden_states, timestep, *args, **kwargs):
514
  nonlocal current_step, fsm_start_time, is_resumed_run_active, resume_step_idx, saved_latents_tensor, active_task_id
515
 
516
- # اگر در مرحله احیا هستیم و هنوز به گام ذخیره شده نرسیده‌ایم، فورا از پردازش گام عبور کن
517
  if is_resumed_run_active and current_step < resume_step_idx:
518
  current_step += 1
519
  return (torch.zeros_like(hidden_states),)
520
 
521
- # اگر دقیقاً به گام قطع شده رسیدیم، لیتنت‌های قبلی را به VRAM تزریق کن
522
  if is_resumed_run_active and current_step == resume_step_idx:
523
  saved_latents_tensor = saved_latents_tensor.to(device=hidden_states.device, dtype=hidden_states.dtype)
524
  hidden_states.copy_(saved_latents_tensor)
525
  is_resumed_run_active = False
526
- logger.info(f"🟢 [Dynamic Monkeypatch] Succeeded in overriding hidden_states at step {current_step}")
527
 
528
- # محاسبه زمان باقیمانده برای فرار از تایم اوت
529
  elapsed_time = time.time() - fsm_start_time
530
  if elapsed_time > timeout_limit:
531
- logger.warning(f"⚠️ [ZeroGPU Timeout Saved] Intercepted at {elapsed_time:.1f}s. Saving state for {active_task_id} at step {current_step}")
532
-
533
- # انتقال لیتنت‌ها به CPU و ذخیره روی هارد پایدار
534
  torch.save(hidden_states.cpu(), resume_path)
535
 
536
- # بروزرسانی فایل متا
537
  current_meta = {"task_id": active_task_id, "resume_step": current_step, "seeds": actual_seed_list}
538
  if lm_generated_metadata:
539
  current_meta["lm_metadata"] = lm_generated_metadata
@@ -541,7 +485,6 @@ def generate_music(
541
  with open(meta_path, 'w', encoding='utf-8') as f:
542
  json.dump(current_meta, f, ensure_ascii=False)
543
 
544
- # بازیابی فوری متد اصلی دکودر
545
  decoder.forward = original_forward
546
  raise TimeoutSavedException(active_task_id, current_step)
547
 
@@ -585,7 +528,6 @@ def generate_music(
585
  finally:
586
  decoder.forward = original_forward
587
 
588
- # در صورت اتمام موفقیت‌آمیز رندر، فایل‌های ذخیره وضعیت میانی را برای پاکیزگی دیسک حذف کن
589
  if os.path.exists(resume_path):
590
  try:
591
  os.remove(resume_path)
@@ -690,7 +632,6 @@ def generate_music(
690
  )
691
 
692
  except TimeoutSavedException as e:
693
- # مدیریت استثنای قطع امن و پرتاب آن به سمت لایه بالاتر
694
  raise e
695
  except Exception as e:
696
  logger.exception("Music generation failed")
 
11
  import torch
12
  from acestep.audio_utils import AudioSaver, generate_uuid_from_params
13
 
 
14
  IS_HUGGINGFACE_SPACE = os.environ.get("SPACE_ID") is not None
15
 
 
16
  class TimeoutSavedException(Exception):
17
  def __init__(self, task_id: str, step: int):
18
  self.task_id = task_id
 
21
 
22
  @dataclass
23
  class GenerationParams:
 
 
24
  task_type: str = "text2music"
25
  instruction: str = "Fill the audio semantic mask based on the given conditions:"
 
 
26
  reference_audio: Optional[str] = None
27
  src_audio: Optional[str] = None
 
 
28
  audio_codes: str = ""
 
 
29
  caption: str = ""
30
  lyrics: str = ""
31
  instrumental: bool = False
 
 
32
  vocal_language: str = "unknown"
33
  bpm: Optional[int] = None
34
  keyscale: str = ""
35
  timesignature: str = ""
36
  duration: float = -1.0
 
 
37
  inference_steps: int = 8
38
  seed: int = -1
39
  guidance_scale: float = 7.0
 
41
  cfg_interval_start: float = 0.0
42
  cfg_interval_end: float = 1.0
43
  shift: float = 1.0
44
+ infer_method: str = "ode"
45
  timesteps: Optional[List[float]] = None
 
46
  repainting_start: float = 0.0
47
  repainting_end: float = -1
48
  audio_cover_strength: float = 1.0
 
 
49
  thinking: bool = True
50
  lm_temperature: float = 0.85
51
  lm_cfg_scale: float = 2.0
 
54
  lm_negative_prompt: str = "NO USER INPUT"
55
  use_cot_metas: bool = True
56
  use_cot_caption: bool = True
57
+ use_cot_lyrics: bool = False
58
  use_cot_language: bool = True
59
  use_constrained_decoding: bool = True
 
60
  cot_bpm: Optional[int] = None
61
  cot_keyscale: str = ""
62
  cot_timesignature: str = ""
 
64
  cot_vocal_language: str = "unknown"
65
  cot_caption: str = ""
66
  cot_lyrics: str = ""
 
 
67
  task_id: Optional[str] = None
68
 
69
  def to_dict(self) -> Dict[str, Any]:
 
70
  return asdict(self)
71
 
 
72
  @dataclass
73
  class GenerationConfig:
 
74
  batch_size: int = 2
75
  allow_lm_batch: bool = False
76
  use_random_seed: bool = True
77
  seeds: Optional[List[int]] = None
78
  lm_batch_chunk_size: int = 8
79
  constrained_decoding_debug: bool = False
80
+ audio_format: str = "flac"
81
 
82
  def to_dict(self) -> Dict[str, Any]:
 
83
  return asdict(self)
84
 
 
85
  @dataclass
86
  class GenerationResult:
 
87
  audios: List[Dict[str, Any]] = field(default_factory=list)
88
  status_message: str = ""
89
  extra_outputs: Dict[str, Any] = field(default_factory=dict)
 
91
  error: Optional[str] = None
92
 
93
  def to_dict(self) -> Dict[str, Any]:
 
94
  return asdict(self)
95
 
 
96
  @dataclass
97
  class UnderstandResult:
 
98
  caption: str = ""
99
  lyrics: str = ""
100
  bpm: Optional[int] = None
 
107
  error: Optional[str] = None
108
 
109
  def to_dict(self) -> Dict[str, Any]:
 
110
  return asdict(self)
111
 
 
112
  @dataclass
113
  class CreateSampleResult:
 
114
  caption: str = ""
115
  lyrics: str = ""
116
  bpm: Optional[int] = None
 
124
  error: Optional[str] = None
125
 
126
  def to_dict(self) -> Dict[str, Any]:
 
127
  return asdict(self)
128
 
 
129
  @dataclass
130
  class FormatSampleResult:
 
131
  caption: str = ""
132
  lyrics: str = ""
133
  bpm: Optional[int] = None
 
140
  error: Optional[str] = None
141
 
142
  def to_dict(self) -> Dict[str, Any]:
 
143
  return asdict(self)
144
 
 
145
  def _update_metadata_from_lm(
146
  metadata: Dict[str, Any],
147
  bpm: Optional[int],
 
152
  caption: str,
153
  lyrics: str,
154
  ) -> Tuple[Optional[int], str, str, Optional[float], str, str, str]:
 
155
  if bpm is None and metadata.get('bpm'):
156
  bpm_value = metadata.get('bpm')
157
  if bpm_value not in ["N/A", ""]:
 
186
  lyrics = metadata.get('lyrics')
187
  return bpm, key_scale, time_signature, audio_duration, vocal_language, caption, lyrics
188
 
 
189
  def generate_music(
190
  dit_handler,
191
  llm_handler,
 
194
  save_dir: Optional[str] = None,
195
  progress=None,
196
  ) -> GenerationResult:
 
197
  try:
198
  audio_code_string_to_use = params.audio_codes
199
  lm_generated_metadata = None
 
204
  "total_time": 0.0,
205
  }
206
 
 
207
  bpm = params.bpm
208
  key_scale = params.keyscale
209
  time_signature = params.timesignature
 
216
  need_audio_codes = not user_provided_audio_codes
217
  actual_batch_size = config.batch_size if config.batch_size is not None else 1
218
 
 
219
  storage_root = "/data" if os.path.exists("/data") else tempfile.gettempdir()
220
  resume_dir = os.path.join(storage_root, "resume_tasks")
221
  os.makedirs(resume_dir, exist_ok=True)
222
 
 
223
  active_task_id = params.task_id
224
  is_resumed_run = False
225
 
 
226
  if isinstance(params.seed, str) and params.seed.strip():
227
  cleaned_seed = params.seed.strip()
228
  if not cleaned_seed.replace("-", "").replace(",", "").isdigit():
229
  active_task_id = cleaned_seed
230
  is_resumed_run = True
231
+ logger.info(f"Resuming request from Seed-Input Tracking ID: {active_task_id}")
232
 
233
  if not active_task_id or not active_task_id.strip():
234
  active_task_id = str(uuid.uuid4())[:8]
235
 
236
  params.task_id = active_task_id
237
 
 
238
  resume_path = os.path.join(resume_dir, f"{active_task_id}_latents.pt")
239
  meta_path = os.path.join(resume_dir, f"{active_task_id}_meta.json")
240
 
241
  if os.path.exists(resume_path) and os.path.exists(meta_path):
242
  is_resumed_run = True
243
+ logger.info(f"State files found for Task {active_task_id}")
244
 
245
  seed_for_generation = ""
246
  if config.seeds is not None and len(config.seeds) > 0:
247
  if isinstance(config.seeds, list):
248
  seed_for_generation = ",".join(str(s) for s in config.seeds)
249
 
 
250
  if is_resumed_run:
251
  config.use_random_seed = False
252
  if os.path.exists(meta_path):
 
262
 
263
  actual_seed_list, _ = dit_handler.prepare_seeds(actual_batch_size, seed_for_generation, config.use_random_seed)
264
 
 
265
  if not is_resumed_run:
266
  temp_meta_save = os.path.join(resume_dir, f"{active_task_id}_meta.json")
267
  try:
 
270
  except Exception as e:
271
  logger.error(f"Failed to pre-save meta seeds: {e}")
272
 
 
273
  if is_resumed_run and os.path.exists(meta_path):
274
  try:
275
  with open(meta_path, 'r', encoding='utf-8') as f:
 
277
  saved_lm_metadata = meta_data.get("lm_metadata")
278
  if saved_lm_metadata:
279
  lm_generated_metadata = saved_lm_metadata
280
+ logger.info(f"Restored CoT Metadata for Task {active_task_id}")
281
  except Exception as e:
282
  logger.error(f"Failed to restore metadata from meta file: {e}")
283
 
 
425
  if params.use_cot_language:
426
  dit_input_vocal_language = lm_generated_metadata.get("vocal_language", dit_input_vocal_language)
427
 
 
428
  temp_meta_save = os.path.join(resume_dir, f"{active_task_id}_meta.json")
429
  try:
430
  with open(temp_meta_save, 'w', encoding='utf-8') as f:
 
437
  except Exception as e:
438
  logger.error(f"Failed to save temporary CoT meta: {e}")
439
 
440
+ # اعمال دکوراتور داینامیک بر روی کلاس مدل
441
  decoder = dit_handler.model.decoder
442
  original_forward = decoder.forward
443
  current_step = 0
444
+ timeout_limit = 95.0
445
  fsm_start_time = time.time()
446
 
 
447
  is_resumed_run_active = False
448
  resume_step_idx = 0
449
  saved_latents_tensor = None
 
455
  resume_step_idx = meta_data.get("resume_step", 0)
456
  saved_latents_tensor = torch.load(resume_path, map_location='cpu')
457
  is_resumed_run_active = True
458
+ logger.info(f"Active. Will inject saved VRAM at step {resume_step_idx}")
459
  except Exception as e:
460
+ logger.error(f"Restore failed: {e}")
461
  is_resumed_run_active = False
462
 
463
  def patched_forward(self_decoder, hidden_states, timestep, *args, **kwargs):
464
  nonlocal current_step, fsm_start_time, is_resumed_run_active, resume_step_idx, saved_latents_tensor, active_task_id
465
 
 
466
  if is_resumed_run_active and current_step < resume_step_idx:
467
  current_step += 1
468
  return (torch.zeros_like(hidden_states),)
469
 
 
470
  if is_resumed_run_active and current_step == resume_step_idx:
471
  saved_latents_tensor = saved_latents_tensor.to(device=hidden_states.device, dtype=hidden_states.dtype)
472
  hidden_states.copy_(saved_latents_tensor)
473
  is_resumed_run_active = False
474
+ logger.info(f"Successfully injected saved VRAM at step {current_step}")
475
 
 
476
  elapsed_time = time.time() - fsm_start_time
477
  if elapsed_time > timeout_limit:
478
+ logger.warning(f"Intercepted at {elapsed_time:.1f}s. Saving state for {active_task_id} at step {current_step}")
 
 
479
  torch.save(hidden_states.cpu(), resume_path)
480
 
 
481
  current_meta = {"task_id": active_task_id, "resume_step": current_step, "seeds": actual_seed_list}
482
  if lm_generated_metadata:
483
  current_meta["lm_metadata"] = lm_generated_metadata
 
485
  with open(meta_path, 'w', encoding='utf-8') as f:
486
  json.dump(current_meta, f, ensure_ascii=False)
487
 
 
488
  decoder.forward = original_forward
489
  raise TimeoutSavedException(active_task_id, current_step)
490
 
 
528
  finally:
529
  decoder.forward = original_forward
530
 
 
531
  if os.path.exists(resume_path):
532
  try:
533
  os.remove(resume_path)
 
632
  )
633
 
634
  except TimeoutSavedException as e:
 
635
  raise e
636
  except Exception as e:
637
  logger.exception("Music generation failed")