metadata
license: apache-2.0
language:
- en
base_model:
- HuggingFaceTB/SmolLM2-135M
library_name: transformers
SmolLM2-135M-Instruct-GGUF
All right reserved to the original owners of the model. For more data refer to the original model card. https://huggingface.co/HuggingFaceTB
Introduction
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.
Quickstart
SmolLM2-135M-Instruct-GGUF can be loaded and used via Llama.cpp, here is a program with GUI.
pip install PyQt5 llama-cpp-python pymupdf
import sys
import os
from PyQt5.QtWidgets import (QApplication, QWidget, QLabel, QPushButton,
QLineEdit, QTextEdit, QVBoxLayout, QHBoxLayout,
QFileDialog, QProgressBar, QMessageBox, QMenu)
from PyQt5.QtCore import Qt, QThread, pyqtSignal
from llama_cpp import Llama
import fitz # For PDF processing
class Worker(QThread):
finished = pyqtSignal(str)
progress = pyqtSignal(int, int)
def __init__(self, model, messages, max_tokens):
super().__init__()
self.model = model
self.messages = messages
self.max_tokens = max_tokens
def run(self):
try:
response = self.model.create_chat_completion(
messages=self.messages,
max_tokens=self.max_tokens,
temperature=0.7,
stream=True
)
total_tokens = 0
full_response = ""
for chunk in response:
if "choices" in chunk:
content = chunk["choices"][0]["delta"].get("content", "")
full_response += content
total_tokens += 1
self.progress.emit(total_tokens, self.max_tokens)
self.finished.emit(full_response)
except Exception as e:
self.finished.emit(f"Error generating response: {str(e)}")
class ChatbotGUI(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("Chatbot GUI")
self.resize(800, 600)
self.model = None
self.messages = [
{"role": "system", "content": "You are a helpful AI assistant."}
]
self.thread_count = 12
self.pdf_content = ""
self.initUI()
def initUI(self):
# Model loading section
model_label = QLabel("Model: No model loaded")
load_button = QPushButton("Load GGUF Model")
load_button.clicked.connect(self.load_model)
model_layout = QHBoxLayout()
model_layout.addWidget(model_label)
model_layout.addWidget(load_button)
# PDF upload section
pdf_label = QLabel("PDF: No PDF loaded")
upload_pdf_button = QPushButton("Upload PDF")
upload_pdf_button.clicked.connect(self.upload_pdf)
pdf_layout = QHBoxLayout()
pdf_layout.addWidget(pdf_label)
pdf_layout.addWidget(upload_pdf_button)
# Thread count section
thread_label = QLabel(f"Thread Count: {self.thread_count}")
self.thread_input = QLineEdit()
self.thread_input.setPlaceholderText("Enter new thread count")
update_thread_button = QPushButton("Update Threads")
update_thread_button.clicked.connect(self.update_thread_count)
thread_layout = QHBoxLayout()
thread_layout.addWidget(thread_label)
thread_layout.addWidget(self.thread_input)
thread_layout.addWidget(update_thread_button)
# Chat display
self.chat_display = QTextEdit()
self.chat_display.setReadOnly(True)
self.chat_display.setContextMenuPolicy(Qt.CustomContextMenu)
self.chat_display.customContextMenuRequested.connect(self.show_context_menu)
# User input
self.user_input = QLineEdit()
self.user_input.returnPressed.connect(self.send_message)
send_button = QPushButton("Send")
send_button.clicked.connect(self.send_message)
input_layout = QHBoxLayout()
input_layout.addWidget(self.user_input)
input_layout.addWidget(send_button)
# Progress bar
self.progress_bar = QProgressBar()
self.progress_bar.hide()
# Clear conversation button
clear_button = QPushButton("Clear Conversation")
clear_button.clicked.connect(self.clear_conversation)
# Main layout
main_layout = QVBoxLayout()
main_layout.addLayout(model_layout)
main_layout.addLayout(pdf_layout) # PDF before threads
main_layout.addLayout(thread_layout)
main_layout.addWidget(self.chat_display)
main_layout.addWidget(self.progress_bar)
main_layout.addLayout(input_layout)
main_layout.addWidget(clear_button)
self.setLayout(main_layout)
def load_model(self):
model_path, _ = QFileDialog.getOpenFileName(self, "Load GGUF Model", "", "GGUF Files (*.gguf)")
if model_path:
try:
self.model = Llama(model_path=model_path, n_ctx=2048, n_gpu_layers=-1, n_threads=self.thread_count)
model_name = os.path.basename(model_path)
self.layout().itemAt(0).itemAt(0).widget().setText(f"Model: {model_name}")
QMessageBox.information(self, "Success", "Model loaded successfully!")
except Exception as e:
error_message = f"Error loading model: {str(e)}"
QMessageBox.critical(self, "Error", error_message)
def update_thread_count(self):
try:
new_thread_count = int(self.thread_input.text())
if new_thread_count > 0:
self.thread_count = new_thread_count
self.layout().itemAt(2).itemAt(0).widget().setText(f"Thread Count: {self.thread_count}") # Updated index
self.thread_input.clear()
if self.model:
self.model.set_thread_count(self.thread_count)
QMessageBox.information(self, "Success", f"Thread count updated to {self.thread_count}")
else:
raise ValueError("Thread count must be a positive integer")
except ValueError as e:
QMessageBox.warning(self, "Invalid Input", str(e))
def upload_pdf(self):
pdf_path, _ = QFileDialog.getOpenFileName(self, "Upload PDF", "", "PDF Files (*.pdf)")
if pdf_path:
try:
doc = fitz.open(pdf_path)
self.pdf_content = ""
for page in doc:
self.pdf_content += page.get_text()
self.layout().itemAt(1).itemAt(0).widget().setText(f"PDF: {os.path.basename(pdf_path)}") # Updated index
QMessageBox.information(self, "Success", "PDF loaded successfully!")
except Exception as e:
QMessageBox.critical(self, "Error", f"Error loading PDF: {str(e)}")
def send_message(self):
user_message = self.user_input.text()
if user_message and self.model:
self.messages.append({"role": "user", "content": user_message})
self.update_chat_display(f"You: {user_message}")
self.user_input.clear()
max_tokens = 1000
self.progress_bar.show()
self.progress_bar.setRange(0, max_tokens)
self.progress_bar.setValue(0)
# Add PDF content if available
if self.pdf_content:
self.messages.append({"role": "user", "content": self.pdf_content})
self.worker = Worker(self.model, self.messages, max_tokens)
self.worker.finished.connect(self.on_response_finished)
self.worker.progress.connect(self.on_response_progress)
self.worker.start()
def on_response_finished(self, assistant_message):
self.progress_bar.hide()
self.messages.append({"role": "assistant", "content": assistant_message})
self.update_chat_display(f"Assistant: {assistant_message}")
# Python Code Download
if assistant_message.startswith("```python") and assistant_message.endswith("```"):
self.offer_code_download(assistant_message)
def on_response_progress(self, current_tokens, total_tokens):
self.progress_bar.setValue(current_tokens)
def offer_code_download(self, code):
reply = QMessageBox.question(self, "Download Code",
"The assistant generated Python code. Do you want to download it?",
QMessageBox.Yes | QMessageBox.No)
if reply == QMessageBox.Yes:
file_path, _ = QFileDialog.getSaveFileName(self, "Save Python Code", "code.py", "Python Files (*.py)")
if file_path:
try:
with open(file_path, "w") as f:
f.write(code.strip("```python").strip("```"))
QMessageBox.information(self, "Success", "Code saved successfully!")
except Exception as e:
QMessageBox.critical(self, "Error", f"Error saving code: {str(e)}")
def update_chat_display(self, message):
self.chat_display.append(message + "\n")
self.chat_display.verticalScrollBar().setValue(self.chat_display.verticalScrollBar().maximum())
def clear_conversation(self):
self.messages = [
{"role": "system", "content": "You are a helpful AI assistant."}
]
self.chat_display.clear()
self.pdf_content = "" # Clear PDF content
self.layout().itemAt(1).itemAt(0).widget().setText("PDF: No PDF loaded") # Updated index
def show_context_menu(self, point):
menu = QMenu(self)
copy_action = menu.addAction("Copy")
copy_action.triggered.connect(self.copy_text)
menu.exec_(self.chat_display.mapToGlobal(point))
def copy_text(self):
cursor = self.chat_display.textCursor()
if cursor.hasSelection():
text = cursor.selectedText()
QApplication.clipboard().setText(text)
if __name__ == "__main__":
app = QApplication(sys.argv)
gui = ChatbotGUI()
gui.show()
sys.exit(app.exec_())