jacob-c commited on
Commit
2690f21
·
1 Parent(s): 4cf4562
Files changed (1) hide show
  1. app.py +71 -87
app.py CHANGED
@@ -57,101 +57,77 @@ def calculate_song_structure(duration):
57
 
58
  def create_lyrics_prompt(classification_results, song_structure):
59
  """Create a prompt for lyrics generation based on classification results and desired structure"""
60
- # Get the top genre and its characteristics
61
- top_result = classification_results[0]
62
- genre = top_result['label']
63
- confidence = float(top_result['score'].strip('%')) / 100
64
 
65
- # Get additional musical elements
66
- additional_elements = [r['label'] for r in classification_results[1:3]]
67
-
68
- # Create a more specific and structured prompt
69
- prompt = f"""Write a song with the following structure:
70
-
71
- Style: {genre} music
72
- Theme: A {genre} song with elements of {' and '.join(additional_elements)}
73
- Length: {song_structure['verses']} verses and {song_structure['choruses']} choruses
74
-
75
- Guidelines:
76
- - Each verse should be exactly 4 lines
77
- - Each chorus should be exactly 4 lines
78
- - Keep the lyrics matching the {genre} style
79
- - Use appropriate musical themes and imagery
80
 
81
- Start with Verse 1:
 
82
 
83
- [Verse 1]"""
 
84
  return prompt
85
 
86
  def format_lyrics(generated_text, song_structure):
87
  """Format the generated lyrics according to desired structure"""
88
- lines = generated_text.split('\n')
89
- cleaned_lines = []
90
  current_section = None
91
  verse_count = 0
92
  chorus_count = 0
93
- lines_in_section = 0
94
-
95
- # Add first verse marker
96
- cleaned_lines.append("[Verse 1]")
97
- current_section = "verse"
98
- verse_count = 1
99
 
100
- for line in lines:
 
101
  line = line.strip()
102
- if not line or line.startswith('###') or line.startswith('```'):
103
- continue
104
-
105
- # Skip section markers in the generated text
106
- if line.lower().startswith('['):
107
  continue
108
 
109
- # Add the line if it's not a marker
110
- if len(line) > 0:
111
- cleaned_lines.append(line)
112
- lines_in_section += 1
113
-
114
- # Check if we need to start a new section
115
- if lines_in_section >= 4: # After 4 lines in current section
116
- lines_in_section = 0
117
-
118
- # Determine next section
119
- if current_section == "verse" and chorus_count < song_structure['choruses']:
120
- # Add a chorus after verse
121
- chorus_count += 1
122
- cleaned_lines.append(f"\n[Chorus {chorus_count}]")
123
- current_section = "chorus"
124
- elif current_section == "chorus" and verse_count < song_structure['verses']:
125
- # Add next verse after chorus
126
- verse_count += 1
127
- cleaned_lines.append(f"\n[Verse {verse_count}]")
128
- current_section = "verse"
129
-
130
- # Ensure we have complete sections
131
- result = []
132
- current_section = None
133
- section_lines = []
134
-
135
- for line in cleaned_lines:
136
- if line.startswith('['):
137
- if current_section and section_lines:
138
- # Pad section to 4 lines if needed
139
- while len(section_lines) < 4:
140
  section_lines.append("...")
141
- result.extend(section_lines)
142
- current_section = line
143
- result.append(f"\n{line}")
144
- section_lines = []
 
 
 
 
 
 
 
 
145
  else:
 
146
  section_lines.append(line)
147
 
148
- # Add the last section
149
  if section_lines:
150
  while len(section_lines) < 4:
151
  section_lines.append("...")
152
- result.extend(section_lines)
 
 
 
 
 
 
 
 
 
 
 
153
 
154
- return "\n".join(result)
155
 
156
  def generate_lyrics_with_retry(prompt, song_structure, max_retries=5, initial_wait=2):
157
  """Generate lyrics using GPT2-XL with retry logic"""
@@ -166,44 +142,52 @@ def generate_lyrics_with_retry(prompt, song_structure, max_retries=5, initial_wa
166
  "inputs": prompt,
167
  "parameters": {
168
  "max_new_tokens": song_structure['tokens'],
169
- "temperature": 0.9,
170
- "top_p": 0.95,
171
  "do_sample": True,
172
  "return_full_text": False,
173
- "stop": ["[End]", "\n\n\n"]
174
  }
175
  }
176
  )
177
 
178
- print(f"Response status: {response.status_code}")
179
-
180
  if response.status_code == 200:
181
  result = response.json()
182
  if isinstance(result, list) and len(result) > 0:
183
  generated_text = result[0].get("generated_text", "")
 
 
 
184
  formatted_lyrics = format_lyrics(generated_text, song_structure)
185
 
186
- # Verify the formatting worked correctly
187
- if formatted_lyrics.count('[Verse') < 1 or '>' in formatted_lyrics:
188
- # If formatting failed, try again
 
189
  if attempt < max_retries - 1:
190
- print("Malformed lyrics, retrying...")
191
  continue
 
192
  return formatted_lyrics
193
- return "Error: No text generated"
194
  elif response.status_code == 503:
195
  print(f"Model loading, attempt {attempt + 1}/{max_retries}. Waiting {wait_time} seconds...")
196
  time.sleep(wait_time)
197
  wait_time *= 1.5
198
  continue
199
  else:
 
 
 
200
  return f"Error generating lyrics: {response.text}"
201
 
202
  except Exception as e:
