jacob-c commited on
Commit
30539fa
·
1 Parent(s): b893150
Files changed (1) hide show
  1. app.py +97 -84
app.py CHANGED
@@ -61,10 +61,10 @@ def create_lyrics_prompt(classification_results, song_structure):
61
  main_style = classification_results[0]['label']
62
  secondary_elements = [result['label'] for result in classification_results[1:3]]
63
 
64
- # Create a more specific prompt with example lyrics
65
- prompt = f"""Create song lyrics in {main_style} style with {', '.join(secondary_elements)} elements.
66
 
67
- Here's an example of the lyric style:
68
 
69
  [Verse 1]
70
  Gentle bells ring in the night
@@ -72,56 +72,63 @@ Stars are shining pure and bright
72
  Music fills the evening air
73
  Magic moments we can share
74
 
75
- Write new original lyrics following this style:
 
 
 
 
 
 
76
 
77
  [Verse 1]"""
 
78
  return prompt
79
 
80
  def format_lyrics(generated_text, song_structure):
81
  """Format the generated lyrics according to desired structure"""
82
  lines = []
83
- current_section = None
84
  verse_count = 0
85
  chorus_count = 0
86
- section_lines = []
87
 
88
- # Process the generated text line by line
89
- for line in generated_text.split('\n'):
 
90
  line = line.strip()
91
 
92
- # Skip empty lines and code blocks
93
  if not line or line.startswith('```') or line.startswith('###'):
94
  continue
95
 
96
  # Handle section markers
97
  if '[verse' in line.lower() or '[chorus' in line.lower():
98
- # Save previous section if exists
99
- if section_lines:
100
- while len(section_lines) < 4: # Ensure 4 lines per section
101
- section_lines.append("...")
102
- lines.extend(section_lines[:4]) # Only take first 4 lines if more
103
- section_lines = []
 
104
 
105
- # Add appropriate section marker
106
  if '[verse' in line.lower() and verse_count < song_structure['verses']:
107
  verse_count += 1
108
  lines.append(f"\n[Verse {verse_count}]")
109
- current_section = 'verse'
110
  elif '[chorus' in line.lower() and chorus_count < song_structure['choruses']:
111
  chorus_count += 1
112
  lines.append(f"\n[Chorus {chorus_count}]")
113
- current_section = 'chorus'
114
  else:
115
- # Add line to current section
116
- section_lines.append(line)
 
117
 
118
- # Handle the last section
119
- if section_lines:
120
- while len(section_lines) < 4:
121
- section_lines.append("...")
122
- lines.extend(section_lines[:4])
123
 
124
- # If we don't have enough sections, add them
125
  while verse_count < song_structure['verses'] or chorus_count < song_structure['choruses']:
126
  if verse_count < song_structure['verses']:
127
  verse_count += 1
@@ -134,8 +141,34 @@ def format_lyrics(generated_text, song_structure):
134
 
135
  return "\n".join(lines)
136
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
137
  def generate_lyrics_with_retry(prompt, song_structure, max_retries=5, initial_wait=2):
138
- """Generate lyrics using GPT2 with retry logic"""
139
  wait_time = initial_wait
140
 
141
  for attempt in range(max_retries):
