CocoAi-Test / app.py
CoCoGames's picture
Update app.py
fceae9a verified
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()