mirror of https://github.com/leafspark/AutoGGUF
Merge pull request #12 from leafspark/modern-ui
feat(ui): add modern UI
This commit is contained in:
commit
7ac297a3bc
389
src/AutoGGUF.py
389
src/AutoGGUF.py
|
@ -1,6 +1,7 @@
|
|||
import json
|
||||
import re
|
||||
import shutil
|
||||
import os
|
||||
|
||||
from functools import partial
|
||||
from PySide6.QtCore import *
|
||||
|
@ -11,6 +12,7 @@
|
|||
from KVOverrideEntry import KVOverrideEntry
|
||||
from Logger import Logger
|
||||
from ModelInfoDialog import ModelInfoDialog
|
||||
from error_handling import show_error, handle_error
|
||||
from imports_and_globals import (
|
||||
open_file_safe,
|
||||
resource_path,
|
||||
|
@ -18,20 +20,88 @@
|
|||
ensure_directory,
|
||||
)
|
||||
from Localizations import *
|
||||
import presets
|
||||
import ui_update
|
||||
import lora_conversion
|
||||
import utils
|
||||
|
||||
|
||||
class CustomTitleBar(QWidget):
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
self.parent = parent
|
||||
layout = QHBoxLayout(self)
|
||||
layout.setContentsMargins(10, 5, 10, 5)
|
||||
|
||||
# Add your logo or app name here
|
||||
self.title = QLabel("AutoGGUF")
|
||||
layout.addWidget(self.title)
|
||||
|
||||
layout.addStretch(1) # This pushes the buttons to the right
|
||||
|
||||
# Add minimize and close buttons
|
||||
self.minimize_button = QPushButton("—")
|
||||
self.close_button = QPushButton("✕")
|
||||
|
||||
for button in (self.minimize_button, self.close_button):
|
||||
button.setFixedSize(30, 30)
|
||||
button.setStyleSheet(
|
||||
"""
|
||||
QPushButton {
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
}
|
||||
QPushButton:hover {
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
"""
|
||||
)
|
||||
|
||||
layout.addWidget(self.minimize_button)
|
||||
layout.addWidget(self.close_button)
|
||||
|
||||
self.minimize_button.clicked.connect(self.parent.showMinimized)
|
||||
self.close_button.clicked.connect(self.parent.close)
|
||||
|
||||
self.start = QPoint(0, 0)
|
||||
self.pressing = False
|
||||
|
||||
def mousePressEvent(self, event):
|
||||
self.start = self.mapToGlobal(event.pos())
|
||||
self.pressing = True
|
||||
|
||||
def mouseMoveEvent(self, event):
|
||||
if self.pressing:
|
||||
end = self.mapToGlobal(event.pos())
|
||||
movement = end - self.start
|
||||
self.parent.setGeometry(
|
||||
self.parent.x() + movement.x(),
|
||||
self.parent.y() + movement.y(),
|
||||
self.parent.width(),
|
||||
self.parent.height(),
|
||||
)
|
||||
self.start = end
|
||||
|
||||
def mouseReleaseEvent(self, event):
|
||||
self.pressing = False
|
||||
|
||||
|
||||
class AutoGGUF(QMainWindow):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.logger = Logger("AutoGGUF", "logs")
|
||||
|
||||
width, height = self.parse_resolution()
|
||||
|
||||
self.logger.info(INITIALIZING_AUTOGGUF)
|
||||
self.setWindowTitle(WINDOW_TITLE)
|
||||
self.setWindowIcon(QIcon(resource_path("assets/favicon.ico")))
|
||||
self.setGeometry(100, 100, 1600, 1200)
|
||||
self.setGeometry(100, 100, width, height)
|
||||
self.setWindowFlag(Qt.FramelessWindowHint)
|
||||
|
||||
self.resize_factor = 1.1 # 10% increase/decrease
|
||||
self.default_width, self.default_height = self.parse_resolution()
|
||||
self.resize(self.default_width, self.default_height)
|
||||
|
||||
ensure_directory(os.path.abspath("quantized_models"))
|
||||
ensure_directory(os.path.abspath("models"))
|
||||
|
@ -49,6 +119,8 @@ def __init__(self):
|
|||
self.browse_lora_output = utils.browse_lora_output.__get__(self)
|
||||
self.convert_lora = lora_conversion.convert_lora.__get__(self)
|
||||
self.show_about = show_about.__get__(self)
|
||||
self.save_preset = presets.save_preset.__get__(self)
|
||||
self.load_preset = presets.load_preset.__get__(self)
|
||||
self.update_threads_spinbox = partial(ui_update.update_threads_spinbox, self)
|
||||
self.update_threads_slider = partial(ui_update.update_threads_slider, self)
|
||||
self.update_gpu_offload_spinbox = partial(
|
||||
|
@ -63,59 +135,97 @@ def __init__(self):
|
|||
ui_update.update_download_progress, self
|
||||
)
|
||||
|
||||
# Create a central widget and main layout
|
||||
central_widget = QWidget()
|
||||
main_layout = QHBoxLayout(central_widget)
|
||||
# Set up main widget and layout
|
||||
main_widget = QWidget()
|
||||
main_layout = QVBoxLayout(main_widget)
|
||||
main_layout.setContentsMargins(0, 0, 0, 0)
|
||||
main_layout.setSpacing(0)
|
||||
|
||||
# Create a scroll area and set it as the central widget
|
||||
scroll = QScrollArea()
|
||||
scroll.setWidgetResizable(True)
|
||||
scroll.setWidget(central_widget)
|
||||
self.setCentralWidget(scroll)
|
||||
# Custom title bar
|
||||
self.title_bar = CustomTitleBar(self)
|
||||
main_layout.addWidget(self.title_bar)
|
||||
|
||||
# Create left and right widgets
|
||||
left_widget = QWidget()
|
||||
right_widget = QWidget()
|
||||
|
||||
# Set minimum widths to maintain proportions
|
||||
left_widget.setMinimumWidth(800)
|
||||
right_widget.setMinimumWidth(400)
|
||||
|
||||
menubar = QMenuBar(self)
|
||||
self.layout().setMenuBar(menubar)
|
||||
# Menu bar
|
||||
self.menubar = QMenuBar()
|
||||
self.title_bar.layout().insertWidget(1, self.menubar)
|
||||
|
||||
# File menu
|
||||
file_menu = menubar.addMenu("&File")
|
||||
file_menu = self.menubar.addMenu("&File")
|
||||
close_action = QAction("&Close", self)
|
||||
close_action.setShortcut(QKeySequence.Quit)
|
||||
close_action.setShortcut(QKeySequence("Alt+F4"))
|
||||
close_action.triggered.connect(self.close)
|
||||
save_preset_action = QAction("&Save Preset", self)
|
||||
save_preset_action.setShortcut(QKeySequence("Ctrl+S"))
|
||||
save_preset_action.triggered.connect(self.save_preset)
|
||||
load_preset_action = QAction("&Load Preset", self)
|
||||
load_preset_action.setShortcut(QKeySequence("Ctrl+S"))
|
||||
load_preset_action.triggered.connect(self.load_preset)
|
||||
file_menu.addAction(close_action)
|
||||
file_menu.addAction(save_preset_action)
|
||||
file_menu.addAction(load_preset_action)
|
||||
|
||||
# Help menu
|
||||
help_menu = menubar.addMenu("&Help")
|
||||
help_menu = self.menubar.addMenu("&Help")
|
||||
about_action = QAction("&About", self)
|
||||
about_action.setShortcut(QKeySequence("Ctrl+Q"))
|
||||
about_action.triggered.connect(self.show_about)
|
||||
help_menu.addAction(about_action)
|
||||
|
||||
# Content widget
|
||||
content_widget = QWidget()
|
||||
content_layout = QHBoxLayout(content_widget)
|
||||
|
||||
# Wrap content in a scroll area
|
||||
scroll_area = QScrollArea()
|
||||
scroll_area.setWidgetResizable(True) # Allow content to resize
|
||||
scroll_area.setWidget(content_widget)
|
||||
|
||||
# Add scroll area to main layout
|
||||
main_layout.addWidget(scroll_area)
|
||||
|
||||
self.setCentralWidget(main_widget)
|
||||
|
||||
# Styling
|
||||
self.setStyleSheet(
|
||||
"""
|
||||
AutoGGUF {
|
||||
background-color: #2b2b2b;
|
||||
border-radius: 10px;
|
||||
}
|
||||
"""
|
||||
)
|
||||
|
||||
# Initialize threads
|
||||
self.quant_threads = []
|
||||
|
||||
# Timer for updating system info
|
||||
self.timer = QTimer()
|
||||
self.timer.timeout.connect(self.update_system_info)
|
||||
self.timer.start(200)
|
||||
|
||||
# Add all widgets to content_layout
|
||||
left_widget = QWidget()
|
||||
right_widget = QWidget()
|
||||
left_widget.setMinimumWidth(1100)
|
||||
right_widget.setMinimumWidth(400)
|
||||
left_layout = QVBoxLayout(left_widget)
|
||||
right_layout = QVBoxLayout(right_widget)
|
||||
|
||||
# Add left and right widgets to the main layout
|
||||
main_layout.addWidget(left_widget, 2)
|
||||
main_layout.addWidget(right_widget, 1)
|
||||
content_layout.addWidget(left_widget)
|
||||
content_layout.addWidget(right_widget)
|
||||
|
||||
# System info
|
||||
self.ram_bar = QProgressBar()
|
||||
self.cpu_label = QLabel(CPU_USAGE)
|
||||
self.cpu_bar = QProgressBar()
|
||||
self.cpu_label = QLabel()
|
||||
self.gpu_monitor = GPUMonitor()
|
||||
left_layout.addWidget(QLabel(RAM_USAGE))
|
||||
left_layout.addWidget(self.ram_bar)
|
||||
left_layout.addWidget(self.cpu_label)
|
||||
left_layout.addWidget(QLabel(CPU_USAGE))
|
||||
left_layout.addWidget(self.cpu_bar)
|
||||
left_layout.addWidget(QLabel(GPU_USAGE))
|
||||
left_layout.addWidget(self.gpu_monitor)
|
||||
|
||||
# Modify the backend selection
|
||||
# Backend selection
|
||||
backend_layout = QHBoxLayout()
|
||||
self.backend_combo = QComboBox()
|
||||
self.refresh_backends_button = QPushButton(REFRESH_BACKENDS)
|
||||
|
@ -125,10 +235,9 @@ def __init__(self):
|
|||
backend_layout.addWidget(self.refresh_backends_button)
|
||||
left_layout.addLayout(backend_layout)
|
||||
|
||||
# Modify the Download llama.cpp section
|
||||
# Download llama.cpp section
|
||||
download_group = QGroupBox(DOWNLOAD_LLAMACPP)
|
||||
download_layout = QFormLayout()
|
||||
|
||||
self.release_combo = QComboBox()
|
||||
self.refresh_releases_button = QPushButton(REFRESH_RELEASES)
|
||||
self.refresh_releases_button.clicked.connect(self.refresh_releases)
|
||||
|
@ -136,35 +245,25 @@ def __init__(self):
|
|||
release_layout.addWidget(self.release_combo)
|
||||
release_layout.addWidget(self.refresh_releases_button)
|
||||
download_layout.addRow(SELECT_RELEASE, release_layout)
|
||||
|
||||
self.asset_combo = QComboBox()
|
||||
self.asset_combo.currentIndexChanged.connect(self.update_cuda_option)
|
||||
download_layout.addRow(SELECT_ASSET, self.asset_combo)
|
||||
|
||||
self.cuda_extract_checkbox = QCheckBox(EXTRACT_CUDA_FILES)
|
||||
self.cuda_extract_checkbox.setVisible(False)
|
||||
download_layout.addRow(self.cuda_extract_checkbox)
|
||||
|
||||
self.cuda_backend_label = QLabel(SELECT_CUDA_BACKEND)
|
||||
self.cuda_backend_label.setVisible(False)
|
||||
self.backend_combo_cuda = QComboBox()
|
||||
self.backend_combo_cuda.setVisible(False)
|
||||
download_layout.addRow(self.cuda_backend_label, self.backend_combo_cuda)
|
||||
|
||||
self.download_progress = QProgressBar()
|
||||
self.download_button = QPushButton(DOWNLOAD)
|
||||
self.download_button.clicked.connect(self.download_llama_cpp)
|
||||
download_layout.addRow(self.download_progress)
|
||||
download_layout.addRow(self.download_button)
|
||||
|
||||
download_group.setLayout(download_layout)
|
||||
right_layout.addWidget(download_group)
|
||||
|
||||
# Initialize releases and backends
|
||||
if os.environ.get("AUTOGGUF_CHECK_BACKEND", "").lower() == "enabled":
|
||||
self.refresh_releases()
|
||||
self.refresh_backends()
|
||||
|
||||
# Models path
|
||||
models_layout = QHBoxLayout()
|
||||
self.models_input = QLineEdit(os.path.abspath("models"))
|
||||
|
@ -374,18 +473,17 @@ def __init__(self):
|
|||
kv_override_main_layout,
|
||||
)
|
||||
|
||||
quant_options_widget.setLayout(quant_options_layout)
|
||||
quant_options_scroll.setWidget(quant_options_widget)
|
||||
quant_options_scroll.setWidgetResizable(True)
|
||||
left_layout.addWidget(quant_options_scroll)
|
||||
|
||||
# Add this after the KV override section
|
||||
self.extra_arguments = QLineEdit()
|
||||
quant_options_layout.addRow(
|
||||
self.create_label(EXTRA_ARGUMENTS, "Additional command-line arguments"),
|
||||
self.extra_arguments,
|
||||
)
|
||||
|
||||
quant_options_widget.setLayout(quant_options_layout)
|
||||
quant_options_scroll.setWidget(quant_options_widget)
|
||||
quant_options_scroll.setWidgetResizable(True)
|
||||
left_layout.addWidget(quant_options_scroll)
|
||||
|
||||
# Quantize button layout
|
||||
quantize_layout = QHBoxLayout()
|
||||
quantize_button = QPushButton(QUANTIZE_MODEL)
|
||||
|
@ -443,23 +541,21 @@ def __init__(self):
|
|||
)
|
||||
|
||||
self.imatrix_frequency = QSpinBox()
|
||||
self.imatrix_frequency.setRange(1, 100) # Set the range from 1 to 100
|
||||
self.imatrix_frequency.setValue(1) # Set a default value
|
||||
self.imatrix_frequency.setRange(1, 100)
|
||||
self.imatrix_frequency.setValue(1)
|
||||
imatrix_layout.addRow(
|
||||
self.create_label(OUTPUT_FREQUENCY, HOW_OFTEN_TO_SAVE_IMATRIX),
|
||||
self.imatrix_frequency,
|
||||
)
|
||||
|
||||
# Context size input (now a spinbox)
|
||||
self.imatrix_ctx_size = QSpinBox()
|
||||
self.imatrix_ctx_size.setRange(1, 1048576) # Up to one million tokens
|
||||
self.imatrix_ctx_size.setValue(512) # Set a default value
|
||||
self.imatrix_ctx_size.setRange(1, 1048576)
|
||||
self.imatrix_ctx_size.setValue(512)
|
||||
imatrix_layout.addRow(
|
||||
self.create_label(CONTEXT_SIZE, CONTEXT_SIZE_FOR_IMATRIX),
|
||||
self.imatrix_ctx_size,
|
||||
)
|
||||
|
||||
# Threads input with slider and spinbox
|
||||
threads_layout = QHBoxLayout()
|
||||
self.threads_slider = QSlider(Qt.Orientation.Horizontal)
|
||||
self.threads_slider.setRange(1, 64)
|
||||
|
@ -476,7 +572,6 @@ def __init__(self):
|
|||
self.create_label(THREADS, NUMBER_OF_THREADS_FOR_IMATRIX), threads_layout
|
||||
)
|
||||
|
||||
# GPU Offload for IMatrix (corrected version)
|
||||
gpu_offload_layout = QHBoxLayout()
|
||||
self.gpu_offload_slider = QSlider(Qt.Orientation.Horizontal)
|
||||
self.gpu_offload_slider.setRange(0, 200)
|
||||
|
@ -530,7 +625,6 @@ def __init__(self):
|
|||
lora_output_layout,
|
||||
)
|
||||
|
||||
# Output Type Dropdown
|
||||
self.lora_output_type_combo = QComboBox()
|
||||
self.lora_output_type_combo.addItems(["GGML", "GGUF"])
|
||||
self.lora_output_type_combo.currentIndexChanged.connect(
|
||||
|
@ -541,30 +635,24 @@ def __init__(self):
|
|||
self.lora_output_type_combo,
|
||||
)
|
||||
|
||||
# Base Model Path (initially hidden)
|
||||
self.base_model_label = self.create_label(BASE_MODEL, SELECT_BASE_MODEL_FILE)
|
||||
self.base_model_path = QLineEdit()
|
||||
base_model_button = QPushButton(BROWSE)
|
||||
base_model_button.clicked.connect(self.browse_base_model)
|
||||
base_model_layout = QHBoxLayout()
|
||||
base_model_layout.addWidget(self.base_model_path, 1) # Give it a stretch factor
|
||||
base_model_layout.addWidget(self.base_model_path, 1)
|
||||
base_model_layout.addWidget(base_model_button)
|
||||
self.base_model_widget = QWidget()
|
||||
self.base_model_widget.setLayout(base_model_layout)
|
||||
|
||||
# Create a wrapper widget to hold both label and input
|
||||
self.base_model_wrapper = QWidget()
|
||||
wrapper_layout = QHBoxLayout(self.base_model_wrapper)
|
||||
wrapper_layout.addWidget(self.base_model_label)
|
||||
wrapper_layout.addWidget(self.base_model_widget, 1) # Give it a stretch factor
|
||||
wrapper_layout.setContentsMargins(
|
||||
0, 0, 0, 0
|
||||
) # Remove margins for better alignment
|
||||
wrapper_layout.addWidget(self.base_model_widget, 1)
|
||||
wrapper_layout.setContentsMargins(0, 0, 0, 0)
|
||||
|
||||
# Add the wrapper to the layout
|
||||
lora_layout.addRow(self.base_model_wrapper)
|
||||
|
||||
# Set initial visibility
|
||||
self.update_base_model_visibility(self.lora_output_type_combo.currentIndex())
|
||||
|
||||
lora_convert_button = QPushButton(CONVERT_LORA)
|
||||
|
@ -598,7 +686,6 @@ def __init__(self):
|
|||
self.create_label(OUTPUT, SELECT_OUTPUT_FILE), export_lora_output_layout
|
||||
)
|
||||
|
||||
# GGML LoRA Adapters
|
||||
self.export_lora_adapters = QListWidget()
|
||||
add_adapter_button = QPushButton(ADD_ADAPTER)
|
||||
add_adapter_button.clicked.connect(self.add_lora_adapter)
|
||||
|
@ -612,10 +699,9 @@ def __init__(self):
|
|||
adapters_layout,
|
||||
)
|
||||
|
||||
# Threads
|
||||
self.export_lora_threads = QSpinBox()
|
||||
self.export_lora_threads.setRange(1, 64)
|
||||
self.export_lora_threads.setValue(8) # Default value
|
||||
self.export_lora_threads.setValue(8)
|
||||
export_lora_layout.addRow(
|
||||
self.create_label(THREADS, NUMBER_OF_THREADS_FOR_LORA_EXPORT),
|
||||
self.export_lora_threads,
|
||||
|
@ -626,9 +712,7 @@ def __init__(self):
|
|||
export_lora_layout.addRow(export_lora_button)
|
||||
|
||||
export_lora_group.setLayout(export_lora_layout)
|
||||
right_layout.addWidget(
|
||||
export_lora_group
|
||||
) # Add the Export LoRA group to the right layout
|
||||
right_layout.addWidget(export_lora_group)
|
||||
|
||||
# HuggingFace to GGUF Conversion
|
||||
hf_to_gguf_group = QGroupBox(HF_TO_GGUF_CONVERSION)
|
||||
|
@ -686,21 +770,98 @@ def __init__(self):
|
|||
self.task_list.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
|
||||
self.task_list.customContextMenuRequested.connect(self.show_task_context_menu)
|
||||
|
||||
# Set inital state
|
||||
# Set initial state
|
||||
self.update_base_model_visibility(self.lora_output_type_combo.currentIndex())
|
||||
|
||||
# Timer for updating system info
|
||||
self.timer = QTimer()
|
||||
self.timer.timeout.connect(self.update_system_info)
|
||||
self.timer.start(200)
|
||||
# Initialize releases and backends
|
||||
if os.environ.get("AUTOGGUF_CHECK_BACKEND", "").lower() == "enabled":
|
||||
self.refresh_releases()
|
||||
self.refresh_backends()
|
||||
|
||||
# Initialize threads
|
||||
self.quant_threads = []
|
||||
# Load theme based on environment variable
|
||||
theme_path = os.environ.get("AUTOGGUF_THEME")
|
||||
if theme_path:
|
||||
try:
|
||||
with open(theme_path, "r") as f:
|
||||
theme = f.read()
|
||||
self.setStyleSheet(theme)
|
||||
except (FileNotFoundError, OSError):
|
||||
# If the specified theme file is not found or inaccessible,
|
||||
# fall back to the default theme
|
||||
with open(resource_path("assets/default.css"), "r") as f:
|
||||
default_theme = f.read()
|
||||
self.setStyleSheet(default_theme)
|
||||
else:
|
||||
# If the environment variable is not set, use the default theme
|
||||
with open(resource_path("assets/default.css"), "r") as f:
|
||||
default_theme = f.read()
|
||||
self.setStyleSheet(default_theme)
|
||||
|
||||
# Load models
|
||||
self.load_models()
|
||||
self.logger.info(AUTOGGUF_INITIALIZATION_COMPLETE)
|
||||
|
||||
def keyPressEvent(self, event):
|
||||
if event.modifiers() == Qt.ControlModifier:
|
||||
if (
|
||||
event.key() == Qt.Key_Equal
|
||||
): # Qt.Key_Plus doesn't work on some keyboards
|
||||
self.resize_window(larger=True)
|
||||
elif event.key() == Qt.Key_Minus:
|
||||
self.resize_window(larger=False)
|
||||
elif event.key() == Qt.Key_0:
|
||||
self.reset_size()
|
||||
super().keyPressEvent(event)
|
||||
|
||||
def resize_window(self, larger):
|
||||
factor = 1.1 if larger else 1 / 1.1
|
||||
current_width = self.width()
|
||||
current_height = self.height()
|
||||
new_width = int(current_width * factor)
|
||||
new_height = int(current_height * factor)
|
||||
self.resize(new_width, new_height)
|
||||
|
||||
def reset_size(self):
|
||||
self.resize(self.default_width, self.default_height)
|
||||
|
||||
def parse_resolution(self):
|
||||
res = os.environ.get("AUTOGGUF_RESOLUTION", "1650x1100")
|
||||
try:
|
||||
width, height = map(int, res.split("x"))
|
||||
if width <= 0 or height <= 0:
|
||||
raise ValueError
|
||||
return width, height
|
||||
except (ValueError, AttributeError):
|
||||
return 1650, 1100
|
||||
|
||||
def resizeEvent(self, event):
|
||||
super().resizeEvent(event)
|
||||
path = QPainterPath()
|
||||
path.addRoundedRect(self.rect(), 10, 10)
|
||||
mask = QRegion(path.toFillPolygon().toPolygon())
|
||||
self.setMask(mask)
|
||||
|
||||
def closeEvent(self, event: QCloseEvent):
|
||||
self.logger.info(APPLICATION_CLOSING)
|
||||
if self.quant_threads:
|
||||
reply = QMessageBox.question(
|
||||
self,
|
||||
WARNING,
|
||||
TASK_RUNNING_WARNING,
|
||||
QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No,
|
||||
QMessageBox.StandardButton.No,
|
||||
)
|
||||
|
||||
if reply == QMessageBox.StandardButton.Yes:
|
||||
for thread in self.quant_threads:
|
||||
thread.terminate()
|
||||
event.accept()
|
||||
else:
|
||||
event.ignore()
|
||||
else:
|
||||
event.accept()
|
||||
self.logger.info(APPLICATION_CLOSED)
|
||||
|
||||
def refresh_backends(self):
|
||||
self.logger.info(REFRESHING_BACKENDS)
|
||||
llama_bin = os.path.abspath("llama_bin")
|
||||
|
@ -725,80 +886,6 @@ def refresh_backends(self):
|
|||
self.backend_combo.setEnabled(False)
|
||||
self.logger.info(FOUND_VALID_BACKENDS.format(self.backend_combo.count()))
|
||||
|
||||
def save_preset(self):
|
||||
self.logger.info(SAVING_PRESET)
|
||||
preset = {
|
||||
"quant_types": [item.text() for item in self.quant_type.selectedItems()],
|
||||
"allow_requantize": self.allow_requantize.isChecked(),
|
||||
"leave_output_tensor": self.leave_output_tensor.isChecked(),
|
||||
"pure": self.pure.isChecked(),
|
||||
"imatrix": self.imatrix.text(),
|
||||
"include_weights": self.include_weights.text(),
|
||||
"exclude_weights": self.exclude_weights.text(),
|
||||
"use_output_tensor_type": self.use_output_tensor_type.isChecked(),
|
||||
"output_tensor_type": self.output_tensor_type.currentText(),
|
||||
"use_token_embedding_type": self.use_token_embedding_type.isChecked(),
|
||||
"token_embedding_type": self.token_embedding_type.currentText(),
|
||||
"keep_split": self.keep_split.isChecked(),
|
||||
"kv_overrides": [
|
||||
entry.get_raw_override_string() for entry in self.kv_override_entries
|
||||
],
|
||||
"extra_arguments": self.extra_arguments.text(),
|
||||
}
|
||||
|
||||
file_name, _ = QFileDialog.getSaveFileName(self, SAVE_PRESET, "", JSON_FILES)
|
||||
if file_name:
|
||||
with open(file_name, "w") as f:
|
||||
json.dump(preset, f, indent=4)
|
||||
QMessageBox.information(
|
||||
self, PRESET_SAVED, PRESET_SAVED_TO.format(file_name)
|
||||
)
|
||||
self.logger.info(PRESET_SAVED_TO.format(file_name))
|
||||
|
||||
def load_preset(self):
|
||||
self.logger.info(LOADING_PRESET)
|
||||
file_name, _ = QFileDialog.getOpenFileName(self, LOAD_PRESET, "", JSON_FILES)
|
||||
if file_name:
|
||||
with open(file_name, "r") as f:
|
||||
preset = json.load(f)
|
||||
|
||||
self.quant_type.clearSelection()
|
||||
for quant_type in preset.get("quant_types", []):
|
||||
items = self.quant_type.findItems(quant_type, Qt.MatchExactly)
|
||||
if items:
|
||||
items[0].setSelected(True)
|
||||
self.allow_requantize.setChecked(preset.get("allow_requantize", False))
|
||||
self.leave_output_tensor.setChecked(
|
||||
preset.get("leave_output_tensor", False)
|
||||
)
|
||||
self.pure.setChecked(preset.get("pure", False))
|
||||
self.imatrix.setText(preset.get("imatrix", ""))
|
||||
self.include_weights.setText(preset.get("include_weights", ""))
|
||||
self.exclude_weights.setText(preset.get("exclude_weights", ""))
|
||||
self.use_output_tensor_type.setChecked(
|
||||
preset.get("use_output_tensor_type", False)
|
||||
)
|
||||
self.output_tensor_type.setCurrentText(preset.get("output_tensor_type", ""))
|
||||
self.use_token_embedding_type.setChecked(
|
||||
preset.get("use_token_embedding_type", False)
|
||||
)
|
||||
self.token_embedding_type.setCurrentText(
|
||||
preset.get("token_embedding_type", "")
|
||||
)
|
||||
self.keep_split.setChecked(preset.get("keep_split", False))
|
||||
self.extra_arguments.setText(preset.get("extra_arguments", ""))
|
||||
|
||||
# Clear existing KV overrides and add new ones
|
||||
for entry in self.kv_override_entries:
|
||||
self.remove_kv_override(entry)
|
||||
for override in preset.get("kv_overrides", []):
|
||||
self.add_kv_override(override)
|
||||
|
||||
QMessageBox.information(
|
||||
self, PRESET_LOADED, PRESET_LOADED_FROM.format(file_name)
|
||||
)
|
||||
self.logger.info(PRESET_LOADED_FROM.format(file_name))
|
||||
|
||||
def save_task_preset(self, task_item):
|
||||
self.logger.info(SAVING_TASK_PRESET.format(task_item.task_name))
|
||||
for thread in self.quant_threads:
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
import json
|
||||
|
||||
from PySide6.QtWidgets import QFileDialog, QMessageBox
|
||||
from Localizations import *
|
||||
|
||||
|
||||
def save_preset(self):
|
||||
self.logger.info(SAVING_PRESET)
|
||||
preset = {
|
||||
"quant_types": [item.text() for item in self.quant_type.selectedItems()],
|
||||
"allow_requantize": self.allow_requantize.isChecked(),
|
||||
"leave_output_tensor": self.leave_output_tensor.isChecked(),
|
||||
"pure": self.pure.isChecked(),
|
||||
"imatrix": self.imatrix.text(),
|
||||
"include_weights": self.include_weights.text(),
|
||||
"exclude_weights": self.exclude_weights.text(),
|
||||
"use_output_tensor_type": self.use_output_tensor_type.isChecked(),
|
||||
"output_tensor_type": self.output_tensor_type.currentText(),
|
||||
"use_token_embedding_type": self.use_token_embedding_type.isChecked(),
|
||||
"token_embedding_type": self.token_embedding_type.currentText(),
|
||||
"keep_split": self.keep_split.isChecked(),
|
||||
"kv_overrides": [
|
||||
entry.get_raw_override_string() for entry in self.kv_override_entries
|
||||
],
|
||||
"extra_arguments": self.extra_arguments.text(),
|
||||
}
|
||||
|
||||
file_name, _ = QFileDialog.getSaveFileName(self, SAVE_PRESET, "", JSON_FILES)
|
||||
if file_name:
|
||||
with open(file_name, "w") as f:
|
||||
json.dump(preset, f, indent=4)
|
||||
QMessageBox.information(self, PRESET_SAVED, PRESET_SAVED_TO.format(file_name))
|
||||
self.logger.info(PRESET_SAVED_TO.format(file_name))
|
||||
|
||||
|
||||
def load_preset(self):
|
||||
self.logger.info(LOADING_PRESET)
|
||||
file_name, _ = QFileDialog.getOpenFileName(self, LOAD_PRESET, "", JSON_FILES)
|
||||
if file_name:
|
||||
with open(file_name, "r") as f:
|
||||
preset = json.load(f)
|
||||
|
||||
self.quant_type.clearSelection()
|
||||
for quant_type in preset.get("quant_types", []):
|
||||
items = self.quant_type.findItems(quant_type, Qt.MatchExactly)
|
||||
if items:
|
||||
items[0].setSelected(True)
|
||||
self.allow_requantize.setChecked(preset.get("allow_requantize", False))
|
||||
self.leave_output_tensor.setChecked(preset.get("leave_output_tensor", False))
|
||||
self.pure.setChecked(preset.get("pure", False))
|
||||
self.imatrix.setText(preset.get("imatrix", ""))
|
||||
self.include_weights.setText(preset.get("include_weights", ""))
|
||||
self.exclude_weights.setText(preset.get("exclude_weights", ""))
|
||||
self.use_output_tensor_type.setChecked(
|
||||
preset.get("use_output_tensor_type", False)
|
||||
)
|
||||
self.output_tensor_type.setCurrentText(preset.get("output_tensor_type", ""))
|
||||
self.use_token_embedding_type.setChecked(
|
||||
preset.get("use_token_embedding_type", False)
|
||||
)
|
||||
self.token_embedding_type.setCurrentText(preset.get("token_embedding_type", ""))
|
||||
self.keep_split.setChecked(preset.get("keep_split", False))
|
||||
self.extra_arguments.setText(preset.get("extra_arguments", ""))
|
||||
|
||||
# Clear existing KV overrides and add new ones
|
||||
for entry in self.kv_override_entries:
|
||||
self.remove_kv_override(entry)
|
||||
for override in preset.get("kv_overrides", []):
|
||||
self.add_kv_override(override)
|
||||
|
||||
QMessageBox.information(
|
||||
self, PRESET_LOADED, PRESET_LOADED_FROM.format(file_name)
|
||||
)
|
||||
self.logger.info(PRESET_LOADED_FROM.format(file_name))
|
|
@ -17,6 +17,7 @@ def update_system_info(self):
|
|||
)
|
||||
)
|
||||
self.cpu_label.setText(CPU_USAGE_FORMAT.format(cpu))
|
||||
self.cpu_bar.setValue(int(cpu))
|
||||
|
||||
|
||||
def update_download_progress(self, progress):
|
||||
|
|
Loading…
Reference in New Issue