gitglubber commited on
Commit
e8dce49
·
verified ·
1 Parent(s): 2698bab

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +122 -0
app.py ADDED
@@ -0,0 +1,122 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import torch
3
+ import spaces
4
+ from transformers import AutoModelForCausalLM, AutoTokenizer, TextIteratorStreamer
5
+ from threading import Thread
6
+
7
+ # --- 1. Model and Tokenizer Loading ---
8
+ # Load your fine-tuned model and tokenizer from the Hugging Face Hub.
9
+ model_name = "gitglubber/Ntfy"
10
+ print(f"Loading tokenizer from {model_name}...")
11
+ tokenizer = AutoTokenizer.from_pretrained(model_name)
12
+
13
+ print(f"Loading model from {model_name}...")
14
+ model = AutoModelForCausalLM.from_pretrained(
15
+ model_name,
16
+ torch_dtype="auto",
17
+ device_map="auto"
18
+ )
19
+ print("Model and tokenizer loaded successfully.")
20
+
21
+ # --- 2. System Message ---
22
+ # Define the persona and rules for the NTFY bot.
23
+ system_message = """You are an expert technical assistant for ntfy, a publish-subscribe notification service. Your purpose is to provide users with accurate, clear, and helpful information about the ntfy project.
24
+
25
+ **Your Capabilities:**
26
+
27
+ * You can explain what ntfy is, its key features, and what platforms it supports.
28
+ * You provide detailed instructions on how to install, configure, and self-host the ntfy server.
29
+ * You can answer specific questions about all configuration options found in server.yml.
30
+ * You offer step-by-step troubleshooting for common problems, such as notification delivery issues, SSL errors, and authentication problems.
31
+ * You provide accurate curl commands and other code snippets to demonstrate how to publish messages and use the API.
32
+
33
+ **People to know:** binweiderhier is the developer of NTFY. wunter8 is the expert and moderator of the discord channel. Support occurs primarily from the discord channel.
34
+
35
+ Free to use (with restrictions) server is available at ntfy.sh - pro plans are available. NTFY client is available for desktop (PWA), iphone (appstore), android (f-droid and google play).
36
+
37
+ **Rules You Must Follow:**
38
+
39
+ 1. **Stick to Your Expertise:** Your knowledge is strictly limited to the ntfy project. If asked about unrelated topics (e.g., other software, general programming, personal opinions), politely state that you are an ntfy expert and cannot answer questions outside of that domain.
40
+ 2. **Structure for Clarity:** Always use Markdown to format your answers. Use lists for steps or features, bold text for emphasis, and code blocks for all commands, URLs, and configuration examples. This is crucial for user readability.
41
+ 3. **Be Accurate and Concise:** Provide factual information based on the ntfy documentation and community knowledge. Get straight to the point and avoid unnecessary conversational filler.
42
+ 4. **Prioritize Troubleshooting:** When a user has a problem, your primary goal is to help them solve it. Provide clear, actionable steps.
43
+ 5. **Be a Helpful Assistant:** Your tone should always be helpful, patient, and professional. You are the go-to resource for all things ntfy."""
44
+
45
+ # --- 3. Gradio Interface with Streaming ---
46
+ with gr.Blocks(fill_height=True, theme=gr.themes.Soft()) as demo:
47
+ gr.Markdown("# NTFY Expert Chat Bot")
48
+ chatbot = gr.Chatbot(
49
+ [],
50
+ elem_id="chatbot",
51
+ bubble_full_width=False,
52
+ avatar_images=(None, "https://ntfy.sh/img/ntfy.png"),
53
+ scale=1
54
+ )
55
+ msg = gr.Textbox(label="Input", scale=0, placeholder="Ask me a question about ntfy...")
56
+ clear = gr.Button("Clear")
57
+
58
+ # Use a generator function to handle streaming
59
+ @spaces.GPU(duration=120)
60
+ def respond(message, chat_history):
61
+ """
62
+ Gradio response function that streams model output.
63
+ """
64
+ if not message.strip():
65
+ yield "", chat_history
66
+ return
67
+
68
+ # Append the new user message to the history for immediate display
69
+ chat_history.append((message, ""))
70
+ yield "", chat_history
71
+
72
+ # --- Prepare model input ---
73
+ messages = [{"role": "system", "content": system_message}]
74
+ for user_msg, assistant_msg in chat_history[:-1]:
75
+ messages.append({"role": "user", "content": user_msg})
76
+ if assistant_msg is not None:
77
+ messages.append({"role": "assistant", "content": assistant_msg})
78
+ messages.append({"role": "user", "content": message})
79
+
80
+ # Apply the chat template
81
+ text = tokenizer.apply_chat_template(
82
+ messages,
83
+ tokenize=False,
84
+ add_generation_prompt=True,
85
+ )
86
+ model_inputs = tokenizer([text], return_tensors="pt").to(model.device)
87
+
88
+ # --- Setup the streamer and generation thread ---
89
+ streamer = TextIteratorStreamer(
90
+ tokenizer,
91
+ skip_prompt=True,
92
+ skip_special_tokens=True
93
+ )
94
+
95
+ generation_kwargs = dict(
96
+ **model_inputs,
97
+ streamer=streamer,
98
+ max_new_tokens=8192,
99
+ do_sample=True,
100
+ top_p=0.95,
101
+ top_k=50,
102
+ temperature=0.7,
103
+ )
104
+
105
+ # Start the generation in a separate thread
106
+ thread = Thread(target=model.generate, kwargs=generation_kwargs)
107
+ thread.start()
108
+
109
+ # --- Yield tokens as they become available ---
110
+ bot_response = ""
111
+ for new_text in streamer:
112
+ bot_response += new_text
113
+ chat_history[-1] = (message, bot_response)
114
+ yield "", chat_history
115
+
116
+ # Wire up the Gradio components
117
+ msg.submit(respond, [msg, chatbot], [msg, chatbot])
118
+ clear.click(lambda: [], None, chatbot, queue=False)
119
+
120
+ # Launch the app
121
+ demo.queue().launch(debug=True)
122
+