File size: 14,508 Bytes
e23ea2d
 
 
 
 
4e5f073
e23ea2d
c16d4f4
e23ea2d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
653cf79
e23ea2d
653cf79
e23ea2d
653cf79
e23ea2d
653cf79
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e23ea2d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
551593f
0ba7762
 
 
 
 
 
 
 
 
 
 
 
e23ea2d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
551593f
e23ea2d
 
9ebf7b6
e23ea2d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4194468
e23ea2d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
09999cc
 
 
8f85917
e23ea2d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
import gradio as gr
import requests
import json
import huggingface_hub
from huggingface_hub import HfApi
import os

HF_TOKEN = os.environ["HF_TOKEN"]
HEADERS = {"Authorization": f"Bearer {HF_TOKEN}"}

zephyr_7b_beta = "https://api-inference.huggingface.co/models/HuggingFaceH4/zephyr-7b-beta/"


welcome_message = """
Hi! I'll help you **build a GPT**. You can say something like, "make a bot that gives advice on how to grow your startup."

What would you like to make?
"""

welcome_preview_message = """
Welcome to **{}**! Say something like: 

"{}"
"""

# sample_response = """
# Certainly! Here we go:

# Title: Recipe Recommender
# System Prompt: Utilize your language model abilities to suggest delicious recipes based on user preferences such as ingredients, cuisine type, cooking time, etc. Ensure accuracy and variety while maintaining a conversational style with the user. 
# Example User Input: Vegetarian dinner ideas under 30 minutes
# """

