xxx777xxxASD commited on
Commit
29d9465
·
verified ·
1 Parent(s): d27e10c

Upload 4 files

Browse files
Source Code/QToggle.py ADDED
@@ -0,0 +1,203 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Author: Luan Dias - https://github.com/luandiasrj
3
+ Url: https://github.com/luandiasrj/QToggle_-_Advanced_QCheckbox_for_PyQT6
4
+
5
+ This code implements a custom QToggle class, which is a toggle switch derived
6
+ from QCheckBox. The QToggle class features customizable colors, and properties.
7
+ It includes smooth transitions when toggling between states.
8
+
9
+ The custom properties include:
10
+
11
+ bg_color: background color of the toggle
12
+ circle_color: color of the circle inside the toggle
13
+ active_color: color of the background when the toggle is checked
14
+ disabled_color: color of the toggle when it's disabled
15
+ text_color: color of the text
16
+
17
+ Main functions and methods in the class include:
18
+
19
+ init: Initializes the QToggle object with default colors and settings
20
+ setDuration: Set the duration for the animation
21
+ update_pos_color: Updates the circle position and background color
22
+ start_transition: Starts the transition animation when the state changes
23
+ create_animation: Creates the circle position animation
24
+ create_bg_color_animation: Creates the background color animation
25
+ sizeHint: Provides the recommended size for the toggle
26
+ hitButton: Determines if the mouse click is inside the toggle area
27
+ paintEvent: Handles the custom painting of the toggle
28
+
29
+ The example demonstrates how to use the QToggle class by creating three
30
+ different toggles with various settings such as custom height, colors, and font.
31
+ """
32
+
33
+ from PyQt6.QtCore import Qt, QRect, pyqtProperty, QPropertyAnimation, QPoint, \
34
+ QEasingCurve
35
+ from PyQt6.QtGui import QColor, QFontMetrics, QPainter, QPainterPath, QBrush, \
36
+ QPen, QFont
37
+ from PyQt6.QtWidgets import QApplication, QWidget, QCheckBox, QVBoxLayout
38
+
39
+
40
+ class QToggle(QCheckBox):
41
+ bg_color = pyqtProperty(
42
+ QColor, lambda self: self._bg_color,
43
+ lambda self, col: setattr(self, '_bg_color', col))
44
+ circle_color = pyqtProperty(
45
+ QColor, lambda self: self._circle_color,
46
+ lambda self, col: setattr(self, '_circle_color', col))
47
+ active_color = pyqtProperty(
48
+ QColor, lambda self: self._active_color,
49
+ lambda self, col: setattr(self, '_active_color', col))
50
+ disabled_color = pyqtProperty(
51
+ QColor, lambda self: self._disabled_color,
52
+ lambda self, col: setattr(self, '_disabled_color', col))
53
+ text_color = pyqtProperty(
54
+ QColor, lambda self: self._text_color,
55
+ lambda self, col: setattr(self, '_text_color', col))
56
+
57
+ def __init__(self, parent=None):
58
+ super().__init__(parent)
59
+ self._bg_color, self._circle_color, self._active_color, \
60
+ self._disabled_color, self._text_color = QColor("#0BF"), \
61
+ QColor("#DDD"), QColor('#777'), QColor("#CCC"), QColor("#000")
62
+ self._circle_pos, self._intermediate_bg_color = None, None
63
+ self.setFixedHeight(18)
64
+ self._animation_duration = 500 # milliseconds
65
+ self.stateChanged.connect(self.start_transition)
66
+ self._user_checked = False # Introduced flag to check user-initiated changes
67
+
68
+ circle_pos = pyqtProperty(
69
+ float, lambda self: self._circle_pos,
70
+ lambda self, pos: (setattr(self, '_circle_pos', pos), self.update()))
71
+ intermediate_bg_color = pyqtProperty(
72
+ QColor, lambda self: self._intermediate_bg_color,
73
+ lambda self, col: setattr(self, '_intermediate_bg_color', col))
74
+
75
+ def setDuration(self, duration: int):
76
+ """
77
+ Set the duration for the animation.
78
+ :param duration: Duration in milliseconds.
79
+ """
80
+ self._animation_duration = duration
81
+
82
+ def update_pos_color(self, checked=None):
83
+ self._circle_pos = self.height() * (1.1 if checked else 0.1)
84
+ if self.isChecked():
85
+ self._intermediate_bg_color = self._active_color
86
+ else:
87
+ self._intermediate_bg_color = self._bg_color
88
+
89
+ def start_transition(self, state):
90
+ if not self._user_checked: # Skip animation if change isn't user-initiated
91
+ self.update_pos_color(state)
92
+ return
93
+ for anim in [self.create_animation, self.create_bg_color_animation]:
94
+ animation = anim(state)
95
+ animation.start()
96
+ self._user_checked = False # Reset the flag after animation starts
97
+
98
+ def mousePressEvent(self, event):
99
+ self._user_checked = True # Set flag when user manually clicks the toggle
100
+ super().mousePressEvent(event)
101
+
102
+ def create_animation(self, state):
103
+ return self._create_common_animation(
104
+ state, b'circle_pos', self.height() * 0.1, self.height() * 1.1)
105
+
106
+ def create_bg_color_animation(self, state):
107
+ return self._create_common_animation(
108
+ state, b'intermediate_bg_color', self._bg_color, self._active_color)
109
+
110
+ def _create_common_animation(self, state, prop, start_val, end_val):
111
+ animation = QPropertyAnimation(self, prop, self)
112
+ animation.setEasingCurve(QEasingCurve.Type.InOutCubic)
113
+ animation.setDuration(self._animation_duration)
114
+ animation.setStartValue(start_val if state else end_val)
115
+ animation.setEndValue(end_val if state else start_val)
116
+ return animation
117
+
118
+ def showEvent(self, event):
119
+ super().showEvent(event) # Ensure to call the super class's implementation
120
+ self.update_pos_color(self.isChecked())
121
+
122
+ def resizeEvent(self, event):
123
+ self.update_pos_color(self.isChecked())
124
+
125
+ def sizeHint(self):
126
+ size = super().sizeHint()
127
+ text_width = QFontMetrics(
128
+ self.font()).boundingRect(self.text()).width()
129
+ size.setWidth(int(self.height() * 2 + text_width * 1.075))
130
+ return size
131
+
132
+ def hitButton(self, pos: QPoint):
133
+ return self.contentsRect().contains(pos)
134
+
135
+ def paintEvent(self, event):
136
+ painter = QPainter(self)
137
+ painter.setRenderHint(QPainter.RenderHint.Antialiasing)
138
+
139
+ circle_color = QColor(
140
+ self.disabled_color if not self.isEnabled() else self.circle_color)
141
+ bg_color = QColor(
142
+ self.disabled_color if not self.isEnabled() else
143
+ self.intermediate_bg_color)
144
+ text_color = QColor(
145
+ self.disabled_color if not self.isEnabled() else self.text_color)
146
+
147
+ bordersradius = self.height() / 2
148
+ togglewidth = self.height() * 2
149
+ togglemargin = self.height() * 0.3
150
+ circlesize = self.height() * 0.8
151
+
152
+ bg_path = QPainterPath()
153
+ bg_path.addRoundedRect(
154
+ 0, 0, togglewidth, self.height(), bordersradius, bordersradius)
155
+ painter.fillPath(bg_path, QBrush(bg_color))
156
+
157
+ circle = QPainterPath()
158
+ circle.addEllipse(
159
+ self.circle_pos, self.height() * 0.1, circlesize, circlesize)
160
+ painter.fillPath(circle, QBrush(circle_color))
161
+
162
+ painter.setPen(QPen(QColor(text_color)))
163
+ painter.setFont(self.font())
164
+ text_rect = QRect(int(togglewidth + togglemargin), 0, self.width() -
165
+ int(togglewidth + togglemargin), self.height())
166
+ text_rect.adjust(
167
+ 0, (self.height() - painter.fontMetrics().height()) // 2, 0, 0)
168
+ painter.drawText(text_rect, Qt.AlignmentFlag.AlignLeft |
169
+ Qt.AlignmentFlag.AlignVCenter, self.text())
170
+ painter.end()
171
+
172
+
173
+ if __name__ == '__main__':
174
+ app = QApplication([])
175
+ window = QWidget()
176
+ layout = QVBoxLayout()
177
+
178
+ checkbox0 = QToggle()
179
+ checkbox0.setFixedHeight(12)
180
+ layout.addWidget(checkbox0)
181
+
182
+ checkbox1 = QToggle()
183
+ checkbox1.setText('Checkbox 1 - Disabled')
184
+ checkbox1.setEnabled(False)
185
+ layout.addWidget(checkbox1)
186
+
187
+ checkbox2 = QToggle()
188
+ checkbox2.setText('Checkbox 2 - Checked, custom height, animation duration, colors and font')
189
+ checkbox2.setFixedHeight(24)
190
+ checkbox2.setFont(QFont('Segoe Print', 10))
191
+ checkbox2.setStyleSheet("QToggle{"
192
+ "qproperty-bg_color:#FAA;"
193
+ "qproperty-circle_color:#DDF;"
194
+ "qproperty-active_color:#AAF;"
195
+ "qproperty-disabled_color:#777;"
196
+ "qproperty-text_color:#A0F;}")
197
+ checkbox2.setDuration(2000)
198
+ checkbox2.setChecked(True)
199
+ layout.addWidget(checkbox2)
200
+
201
+ window.setLayout(layout)
202
+ window.show()
203
+ app.exec()
Source Code/main.py ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ import sys
2
+ from PyQt6.QtWidgets import QApplication
3
+ from ui_loader import UILoader
4
+
5
+ if __name__ == "__main__":
6
+ app = QApplication(sys.argv)
7
+ ui_loader = UILoader()
8
+ ui_loader.show()
9
+ sys.exit(app.exec())
Source Code/ui_loader.py ADDED
@@ -0,0 +1,132 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from PyQt6.QtWidgets import QMainWindow, QFileDialog
2
+ from PyQt6.QtCore import Qt
3
+ from ui_main import Ui_MainWindow
4
+ import configparser
5
+ import subprocess
6
+ import os
7
+ from PyQt6.QtCore import Qt, QPoint
8
+ from PyQt6.QtWidgets import QStackedWidget
9
+ from PyQt6.QtWidgets import QMainWindow, QFileDialog
10
+
11
+ class UILoader(QMainWindow, Ui_MainWindow):
12
+ def __init__(self):
13
+ super().__init__()
14
+ self.setupUi(self)
15
+ self.setWindowFlag(Qt.WindowType.FramelessWindowHint)
16
+ self.setAttribute(Qt.WidgetAttribute.WA_TranslucentBackground)
17
+ self.init_ui()
18
+ self.update_batch_size_label(3)
19
+ self.update_ctx_size_label(4)
20
+ #self.load_config()
21
+ self.offset = None # Add this line
22
+
23
+ def init_ui(self):
24
+ self.minimize_button.clicked.connect(self.showMinimized)
25
+ self.close_button.clicked.connect(self.close)
26
+ self.model_browse_button.clicked.connect(self.browse_model)
27
+ self.run_server_button.clicked.connect(self.run_server)
28
+ self.save_config_button.clicked.connect(self.save_config)
29
+ self.load_config_button.clicked.connect(self.load_config)
30
+
31
+ self.top_bar.mousePressEvent = self.mouse_press_event
32
+ self.top_bar.mouseMoveEvent = self.mouse_move_event
33
+
34
+ def mouse_press_event(self, event):
35
+ self.offset = event.pos()
36
+
37
+ def update_threads_label(self, value):
38
+ self.threads_label.setText(f"Threads: {value + 1}")
39
+
40
+ def mouse_move_event(self, event):
41
+ if self.offset is not None and event.buttons() == Qt.MouseButton.LeftButton:
42
+ self.move(self.pos() + event.pos() - self.offset)
43
+
44
+ def browse_model(self):
45
+ model_path, _ = QFileDialog.getOpenFileName(self, "Select Model", os.getcwd(), "Model Files (*.gguf)")
46
+ self.model_path_line_edit.setText(model_path)
47
+
48
+ def run_server(self):
49
+ model_path = self.model_path_line_edit.text()
50
+ batch_size = self.batch_size_values[self.batch_size_slider.value()]
51
+ ctx_size = self.ctx_size_values[self.ctx_size_slider.value()]
52
+ layers_offload = self.layers_offload_spin_box.value()
53
+ threads = self.threads_spin_box.value()
54
+ use_flash_attention = self.flash_attention_checkbox.isChecked()
55
+ is_moe = self.moe_checkbox.isChecked()
56
+ moe_experts_string = ""
57
+ if is_moe:
58
+ experts_use = self.moe_experts_spin_box.value()
59
+ moe_experts_string = f"--override-kv llama.expert_used_count=int:{experts_use}"
60
+
61
+ custom_rope_freq_base = self.rope_freq_base_spin_box.value() if self.rope_freq_base_checkbox.isChecked() else None
62
+ mlock = self.mlock_checkbox.isChecked()
63
+ no_mmap = self.no_mmap_checkbox.isChecked()
64
+ no_kv_offload = self.no_kv_offload_checkbox.isChecked()
65
+
66
+ command = [
67
+ "LlamaCPP\\llama-server.exe",
68
+ f"--model {model_path}",
69
+ f"--batch-size {batch_size}",
70
+ f"--ctx-size {ctx_size}",
71
+ f"--n-gpu-layers {layers_offload}",
72
+ f"--threads {threads}",
73
+ ]
74
+
75
+ if use_flash_attention:
76
+ command.append("--flash-attn")
77
+ if mlock:
78
+ command.append("--mlock")
79
+ if no_mmap:
80
+ command.append("--no-mmap")
81
+ if no_kv_offload:
82
+ command.append("--no-kv-offload")
83
+ if custom_rope_freq_base is not None:
84
+ command.append(f"--rope-freq-base {custom_rope_freq_base}")
85
+ if moe_experts_string:
86
+ command.append(moe_experts_string)
87
+
88
+ print(" ".join(command))
89
+ subprocess.run(" ".join(command), shell=True)
90
+
91
+ def save_config(self):
92
+ config = configparser.ConfigParser()
93
+ config["Server"] = {
94
+ "model_path": self.model_path_line_edit.text(),
95
+ "batch_size": str(self.batch_size_slider.value()),
96
+ "ctx_size": str(self.ctx_size_slider.value()),
97
+ "layers_offload": str(self.layers_offload_spin_box.value()),
98
+ "threads": str(self.threads_spin_box.value()),
99
+ "use_flash_attention": str(self.flash_attention_checkbox.isChecked()),
100
+ "is_moe": str(self.moe_checkbox.isChecked()),
101
+ "moe_experts": str(self.moe_experts_spin_box.value()),
102
+ "rope_freq_base_custom": str(self.rope_freq_base_checkbox.isChecked()),
103
+ "rope_freq_base_value": str(self.rope_freq_base_spin_box.value()),
104
+ "mlock": str(self.mlock_checkbox.isChecked()),
105
+ "no_mmap": str(self.no_mmap_checkbox.isChecked()),
106
+ "no_kv_offload": str(self.no_kv_offload_checkbox.isChecked()),
107
+ }
108
+
109
+ file_path, _ = QFileDialog.getSaveFileName(self, "Save Configuration", os.getcwd(), "INI Files (*.ini)")
110
+ if file_path:
111
+ with open(file_path, "w") as config_file:
112
+ config.write(config_file)
113
+
114
+ def load_config(self):
115
+ file_path, _ = QFileDialog.getOpenFileName(self, "Load Configuration", os.getcwd(), "INI Files (*.ini)")
116
+ if file_path:
117
+ config = configparser.ConfigParser()
118
+ config.read(file_path)
119
+
120
+ self.model_path_line_edit.setText(config.get("Server", "model_path", fallback=""))
121
+ self.batch_size_slider.setValue(config.getint("Server", "batch_size", fallback=512))
122
+ self.ctx_size_slider.setValue(config.getint("Server", "ctx_size", fallback=8192))
123
+ self.layers_offload_spin_box.setValue(config.getint("Server", "layers_offload", fallback=22))
124
+ self.threads_spin_box.setValue(config.getint("Server", "threads", fallback=14))
125
+ self.flash_attention_checkbox.setChecked(config.getboolean("Server", "use_flash_attention", fallback=False))
126
+ self.moe_checkbox.setChecked(config.getboolean("Server", "is_moe", fallback=False))
127
+ self.moe_experts_spin_box.setValue(config.getint("Server", "moe_experts", fallback=1))
128
+ self.rope_freq_base_checkbox.setChecked(config.getboolean("Server", "rope_freq_base_custom", fallback=False))
129
+ self.rope_freq_base_spin_box.setValue(config.getint("Server", "rope_freq_base_value", fallback=1))
130
+ self.mlock_checkbox.setChecked(config.getboolean("Server", "mlock", fallback=False))
131
+ self.no_mmap_checkbox.setChecked(config.getboolean("Server", "no_mmap", fallback=False))
132
+ self.no_kv_offload_checkbox.setChecked(config.getboolean("Server", "no_kv_offload", fallback=False))
Source Code/ui_main.py ADDED
@@ -0,0 +1,497 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from PyQt6 import QtCore, QtGui, QtWidgets
2
+ import os
3
+ from QToggle import QToggle
4
+
5
+ class FixedValueSlider(QtWidgets.QSlider):
6
+ def __init__(self, values, parent=None):
7
+ super().__init__(QtCore.Qt.Orientation.Horizontal, parent)
8
+ self.setMinimum(0)
9
+ self.setMaximum(len(values) - 1)
10
+ self.setTickPosition(QtWidgets.QSlider.TickPosition.TicksBelow)
11
+ self.setTickInterval(1)
12
+ self.values = values
13
+ self.valueChanged.connect(self.update_value_label)
14
+
15
+ def value(self):
16
+ return self.values[super().value()]
17
+
18
+ def setValue(self, value):
19
+ super().setValue(self.values.index(value))
20
+
21
+ def update_value_label(self, index):
22
+ self.valueChanged.emit(self.values[index])
23
+
24
+ class Ui_MainWindow(object):
25
+ def retranslateUi(self, MainWindow):
26
+ _translate = QtCore.QCoreApplication.translate
27
+ MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
28
+ self.title_label.setText(_translate("MainWindow", " 🔵 LLAMACPP SERVER UI"))
29
+ self.minimize_button.setText(_translate("MainWindow", "-"))
30
+ self.close_button.setText(_translate("MainWindow", "X"))
31
+ self.model_path_label.setText(_translate("MainWindow", "Model Path:"))
32
+ self.model_browse_button.setText(_translate("MainWindow", "Browse"))
33
+ self.batch_size_label.setText(_translate("MainWindow", "Batch Size:"))
34
+ self.ctx_size_label.setText(_translate("MainWindow", "Context Size:"))
35
+ self.layers_offload_label.setText(_translate("MainWindow", "Layers Offload:"))
36
+ self.threads_label.setText(_translate("MainWindow", "Threads:"))
37
+ self.flash_attention_checkbox.setText(_translate("MainWindow", "Flash Attention"))
38
+ self.moe_checkbox.setText(_translate("MainWindow", "Custom MoE Experts"))
39
+ self.moe_experts_label.setText(_translate("MainWindow", "MoE Active Experts:"))
40
+ self.rope_freq_base_checkbox.setText(_translate("MainWindow", "Custom RoPE Freq Base"))
41
+ self.rope_freq_base_label.setText(_translate("MainWindow", "RoPE Freq Base:"))
42
+ self.mlock_checkbox.setText(_translate("MainWindow", "Use mlock"))
43
+ self.no_mmap_checkbox.setText(_translate("MainWindow", "Disable MMAP"))
44
+ self.no_kv_offload_checkbox.setText(_translate("MainWindow", "No KV Offload"))
45
+ self.run_server_button.setText(_translate("MainWindow", "Run Server"))
46
+ self.save_config_button.setText(_translate("MainWindow", "Save Config"))
47
+ self.load_config_button.setText(_translate("MainWindow", "Load Config"))
48
+
49
+ def update_batch_size_label(self, value):
50
+ self.batch_size_label.setText(f"Batch Size: {self.batch_size_values[value]}")
51
+
52
+ def update_ctx_size_label(self, value):
53
+ self.ctx_size_label.setText(f"Context Size: {self.ctx_size_values[value]}")
54
+
55
+ def setupUi(self, MainWindow):
56
+ MainWindow.setObjectName("MainWindow")
57
+ MainWindow.resize(800, 600)
58
+
59
+
60
+ self.centralwidget = QtWidgets.QWidget(MainWindow)
61
+ self.centralwidget.setObjectName("centralwidget")
62
+ self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)
63
+ self.verticalLayout.setObjectName("verticalLayout")
64
+ self.top_bar = QtWidgets.QFrame(self.centralwidget)
65
+ self.top_bar.setMaximumSize(QtCore.QSize(16777215, 40))
66
+ self.top_bar.setStyleSheet("background-color: #2c313c;")
67
+ self.top_bar.setFrameShape(QtWidgets.QFrame.Shape.NoFrame)
68
+ self.top_bar.setFrameShadow(QtWidgets.QFrame.Shadow.Raised)
69
+ self.top_bar.setObjectName("top_bar")
70
+ self.horizontalLayout = QtWidgets.QHBoxLayout(self.top_bar)
71
+ self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
72
+ self.horizontalLayout.setSpacing(0)
73
+ self.horizontalLayout.setObjectName("horizontalLayout")
74
+
75
+ #TITLE LABEL
76
+ self.title_label = QtWidgets.QLabel(self.top_bar)
77
+ font = QtGui.QFont()
78
+ font.setPointSize(10)
79
+ font.setBold(True)
80
+ self.title_label.setFont(font)
81
+ self.title_label.setStyleSheet("color: white;")
82
+ self.title_label.setObjectName("title_label")
83
+ self.horizontalLayout.addWidget(self.title_label)
84
+ self.minimize_button = QtWidgets.QPushButton(self.top_bar)
85
+ self.minimize_button.setMaximumSize(QtCore.QSize(30, 30))
86
+ self.minimize_button.setStyleSheet("QPushButton {\n"
87
+ " background-color: #2c313c;\n"
88
+ " border: none;\n"
89
+ " color: white;\n"
90
+ "}\n"
91
+ "\n"
92
+ "QPushButton:hover {\n"
93
+ " background-color: #495057;\n"
94
+ "}\n"
95
+ "\n"
96
+ "QPushButton:pressed {\n"
97
+ " background-color: #6c757d;\n"
98
+ "}")
99
+ self.minimize_button.setObjectName("minimize_button")
100
+ self.horizontalLayout.addWidget(self.minimize_button)
101
+ self.close_button = QtWidgets.QPushButton(self.top_bar)
102
+ self.close_button.setMaximumSize(QtCore.QSize(30, 30))
103
+ self.close_button.setStyleSheet("QPushButton {\n"
104
+ " background-color: #2c313c;\n"
105
+ " border: none;\n"
106
+ " color: white;\n"
107
+ "}\n"
108
+ "\n"
109
+ "QPushButton:hover {\n"
110
+ " background-color: #dc3545;\n"
111
+ "}\n"
112
+ "\n"
113
+ "QPushButton:pressed {\n"
114
+ " background-color: #c82333;\n"
115
+ "}")
116
+ self.close_button.setObjectName("close_button")
117
+ self.horizontalLayout.addWidget(self.close_button)
118
+ self.verticalLayout.addWidget(self.top_bar)
119
+ self.content_area = QtWidgets.QFrame(self.centralwidget)
120
+ self.content_area.setStyleSheet("background-color: #212529;")
121
+ self.content_area.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel)
122
+ self.content_area.setFrameShadow(QtWidgets.QFrame.Shadow.Raised)
123
+ self.content_area.setObjectName("content_area")
124
+ self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.content_area)
125
+ self.verticalLayout_2.setObjectName("verticalLayout_2")
126
+ self.model_path_layout = QtWidgets.QHBoxLayout()
127
+ self.model_path_layout.setObjectName("model_path_layout")
128
+ self.model_path_label = QtWidgets.QLabel(self.content_area)
129
+ font = QtGui.QFont()
130
+ font.setPointSize(10)
131
+ self.model_path_label.setFont(font)
132
+ self.model_path_label.setStyleSheet("color: white;")
133
+ self.model_path_label.setObjectName("model_path_label")
134
+ self.model_path_layout.addWidget(self.model_path_label)
135
+ self.model_path_line_edit = QtWidgets.QLineEdit(self.content_area)
136
+ self.model_path_line_edit.setStyleSheet("background-color: #495057;\n"
137
+ "color: white;\n"
138
+ "border-radius: 8px;\n"
139
+ "padding: 5px;")
140
+ self.model_path_line_edit.setObjectName("model_path_line_edit")
141
+ self.model_path_layout.addWidget(self.model_path_line_edit)
142
+ self.model_browse_button = QtWidgets.QPushButton(self.content_area)
143
+ self.model_browse_button.setStyleSheet("QPushButton {\n"
144
+ " background-color: #495057;\n"
145
+ " color: white;\n"
146
+ " border-radius: 8px;\n"
147
+ " padding: 5px;\n"
148
+ "}\n"
149
+ "\n"
150
+ "QPushButton:hover {\n"
151
+ " background-color: #6c757d;\n"
152
+ "}\n"
153
+ "\n"
154
+ "QPushButton:pressed {\n"
155
+ " background-color: #343a40;\n"
156
+ "}")
157
+ self.model_browse_button.setObjectName("model_browse_button")
158
+ self.model_path_layout.addWidget(self.model_browse_button)
159
+ self.verticalLayout_2.addLayout(self.model_path_layout)
160
+ self.settings_layout = QtWidgets.QGridLayout()
161
+ self.settings_layout.setObjectName("settings_layout")
162
+
163
+
164
+
165
+ ############
166
+ # BATCH SIZE/ CTX
167
+ ############
168
+
169
+ self.batch_size_label = QtWidgets.QLabel(self.content_area)
170
+ font = QtGui.QFont()
171
+ font.setPointSize(10)
172
+ self.batch_size_label.setFont(font)
173
+ self.batch_size_label.setStyleSheet("color: white;")
174
+ self.batch_size_label.setObjectName("batch_size_label")
175
+ self.settings_layout.addWidget(self.batch_size_label, 0, 0, 1, 1)
176
+
177
+ self.batch_size_slider = QtWidgets.QSlider(self.content_area)
178
+ self.batch_size_slider.setStyleSheet("QSlider::groove:horizontal {\n"
179
+ " background-color: #495057;\n"
180
+ " height: 10px;\n"
181
+ "}\n"
182
+ "\n"
183
+ "QSlider::handle:horizontal {\n"
184
+ " background-color: white;\n"
185
+ " width: 20px;\n"
186
+ " border-radius: 5px;\n"
187
+ " margin: -5px 0;\n"
188
+ "}")
189
+ self.batch_size_slider.setOrientation(QtCore.Qt.Orientation.Horizontal)
190
+ self.batch_size_slider.setMinimum(0)
191
+ self.batch_size_slider.setMaximum(4)
192
+ self.batch_size_slider.setTickPosition(QtWidgets.QSlider.TickPosition.TicksBelow)
193
+ self.batch_size_slider.setTickInterval(1)
194
+ self.batch_size_values = [64, 128, 256, 512, 1024]
195
+ self.batch_size_slider.valueChanged.connect(self.update_batch_size_label)
196
+ self.batch_size_slider.setProperty("value", 3)
197
+ self.settings_layout.addWidget(self.batch_size_slider, 0, 1, 1, 3)
198
+
199
+ self.ctx_size_label = QtWidgets.QLabel(self.content_area)
200
+ font = QtGui.QFont()
201
+ font.setPointSize(10)
202
+ self.ctx_size_label.setFont(font)
203
+ self.ctx_size_label.setStyleSheet("color: white;")
204
+ self.ctx_size_label.setObjectName("ctx_size_label")
205
+ self.settings_layout.addWidget(self.ctx_size_label, 1, 0, 1, 3)
206
+
207
+ self.ctx_size_slider = QtWidgets.QSlider(self.content_area)
208
+ self.ctx_size_slider.setStyleSheet("QSlider::groove:horizontal {\n"
209
+ " background-color: #495057;\n"
210
+ " height: 10px;\n"
211
+ "}\n"
212
+ "\n"
213
+ "QSlider::handle:horizontal {\n"
214
+ " background-color: white;\n"
215
+ " width: 20px;\n"
216
+ " border-radius: 5px;\n"
217
+ " margin: -5px 0;\n"
218
+ "}")
219
+ self.ctx_size_slider.setOrientation(QtCore.Qt.Orientation.Horizontal)
220
+ self.ctx_size_slider.setMinimum(0)
221
+ self.ctx_size_slider.setMaximum(64)
222
+
223
+ self.ctx_size_slider.setTickPosition(QtWidgets.QSlider.TickPosition.TicksBelow)
224
+ self.ctx_size_slider.setTickInterval(1)
225
+ self.ctx_size_values = [1024 * (i) for i in range(65)]
226
+ self.ctx_size_slider.valueChanged.connect(self.update_ctx_size_label)
227
+ self.ctx_size_slider.setProperty("value", 4)
228
+ self.settings_layout.addWidget(self.ctx_size_slider, 1, 1, 1, 3)
229
+
230
+ ############
231
+ # UI THREADS / LAYERS
232
+ ############
233
+
234
+ # GPU OFFLOAD
235
+ self.layers_offload_label = QtWidgets.QLabel(self.content_area)
236
+ font = QtGui.QFont()
237
+ font.setPointSize(10)
238
+ self.layers_offload_label.setFont(font)
239
+ self.layers_offload_label.setStyleSheet("color: white;")
240
+ self.layers_offload_label.setObjectName("layers_offload_label")
241
+ self.settings_layout.addWidget(self.layers_offload_label, 2, 0, 1, 1)
242
+ self.layers_offload_spin_box = QtWidgets.QSpinBox(self.content_area)
243
+ self.layers_offload_spin_box.setStyleSheet("background-color: #495057;\n"
244
+ "color: white;\n"
245
+ "border-radius: 8px;\n"
246
+ "padding: 5px;")
247
+ self.layers_offload_spin_box.setMinimum(0)
248
+ self.layers_offload_spin_box.setMaximum(200)
249
+ self.layers_offload_spin_box.setProperty("value", 0)
250
+ self.layers_offload_spin_box.setObjectName("layers_offload_spin_box")
251
+ self.settings_layout.addWidget(self.layers_offload_spin_box, 2, 1, 1, 1)
252
+
253
+
254
+ # THREADS
255
+ self.threads_label = QtWidgets.QLabel(self.content_area)
256
+ font = QtGui.QFont()
257
+ font.setPointSize(10)
258
+ self.threads_label.setFont(font)
259
+ self.threads_label.setStyleSheet("color: white;")
260
+ self.threads_label.setObjectName("threads_label")
261
+ self.settings_layout.addWidget(self.threads_label, 2, 2, 1, 1)
262
+
263
+ self.threads_spin_box = QtWidgets.QSpinBox(self.content_area)
264
+ self.threads_spin_box.setStyleSheet("background-color: #495057;\n"
265
+ "color: white;\n"
266
+ "border-radius: 8px;\n"
267
+ "padding: 5px;")
268
+ self.threads_spin_box.setMinimum(0)
269
+ self.threads_spin_box.setMaximum(os.cpu_count())
270
+ self.threads_spin_box.setProperty("value", int(os.cpu_count()/2))
271
+ self.threads_spin_box.setObjectName("threads_spin_box")
272
+ self.settings_layout.addWidget(self.threads_spin_box, 2, 3, 1, 1)
273
+
274
+
275
+
276
+
277
+ ###
278
+ self.verticalLayout_2.addLayout(self.settings_layout)
279
+ self.advanced_options_layout = QtWidgets.QGridLayout()
280
+ self.advanced_options_layout.setObjectName("advanced_options_layout")
281
+ ###
282
+
283
+
284
+
285
+
286
+
287
+ ############
288
+ # UI MOE
289
+ ############
290
+ self.moe_checkbox = QToggle()
291
+ self.moe_checkbox.setFixedHeight(20)
292
+ self.moe_checkbox.setDuration(250)
293
+ self.moe_checkbox.setStyleSheet("QToggle{"
294
+ "qproperty-bg_color:#495057;"
295
+ "qproperty-circle_color:#FFF;"
296
+ "qproperty-active_color:#0066ff;"
297
+ "qproperty-disabled_color:#383838;"
298
+ "qproperty-text_color:#FFF;}")
299
+
300
+ self.moe_checkbox.setObjectName("moe_checkbox")
301
+ self.advanced_options_layout.addWidget(self.moe_checkbox, 0, 0, 1, 1)
302
+
303
+
304
+
305
+ self.moe_experts_label = QtWidgets.QLabel(self.content_area)
306
+ font = QtGui.QFont()
307
+ font.setPointSize(10)
308
+ self.moe_experts_label.setFont(font)
309
+ self.moe_experts_label.setStyleSheet("color: white;")
310
+ self.moe_experts_label.setObjectName("moe_experts_label")
311
+ self.advanced_options_layout.addWidget(self.moe_experts_label, 0, 2, 1, 1)
312
+ self.moe_experts_spin_box = QtWidgets.QSpinBox(self.content_area)
313
+ self.moe_experts_spin_box.setStyleSheet("background-color: #495057;\n"
314
+ "color: white;\n"
315
+ "border-radius: 8px;\n"
316
+ "padding: 5px;")
317
+ self.moe_experts_spin_box.setMinimum(1)
318
+ self.moe_experts_spin_box.setMaximum(32)
319
+ self.moe_experts_spin_box.setProperty("value", 2)
320
+ self.moe_experts_spin_box.setObjectName("moe_experts_spin_box")
321
+ self.advanced_options_layout.addWidget(self.moe_experts_spin_box, 0, 3, 1, 1)
322
+
323
+ ############
324
+ # UI ROPE FREQ BASE
325
+ ############
326
+ # CUSTOM ROPE FREQ BASE CHECKBOX
327
+ self.rope_freq_base_checkbox = QToggle()
328
+ self.rope_freq_base_checkbox.setFixedHeight(20)
329
+ self.rope_freq_base_checkbox.setDuration(250)
330
+ self.rope_freq_base_checkbox.setStyleSheet("QToggle{"
331
+ "qproperty-bg_color:#495057;"
332
+ "qproperty-circle_color:#FFF;"
333
+ "qproperty-active_color:#0066ff;"
334
+ "qproperty-disabled_color:#383838;"
335
+ "qproperty-text_color:#FFF;}")
336
+ self.rope_freq_base_checkbox.setObjectName("rope_freq_base_checkbox")
337
+ self.advanced_options_layout.addWidget(self.rope_freq_base_checkbox, 1, 0, 1, 1)
338
+
339
+ # CUSTOM ROPE FREQ BASE LABEL
340
+ self.rope_freq_base_label = QtWidgets.QLabel(self.content_area)
341
+ font = QtGui.QFont()
342
+ font.setPointSize(10)
343
+ self.rope_freq_base_label.setFont(font)
344
+ self.rope_freq_base_label.setStyleSheet("color: white;")
345
+ self.rope_freq_base_label.setObjectName("rope_freq_base_label")
346
+ self.advanced_options_layout.addWidget(self.rope_freq_base_label, 1, 2, 1, 1)
347
+ self.rope_freq_base_spin_box = QtWidgets.QSpinBox(self.content_area)
348
+ self.rope_freq_base_spin_box.setStyleSheet("background-color: #495057;\n"
349
+ "color: white;\n"
350
+ "border-radius: 8px;\n"
351
+ "padding: 5px;")
352
+ self.rope_freq_base_spin_box.setMinimum(1)
353
+ self.rope_freq_base_spin_box.setMaximum(1000)
354
+ self.rope_freq_base_spin_box.setProperty("value", 1)
355
+ self.rope_freq_base_spin_box.setObjectName("rope_freq_base_spin_box")
356
+ self.advanced_options_layout.addWidget(self.rope_freq_base_spin_box, 1, 3, 1, 1)
357
+
358
+
359
+
360
+ ############
361
+ # UI ADDITIONAL
362
+ ############
363
+
364
+ # FLASH ATTENTION CHECKBOX
365
+ self.flash_attention_checkbox = QToggle()
366
+ self.flash_attention_checkbox.setFixedHeight(20)
367
+ self.flash_attention_checkbox.setDuration(250)
368
+ self.flash_attention_checkbox.setStyleSheet("QToggle{"
369
+ "qproperty-bg_color:#495057;"
370
+ "qproperty-circle_color:#FFF;"
371
+ "qproperty-active_color:#0066ff;"
372
+ "qproperty-disabled_color:#383838;"
373
+ "qproperty-text_color:#FFF;}")
374
+
375
+ self.flash_attention_checkbox.setObjectName("flash_attention_checkbox")
376
+ self.advanced_options_layout.addWidget(self.flash_attention_checkbox, 2, 3, 1, 1)
377
+
378
+ # MLOCK CHECKBOX
379
+ self.mlock_checkbox = QToggle()
380
+ self.mlock_checkbox.setFixedHeight(20)
381
+ self.mlock_checkbox.setDuration(250)
382
+ self.mlock_checkbox.setStyleSheet("QToggle{"
383
+ "qproperty-bg_color:#495057;"
384
+ "qproperty-circle_color:#FFF;"
385
+ "qproperty-active_color:#0066ff;"
386
+ "qproperty-disabled_color:#383838;"
387
+ "qproperty-text_color:#FFF;}")
388
+ self.mlock_checkbox.setObjectName("mlock_checkbox")
389
+ self.advanced_options_layout.addWidget(self.mlock_checkbox, 2, 0, 1, 1)
390
+
391
+ # NO MMAP CHECKBOX
392
+ self.no_mmap_checkbox = QToggle()
393
+ self.no_mmap_checkbox.setFixedHeight(20)
394
+ self.no_mmap_checkbox.setDuration(250)
395
+ self.no_mmap_checkbox.setStyleSheet("QToggle{"
396
+ "qproperty-bg_color:#495057;"
397
+ "qproperty-circle_color:#FFF;"
398
+ "qproperty-active_color:#0066ff;"
399
+ "qproperty-disabled_color:#383838;"
400
+ "qproperty-text_color:#FFF;}")
401
+
402
+ self.no_mmap_checkbox.setObjectName("no_mmap_checkbox")
403
+ self.advanced_options_layout.addWidget(self.no_mmap_checkbox, 2, 1, 1, 1)
404
+
405
+ # NO KV OFFLOAD CHECKBOX
406
+ self.no_kv_offload_checkbox = QToggle()
407
+ self.no_kv_offload_checkbox.setFixedHeight(20)
408
+ self.no_kv_offload_checkbox.setDuration(250)
409
+ self.no_kv_offload_checkbox.setStyleSheet("QToggle{"
410
+ "qproperty-bg_color:#495057;"
411
+ "qproperty-circle_color:#FFF;"
412
+ "qproperty-active_color:#0066ff;"
413
+ "qproperty-disabled_color:#383838;"
414
+ "qproperty-text_color:#FFF;}")
415
+
416
+ self.no_kv_offload_checkbox.setObjectName("no_kv_offload_checkbox")
417
+ self.advanced_options_layout.addWidget(self.no_kv_offload_checkbox, 2, 2, 1, 1)
418
+
419
+
420
+
421
+
422
+
423
+
424
+
425
+
426
+
427
+
428
+
429
+
430
+ ##################################
431
+ # DOWN BUTTONS
432
+ ##################################
433
+ self.verticalLayout_2.addLayout(self.advanced_options_layout)
434
+ self.run_server_button = QtWidgets.QPushButton(self.content_area)
435
+ self.run_server_button.setStyleSheet("QPushButton {\n"
436
+ " background-color: #0066ff;\n"
437
+ " color: white;\n"
438
+ " padding: 10px;\n"
439
+ " border-radius: 8px;\n"
440
+ " font-size: 16px;\n"
441
+ "}\n"
442
+ "\n"
443
+ "QPushButton:hover {\n"
444
+ " background-color: #1774ff;\n"
445
+
446
+
447
+ "}\n"
448
+ "\n"
449
+ "QPushButton:pressed {\n"
450
+ " background-color: #0049b8;\n"
451
+ "}")
452
+ self.run_server_button.setObjectName("run_server_button")
453
+ self.verticalLayout_2.addWidget(self.run_server_button)
454
+ self.config_layout = QtWidgets.QHBoxLayout()
455
+ self.config_layout.setObjectName("config_layout")
456
+ self.save_config_button = QtWidgets.QPushButton(self.content_area)
457
+ self.save_config_button.setStyleSheet("QPushButton {\n"
458
+ " background-color: #2e82ff;\n"
459
+ " color: white;\n"
460
+ " border-radius: 8px;\n"
461
+ " padding: 5px;\n"
462
+ "}\n"
463
+ "\n"
464
+ "QPushButton:hover {\n"
465
+ " background-color: #428eff;\n"
466
+ "}\n"
467
+ "\n"
468
+ "QPushButton:pressed {\n"
469
+ " background-color: #1e6ce3;\n"
470
+ "}")
471
+ self.save_config_button.setObjectName("save_config_button")
472
+ self.config_layout.addWidget(self.save_config_button)
473
+ self.load_config_button = QtWidgets.QPushButton(self.content_area)
474
+ self.load_config_button.setStyleSheet("QPushButton {\n"
475
+ " background-color: #2e82ff;\n"
476
+ " color: white;\n"
477
+ " border-radius: 8px;\n"
478
+ " padding: 5px;\n"
479
+ "}\n"
480
+ "\n"
481
+ "QPushButton:hover {\n"
482
+ " background-color: #428eff;\n"
483
+ "}\n"
484
+ "\n"
485
+ "QPushButton:pressed {\n"
486
+ " background-color: #1e6ce3;\n"
487
+ "}")
488
+ self.load_config_button.setObjectName("load_config_button")
489
+ self.config_layout.addWidget(self.load_config_button)
490
+ self.verticalLayout_2.addLayout(self.config_layout)
491
+ self.verticalLayout.addWidget(self.content_area)
492
+ MainWindow.setCentralWidget(self.centralwidget)
493
+
494
+ self.retranslateUi(MainWindow)
495
+ QtCore.QMetaObject.connectSlotsByName(MainWindow)
496
+
497
+