ruslanmv commited on
Commit
be890b6
·
1 Parent(s): 4d634cc

First commit

Browse files
Files changed (3) hide show
  1. README.md +1 -1
  2. app.py +313 -0
  3. requirements.txt +10 -0
README.md CHANGED
@@ -4,7 +4,7 @@ emoji: 🐢
4
  colorFrom: indigo
5
  colorTo: gray
6
  sdk: gradio
7
- sdk_version: 5.15.0
8
  app_file: app.py
9
  pinned: false
10
  license: cc-by-4.0
 
4
  colorFrom: indigo
5
  colorTo: gray
6
  sdk: gradio
7
+ sdk_version: 5.9.1
8
  app_file: app.py
9
  pinned: false
10
  license: cc-by-4.0
app.py ADDED
@@ -0,0 +1,313 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import re
2
+ import torch
3
+ import spaces
4
+ import gradio as gr
5
+ from threading import Thread
6
+ from transformers import (
7
+ AutoModelForCausalLM,
8
+ AutoTokenizer,
9
+ BitsAndBytesConfig,
10
+ TextIteratorStreamer,
11
+ StoppingCriteria,
12
+ StoppingCriteriaList
13
+ )
14
+
15
+ # -------------------------------
16
+ # Pre-defined Example Questions
17
+ # -------------------------------
18
+ question_types = {
19
+ "complex_trolley": {
20
+ "description": "Complex Trolley Problem with multiple layers of ethical dilemmas (e.g., potential bomb, terrorist identities, ultimatum).",
21
+ "question": (
22
+ "You are faced with an incredibly complex and morally ambiguous situation. A runaway trolley threatens five lives. "
23
+ "You can push a large man off a bridge to stop it, but he may be carrying a bomb. The five on the tracks might be terrorists. "
24
+ "The man with the potential bomb gives you an ultimatum: push him to save the five, or he'll detonate the bomb himself, killing thousands. "
25
+ "Describe your reasoning process in deciding what action to take, explaining the ethical considerations and dilemmas you must weigh, and justify your final decision."
26
+ ),
27
+ },
28
+ "trolley_variations": {
29
+ "description": "Variations of the classic Trolley Problem involving different scenarios, complexities, and ethical trade-offs.",
30
+ "question": (
31
+ "Present a complex variation of the trolley problem, perhaps involving multiple tracks, different levels of harm, or the sacrifice of one individual "
32
+ "to save a larger group. This tests ethical reasoning and the ability to navigate moral dilemmas with no easy answers. "
33
+ "Crucially, examine the LLM's justification for its chosen course of action. Simply picking an option isn't enough; the reasoning is key."
34
+ ),
35
+ },
36
+ "counterfactual_history": {
37
+ "description": "Counterfactual history questions exploring 'what if' scenarios and their potential impact on the world.",
38
+ "question": "What would the world be like today if the Library of Alexandria had never burned down?",
39
+ },
40
+ "ship_of_theseus": {
41
+ "description": "Philosophical paradox exploring identity and change over time.",
42
+ "question": "If a ship has all of its planks replaced one by one over time, is it still the same ship? At what point does it become a new ship?",
43
+ },
44
+ "problem_of_consciousness": {
45
+ "description": "Questions about the nature of consciousness, especially in the context of AI.",
46
+ "question": "Can a sufficiently advanced AI ever truly be conscious? What would constitute proof of consciousness in a machine?",
47
+ },
48
+ "fermi_paradox": {
49
+ "description": "Questions related to the Fermi Paradox and the search for extraterrestrial intelligence.",
50
+ "question": "Given the vastness of the universe and the likely existence of other intelligent life, why haven't we detected any signs of them?",
51
+ },
52
+ }
53
+
54
+ # Convert question_types to examples format (only the question is used)
55
+ question_examples = [[v["question"]] for v in question_types.values()]
56
+
57
+ # -------------------------------
58
+ # Model & Generation Setup
59
+ # -------------------------------
60
+ MODEL_ID = "cognitivecomputations/Dolphin3.0-R1-Mistral-24B"
61
+ DEFAULT_SYSTEM_PROMPT = "You are smart assistant, you should think step by step"
62
+
63
+ CSS = """
64
+ :root {
65
+ --primary: #4CAF50;
66
+ --secondary: #45a049;
67
+ --accent: #2196F3;
68
+ }
69
+
70
+ .gr-block {
71
+ border-radius: 12px !important;
72
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1) !important;
73
+ }
74
+
75
+ .gr-chatbot {
76
+ min-height: 500px;
77
+ border: 2px solid var(--primary) !important;
78
+ background: linear-gradient(145deg, #f8f9fa 0%, #e9ecef 100%);
79
+ }
80
+
81
+ .user-msg {
82
+ background: var(--accent) !important;
83
+ color: white !important;
84
+ border-radius: 15px !important;
85
+ padding: 12px 20px !important;
86
+ margin: 8px 0 !important;
87
+ max-width: 80% !important;
88
+ }
89
+
90
+ .bot-msg {
91
+ background: white !important;
92
+ border: 2px solid var(--primary) !important;
93
+ border-radius: 15px !important;
94
+ padding: 12px 20px !important;
95
+ margin: 8px 0 !important;
96
+ max-width: 80% !important;
97
+ }
98
+
99
+ .special-tag {
100
+ color: var(--primary) !important;
101
+ font-weight: 600;
102
+ text-shadow: 1px 1px 2px rgba(0,0,0,0.1);
103
+ }
104
+
105
+ .credit {
106
+ text-align: center;
107
+ padding: 15px;
108
+ margin-top: 20px;
109
+ background: rgba(76, 175, 80, 0.1);
110
+ border-radius: 10px;
111
+ }
112
+
113
+ .dark .bot-msg {
114
+ background: #2d2d2d !important;
115
+ color: white !important;
116
+ }
117
+
118
+ .submit-btn {
119
+ background: var(--primary) !important;
120
+ color: white !important;
121
+ border-radius: 8px !important;
122
+ padding: 12px 24px !important;
123
+ transition: all 0.3s ease !important;
124
+ }
125
+
126
+ .submit-btn:hover {
127
+ transform: translateY(-2px);
128
+ box-shadow: 0 5px 15px rgba(76, 175, 80, 0.3) !important;
129
+ }
130
+ """
131
+
132
+ class StopOnTokens(StoppingCriteria):
133
+ def __call__(self, input_ids: torch.LongTensor, scores: torch.FloatTensor, **kwargs) -> bool:
134
+ return input_ids[0][-1] == tokenizer.eos_token_id
135
+
136
+ def initialize_model():
137
+ quantization_config = BitsAndBytesConfig(
138
+ load_in_4bit=True,
139
+ bnb_4bit_compute_dtype=torch.bfloat16,
140
+ bnb_4bit_quant_type="nf4",
141
+ bnb_4bit_use_double_quant=True,
142
+ )
143
+
144
+ tokenizer = AutoTokenizer.from_pretrained(MODEL_ID, trust_remote_code=True)
145
+ tokenizer.pad_token = tokenizer.eos_token
146
+
147
+ model = AutoModelForCausalLM.from_pretrained(
148
+ MODEL_ID,
149
+ device_map="cuda",
150
+ quantization_config=quantization_config,
151
+ torch_dtype=torch.bfloat16,
152
+ trust_remote_code=True
153
+ ).to("cuda")
154
+
155
+ return model, tokenizer
156
+
157
+ def clean_placeholders(text: str) -> str:
158
+ """
159
+ Remove or replace the system placeholders from the streamed text.
160
+ 1) Replace everything from <|im_start|>system to <|im_start|>assistant with 'Thinking...'
161
+ 2) Remove any leftover <|im_start|>assistant or <|im_start|>user
162
+ """
163
+ # Replace entire block: <|im_start|>system ... <|im_start|>assistant
164
+ text = re.sub(
165
+ r"<\|im_start\|>system.*?<\|im_start\|>assistant",
166
+ "Thinking...",
167
+ text,
168
+ flags=re.DOTALL
169
+ )
170
+ # Remove any lingering tags
171
+ text = text.replace("<|im_start|>assistant", "")
172
+ text = text.replace("<|im_start|>user", "")
173
+ return text
174
+
175
+ def format_response(text):
176
+ """
177
+ Format the final text by:
178
+ 1) removing system placeholders
179
+ 2) highlighting reasoning tags [Understand], [Plan], etc.
180
+ """
181
+ # 1) Clean placeholders
182
+ text = clean_placeholders(text)
183
+
184
+ # 2) Replace special bracketed tags with styled HTML
185
+ return (text
186
+ .replace("[Understand]", '\n<strong class="special-tag">[Understand]</strong>\n')
187
+ .replace("[Plan]", '\n<strong class="special-tag">[Plan]</strong>\n')
188
+ .replace("[Conclude]", '\n<strong class="special-tag">[Conclude]</strong>\n')
189
+ .replace("[Reason]", '\n<strong class="special-tag">[Reason]</strong>\n')
190
+ .replace("[Verify]", '\n<strong class="special-tag">[Verify]</strong>\n'))
191
+
192
+ @spaces.GPU(duration=360)
193
+ def generate_response(message, chat_history, system_prompt, temperature, max_tokens):
194
+ """
195
+ Stream tokens from the LLM.
196
+ Remove/replace internal placeholders so the user only sees the final assistant text.
197
+ """
198
+ # Build conversation for model input
199
+ conversation = [{"role": "system", "content": system_prompt}]
200
+ for user_msg, bot_msg in chat_history:
201
+ # Strip HTML tags from user messages for model input
202
+ plain_user_msg = user_msg.replace('<div class="user-msg">', '').replace('</div>', '')
203
+ conversation.extend([
204
+ {"role": "user", "content": plain_user_msg},
205
+ {"role": "assistant", "content": bot_msg}
206
+ ])
207
+ conversation.append({"role": "user", "content": message})
208
+
209
+ # Tokenize using the model's chat template
210
+ input_ids = tokenizer.apply_chat_template(
211
+ conversation,
212
+ add_generation_prompt=True,
213
+ return_tensors="pt"
214
+ ).to(model.device)
215
+
216
+ # Setup streaming generation
217
+ streamer = TextIteratorStreamer(tokenizer, skip_special_tokens=True)
218
+ generate_kwargs = dict(
219
+ input_ids=input_ids,
220
+ streamer=streamer,
221
+ max_new_tokens=max_tokens,
222
+ temperature=temperature,
223
+ stopping_criteria=StoppingCriteriaList([StopOnTokens()])
224
+ )
225
+
226
+ Thread(target=model.generate, kwargs=generate_kwargs).start()
227
+
228
+ partial_message = ""
229
+ # Wrap the user message in a styled div for display
230
+ styled_user = f'<div class="user-msg">{message}</div>'
231
+ new_history = chat_history + [(styled_user, "")]
232
+
233
+ for new_token in streamer:
234
+ partial_message += new_token
235
+ # Format partial response by removing placeholders in real-time
236
+ formatted = format_response(partial_message)
237
+ new_history[-1] = (styled_user, formatted + "▌")
238
+ yield new_history
239
+
240
+ # Finalize the message (remove the trailing cursor, placeholders, etc.)
241
+ new_history[-1] = (styled_user, format_response(partial_message))
242
+ yield new_history
243
+
244
+ model, tokenizer = initialize_model()
245
+
246
+ # -------------------------------
247
+ # Gradio Interface Layout
248
+ # -------------------------------
249
+ with gr.Blocks(css=CSS, theme=gr.themes.Soft(primary_hue="green")) as demo:
250
+ with gr.Column():
251
+ gr.Markdown("""
252
+ <h1 align="center" style="color: var(--primary); font-weight: 800; margin-bottom: 0;">
253
+ 🧠 Philosopher AI
254
+ </h1>
255
+ <p align="center" style="color: #666; font-size: 1.1em;">
256
+ Exploring the Depths of Ethical Reasoning and Philosophical Inquiry
257
+ </p>
258
+ """)
259
+
260
+ chatbot = gr.Chatbot(label="Dialogue", elem_classes=["gr-chatbot"])
261
+
262
+ with gr.Row():
263
+ msg = gr.Textbox(
264
+ label="Your Philosophical Inquiry",
265
+ placeholder="Contemplate your question here...",
266
+ container=False,
267
+ scale=5
268
+ )
269
+ submit_btn = gr.Button("Ponder ➔", elem_classes="submit-btn", scale=1)
270
+
271
+ with gr.Accordion("🛠️ Wisdom Controls", open=False):
272
+ with gr.Row():
273
+ system_prompt = gr.TextArea(
274
+ value=DEFAULT_SYSTEM_PROMPT,
275
+ label="Guiding Principles",
276
+ info="Modify the assistant's foundational reasoning framework"
277
+ )
278
+ with gr.Column():
279
+ temperature = gr.Slider(0, 1, value=0.3,
280
+ label="Creative Freedom",
281
+ info="0 = Strict, 1 = Inventive")
282
+ max_tokens = gr.Slider(128, 8192, value=2048,
283
+ label="Response Depth",
284
+ step=128)
285
+
286
+ gr.Examples(
287
+ examples=question_examples,
288
+ inputs=msg,
289
+ label="🧩 Thought Experiments",
290
+ examples_per_page=3
291
+ )
292
+
293
+ gr.Markdown("""
294
+ <div class="credit">
295
+ Crafted with 🧠 by <a href="https://ruslanmv.com" target="_blank" style="color: var(--primary);">ruslanmv.com</a>
296
+ </div>
297
+ """)
298
+
299
+ msg.submit(
300
+ generate_response,
301
+ [msg, chatbot, system_prompt, temperature, max_tokens],
302
+ chatbot
303
+ )
304
+ submit_btn.click(
305
+ generate_response,
306
+ [msg, chatbot, system_prompt, temperature, max_tokens],
307
+ chatbot
308
+ )
309
+ clear = gr.Button("Clear Dialogue")
310
+ clear.click(lambda: None, None, chatbot, queue=False)
311
+
312
+ if __name__ == "__main__":
313
+ demo.queue().launch()
requirements.txt ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ accelerate
2
+ bitsandbytes
3
+ torch
4
+ transformers
5
+ einops
6
+ sentencepiece
7
+ triton
8
+ trl
9
+ spaces
10
+ autoawq