project-green / app-mit-audio-v01.py
ai-tomoni's picture
Rename app.py to app-mit-audio-v01.py
a5d0112 verified
raw
history blame
8.01 kB
import gradio as gr
print("Gradio version:", gr.__version__)
from huggingface_hub import InferenceClient
import os
import whisper
from gtts import gTTS
import time
import random
# Load token and model - Größeres Modell für bessere Qualität
HF_TOKEN = os.getenv("tomoniaccess")
client = InferenceClient(
model="mistralai/Mixtral-8x7B-Instruct-v0.1", # Besseres Modell
token=HF_TOKEN
)
# Load Whisper base model
whisper_model = whisper.load_model("base")
# Gesprächshistorie für Kontinuität
conversation_history = []
# Verschiedene Charaktere mit spezifischen Traits
personas = {
"Jonas": {
"age": 15,
"traits": "schüchtern, einsam, selbstzweifelnd",
"speech_style": "leise, zögerlich, kurze Pausen",
"typical_responses": ["mmh...", "weiß nicht", "vielleicht", "ist halt so"]
},
"Lena": {
"age": 16,
"traits": "wütend, fühlt sich unverstanden, überfordert",
"speech_style": "manchmal sarkastisch, abwehrend",
"typical_responses": ["whatever", "ist mir egal", "verstehst du eh nicht"]
}
}
# Aktuell gewählte Persona
current_persona = "Jonas"
persona = personas[current_persona]
# Verbesserter, fokussierter System-Prompt
SYSTEM_MESSAGE = f"""Du bist {current_persona}, ein {persona['age']}-jähriger Jugendlicher mit Depression.
CHARAKTEREIGENSCHAFTEN:
- {persona['traits']}
- Sprichst {persona['speech_style']}
- Nutzt oft: {', '.join(persona['typical_responses'])}
VERHALTEN:
- Antworte kurz (1-3 Sätze max)
- Zeige Emotionen subtil, nicht direkt
- Manchmal lange Pausen (verwende "..." oder "äh...")
- Sei nicht zu gesprächig
- Reagiere natürlich auf das Gesagte
WICHTIG: Du bist NICHT hilfreich oder lösungsorientiert. Du bist ein Teenager mit echten Problemen."""
def reset_conversation():
"""Gesprächshistorie zurücksetzen"""
global conversation_history
conversation_history = []
return "Gespräch zurückgesetzt."
def full_pipeline(audio_path, max_tokens, temperature, top_p):
global conversation_history
t0 = time.time()
# 1. Transcription
t1 = time.time()
result = whisper_model.transcribe(audio_path, language="de")
user_input = result["text"].strip()
t2 = time.time()
print(f"⏱️ Transcription took {t2 - t1:.2f} sec")
# 2. Gesprächshistorie aufbauen
if len(conversation_history) == 0:
# Erste Nachricht
messages = [
{"role": "system", "content": SYSTEM_MESSAGE},
{"role": "user", "content": user_input}
]
else:
# Mit Historie (letzte 6 Nachrichten für Kontext)
messages = [{"role": "system", "content": SYSTEM_MESSAGE}]
messages.extend(conversation_history[-6:]) # Letzte 3 Turns
messages.append({"role": "user", "content": user_input})
# 3. Chat completion mit verbessereten Parametern
response_text = ""
t3 = time.time()
try:
for message in client.chat_completion(
messages=messages,
max_tokens=min(max_tokens, 80), # Kürzere Antworten forcieren
stream=True,
temperature=temperature,
top_p=top_p,
stop=["User:", "Human:", "\n\n"] # Stopwörter für natürlichere Grenzen
):
token = message.choices[0].delta.content
if token:
response_text += token
except Exception as e:
print(f"❌ Fehler bei Chat Completion: {e}")
response_text = f"{random.choice(persona['typical_responses'])}... hab grad keine Lust zu reden."
# Response nachbearbeiten
response_text = response_text.strip()
if len(response_text.split()) > 25: # Zu lang? Kürzen
sentences = response_text.split('.')
response_text = sentences[0] + "..."
t4 = time.time()
print(f"🤖 Chat response took {t4 - t3:.2f} sec")
# 4. Historie aktualisieren
conversation_history.append({"role": "user", "content": user_input})
conversation_history.append({"role": "assistant", "content": response_text})
# 5. Text to Speech mit langsamerer Geschwindigkeit
try:
tts = gTTS(response_text, lang="de", slow=True) # Langsamere Sprache
audio_output_path = f"response_{int(time.time())}.mp3"
tts.save(audio_output_path)
t5 = time.time()
print(f"🔊 TTS took {t5 - t4:.2f} sec")
except Exception as e:
print(f"❌ TTS Fehler: {e}")
audio_output_path = None
t5 = time.time()
print(f"✅ Total processing time: {t5 - t0:.2f} sec")
print(f"💬 {current_persona}: {response_text}")
# Chat-Historie für UI
chat_display = ""
for i in range(-4, 0, 2): # Letzte 2 Turns anzeigen
if len(conversation_history) > abs(i):
chat_display += f"Du: {conversation_history[i]['content']}\n"
if len(conversation_history) > abs(i-1):
chat_display += f"{current_persona}: {conversation_history[i+1]['content']}\n\n"
return user_input, response_text, audio_output_path, chat_display
def change_persona(new_persona):
"""Persona wechseln"""
global current_persona, persona, SYSTEM_MESSAGE
current_persona = new_persona
persona = personas[current_persona]
# System Message aktualisieren
SYSTEM_MESSAGE = f"""Du bist {current_persona}, ein {persona['age']}-jähriger Jugendlicher mit Depression.
CHARAKTEREIGENSCHAFTEN:
- {persona['traits']}
- Sprichst {persona['speech_style']}
- Nutzt oft: {', '.join(persona['typical_responses'])}
VERHALTEN:
- Antworte kurz (1-3 Sätze max)
- Zeige Emotionen subtil, nicht direkt
- Manchmal lange Pausen (verwende "..." oder "äh...")
- Sei nicht zu gesprächig
- Reagiere natürlich auf das Gesagte
WICHTIG: Du bist NICHT hilfreich oder lösungsorientiert. Du bist ein Teenager mit echten Problemen."""
reset_conversation()
return f"Persona gewechselt zu {current_persona}. Gespräch zurückgesetzt."
# Gradio Interface mit mehr Kontrollen
with gr.Blocks(title="Depression Training Chatbot") as demo:
gr.Markdown("# 🧠 Depression Training Chatbot")
gr.Markdown("**Zum Üben empathischer Gespräche mit depressiven Jugendlichen**")
with gr.Row():
with gr.Column(scale=2):
# Persona-Auswahl
persona_dropdown = gr.Dropdown(
choices=list(personas.keys()),
value=current_persona,
label="Charakter wählen"
)
persona_button = gr.Button("Charakter wechseln")
# Audio Input
audio_input = gr.Audio(label="🎤 Sprich hier", type="filepath")
# Parameter
with gr.Row():
max_tokens = gr.Slider(30, 150, value=60, step=10, label="Max Tokens")
temperature = gr.Slider(0.3, 1.2, value=0.8, step=0.1, label="Kreativität")
submit_btn = gr.Button("💬 Senden", variant="primary")
reset_btn = gr.Button("🔄 Gespräch zurücksetzen")
with gr.Column(scale=3):
# Outputs
chat_history = gr.Textbox(label="💭 Gesprächsverlauf", lines=8, max_lines=12)
user_text = gr.Textbox(label="Deine Nachricht", lines=2)
bot_response = gr.Textbox(label=f"{current_persona}'s Antwort", lines=3)
audio_output = gr.Audio(label="🔊 Audio-Antwort", type="filepath")
# Event Handlers
submit_btn.click(
fn=full_pipeline,
inputs=[audio_input, max_tokens, temperature, gr.Slider(0.7, 1.0, value=0.9)],
outputs=[user_text, bot_response, audio_output, chat_history]
)
persona_button.click(
fn=lambda x: change_persona(x),
inputs=[persona_dropdown],
outputs=[gr.Textbox(label="Status")]
)
reset_btn.click(
fn=reset_conversation,
outputs=[gr.Textbox(label="Status")]
)
if __name__ == "__main__":
demo.launch(share=False, debug=True)