@@ -143,70 +176,47 @@ def generate_lyrics_with_retry(prompt, song_structure, max_retries=5, initial_wa
143
  print(f"\nAttempt {attempt + 1}: Generating lyrics...")
144
 
145
  response = requests.post(
146
- "https://api-inference.huggingface.co/models/distilgpt2",
147
  headers=headers,
148
  json={
149
  "inputs": prompt,
150
  "parameters": {
151
- "max_new_tokens": 200,
152
- "temperature": 0.7, # Lower temperature for more coherent output
153
- "top_p": 0.85,
154
  "do_sample": True,
155
- "return_full_text": False,
156
  "num_return_sequences": 1,
157
- "repetition_penalty": 1.2
158
  }
159
  }
160
  )
161
 
162
  if response.status_code == 200:
163
- try:
164
- result = response.json()
165
- if isinstance(result, list) and len(result) > 0:
166
- generated_text = result[0].get("generated_text", "")
167
- if not generated_text:
168
- continue
169
-
170
- # Clean up and format the text
171
- lines = []
172
- current_lines = []
173
-
174
- for line in generated_text.split('\n'):
175
- line = line.strip()
176
- # Skip empty lines, section markers, and non-lyric content
177
- if not line or line.startswith(('```', '###', '[', 'Start', 'Write')):
178
- continue
179
- # Only include lines that look like lyrics (not too long, no punctuation at start)
180
- if len(line.split()) <= 12 and not line[0] in '.,!?':
181
- current_lines.append(line)
182
-
183
- if len(current_lines) >= 4:
184
- # Format into song structure
185
- lines.append("[Verse 1]")
186
- lines.extend(current_lines[:4])
187
-
188
- if song_structure['choruses'] > 0:
189
- chorus_lines = [
190
- "Hear the music in the air",
191
- "Feel the rhythm everywhere",
192
- "Let the melody take flight",
193
- "As we sing into the night"
194
- ]
195
- lines.append("\n[Chorus]")
196
- lines.extend(chorus_lines)
197
-
198
- if song_structure['verses'] > 1 and len(current_lines) >= 8:
199
- lines.append("\n[Verse 2]")
200
- lines.extend(current_lines[4:8])
201
-
202
- return "\n".join(lines)
203
- else:
204
- print(f"Not enough valid lines generated (got {len(current_lines)}), retrying...")
205
-
206
- except Exception as e:
207
- print(f"Error processing response: {str(e)}")
208
- if attempt < max_retries - 1:
209
- continue
210
 
211
  elif response.status_code == 503:
212
  print(f"Model loading, waiting {wait_time} seconds...")
@@ -216,18 +226,21 @@ def generate_lyrics_with_retry(prompt, song_structure, max_retries=5, initial_wa
216
  else:
217
  print(f"Error response: {response.text}")
218
  if attempt < max_retries - 1:
 
219
  continue
220
- return f"Error generating lyrics: {response.text}"
221
-
222
  except Exception as e:
223
  print(f"Exception during generation: {str(e)}")
224
  if attempt < max_retries - 1:
225
  time.sleep(wait_time)
226
  wait_time *= 1.5
227
  continue
228
- return f"Error after {max_retries} attempts: {str(e)}"
 
 
229
 
230
- return "Failed to generate lyrics after multiple attempts. Please try again."
 
231
 
232
  def format_results(classification_results, lyrics, prompt):
233
  """Format the results for display"""
 
61
  main_style = classification_results[0]['label']
62
  secondary_elements = [result['label'] for result in classification_results[1:3]]
63
 
64
+ # Create a more specific prompt with example structure and style guidance
65
+ prompt = f"""Create {song_structure['verses']} verses and {song_structure['choruses']} choruses in {main_style} style with {', '.join(secondary_elements)} elements.
66
 
67
+ Structure example:
68
 
69
  [Verse 1]
70
  Gentle bells ring in the night
 
72
  Music fills the evening air
73
  Magic moments we can share
74
 
75
+ [Chorus]
76
+ Let the rhythm take control
77
+ Music flowing through your soul
78
+ Dancing in the silver light
79
+ Making magic through the night
80
+
81
+ Write new original lyrics following this style and structure:
82
 
83
  [Verse 1]"""
84
+
85
  return prompt
86
 
87
  def format_lyrics(generated_text, song_structure):
88
  """Format the generated lyrics according to desired structure"""
89
  lines = []
 
90
  verse_count = 0
91
  chorus_count = 0
92
+ current_section = []
93
 
94
+ # Split text into lines and process
95
+ text_lines = generated_text.split('\n')
96
+ for line in text_lines:
97
  line = line.strip()
98
 
99
+ # Skip empty lines and metadata
100
  if not line or line.startswith('```') or line.startswith('###'):
101
  continue
102
 
103
  # Handle section markers
104
  if '[verse' in line.lower() or '[chorus' in line.lower():
105
+ # Save previous section if it exists
106
+ if current_section:
107
+ # Pad section to 4 lines if needed
108
+ while len(current_section) < 4:
109
+ current_section.append("...")
110
+ lines.extend(current_section[:4])
111
+ current_section = []
112
 
113
+ # Add new section marker
114
  if '[verse' in line.lower() and verse_count < song_structure['verses']:
115
  verse_count += 1
116
  lines.append(f"\n[Verse {verse_count}]")
 
117
  elif '[chorus' in line.lower() and chorus_count < song_structure['choruses']:
118
  chorus_count += 1
119
  lines.append(f"\n[Chorus {chorus_count}]")
 
120
  else:
121
+ # Add line to current section if it looks like lyrics
122
+ if len(line.split()) <= 12 and not line[0] in '.,!?':
123
+ current_section.append(line)
124
 
125
+ # Handle last section
126
+ if current_section:
127
+ while len(current_section) < 4:
128
+ current_section.append("...")
129
+ lines.extend(current_section[:4])
130
 
131
+ # Add any missing sections
132
  while verse_count < song_structure['verses'] or chorus_count < song_structure['choruses']:
133
  if verse_count < song_structure['verses']:
134
  verse_count += 1
 
141
 
142
  return "\n".join(lines)
143
 
144
+ def create_default_lyrics(song_structure):
145
+ """Create default lyrics when generation fails"""
146
+ lyrics = []
147
+
148
+ # Add verses
149
+ for i in range(song_structure['verses']):
150
+ lyrics.append(f"\n[Verse {i+1}]")
151
+ lyrics.extend([
152
+ "Through the gentle evening light",
153
+ "Melodies take wings in flight",
154
+ "Every note a story tells",
155
+ "Like the sound of silver bells"
156
+ ])
157
+
158
+ # Add choruses
159
+ for i in range(song_structure['choruses']):
160
+ lyrics.append(f"\n[Chorus {i+1}]")
161
+ lyrics.extend([
162
+ "Let the music fill the air",
163
+ "Feel the rhythm everywhere",
164
+ "Time stands still as we all sing",
165
+ "Joy and wonder it will bring"
166
+ ])
167
+
168
+ return "\n".join(lyrics)
169
+
170
  def generate_lyrics_with_retry(prompt, song_structure, max_retries=5, initial_wait=2):
171
+ """Generate lyrics using GPT2 with improved retry logic and error handling"""
172
  wait_time = initial_wait
173
 
174
  for attempt in range(max_retries):
 
176
  print(f"\nAttempt {attempt + 1}: Generating lyrics...")
177
 
178
  response = requests.post(
179
+ LYRICS_API_URL,
180
  headers=headers,
181
  json={
182
  "inputs": prompt,
183
  "parameters": {
184
+ "max_new_tokens": song_structure['tokens'],
185
+ "temperature": 0.8,
186
+ "top_p": 0.9,
187
  "do_sample": True,
188
+ "return_full_text": True,
189
  "num_return_sequences": 1,
190
+ "repetition_penalty": 1.1
191
  }
192
  }
193
  )
194
 
195
  if response.status_code == 200:
196
+ result = response.json()
197
+
198
+ # Handle different response formats
199
+ if isinstance(result, list):
200
+ generated_text = result[0].get('generated_text', '')
201
+ elif isinstance(result, dict):
202
+ generated_text = result.get('generated_text', '')
203
+ else:
204
+ generated_text = str(result)
205
+
206
+ if not generated_text:
207
+ print("Empty response received, retrying...")
208
+ time.sleep(wait_time)
209
+ continue
210
+
211
+ # Process the generated text into verses and chorus
212
+ formatted_lyrics = format_lyrics(generated_text, song_structure)
213
+
214
+ # Verify we have enough content
215
+ if formatted_lyrics.count('[Verse') >= song_structure['verses'] and \
216
+ formatted_lyrics.count('[Chorus') >= song_structure['choruses']:
217
+ return formatted_lyrics
218
+ else:
219
+ print("Not enough sections generated, retrying...")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
220
 
221
  elif response.status_code == 503:
222
  print(f"Model loading, waiting {wait_time} seconds...")
 
226
  else:
227
  print(f"Error response: {response.text}")
228
  if attempt < max_retries - 1:
229
+ time.sleep(wait_time)
230
  continue
231
+
 
232
  except Exception as e:
233
  print(f"Exception during generation: {str(e)}")
234
  if attempt < max_retries - 1:
235
  time.sleep(wait_time)
236
  wait_time *= 1.5
237
  continue
238
+
239
+ time.sleep(wait_time)
240
+ wait_time = min(wait_time * 1.5, 10) # Cap maximum wait time at 10 seconds
241
 
242
+ # If we failed to generate after all retries, return a default structure
243
+ return create_default_lyrics(song_structure)
244
 
245
  def format_results(classification_results, lyrics, prompt):
246
  """Format the results for display"""