LMLK commited on
Commit
7482c23
1 Parent(s): b4b24f6

Update README.md

Browse files
Files changed (1) hide show
  1. README.md +266 -3
README.md CHANGED
@@ -1,3 +1,266 @@
1
- ---
2
- license: apache-2.0
3
- ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: apache-2.0
3
+ language:
4
+ - en
5
+ base_model:
6
+ - HuggingFaceTB/SmolLM2-135M
7
+ library_name: transformers
8
+ ---
9
+ # SmolLM2-135M-Instruct-GGUF
10
+
11
+ All right reserved to the original owners of the model.
12
+ For more data refer to the original model card.
13
+ https://huggingface.co/HuggingFaceTB
14
+
15
+ ## Introduction
16
+ SmolLM2 is a family of compact language models available in three size: 135M, 360M, and 1.7B parameters. They are capable of solving a wide range of tasks while being lightweight enough to run on-device.
17
+
18
+
19
+ ## Quickstart
20
+ SmolLM2-135M-Instruct-GGUF can be loaded and used via Llama.cpp, here is a program with GUI.
21
+
22
+ ```bash
23
+ pip install PyQt5 llama-cpp-python pymupdf
24
+ ```
25
+
26
+ ```python
27
+ import sys
28
+ import os
29
+ from PyQt5.QtWidgets import (QApplication, QWidget, QLabel, QPushButton,
30
+ QLineEdit, QTextEdit, QVBoxLayout, QHBoxLayout,
31
+ QFileDialog, QProgressBar, QMessageBox, QMenu)
32
+ from PyQt5.QtCore import Qt, QThread, pyqtSignal
33
+ from llama_cpp import Llama
34
+ import fitz # For PDF processing
35
+
36
+ class Worker(QThread):
37
+ finished = pyqtSignal(str)
38
+ progress = pyqtSignal(int, int)
39
+
40
+ def __init__(self, model, messages, max_tokens):
41
+ super().__init__()
42
+ self.model = model
43
+ self.messages = messages
44
+ self.max_tokens = max_tokens
45
+
46
+ def run(self):
47
+ try:
48
+ response = self.model.create_chat_completion(
49
+ messages=self.messages,
50
+ max_tokens=self.max_tokens,
51
+ temperature=0.7,
52
+ stream=True
53
+ )
54
+
55
+ total_tokens = 0
56
+ full_response = ""
57
+ for chunk in response:
58
+ if "choices" in chunk:
59
+ content = chunk["choices"][0]["delta"].get("content", "")
60
+ full_response += content
61
+ total_tokens += 1
62
+ self.progress.emit(total_tokens, self.max_tokens)
63
+ self.finished.emit(full_response)
64
+ except Exception as e:
65
+ self.finished.emit(f"Error generating response: {str(e)}")
66
+
67
+ class ChatbotGUI(QWidget):
68
+ def __init__(self):
69
+ super().__init__()
70
+ self.setWindowTitle("Chatbot GUI")
71
+ self.resize(800, 600)
72
+
73
+ self.model = None
74
+ self.messages = [
75
+ {"role": "system", "content": "You are a helpful AI assistant."}
76
+ ]
77
+ self.thread_count = 12
78
+ self.pdf_content = ""
79
+
80
+ self.initUI()
81
+
82
+ def initUI(self):
83
+ # Model loading section
84
+ model_label = QLabel("Model: No model loaded")
85
+ load_button = QPushButton("Load GGUF Model")
86
+ load_button.clicked.connect(self.load_model)
87
+
88
+ model_layout = QHBoxLayout()
89
+ model_layout.addWidget(model_label)
90
+ model_layout.addWidget(load_button)
91
+
92
+ # PDF upload section
93
+ pdf_label = QLabel("PDF: No PDF loaded")
94
+ upload_pdf_button = QPushButton("Upload PDF")
95
+ upload_pdf_button.clicked.connect(self.upload_pdf)
96
+
97
+ pdf_layout = QHBoxLayout()
98
+ pdf_layout.addWidget(pdf_label)
99
+ pdf_layout.addWidget(upload_pdf_button)
100
+
101
+ # Thread count section
102
+ thread_label = QLabel(f"Thread Count: {self.thread_count}")
103
+ self.thread_input = QLineEdit()
104
+ self.thread_input.setPlaceholderText("Enter new thread count")
105
+ update_thread_button = QPushButton("Update Threads")
106
+ update_thread_button.clicked.connect(self.update_thread_count)
107
+
108
+ thread_layout = QHBoxLayout()
109
+ thread_layout.addWidget(thread_label)
110
+ thread_layout.addWidget(self.thread_input)
111
+ thread_layout.addWidget(update_thread_button)
112
+
113
+ # Chat display
114
+ self.chat_display = QTextEdit()
115
+ self.chat_display.setReadOnly(True)
116
+ self.chat_display.setContextMenuPolicy(Qt.CustomContextMenu)
117
+ self.chat_display.customContextMenuRequested.connect(self.show_context_menu)
118
+
119
+ # User input
120
+ self.user_input = QLineEdit()
121
+ self.user_input.returnPressed.connect(self.send_message)
122
+ send_button = QPushButton("Send")
123
+ send_button.clicked.connect(self.send_message)
124
+
125
+ input_layout = QHBoxLayout()
126
+ input_layout.addWidget(self.user_input)
127
+ input_layout.addWidget(send_button)
128
+
129
+ # Progress bar
130
+ self.progress_bar = QProgressBar()
131
+ self.progress_bar.hide()
132
+
133
+ # Clear conversation button
134
+ clear_button = QPushButton("Clear Conversation")
135
+ clear_button.clicked.connect(self.clear_conversation)
136
+
137
+ # Main layout
138
+ main_layout = QVBoxLayout()
139
+ main_layout.addLayout(model_layout)
140
+ main_layout.addLayout(pdf_layout) # PDF before threads
141
+ main_layout.addLayout(thread_layout)
142
+ main_layout.addWidget(self.chat_display)
143
+ main_layout.addWidget(self.progress_bar)
144
+ main_layout.addLayout(input_layout)
145
+ main_layout.addWidget(clear_button)
146
+
147
+ self.setLayout(main_layout)
148
+
149
+ def load_model(self):
150
+ model_path, _ = QFileDialog.getOpenFileName(self, "Load GGUF Model", "", "GGUF Files (*.gguf)")
151
+ if model_path:
152
+ try:
153
+ self.model = Llama(model_path=model_path, n_ctx=2048, n_gpu_layers=-1, n_threads=self.thread_count)
154
+ model_name = os.path.basename(model_path)
155
+ self.layout().itemAt(0).itemAt(0).widget().setText(f"Model: {model_name}")
156
+ QMessageBox.information(self, "Success", "Model loaded successfully!")
157
+ except Exception as e:
158
+ error_message = f"Error loading model: {str(e)}"
159
+ QMessageBox.critical(self, "Error", error_message)
160
+
161
+ def update_thread_count(self):
162
+ try:
163
+ new_thread_count = int(self.thread_input.text())
164
+ if new_thread_count > 0:
165
+ self.thread_count = new_thread_count
166
+ self.layout().itemAt(2).itemAt(0).widget().setText(f"Thread Count: {self.thread_count}") # Updated index
167
+ self.thread_input.clear()
168
+ if self.model:
169
+ self.model.set_thread_count(self.thread_count)
170
+ QMessageBox.information(self, "Success", f"Thread count updated to {self.thread_count}")
171
+ else:
172
+ raise ValueError("Thread count must be a positive integer")
173
+ except ValueError as e:
174
+ QMessageBox.warning(self, "Invalid Input", str(e))
175
+
176
+ def upload_pdf(self):
177
+ pdf_path, _ = QFileDialog.getOpenFileName(self, "Upload PDF", "", "PDF Files (*.pdf)")
178
+ if pdf_path:
179
+ try:
180
+ doc = fitz.open(pdf_path)
181
+ self.pdf_content = ""
182
+ for page in doc:
183
+ self.pdf_content += page.get_text()
184
+ self.layout().itemAt(1).itemAt(0).widget().setText(f"PDF: {os.path.basename(pdf_path)}") # Updated index
185
+ QMessageBox.information(self, "Success", "PDF loaded successfully!")
186
+ except Exception as e:
187
+ QMessageBox.critical(self, "Error", f"Error loading PDF: {str(e)}")
188
+
189
+ def send_message(self):
190
+ user_message = self.user_input.text()
191
+ if user_message and self.model:
192
+ self.messages.append({"role": "user", "content": user_message})
193
+ self.update_chat_display(f"You: {user_message}")
194
+ self.user_input.clear()
195
+
196
+ max_tokens = 1000
197
+ self.progress_bar.show()
198
+ self.progress_bar.setRange(0, max_tokens)
199
+ self.progress_bar.setValue(0)
200
+
201
+ # Add PDF content if available
202
+ if self.pdf_content:
203
+ self.messages.append({"role": "user", "content": self.pdf_content})
204
+
205
+ self.worker = Worker(self.model, self.messages, max_tokens)
206
+ self.worker.finished.connect(self.on_response_finished)
207
+ self.worker.progress.connect(self.on_response_progress)
208
+ self.worker.start()
209
+
210
+ def on_response_finished(self, assistant_message):
211
+ self.progress_bar.hide()
212
+ self.messages.append({"role": "assistant", "content": assistant_message})
213
+ self.update_chat_display(f"Assistant: {assistant_message}")
214
+
215
+ # Python Code Download
216
+ if assistant_message.startswith("```python") and assistant_message.endswith("```"):
217
+ self.offer_code_download(assistant_message)
218
+
219
+ def on_response_progress(self, current_tokens, total_tokens):
220
+ self.progress_bar.setValue(current_tokens)
221
+
222
+ def offer_code_download(self, code):
223
+ reply = QMessageBox.question(self, "Download Code",
224
+ "The assistant generated Python code. Do you want to download it?",
225
+ QMessageBox.Yes | QMessageBox.No)
226
+ if reply == QMessageBox.Yes:
227
+ file_path, _ = QFileDialog.getSaveFileName(self, "Save Python Code", "code.py", "Python Files (*.py)")
228
+ if file_path:
229
+ try:
230
+ with open(file_path, "w") as f:
231
+ f.write(code.strip("```python").strip("```"))
232
+ QMessageBox.information(self, "Success", "Code saved successfully!")
233
+ except Exception as e:
234
+ QMessageBox.critical(self, "Error", f"Error saving code: {str(e)}")
235
+
236
+ def update_chat_display(self, message):
237
+ self.chat_display.append(message + "\n")
238
+ self.chat_display.verticalScrollBar().setValue(self.chat_display.verticalScrollBar().maximum())
239
+
240
+ def clear_conversation(self):
241
+ self.messages = [
242
+ {"role": "system", "content": "You are a helpful AI assistant."}
243
+ ]
244
+ self.chat_display.clear()
245
+ self.pdf_content = "" # Clear PDF content
246
+ self.layout().itemAt(1).itemAt(0).widget().setText("PDF: No PDF loaded") # Updated index
247
+
248
+ def show_context_menu(self, point):
249
+ menu = QMenu(self)
250
+ copy_action = menu.addAction("Copy")
251
+ copy_action.triggered.connect(self.copy_text)
252
+ menu.exec_(self.chat_display.mapToGlobal(point))
253
+
254
+ def copy_text(self):
255
+ cursor = self.chat_display.textCursor()
256
+ if cursor.hasSelection():
257
+ text = cursor.selectedText()
258
+ QApplication.clipboard().setText(text)
259
+
260
+
261
+ if __name__ == "__main__":
262
+ app = QApplication(sys.argv)
263
+ gui = ChatbotGUI()
264
+ gui.show()
265
+ sys.exit(app.exec_())
266
+ ```