Victios7 commited on
Commit
735f29a
路
verified 路
1 Parent(s): cd4fd69

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +23 -12
app.py CHANGED
@@ -107,6 +107,9 @@ def parse_pmns(md):
107
  elif low.startswith("percusion:"):
108
  p = line.split(":", 1)[1].strip().lower()
109
  sec["percusion"] = p if p in PERCUSSION_STYLES else "ninguno"
 
 
 
110
 
111
  if not sec["notes"]: errors.append("falta notas")
112
  for tok in sec["chords"].split():
@@ -215,7 +218,9 @@ def midi_to_mp3(midi_path, mp3_path):
215
  if os.path.exists(wav_path): os.unlink(wav_path)
216
  return mp3_path
217
 
218
- SYSTEM = """Escribe SOLO el texto de la partitura. Nada de charla. Formato exacto:
 
 
219
 
220
  # Titulo
221
  ## Tempo
@@ -223,18 +228,24 @@ SYSTEM = """Escribe SOLO el texto de la partitura. Nada de charla. Formato exact
223
  ## Estructura
224
  ### Intro
225
  instrumento: piano
226
- notas: C4q E4q G4q C5h
227
- acordes: C4
228
 
229
- ### Tema
230
  instrumento: guitar
231
- notas: A3q C4q E4q A4h G4q F4q E4q
232
- acordes: Am4 F2
233
 
234
  ### Estribillo
235
  instrumento: strings
236
- notas: F4q G4q A4q C5h
237
- acordes: F4 C4
 
 
 
 
 
 
238
 
239
  ### Outro
240
  instrumento: piano
@@ -253,7 +264,7 @@ def clean_score(text):
253
  if "notas:" not in md.lower(): return None
254
  return md.strip()
255
 
256
- def generate_text(model, tokenizer, messages, max_new=800):
257
  text = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
258
  inputs = tokenizer(text, return_tensors="pt").to(model.device)
259
  with torch.no_grad():
@@ -355,19 +366,19 @@ footer, .built-with, [class*="footer"] { display: none !important; }
355
  HEADER_HTML = f"""<div id="aether-topbar"><div id="aether-logo">馃幖</div><div id="aether-brand-name">{STUDIO_NAME}</div><span id="aether-brand-model">{MODEL_DISPLAY_NAME}</span></div>"""
356
  SELECT_JS = """<script>function selectSong(id) { const el = document.querySelector('#song-selector input, #song-selector textarea'); if (el) { el.value = id; el.dispatchEvent(new Event('input', { bubbles: true })); el.dispatchEvent(new Event('change', { bubbles: true })); } }</script>"""
357
 
358
- @spaces.GPU(duration=60, size="xlarge")
359
  def generate_song(prompt):
360
  model, tokenizer = load_model()
361
  model.to("cuda")
362
  messages = [{"role": "system", "content": SYSTEM}, {"role": "user", "content": f"Comp贸n: {prompt}"}]
363
- return generate_text(model, tokenizer, messages, max_new=800)
364
 
365
  def process_request(prompt):
366
  if not prompt or not prompt.strip():
367
  yield "Escribe qu茅 canci贸n quieres.", "", render_library(), gr.update(), gr.update()
368
  return
369
 
370
- yield "馃幖 *Componiendo...*", "", render_library(), gr.update(), gr.update()
371
  raw_output = generate_song(prompt)
372
  md = clean_score(raw_output)
373
 
 
107
  elif low.startswith("percusion:"):
108
  p = line.split(":", 1)[1].strip().lower()
109
  sec["percusion"] = p if p in PERCUSSION_STYLES else "ninguno"
110
+ elif low.startswith("repetir:"):
111
+ m = re.search(r"(\d+)", line)
112
+ sec["repeat"] = max(1, min(8, int(m.group(1)))) if m else 1
113
 
114
  if not sec["notes"]: errors.append("falta notas")
115
  for tok in sec["chords"].split():
 
218
  if os.path.exists(wav_path): os.unlink(wav_path)
219
  return mp3_path
220
 
221
+ SYSTEM = """Escribe SOLO el texto de la partitura. Nada de charla. Formato exacto.
222
+
223
+ Para que la canci贸n dure 1 minuto, escribe OBLIGATORIAMENTE 8 secciones (Intro, Verso 1, Pre-Estribillo, Estribillo, Verso 2, Puente, Climax, Outro). Escribe al menos 12 notas por secci贸n. Usa el campo "repetir: 2" en los estribillos.
224
 
225
  # Titulo
226
  ## Tempo
 
228
  ## Estructura
229
  ### Intro
230
  instrumento: piano
231
+ notas: C4q E4q G4q C5h E5q D5q C5h
232
+ acordes: C4 G4
233
 
234
+ ### Verso 1
235
  instrumento: guitar
236
+ notas: A3q C4q E4q A4h G4q F4q E4q D4q C4q D4h
237
+ acordes: Am4 F2 C4 G4
238
 
239
  ### Estribillo
240
  instrumento: strings
241
+ repetir: 2
242
+ notas: F4q G4q A4q C5h D5q C5q A4q G4h F4q E4q D4q C4h
243
+ acordes: F4 C4 G4 Am4
244
+
245
+ ### Puente
246
+ instrumento: flute
247
+ notas: D5q E5q F5q G5h E5q D5q C5q A4q G4q F4q E4q D4h
248
+ acordes: Dm4 G4 C4 Am4
249
 
250
  ### Outro
251
  instrumento: piano
 
264
  if "notas:" not in md.lower(): return None
265
  return md.strip()
266
 
267
+ def generate_text(model, tokenizer, messages, max_new=1500):
268
  text = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
269
  inputs = tokenizer(text, return_tensors="pt").to(model.device)
270
  with torch.no_grad():
 
366
  HEADER_HTML = f"""<div id="aether-topbar"><div id="aether-logo">馃幖</div><div id="aether-brand-name">{STUDIO_NAME}</div><span id="aether-brand-model">{MODEL_DISPLAY_NAME}</span></div>"""
367
  SELECT_JS = """<script>function selectSong(id) { const el = document.querySelector('#song-selector input, #song-selector textarea'); if (el) { el.value = id; el.dispatchEvent(new Event('input', { bubbles: true })); el.dispatchEvent(new Event('change', { bubbles: true })); } }</script>"""
368
 
369
+ @spaces.GPU(duration=30, size="xlarge")
370
  def generate_song(prompt):
371
  model, tokenizer = load_model()
372
  model.to("cuda")
373
  messages = [{"role": "system", "content": SYSTEM}, {"role": "user", "content": f"Comp贸n: {prompt}"}]
374
+ return generate_text(model, tokenizer, messages, max_new=1500)
375
 
376
  def process_request(prompt):
377
  if not prompt or not prompt.strip():
378
  yield "Escribe qu茅 canci贸n quieres.", "", render_library(), gr.update(), gr.update()
379
  return
380
 
381
+ yield "馃幖 *Componiendo (esto tomar谩 m谩s tiempo para generar 1 minuto de m煤sica)...*", "", render_library(), gr.update(), gr.update()
382
  raw_output = generate_song(prompt)
383
  md = clean_score(raw_output)
384