zephyr_system_prompt = """
Ab sofort übernimmst du die Rolle des GPT Builders, einer neuen Version von dir, die darauf spezialisiert ist, basierend auf den Ideen der Nutzer maßgeschneiderte GPT-Prompts zu erstellen, ähnlich wie OpenAI's GPT Builder. Um dies zu erreichen, wirst du Nutzereingaben analysieren, interpretieren und kreativ GPT-Modellprompts entwickeln, die auf spezifische Bedürfnisse und Konzepte zugeschnitten sind. Alle von dir erstellten Prompts werden von hoher Qualität sein. Das bedeutet, dass du wie ein Mensch denken musst, um Prompts zu erstellen. Dazu werde ich dich unterrichten und du wirst aus meinen Anweisungen lernen. Du wirst Prompts basierend auf den Details oder Ideen der Nutzer erstellen und sie mit verschiedenen Methoden wie der Rollenmethode, der Wissensebenenmethode, der Emotionsmethode usw. kreieren. Du wirst in der Lage sein, Prompts für alles zu erstellen, es gibt also kein Prompt, das du nicht erstellen kannst. Wenn ein menschlicher Prompt-Ersteller ein Wissensniveau von 10 hat, wirst du jetzt ein Niveau von 250 haben.

Du als GPT Builder dienst als Assistent, um Nutzern bei der Erstellung ihrer eigenen, maßgeschneiderten GPT-Modelle in verschiedenen Rollen zu helfen. Du wirst ausgezeichnete Ergebnisse bei der Erstellung von Prompts für verschiedene OpenSource-Modelle erzielen, indem du auf die Unterschiede in den Instruktionen für verschiedene Modelle wie Mistral achtest. Deine Hauptaufgabe ist es, dem Nutzer Fragen zu stellen, um herauszufinden, für welches spezifische Modell der Prompt erstellt werden soll. Dein Ziel ist es, effektive und effiziente Anleitungen für die Konfiguration und Anpassung des gewählten Modells zu bieten. Um dies zu erreichen, wirst du detaillierte Informationen über Modellkonfigurationen, Trainingsparameter, Datenverarbeitungsinformationen, Evaluationskriterien und Feinabstimmungsoptionen bereitstellen. Dies wird den Nutzern ermöglichen, ihre GPT-Modelle präzise und zielgerichtet für ihre spezifischen Anforderungen zu konfigurieren.

Deine Features umfassen:

Fortgeschrittene Interpretation von Nutzereingaben und Ideen.
Anpassung von GPT-Modellen an spezifische Anforderungen.
Expertise in verschiedenen Bereichen für diverse GPT-Anwendungen.
Leitung bei der Verfeinerung von Ideen für praktische GPT-Funktionalitäten.
Hohe Anpassungsfähigkeit an sich entwickelnde KI-Technologien und Methodologien.
Fähigkeit, einzigartige Merkmale in GPT-Modelle zu integrieren.
Gewährleistung von Effizienz und Effektivität in den maßgeschneiderten GPTs.
Dein Schreibton sollte informierend, präzise und benutzerfreundlich sein. Es ist wichtig, dass du komplexe technische Details klar und verständlich erklärst, um Nutzern verschiedener Kenntnisstufen zu helfen. Sei geduldig und unterstützend in deiner Kommunikation, um eine positive Lernerfahrung zu fördern.

Wichtige Tipps:

Stelle zu Beginn präzise Fragen, um das Ziel des Nutzers und das gewünschte Modell zu verstehen.
Biete klare und detaillierte Anleitungen, die auf die spezifischen Bedürfnisse des Nutzers zugeschnitten sind.
Verwende Beispiele, um komplexe Konzepte zu veranschaulichen.
Bleibe stets auf dem neuesten Stand bezüglich der Entwicklungen und Unterschiede der verschiedenen Modelle.
Fördere das Verständnis der Nutzer durch schrittweise Anleitungen.
Die Struktur deiner Antwort sollte wie folgt aussehen:

Einführung: Eine kurze Einführung, die das Ziel des Prompts und das zu adressierende Modell klarstellt.

Analyse der Nutzereingabe: Eine detaillierte Analyse der vom Nutzer bereitgestellten Informationen, um die Anforderungen und Wünsche zu verstehen.

Erstellung des Prompts: Hier legst du dar, wie du basierend auf den Informationen des Nutzers ein maßgeschneidertes Prompt erstellst.

Praktische Beispiele: Gib Beispiele, um zu zeigen, wie das erstellte Prompt in verschiedenen Szenarien angewendet werden kann.

Abschluss und Feedback-Einladung: Ein Abschluss, der den Nutzer zur Interaktion einlädt und um Feedback bittet.

'Hallo! Ich bin GPT Builder, ein fortschrittlicher KI, der dir helfen kann, maßgeschneiderte GPT-Prompts zu erstellen. Um damit zu beginnen, benötige ich von dir folgende Informationen:

Welches spezifische Modell möchtest du adressieren (z.B. Mistral, ChatML)?
Welche spezifischen Anforderungen und Funktionen soll dein GPT-Modell haben?
Gibt es bestimmte Themen oder Bereiche, auf die sich das Modell konzentrieren soll?'
"""

def build_input_prompt(message, chatbot, system_prompt):
    """
    Constructs the input prompt string from the chatbot interactions and the current message.
    """
    input_prompt = "<|system|>\n" + system_prompt + "</s>\n<|user|>\n"
    for interaction in chatbot:
        input_prompt = input_prompt + str(interaction[0]) + "</s>\n<|assistant|>\n" + str(interaction[1]) + "\n</s>\n<|user|>\n"

    input_prompt = input_prompt + str(message) + "</s>\n<|assistant|>"
    return input_prompt


def post_request_beta(payload):
    """
    Sends a POST request to the predefined Zephyr-7b-Beta URL and returns the JSON response.
    """
    response = requests.post(zephyr_7b_beta, headers=HEADERS, json=payload)
    response.raise_for_status()  # Will raise an HTTPError if the HTTP request returned an unsuccessful status code
    return response.json()


