mclemcrew commited on
Commit
eba7df8
·
1 Parent(s): 567c1ca

audio change

Browse files
Files changed (1) hide show
  1. app.py +71 -65
app.py CHANGED
@@ -120,72 +120,65 @@ def process_audio(audio_url):
120
  logger.error(f"Error processing audio: {e}")
121
  return None
122
 
123
- def generate_response(audio_data, message, chat_history=[]):
124
  """Generate response using the model"""
125
  global model, processor
126
-
127
  try:
128
- # Load model if not already loaded
129
  if model is None or processor is None:
130
  model, processor = load_model()
131
-
132
- # Define system prompt
 
 
133
  system_prompt = "You are an expert audio engineer assisting with music production and mixing. Provide clear, specific advice on audio engineering techniques, mixing adjustments, and production decisions based on the audio samples and the user's questions. Focus on practical, actionable guidance."
134
-
135
- # Build conversation history
136
- conversation = [
137
- {"role": "system", "content": system_prompt}
138
- ]
139
-
140
- # Add chat history (limited to last 3 turns)
141
- history_limit = min(len(chat_history), 3)
142
- for user_msg, bot_msg in chat_history[-history_limit:]:
143
- conversation.append({"role": "user", "content": user_msg})
144
- if bot_msg: # Skip None responses
145
- conversation.append({"role": "assistant", "content": bot_msg})
146
-
147
- # Add current message with audio
148
- if audio_data is not None:
149
- # First message with audio - use proper format with audio_url
150
  conversation.append({
151
  "role": "user",
152
  "content": [
153
- {"type": "audio", "audio_url": "https://cdn.freesound.org/previews/92/92990_321967-lq.mp3"}, # Placeholder URL
154
  {"type": "text", "text": message}
155
  ]
156
  })
 
 
 
 
 
157
  else:
158
- # Text-only follow-up message
159
- conversation.append({
160
- "role": "user",
161
- "content": message
162
- })
163
-
164
- # Apply chat template
165
  logger.info("Applying chat template")
166
  text = processor.apply_chat_template(
167
- conversation,
168
- add_generation_prompt=True,
169
- tokenize=False
170
  )
171
-
172
- # Process inputs
173
  logger.info("Processing inputs")
174
  inputs = processor(
175
  text=text,
176
- audios=[audio_data] if audio_data is not None else None,
177
  return_tensors="pt",
178
  padding=True,
179
  truncation=True
180
  )
181
-
182
  # Move inputs to the same device as model
183
  device = next(model.parameters()).device
184
  inputs = {k: v.to(device) for k, v in inputs.items()}
185
-
 
 
186
  log_gpu_memory("Before generation")
187
-
188
- # Generate response
189
  logger.info("Generating response")
190
  with torch.no_grad():
191
  output = model.generate(
@@ -197,22 +190,23 @@ def generate_response(audio_data, message, chat_history=[]):
197
  use_cache=True,
198
  pad_token_id=processor.tokenizer.pad_token_id
199
  )
200
-
201
- # Decode only the new tokens
 
202
  generated_text = processor.batch_decode(
203
- output[:, inputs.input_ids.shape[1]:],
204
  skip_special_tokens=True
205
  )[0]
206
-
207
- # Clean up
208
  del inputs, output
209
  gc.collect()
210
  if torch.cuda.is_available():
211
  torch.cuda.empty_cache()
212
-
213
  log_gpu_memory("After generation")
214
-
215
  return generated_text
 
216
  except Exception as e:
217
  logger.error(f"Error generating response: {e}")
218
  return f"I encountered an error while processing your request: {str(e)}"
@@ -225,7 +219,7 @@ def create_interface():
225
 
226
  # Chat state
227
  audio_url_state = gr.State("")
228
- audio_processed_state = gr.State(None)
229
 
230
  with gr.Row():
231
  with gr.Column(scale=2):
@@ -236,9 +230,10 @@ def create_interface():
236
  msg = gr.Textbox(
237
  placeholder="Ask about your mix...",
238
  show_label=False,
239
- container=False
 
240
  )
241
- submit_btn = gr.Button("Send", variant="primary")
242
 
243
  with gr.Row():
244
  clear_btn = gr.Button("Clear Chat")
@@ -258,44 +253,49 @@ def create_interface():
258
  audio_preview = gr.Audio(label="Audio Preview", type="filepath")
259
 
260
  # Status display
