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)