quazim commited on
Commit
e8054e6
·
1 Parent(s): a47122b
Files changed (1) hide show
  1. app.py +49 -244
app.py CHANGED
@@ -6,25 +6,11 @@ import random
6
  import os
7
  import tempfile
8
  import soundfile as sf
9
- import time
10
 
11
  os.environ['ELASTIC_LOG_LEVEL'] = 'DEBUG'
12
  from transformers import AutoProcessor, pipeline
13
  from elastic_models.transformers import MusicgenForConditionalGeneration
14
 
15
- MODEL_CONFIG = {
16
- 'cost_per_hour': 1.8, # $1.8 per hour on L40S
17
- 'cost_savings_1000h': {
18
- 'savings_dollars': 8.4, # $8.4 saved per 1000 hours
19
- 'savings_percent': 74.9, # 74.9% savings
20
- 'compressed_cost': 2.8, # $2.8 for compressed
21
- 'original_cost': 11.3, # $11.3 for original
22
- },
23
- 'batch_mode': False
24
- }
25
-
26
- original_time_cache = {"original_time": 22.57}
27
-
28
 
29
  def set_seed(seed: int = 42):
30
  random.seed(seed)
@@ -37,6 +23,7 @@ def set_seed(seed: int = 42):
37
 
38
 
39
  def cleanup_gpu():
 
40
  if torch.cuda.is_available():
41
  torch.cuda.empty_cache()
42
  torch.cuda.synchronize()
@@ -44,6 +31,7 @@ def cleanup_gpu():
44
 
45
 
46
  def cleanup_temp_files():
 
47
  import glob
48
  import time
49
  temp_dir = tempfile.gettempdir()
@@ -59,8 +47,6 @@ def cleanup_temp_files():
59
 
60
  _generator = None
61
  _processor = None
62
- _original_generator = None
63
- _original_processor = None
64
 
65
 
66
  def load_model():
@@ -102,43 +88,6 @@ def load_model():
102
  return _generator, _processor
103
 
104
 
105
- def load_original_model():
106
- global _original_generator, _original_processor
107
-
108
- if _original_generator is None:
109
- print("[ORIGINAL MODEL] Starting original model initialization...")
110
- cleanup_gpu()
111
-
112
- device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
113
- print(f"[ORIGINAL MODEL] Using device: {device}")
114
-
115
- print("[ORIGINAL MODEL] Loading processor...")
116
- _original_processor = AutoProcessor.from_pretrained(
117
- "facebook/musicgen-large"
118
- )
119
- from transformers import MusicgenForConditionalGeneration as HFMusicgenForConditionalGeneration
120
-
121
- print("[ORIGINAL MODEL] Loading original model...")
122
- model = HFMusicgenForConditionalGeneration.from_pretrained(
123
- "facebook/musicgen-large",
124
- torch_dtype=torch.float16,
125
- ).to(device)
126
-
127
- model.eval()
128
-
129
- print("[ORIGINAL MODEL] Creating pipeline...")
130
- _original_generator = pipeline(
131
- task="text-to-audio",
132
- model=model,
133
- tokenizer=_original_processor.tokenizer,
134
- device=device,
135
- )
136
-
137
- print("[ORIGINAL MODEL] Original model initialization completed successfully")
138
-
139
- return _original_generator, _original_processor
140
-
141
-
142
  def calculate_max_tokens(duration_seconds):
143
  token_rate = 50
144
  max_new_tokens = int(duration_seconds * token_rate)
@@ -211,9 +160,9 @@ def generate_music(text_prompt, duration=10, guidance_scale=3.0):
211
 
212
  max_val = np.max(np.abs(audio_data))
213
  if max_val > 0:
214
- audio_data = audio_data / max_val * 0.95
215
 
216
- audio_data = (audio_data * 32767).astype(np.int16)
217
 
218
  print(f"[GENERATION] Final audio shape: {audio_data.shape}")
219
  print(f"[GENERATION] Audio range: [{np.min(audio_data)}, {np.max(audio_data)}]")
@@ -231,7 +180,6 @@ def generate_music(text_prompt, duration=10, guidance_scale=3.0):
231
  print(f"[GENERATION] Audio saved to: {temp_path}")
232
  print(f"[GENERATION] File size: {file_size} bytes")
233
 
234
- # Try returning numpy format instead
235
  print(f"[GENERATION] Returning numpy tuple: ({sample_rate}, audio_array)")
236
  return (sample_rate, audio_data)
237
  else:
@@ -244,194 +192,56 @@ def generate_music(text_prompt, duration=10, guidance_scale=3.0):
244
  return None