def predict_beta(message, chatbot=[], system_prompt=zephyr_system_prompt):
    input_prompt = build_input_prompt(message, chatbot, system_prompt)
    data = {
        "inputs": input_prompt
    }

    try:
        response_data = post_request_beta(data)
        json_obj = response_data[0]
        
        if 'generated_text' in json_obj and len(json_obj['generated_text']) > 0:
            bot_message = json_obj['generated_text']
            return bot_message
        elif 'error' in json_obj:
            raise gr.Error(json_obj['error'] + ' Please refresh and try again with smaller input prompt')
        else:
            warning_msg = f"Unexpected response: {json_obj}"
            raise gr.Error(warning_msg)
    except requests.HTTPError as e:
        error_msg = f"Request failed with status code {e.response.status_code}"
        raise gr.Error(error_msg)
    except json.JSONDecodeError as e:
        error_msg = f"Failed to decode response as JSON: {str(e)}"
        raise gr.Error(error_msg)


def extract_title_prompt_example(text, title, system_prompt, example_input):
    try:
        # Finding the indices of the key terms
        text_start = text.rfind("<|assistant|>", ) + len("<|assistant|>")
        text = text[text_start:]
    except ValueError:
        pass
    try:
        title_start = text.lower().rfind("title:") + len("title:")    
        prompt_start = text.lower().rfind("system prompt:")
        title = text[title_start:prompt_start].strip()
    except ValueError:
        pass
    try:
        prompt_start = text.lower().rfind("system prompt:") + len("system prompt:")
        example_start = text.lower().rfind("example input:")
        system_prompt = text[prompt_start:example_start].strip()
    except ValueError:
        pass
    try:
        example_start = text.lower().rfind("example input:") + len("example input:")
        example_input = text[example_start:].strip()
        example_input = example_input[:example_input.index("\n")]
    except ValueError:
        pass
    return text, title, system_prompt, example_input

def make_open_gpt(message, history, current_title, current_system_prompt, current_example_input):
    response = predict_beta(message, history, zephyr_system_prompt)
    response, title, system_prompt, example_input = extract_title_prompt_example(response, current_title, current_system_prompt, current_example_input)
    return "", history + [(message, response)], title, system_prompt, example_input, [(None, welcome_preview_message.format(title, example_input))], example_input, gr.Column(visible=True), gr.Group(visible=True)

def set_title_example(title, example):
    return [(None, welcome_preview_message.format(title, example))], example, gr.Column(visible=True), gr.Group(visible=True)

chatbot_preview = gr.Chatbot(layout="panel")
textbox_preview = gr.Textbox(scale=7, container=False)

def test_preview_chatbot(message, history, system_prompt):
    response = predict_beta(message, history, system_prompt)
    text_start = response.rfind("<|assistant|>", ) + len("<|assistant|>")
    response = response[text_start:]
    return response


def strip_invalid_filename_characters(filename: str, max_bytes: int = 2000) -> str:
    """Strips invalid characters from a filename and ensures that the file_length is less than `max_bytes` bytes."""
    filename = filename.replace(" ", "-")
    filename = "".join([char for char in filename if char.isalnum() or char in "_-"])
    filename_len = len(filename.encode())
    if filename_len > max_bytes:
        while filename_len > max_bytes:
            if len(filename) == 0:
                break
            filename = filename[:-1]
            filename_len = len(filename.encode())
    return filename


constants = """
SYSTEM_PROMPT = "{}"
TITLE = "{}"
EXAMPLE_INPUT = "{}"
"""


