Spaces:
Sleeping
Sleeping
audio change
Browse files
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(
|
| 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 |
-
|
|
|
|
|
|
|
| 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 |
-
|
| 136 |
-
|
| 137 |
-
|
| 138 |
-
|
| 139 |
-
|
| 140 |
-
|
| 141 |
-
|
| 142 |
-
|
| 143 |
-
|
| 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":
|
| 154 |
{"type": "text", "text": message}
|
| 155 |
]
|
| 156 |
})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 157 |
else:
|
| 158 |
-
|
| 159 |
-
|
| 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=
|
| 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 |
-
|
|
|
|
| 202 |
generated_text = processor.batch_decode(
|
| 203 |
-
output[:, inputs
|
| 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 |
-
|
| 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("*
|
| 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,
|
| 268 |
|
| 269 |
try:
|
| 270 |
# Try processing audio
|
| 271 |
-
|
| 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,
|
| 277 |
except Exception as e:
|
| 278 |
-
return url,
|
| 279 |
|
| 280 |
set_audio_btn.click(
|
| 281 |
set_audio,
|
| 282 |
inputs=[audio_input],
|
| 283 |
-
outputs=[audio_url_state,
|
| 284 |
)
|
| 285 |
|
| 286 |
# Chat response handler
|
| 287 |
-
def chat_response(message, chat_history,
|
| 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(
|
| 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,
|
| 311 |
-
outputs=[chatbot, msg]
|
|
|
|
| 312 |
)
|
| 313 |
|
| 314 |
# Connect message box submit
|
| 315 |
msg.submit(
|
| 316 |
chat_response,
|
| 317 |
-
inputs=[msg, chatbot,
|
| 318 |
-
outputs=[chatbot, msg]
|
|
|
|
| 319 |
)
|
| 320 |
|
| 321 |
# Clear button
|
|
|
|
|
|
|
|
|
|
|
|
|
| 322 |
clear_btn.click(
|
| 323 |
-
|
| 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 |
|