245
 
246
 
247
- def calculate_generation_cost(generation_time_seconds, mode='S'):
248
- hours = generation_time_seconds / 3600
249
- cost_per_hour = MODEL_CONFIG['cost_per_hour']
250
- return hours * cost_per_hour
251
-
252
-
253
- def calculate_cost_savings(compressed_time, original_time):
254
- compressed_cost = calculate_generation_cost(compressed_time, 'S')
255
- original_cost = calculate_generation_cost(original_time, 'original')
256
- savings = original_cost - compressed_cost
257
- savings_percent = (savings / original_cost * 100) if original_cost > 0 else 0
258
- return {
259
- 'compressed_cost': compressed_cost,
260
- 'original_cost': original_cost,
261
- 'savings': savings,
262
- 'savings_percent': savings_percent
263
- }
264
-
265
-
266
- def get_fixed_savings_message():
267
- config = MODEL_CONFIG['cost_savings_1000h']
268
- return f"💰 **Cost Savings on L40S (1000h)**: ${config['savings_dollars']:.1f}" \
269
- f" ({config['savings_percent']:.1f}%) - Compressed: ${config['compressed_cost']:.1f} " \
270
- f"vs Original: ${config['original_cost']:.1f}"
271
-
272
-
273
- def get_cache_key(prompt, duration, guidance_scale):
274
- return f"{hash(prompt)}_{duration}_{guidance_scale}"
275
-
276
-
277
- def generate_music_batch(text_prompt, duration=10, guidance_scale=3.0, model_mode="compressed"):
278
- try:
279
-
280
- generator, processor = load_model()
281
- model_name = "Compressed (S)"
282
-
283
- print(f"[GENERATION] Starting generation using {model_name} model...")
284
- print(f"[GENERATION] Prompt: '{text_prompt}'")
285
- print(f"[GENERATION] Duration: {duration}s")
286
- print(f"[GENERATION] Guidance scale: {guidance_scale}")
287
- print(f"[GENERATION] Batch mode: {MODEL_CONFIG['batch_mode']}")
288
-
289
- cleanup_gpu()
290
- set_seed(42)
291
- print(f"[GENERATION] Using seed: 42")
292
-
293
- max_new_tokens = calculate_max_tokens(duration)
294
-
295
- generation_params = {
296
- 'do_sample': True,
297
- 'guidance_scale': guidance_scale,
298
- 'max_new_tokens': max_new_tokens,
299
- 'min_new_tokens': max_new_tokens,
300
- 'cache_implementation': 'paged',
301
- }
302
-
303
- batch_size = 4 if MODEL_CONFIG['batch_mode'] else 1
304
- prompts = [text_prompt] * batch_size
305
-
306
- start_time = time.time()
307
- outputs = generator(
308
- prompts,
309
- batch_size=batch_size,
310
- generate_kwargs=generation_params
311
- )
312
- generation_time = time.time() - start_time
313
-
314
- print(f"[GENERATION] Generation completed in {generation_time:.2f}s")
315
-
316
- audio_variants = []
317
- sample_rate = outputs[0]['sampling_rate']
318
-
319
- for i, output in enumerate(outputs):
320
- audio_data = output['audio']
321
-
322
- print(f"[GENERATION] Processing variant {i + 1} audio shape: {audio_data.shape}")
323
-
324
- if hasattr(audio_data, 'cpu'):
325
- audio_data = audio_data.cpu().numpy()
326
-
327
- if len(audio_data.shape) == 3:
328
- audio_data = audio_data[0]
329
-
330
- if len(audio_data.shape) == 2:
331
- if audio_data.shape[0] < audio_data.shape[1]:
332
- audio_data = audio_data.T
333
- if audio_data.shape[1] > 1:
334
- audio_data = audio_data[:, 0]
335
- else:
336
- audio_data = audio_data.flatten()
337
-
338
- audio_data = audio_data.flatten()
339
-
340
- max_val = np.max(np.abs(audio_data))
341
- if max_val > 0:
342
- audio_data = audio_data / max_val * 0.95
343
-
344
- audio_data = (audio_data * 32767).astype(np.int16)
345
- audio_variants.append((sample_rate, audio_data))
346
-
347
- print(f"[GENERATION] Variant {i + 1} final shape: {audio_data.shape}")
348
-
349
- while len(audio_variants) < 4:
350
- audio_variants.append(None)
351
-
352
- savings_message = get_fixed_savings_message()
353
-
354
- variants_text = "4 variants" if MODEL_CONFIG['batch_mode'] else "1 variant"
355
- generation_info = f"✅ Generated {variants_text} in {generation_time:.2f}s\n{savings_message}"
356
-
357
- return audio_variants[0], audio_variants[1], audio_variants[2], audio_variants[3], generation_info
358
-
359
- except Exception as e:
360
- print(f"[ERROR] Batch generation failed: {str(e)}")
361
- cleanup_gpu()
362
- error_msg = f"❌ Generation failed: {str(e)}"
363
- return None, None, None, None, error_msg
364
-
365
-
366
- with gr.Blocks(title="MusicGen Large - Music Generation", theme=gr.themes.Soft()) as demo:
367
  gr.Markdown("# 🎵 MusicGen Large Music Generator")