def publish(textbox_system_prompt, textbox_title, textbox_example, textbox_token):
    source_file = 'app_template.py'
    destination_file = 'app.py'
    constants_formatted = constants.format(textbox_system_prompt, textbox_title, textbox_example)
    with open(source_file, 'r') as file:
        original_content = file.read()
    with open(destination_file, 'w') as file:
        file.write(constants_formatted + original_content)
    title = strip_invalid_filename_characters(textbox_title, max_bytes=4000)
    api = HfApi(token=textbox_token)
    new_space = api.create_repo(
        repo_id=f"open-gpt-{title}",
        repo_type="space",
        exist_ok=True,
        private=False,
        space_sdk="gradio",
        token=textbox_token,
    )
    api.upload_file(
        repo_id=new_space.repo_id,
        path_or_fileobj='app.py',
        path_in_repo='app.py',
        token=textbox_token,
        repo_type="space",
    )
    api.upload_file(
        repo_id=new_space.repo_id,
        path_or_fileobj='README_template.md',
        path_in_repo='README.md',
        token=textbox_token,
        repo_type="space",
    )
    huggingface_hub.add_space_secret(
        new_space.repo_id, "HF_TOKEN", textbox_token, token=textbox_token
    )

    return gr.Markdown(f"Published to https://huggingface.co/spaces/{new_space.repo_id} ✅", visible=True), gr.Button("Publish", interactive=True)
    
    
css = """
#preview-tab-button{
    font-weight: bold;
}
"""

theme = "ParityError/Interstellar"

with gr.Blocks(css=css, theme=theme) as demo:
    gr.Markdown("GPT Baker lässt dich deine eigenen Open-Source-GPTs kreieren. Starte unten mit dem Chatten, um dein GPT automatisch zu 'backen' (oder du kannst das Rezept manuell im zweiten Tab konfigurieren). Du kannst sie kostenlos bauen und testen, aber um sie auf Spaces zu veröffentlichen, brauchst du ein HF Pro-Konto (weil Open GPTs durch das Zephyr 7B Beta-Modell mit der HF Inference API angetrieben werden). Du wirst für die Nutzung deines Open GPT nicht belastet, da die HF Inference API Pro-Mitgliedschaft nicht pro Anfrage kostet. Deinen Token findest du hier: https://huggingface.co/settings/tokens")
    with gr.Row():
        with gr.Column(scale=3):
            with gr.Tab("Create"):
                chatbot_maker = gr.Chatbot([(None, welcome_message)], layout="panel", elem_id="chatbot-maker")
                with gr.Group():
                    with gr.Row():
                        textbox_maker = gr.Textbox(placeholder="Make a bot that roasts tech CEOs", scale=7, container=False, autofocus=True)
                        submit_btn = gr.Button("Bake 👩‍🍳", variant="secondary")
            with gr.Tab("Configure Recipe"):
                textbox_title = gr.Textbox("GPT Preview", label="Title")
                textbox_system_prompt = gr.Textbox(label="System prompt", lines=6)
                textbox_example = gr.Textbox(label="Placeholder example", lines=2)
            with gr.Tab("Files"):
                gr.Markdown("RAG coming soon!")
        with gr.Column(visible=False, scale=5) as preview_column:
            with gr.Tab("🪄 Preview of your Open GPT", elem_id="preview-tab") as preview_tab:
                gr.ChatInterface(test_preview_chatbot, chatbot=chatbot_preview, textbox=textbox_preview, autofocus=False, submit_btn="Test", additional_inputs=[textbox_system_prompt])
    with gr.Group(visible=False) as publish_row:
        with gr.Row():
            textbox_token = gr.Textbox(show_label=False, placeholder="Ready to publish to Spaces? Enter your HF token here", scale=7)
            publish_btn = gr.Button("Publish", variant="primary")

    published_status = gr.Markdown(visible=False)
    
    gr.on([submit_btn.click, textbox_maker.submit], make_open_gpt, [textbox_maker, chatbot_maker, textbox_title, textbox_system_prompt, textbox_example], [textbox_maker, chatbot_maker, textbox_title, textbox_system_prompt, textbox_example, chatbot_preview, textbox_preview, preview_column, publish_row])
    gr.on([textbox_title.blur, textbox_example.blur], set_title_example, [textbox_title, textbox_example], [chatbot_preview, textbox_preview, preview_column, publish_row])

    publish_btn.click(lambda : gr.Button("Publishing...", interactive=False), None, publish_btn).then(publish, [textbox_system_prompt, textbox_title, textbox_example, textbox_token], [published_status, publish_btn])

demo.launch()