261
- status = gr.Markdown("*Ready to assist with your mix*")
262
 
263
  # Set audio handler
264
  def set_audio(url):
265
  """Set the audio URL and process audio data"""
266
  if not url or not url.strip():
267
- return url, None, gr.update(value=None), "*Please enter a valid audio URL*"
268
 
269
  try:
270
  # Try processing audio
271
- audio_data = process_audio(url)
272
- if audio_data is None:
273
- return url, None, gr.update(value=None), "*Failed to process audio file*"
274
 
275
- # Return success
276
- return url, audio_data, gr.update(value=url), "*Audio loaded successfully!*"
277
  except Exception as e:
278
- return url, None, gr.update(value=None), f"*Error: {str(e)}*"
279
 
280
  set_audio_btn.click(
281
  set_audio,
282
  inputs=[audio_input],
283
- outputs=[audio_url_state, audio_processed_state, audio_preview, status]
284
  )
285
 
286
  # Chat response handler
287
- def chat_response(message, chat_history, audio_data):
288
  """Handle chat message and generate response"""
289
  if not message or not message.strip():
290
  return chat_history, ""
291
 
 
 
 
 
292
  # Add user message to history
293
  chat_history.append((message, None))
294
  yield chat_history, ""
295
 
 
 
 
296
  try:
297
  # Generate response
298
- response = generate_response(audio_data, message, chat_history[:-1])
299
 
300
  # Update history with response
301
  chat_history[-1] = (message, response)
@@ -307,20 +307,26 @@ def create_interface():
307
  # Connect submit button
308
  submit_btn.click(
309
  chat_response,
310
- inputs=[msg, chatbot, audio_processed_state],
311
- outputs=[chatbot, msg]
 
312
  )
313
 
314
  # Connect message box submit
315
  msg.submit(
316
  chat_response,
317
- inputs=[msg, chatbot, audio_processed_state],
318
- outputs=[chatbot, msg]
 
319
  )
320
 
321
  # Clear button
 
 
 
 
322
  clear_btn.click(
323
- lambda: ([], "", "*Chat cleared*"),
324
  outputs=[chatbot, msg, status]
325
  )
326
 
 
120
  logger.error(f"Error processing audio: {e}")
121
  return None
122
 
123
+ def generate_response(audio_url, message, chat_history=None):
124
  """Generate response using the model"""
125
  global model, processor
126
+
127
  try:
 
128
  if model is None or processor is None:
129
  model, processor = load_model()
130
+
131
+ conversation = []
132
+ audios = []
133
+
134
  system_prompt = "You are an expert audio engineer assisting with music production and mixing. Provide clear, specific advice on audio engineering techniques, mixing adjustments, and production decisions based on the audio samples and the user's questions. Focus on practical, actionable guidance."
135
+ conversation.append({"role": "system", "content": system_prompt})
136
+
137
+ if chat_history:
138
+ history_limit = min(len(chat_history), 3)
139
+ for user_msg, bot_msg in chat_history[-history_limit:]:
140
+ conversation.append({"role": "user", "content": user_msg})
141
+ if bot_msg:
142
+ conversation.append({"role": "assistant", "content": bot_msg})
143
+
144
+ if audio_url:
 
 
 
 
 
 
145
  conversation.append({
146
  "role": "user",
147
  "content": [
148
+ {"type": "audio", "audio_url": audio_url},
149
  {"type": "text", "text": message}
150
  ]
151
  })
152
+
153
+ audio_data = process_audio(audio_url)
154
+ if audio_data is not None:
155
+ audios.append(audio_data)
156
+
157
  else:
158
+ conversation.append({"role": "user", "content": message})
159
+
 
 
 
 
 
160
  logger.info("Applying chat template")
161
  text = processor.apply_chat_template(
162
+ conversation, add_generation_prompt=True, tokenize=False
 
 
163
  )
164
+
 
165
  logger.info("Processing inputs")
166
  inputs = processor(
167
  text=text,
168
+ audios=audios if audios else None,
169
  return_tensors="pt",
170
  padding=True,
171
  truncation=True
172
  )
173
+
174
  # Move inputs to the same device as model
175
  device = next(model.parameters()).device
176
  inputs = {k: v.to(device) for k, v in inputs.items()}
177
+
178
+ logger.info(f"Processor output: {inputs}")
179
+
180
  log_gpu_memory("Before generation")