368
-
369
- gr.Markdown(
370
- f"Generate music from text descriptions using Facebook's MusicGen "
371
- f"Large model accelerated by TheStage for 2.3x faster performance.")
372
-
373
- with gr.Column():
374
- text_input = gr.Textbox(
375
- label="Music Description",
376
- placeholder="Enter a description of the music you want to generate",
377
- lines=3,
378
- value="A groovy funk bassline with a tight drum beat"
379
- )
380
-
381
- with gr.Row():
382
- duration = gr.Slider(
383
- minimum=5,
384
- maximum=30,
385
- value=10,
386
- step=1,
387
- label="Duration (seconds)"
388
  )
389
- guidance_scale = gr.Slider(
390
- minimum=1.0,
391
- maximum=10.0,
392
- value=3.0,
393
- step=0.5,
394
- label="Guidance Scale",
395
- info="Higher values follow prompt more closely"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
396
  )
397
-
398
- generate_btn = gr.Button("🎵 Generate Music", variant="primary", size="lg")
399
-
400
- generation_info = gr.Markdown("Ready to generate music with elastic acceleration")
401
-
402
- audio_section_title = "### Generated Music" + (f" ({4 if MODEL_CONFIG['batch_mode'] else 1} variant{'s' if MODEL_CONFIG['batch_mode'] else ''})")
403
- gr.Markdown(audio_section_title)
404
-
405
- with gr.Row():
406
- audio_output1 = gr.Audio(label="Variant 1", type="numpy")
407
- audio_output2 = gr.Audio(label="Variant 2", type="numpy", visible=MODEL_CONFIG['batch_mode'])
408
-
409
- with gr.Row():
410
- audio_output3 = gr.Audio(label="Variant 3", type="numpy", visible=MODEL_CONFIG['batch_mode'])
411
- audio_output4 = gr.Audio(label="Variant 4", type="numpy", visible=MODEL_CONFIG['batch_mode'])
412
-
413
- savings_banner = gr.Markdown(get_fixed_savings_message())
414
-
415
- with gr.Accordion("💡 Tips & Information", open=False):
416
- gr.Markdown(f"""
417
- **Generation Tips:**
418
- - Be specific in your descriptions (e.g., "slow blues guitar with harmonica")
419
- - Higher guidance scale = follows prompt more closely
420
- - Lower guidance scale = more creative/varied results
421
- - Duration is limited to 30 seconds for faster generation
422
-
423
- **Performance:**
424
- - Accelerated by TheStage elastic compression
425
- - L40S GPU pricing: $1.8/hour
426
- """)
427
-
428
- def generate_simple(text_prompt, duration, guidance_scale):
429
- return generate_music_batch(text_prompt, duration, guidance_scale, "compressed")
430
 
431
  generate_btn.click(
432
- fn=generate_simple,
433
  inputs=[text_input, duration, guidance_scale],
434
- outputs=[audio_output1, audio_output2, audio_output3, audio_output4, generation_info],
435
  show_progress=True
436
  )
437
 
