File size: 6,623 Bytes
f4830bf
10d3da5
f4830bf
 
10d3da5
f4830bf
10d3da5
f4830bf
555d322
10d3da5
 
 
 
f4830bf
10d3da5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f4830bf
 
10d3da5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
fceae9a
f4830bf
fceae9a
 
 
 
 
 
 
 
 
 
10d3da5
f4830bf
10d3da5
 
 
fceae9a
10d3da5
fceae9a
 
10d3da5
 
f4830bf
fceae9a
 
f4830bf
10d3da5
f4830bf
 
fceae9a
10d3da5
 
 
f4830bf
10d3da5
f4830bf
10d3da5
f4830bf
10d3da5
 
 
 
 
 
 
 
 
 
 
 
 
f4830bf
10d3da5
 
 
 
 
 
 
 
 
 
 
 
f4830bf
 
10d3da5
f4830bf
 
 
10d3da5
 
f4830bf
 
 
 
 
10d3da5
f4830bf
 
 
 
10d3da5
 
f4830bf
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
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()