181
+
 
182
  logger.info("Generating response")
183
  with torch.no_grad():
184
  output = model.generate(
 
190
  use_cache=True,
191
  pad_token_id=processor.tokenizer.pad_token_id
192
  )
193
+
194
+ logger.info(f"Model output: {output}")
195
+
196
  generated_text = processor.batch_decode(
197
+ output[:, inputs["input_ids"].shape[1]:],
198
  skip_special_tokens=True
199
  )[0]
200
+
 
201
  del inputs, output
202
  gc.collect()
203
  if torch.cuda.is_available():
204
  torch.cuda.empty_cache()
205
+
206
  log_gpu_memory("After generation")
207
+
208
  return generated_text
209
+
210
  except Exception as e:
211
  logger.error(f"Error generating response: {e}")
212
  return f"I encountered an error while processing your request: {str(e)}"
 
219
 
220
  # Chat state
221
  audio_url_state = gr.State("")
222
+ audio_loaded_state = gr.State(False)
223
 
224
  with gr.Row():
225
  with gr.Column(scale=2):
 
230
  msg = gr.Textbox(
231
  placeholder="Ask about your mix...",
232
  show_label=False,
233
+ container=False,
234
+ interactive=False # Disabled until audio is loaded
235
  )
236
+ submit_btn = gr.Button("Send", variant="primary", interactive=False) # Disabled until audio is loaded
237
 
238
  with gr.Row():
239
  clear_btn = gr.Button("Clear Chat")
 
253
  audio_preview = gr.Audio(label="Audio Preview", type="filepath")
254
 
255
  # Status display
256
+ status = gr.Markdown("*⚠️ Please load an audio file before chatting*")
257
 
258
  # Set audio handler
259
  def set_audio(url):
260
  """Set the audio URL and process audio data"""
261
  if not url or not url.strip():
262
+ return url, gr.update(value=None), "*⚠️ Please enter a valid audio URL*", False, gr.update(interactive=False), gr.update(interactive=False)
263
 
264
  try:
265
  # Try processing audio
266
+ process_audio(url) # Process audio just to test if the url is valid
 
 
267
 
268
+ # Return success and enable chat input
269
+ return url, gr.update(value=url), "*✅ Audio loaded successfully! You can start chatting now.*", True, gr.update(interactive=True), gr.update(interactive=True)
270
  except Exception as e:
271
+ return url, gr.update(value=None), f"*❌ Error: {str(e)}*", False, gr.update(interactive=False), gr.update(interactive=False)
272
 
273
  set_audio_btn.click(
274
  set_audio,
275
  inputs=[audio_input],
276
+ outputs=[audio_url_state, audio_preview, status, audio_loaded_state, msg, submit_btn]
277
  )
278
 
279
  # Chat response handler
280
+ def chat_response(message, chat_history, audio_url, audio_loaded):
281
  """Handle chat message and generate response"""
282
  if not message or not message.strip():
283
  return chat_history, ""
284
 
285
+ if not audio_loaded:
286
+ chat_history.append((message, "Please load an audio file before chatting."))
287
+ return chat_history, ""
288
+
289
  # Add user message to history
290
  chat_history.append((message, None))
291
  yield chat_history, ""
292
 
293
+ # Update status to show loading
294
+ yield chat_history, ""
295
+
296
  try:
297
  # Generate response
298
+ response = generate_response(audio_url, message, chat_history[:-1])
299
 
300
  # Update history with response
301
  chat_history[-1] = (message, response)
 
307
  # Connect submit button
308
  submit_btn.click(
309
  chat_response,
310
+ inputs=[msg, chatbot, audio_url_state, audio_loaded_state],
311
+ outputs=[chatbot, msg],
312
+ show_progress="full" # Show loading indicator during processing
313
  )
314
 
315
  # Connect message box submit
316
  msg.submit(
317
  chat_response,
318
+ inputs=[msg, chatbot, audio_url_state, audio_loaded_state],
319
+ outputs=[chatbot, msg],
320
+ show_progress="full" # Show loading indicator during processing
321
  )
322
 
323
  # Clear button
324
+ def clear_chat():
325
+ """Clear the chat and keep audio loaded state"""
326
+ return [], "", "*✅ Chat cleared. Audio file remains loaded.*"
327
+
328
  clear_btn.click(
329
+ clear_chat,
330
  outputs=[chatbot, msg, status]
331
  )
332