@@ -453,12 +263,7 @@ with gr.Blocks(title="MusicGen Large - Music Generation", theme=gr.themes.Soft()
453
  gr.Markdown("---")
454
  gr.Markdown("""
455
  <div style="text-align: center; color: #666; font-size: 12px; margin-top: 2rem;">
456
- <strong>TheStage Elastic Acceleration:</strong><br>
457
- • 2.3x faster generation vs original MusicGen model<br>
458
- • Benchmarked on L40S GPU @ $1.8/hour pricing<br>
459
- • Elastic compression maintains audio quality while reducing compute time<br>
460
-
461
- <strong>Model Limitations:</strong><br>
462
  • The model is not able to generate realistic vocals.<br>
463
  • The model has been trained with English descriptions and will not perform as well in other languages.<br>
464
  • The model does not perform equally well for all music styles and cultures.<br>
 
6
  import os
7
  import tempfile
8
  import soundfile as sf
 
9
 
10
  os.environ['ELASTIC_LOG_LEVEL'] = 'DEBUG'
11
  from transformers import AutoProcessor, pipeline
12
  from elastic_models.transformers import MusicgenForConditionalGeneration
13
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
 
15
  def set_seed(seed: int = 42):
16
  random.seed(seed)
 
23
 
24
 
25
  def cleanup_gpu():
26
+ """Clean up GPU memory to avoid TensorRT conflicts."""
27
  if torch.cuda.is_available():
28
  torch.cuda.empty_cache()
29
  torch.cuda.synchronize()
 
31
 
32
 
33
  def cleanup_temp_files():
34
+ """Clean up old temporary audio files."""
35
  import glob
36
  import time
37
  temp_dir = tempfile.gettempdir()
 
47
 
48
  _generator = None
49
  _processor = None
 
 
50
 
51
 
52
  def load_model():
 
88
  return _generator, _processor
89
 
90
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
91
  def calculate_max_tokens(duration_seconds):
92
  token_rate = 50
93
  max_new_tokens = int(duration_seconds * token_rate)
 
160
 
161
  max_val = np.max(np.abs(audio_data))
162
  if max_val > 0:
163
+ audio_data = audio_data / max_val * 0.95 # Scale to 95% to avoid clipping
164
 
165
+ audio_data = (audio_data * 32767).astype(np.int16) ###
166
 
167
  print(f"[GENERATION] Final audio shape: {audio_data.shape}")
168
  print(f"[GENERATION] Audio range: [{np.min(audio_data)}, {np.max(audio_data)}]")
 
180
  print(f"[GENERATION] Audio saved to: {temp_path}")
181
  print(f"[GENERATION] File size: {file_size} bytes")
182
 
 
183
  print(f"[GENERATION] Returning numpy tuple: ({sample_rate}, audio_array)")
184
  return (sample_rate, audio_data)
185
  else:
 
192
  return None
193
 
194
 
195
+ with gr.Blocks(title="MusicGen Large - Music Generation") as demo:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
196
  gr.Markdown("# 🎵 MusicGen Large Music Generator")
197
+ gr.Markdown("Generate music from text descriptions using Facebook's MusicGen Large model with elastic compression.")
198
+
199
+ with gr.Row():
200
+ with gr.Column():
201
+ text_input = gr.Textbox(
202
+ label="Music Description",
203
+ placeholder="Enter a description of the music you want to generate",
204
+ lines=3,
205
+ value="A groovy funk bassline with a tight drum beat"
 
 
 
 
 
 
 
 
 
 
 
206
  )
207
+
208
+ with gr.Row():
209
+ duration = gr.Slider(
210
+ minimum=5,
211
+ maximum=30,
212
+ value=10,
213
+ step=1,
214
+ label="Duration (seconds)"
215
+ )
216
+ guidance_scale = gr.Slider(
217
+ minimum=1.0,
218
+ maximum=10.0,
219
+ value=3.0,
220
+ step=0.5,
221
+ label="Guidance Scale",
222
+ info="Higher values follow prompt more closely"
223
+ )
224
+
225
+ generate_btn = gr.Button("🎵 Generate Music", variant="primary", size="lg")
226
+
227
+ with gr.Column():
228
+ audio_output = gr.Audio(
229
+ label="Generated Music",
230
+ type="numpy"
231
  )
232
+
233
+ with gr.Accordion("Tips", open=False):
234
+ gr.Markdown("""
235
+ - Be specific in your descriptions (e.g., "slow blues guitar with harmonica")
236
+ - Higher guidance scale = follows prompt more closely
237
+ - Lower guidance scale = more creative/varied results
238
+ - Duration is limited to 30 seconds for faster generation
239
+ """)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
240
 
241
  generate_btn.click(
242
+ fn=generate_music,
243
  inputs=[text_input, duration, guidance_scale],
244
+ outputs=audio_output,
245
  show_progress=True
246
  )
247
 
 
263
  gr.Markdown("---")
264
  gr.Markdown("""
265
  <div style="text-align: center; color: #666; font-size: 12px; margin-top: 2rem;">
266
+ <strong>Limitations:</strong><br>
 
 
 
 
 
267
  • The model is not able to generate realistic vocals.<br>
268
  • The model has been trained with English descriptions and will not perform as well in other languages.<br>
269
  • The model does not perform equally well for all music styles and cultures.<br>