203
- if attempt == max_retries - 1: # Last attempt
204
- return f"Error after {max_retries} attempts: {str(e)}"
205
- time.sleep(wait_time)
206
- wait_time *= 1.5
 
 
207
 
208
  return "Failed to generate lyrics after multiple attempts. Please try again."
209
 
 
57
 
58
  def create_lyrics_prompt(classification_results, song_structure):
59
  """Create a prompt for lyrics generation based on classification results and desired structure"""
60
+ # Get the top genres and characteristics
61
+ genres = [f"{result['label']} ({result['score']})" for result in classification_results[:3]]
 
 
62
 
63
+ # Create a simpler, more focused prompt
64
+ prompt = f"""Write a cheerful song with the following elements:
65
+ Main style: {genres[0]}
66
+ Additional elements: {', '.join(genres[1:])}
 
 
 
 
 
 
 
 
 
 
 
67
 
68
+ Write exactly {song_structure['verses']} verse(s) and {song_structure['choruses']} chorus(es).
69
+ Each section should be 4 lines long.
70
 
71
+ [Verse 1]
72
+ """
73
  return prompt
74
 
75
  def format_lyrics(generated_text, song_structure):
76
  """Format the generated lyrics according to desired structure"""
77
+ lines = []
 
78
  current_section = None
79
  verse_count = 0
80
  chorus_count = 0
81
+ section_lines = []
 
 
 
 
 
82
 
83
+ # Process the generated text line by line
84
+ for line in generated_text.split('\n'):
85
  line = line.strip()
86
+
87
+ # Skip empty lines and code blocks
88
+ if not line or line.startswith('```') or line.startswith('###'):
 
 
89
  continue
90
 
91
+ # Handle section markers
92
+ if '[verse' in line.lower() or '[chorus' in line.lower():
93
+ # Save previous section if exists
94
+ if section_lines:
95
+ while len(section_lines) < 4: # Ensure 4 lines per section
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
96
  section_lines.append("...")
97
+ lines.extend(section_lines[:4]) # Only take first 4 lines if more
98
+ section_lines = []
99
+
100
+ # Add appropriate section marker
101
+ if '[verse' in line.lower() and verse_count < song_structure['verses']:
102
+ verse_count += 1
103
+ lines.append(f"\n[Verse {verse_count}]")
104
+ current_section = 'verse'
105
+ elif '[chorus' in line.lower() and chorus_count < song_structure['choruses']:
106
+ chorus_count += 1
107
+ lines.append(f"\n[Chorus {chorus_count}]")
108
+ current_section = 'chorus'
109
  else:
110
+ # Add line to current section
111
  section_lines.append(line)
112
 
113
+ # Handle the last section
114
  if section_lines:
115
  while len(section_lines) < 4:
116
  section_lines.append("...")
117
+ lines.extend(section_lines[:4])
118
+
119
+ # If we don't have enough sections, add them
120
+ while verse_count < song_structure['verses'] or chorus_count < song_structure['choruses']:
121
+ if verse_count < song_structure['verses']:
122
+ verse_count += 1
123
+ lines.append(f"\n[Verse {verse_count}]")
124
+ lines.extend(["..." for _ in range(4)])
125
+ if chorus_count < song_structure['choruses']:
126
+ chorus_count += 1
127
+ lines.append(f"\n[Chorus {chorus_count}]")
128
+ lines.extend(["..." for _ in range(4)])
129
 
130
+ return "\n".join(lines)
131
 
132
  def generate_lyrics_with_retry(prompt, song_structure, max_retries=5, initial_wait=2):
133
  """Generate lyrics using GPT2-XL with retry logic"""
 
142
  "inputs": prompt,
143
  "parameters": {
144
  "max_new_tokens": song_structure['tokens'],
145
+ "temperature": 0.8, # Slightly lower temperature for more focused output
146
+ "top_p": 0.9,
147
  "do_sample": True,
148
  "return_full_text": False,
149
+ "repetition_penalty": 1.2 # Add repetition penalty
150
  }
151
  }
152
  )
153
 
 
 
154
  if response.status_code == 200:
155
  result = response.json()
156
  if isinstance(result, list) and len(result) > 0:
157
  generated_text = result[0].get("generated_text", "")
158
+ if not generated_text:
159
+ continue
160
+
161
  formatted_lyrics = format_lyrics(generated_text, song_structure)
162
 
163
+ # Verify we have actual content
164
+ content_lines = [l for l in formatted_lyrics.split('\n')
165
+ if l.strip() and not l.strip().startswith('[') and l.strip() != '...']
166
+ if len(content_lines) < 4: # At least one section worth of content
167
  if attempt < max_retries - 1:
168
+ print("Not enough content generated, retrying...")
169
  continue
170
+
171
  return formatted_lyrics
172
+
173
  elif response.status_code == 503:
174
  print(f"Model loading, attempt {attempt + 1}/{max_retries}. Waiting {wait_time} seconds...")
175
  time.sleep(wait_time)
176
  wait_time *= 1.5
177
  continue
178
  else:
179
+ print(f"Error response: {response.text}")
180
+ if attempt < max_retries - 1:
181
+ continue
182
  return f"Error generating lyrics: {response.text}"
183
 
184
  except Exception as e:
185
+ print(f"Error on attempt {attempt + 1}: {str(e)}")
186
+ if attempt < max_retries - 1:
187
+ time.sleep(wait_time)
188
+ wait_time *= 1.5
189
+ continue
190
+ return f"Error after {max_retries} attempts: {str(e)}"
191
 
192
  return "Failed to generate lyrics after multiple attempts. Please try again."
193