import gradio as gr import torch from transformers import AutoTokenizer, AutoModelForCausalLM, pipeline import re import os # --- 1. KONFIGURATION --- # Ersetzen Sie dies durch den tatsächlichen Pfad oder Namen Ihres Modells auf Hugging Face MODEL_NAME = "CocoEntertainment/CocoAi-1PTE" # Setzt den Datentyp auf float16 (halbe Präzision), um den Speicherbedarf beim Laden zu minimieren. DTYPE = torch.float16 DESCRIPTION_TEXT = """ # 🤖 Willkommen bei CocoAi ## Ein Chatbot von CocoEntertainment Hier kannst du auf Deutsch mit **CocoAi** chatten. CocoAi ist ein **Mistral 7B** Modell, das spezifisch für Unterhaltung und kreative Inhalte feingetuned und quantisiert wurde, um eine effiziente Nutzung zu ermöglichen. ### 💡 CocoAi Markdown Syntax (wie die Antworten formatiert werden) Das Modell antwortet unter Verwendung der folgenden speziellen Formatierungsregeln. Das Interface konvertiert diese in Standard-Markdown zur Anzeige: * **\*Text example\*** = Fett (**Bold**) * **\*\*Text example\*\* ** = Kursiv (*Italic*) * **\*\*\*Text example\*\*\* ** = Fett und Kursiv (***Bold and Italic***) * **#Text example** = Haupttitel (Sehr groß) * **/n** = Zeilenumbruch * **'Text example'** = Inline-Text/Code (Monospace) * **'''Text example'''** = Code-Block (Block Monospace) """ # --- 2. HILFSFUNKTION ZUR ANPASSUNG DER SYNTAX --- def convert_to_gradio_markdown(text): """Konvertiert die CocoAi-Markdown-Syntax in Gradio-kompatibles Standard-Markdown.""" # 1. Code-Block ('''Text example''' -> ```Text example```) # Re.DOTALL erlaubt es, über Zeilenumbrüche hinweg zu matchen text = re.sub(r"'''(.*?)'''", r"```\1```", text, flags=re.DOTALL) # 2. Inline Text ('Text example' -> `Text example`) text = re.sub(r"'(.*?)'", r"`\1`", text) # 3. Fett und Kursiv (***Text example*** -> ***Text example***) # Standard-Markdown wird hier beibehalten. # 4. Kursiv (**Text example** -> *Text example*) # Wenn **Ihr** Modell **kursiv** mit **zwei** Sternen markiert (Abweichung vom Standard). # Hier nehmen wir an, dass Sie die Standard-Logik von *fett* (CocoAi:*) und *kursiv* (CocoAi:**) invertieren wollen. text = re.sub(r"\*\*(.*?)\*\*", r"*\1*", text) # 5. Fett (*Text example* -> **Text example**) # Wenn **Ihr** Modell **fett** mit **einem** Stern markiert. text = re.sub(r"\*(.*?)\*", r"**\1**", text) # 6. Zeilenumbruch (/n -> \n) text = text.replace("/n", "\n") return text # --- 3. MODELL LADEN (MAXIMALE SPEICHEROPTIMIERUNG) --- try: print(f"--- Starte Ladevorgang für {MODEL_NAME} mit maximaler Optimierung ---") # Konfiguration für 4-Bit Quantisierung bnb_config = BitsAndBytesConfig( load_in_4bit=True, bnb_4bit_quant_type="nf4", # Auf CPU ignorieren diese Parameter oft, aber sie helfen, # das Laden explizit in den minimalen Speicherzustand zu versetzen bnb_4bit_compute_dtype=DTYPE ) tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME) model = AutoModelForCausalLM.from_pretrained( MODEL_NAME, quantization_config=bnb_config, # Versucht, es als 4-Bit zu laden device_map="auto", # Fügen Sie 'low_cpu_mem_usage=True' hinzu, um den CPU-Speicherverbrauch zu optimieren low_cpu_mem_usage=True, trust_remote_code=True, ) # Erstellt die Pipeline... (Rest des Codes wie gehabt) # ... print(f"Modell '{MODEL_NAME}' erfolgreich geladen und Pipeline erstellt.") except Exception as e: # ... (Rest des except-Blocks wie gehabt) print(f"FATALER FEHLER beim Laden des Modells {MODEL_NAME}: {e}") print("--- Verwende GPT-2 als langsamen Platzhalter ---") coco_pipe = pipeline("text-generation", model="gpt2") # --- 4. CHAT-LOGIK --- def generate_response(message, chat_history): """Generiert die Antwort des Chatbots.""" # Hier müssten Sie das Prompt-Template Ihres Mistral-Modells anwenden (z.B. ChatML, Alpaca, etc.) # Dies ist ein generisches Beispiel: prompt = f"### Instruction: Beantworte die folgende Frage als CocoAi und verwende die CocoAi Markdown Syntax. ###\n\nUser: {message}\n\nCocoAi:" try: # Generierung mit der Pipeline model_output = coco_pipe( prompt, num_return_sequences=1, do_sample=True, temperature=0.7, top_p=0.9 ) # Extrahieren des Texts und Entfernen des Prompts raw_response = model_output[0]['generated_text'] # WICHTIG: Nur der Teil nach "CocoAi:" ist die eigentliche Antwort if "CocoAi:" in raw_response: raw_response = raw_response.split("CocoAi:", 1)[-1].strip() except Exception as e: raw_response = f"Entschuldigung, beim Generieren der Antwort ist ein technischer Fehler aufgetreten: /n'Fehler: {e}'" # 2. Konvertiere die rohe Antwort in Gradio-kompatibles Markdown formatted_response = convert_to_gradio_markdown(raw_response) # 3. Füge die Nachricht zur Historie hinzu chat_history.append((message, formatted_response)) return chat_history, "" # --- 5. GRADIO OBERFLÄCHE --- # Der Tab für die Beschreibung description_tab = gr.Markdown(DESCRIPTION_TEXT) # Der Tab für den Chat with gr.Blocks() as chat_tab: gr.Markdown(f"# 💬 Chat mit CocoAi ({MODEL_NAME})") chatbot = gr.Chatbot( label="CocoAi Chat", height=500, # Wenn Sie die Syntax-Regeln im Chat sehen wollen, lassen Sie die Markdown-Verarbeitung zu: render_markdown=True ) msg = gr.Textbox( show_label=False, placeholder="Geben Sie Ihre Nachricht hier ein...", lines=1 ) with gr.Row(): submit_btn = gr.Button("Senden", variant="primary", scale=2) clear_btn = gr.Button("Chat leeren", scale=1) # Ereignis-Handler für das Senden (durch Klicken oder Enter) submit_btn.click( fn=generate_response, inputs=[msg, chatbot], outputs=[chatbot, msg], queue=False ) msg.submit( fn=generate_response, inputs=[msg, chatbot], outputs=[chatbot, msg], queue=False ) # Ereignis-Handler für das Löschen clear_btn.click( fn=lambda: ([], ""), inputs=None, outputs=[chatbot, msg], queue=False ) # Definiere das Tabbed Interface iface = gr.TabbedInterface( [chat_tab, description_tab], ["CocoAi Chat", "Beschreibung & Syntax"] ) # Starte die App iface.launch()