From d55cb9ea9b2ce02389b1415604413a4e050e7573 Mon Sep 17 00:00:00 2001 From: BuildTools Date: Wed, 4 Sep 2024 17:19:54 -0700 Subject: [PATCH] refactor: prepare repo for v1.8.1 - add localizations for AutoFP8 - remove unnecessary assets - update CHANGELOG.md - add DownloadThread.py docs --- .env.example | 3 +++ CHANGELOG.md | 30 ++++++++++++++++++++++++++++ assets/icon.RES | Bin 4396 -> 0 bytes assets/icon.rc | 1 - docs/AutoGGUF.py | 27 ++++++++++++++----------- docs/DownloadThread.py | 44 +++++++++++++++++++++++++++++++++++++++++ src/AutoGGUF.py | 22 +++++++++++---------- src/Localizations.py | 13 +++++++++++- 8 files changed, 117 insertions(+), 23 deletions(-) delete mode 100644 assets/icon.RES delete mode 100644 assets/icon.rc create mode 100644 docs/DownloadThread.py diff --git a/.env.example b/.env.example index 993b8a3..da700ce 100644 --- a/.env.example +++ b/.env.example @@ -3,3 +3,6 @@ AUTOGGUF_THEME= AUTOGGUF_CHECK_BACKEND=enabled AUTOGGUF_CHECK_UPDATE=enabled AUTOGGUF_SERVER_API_KEY= +AUTOGGUF_MODEL_DIR_NAME=models +AUTOGGUF_OUTPUT_DIR_NAME=quantized_models +AUTOGGUF_RESIZE_FACTOR=1.1 diff --git a/CHANGELOG.md b/CHANGELOG.md index 16cf044..54a2801 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,35 @@ # Changelog +## [v1.8.1] - 2024-09-04 + +### Added +- AutoFP8 quantization classes and window (currently WIP) +- Minimize/maximize buttons to title bar +- API key authentication support for the local server +- HuggingFace upload/download class +- OpenAPI docs for endpoints + +### Changed +- Replaced Flask with FastAPI and Uvicorn for improved performance +- Moved functions out of AutoGGUF.py into utils.py and TaskListItem.py +- Updated llama.cpp convert scripts +- Improved LoRA conversion process: + - Allow specifying output path in arguments + - Removed shutil.move operation + - Increased max number of LoRA layers +- Changed default port to 7001 +- Now binding to localhost (127.0.0.1) instead of 0.0.0.0 +- Upadted Spanish localizations +- Updated setuptools requirement from ~=68.2.0 to ~=74.0.0 + +### Fixed +- Web page not found error +- Use of proper status in TaskListItem +- Passing of quant_threads and Logger to TaskListItem +- Improved window moving smoothness +- Prevention of moving window below taskbar +- Optimized imports in various files + ## [v1.8.0] - 2024-08-26 ### Added diff --git a/assets/icon.RES b/assets/icon.RES deleted file mode 100644 index 6627e353d0f444269d79b4ffcd45219d22129589..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4396 zcmeHLYitzP6+VkgT>`oT2Izo*&9t-i0X_pbjCe4-8lQo|EIzOL2B)g1A0)!T8Q zZb4Ac-PdliqVw`5AO$f?^;7uM{dk94565y_=R|qeF@#+q&Iy&t?i+2pPq;u?YA8Y=>P{RqJss{JT_JKJDy zV|5o%?8QN(f7s|2)&nKEATF=k7*o90I|f%JJ4c&NBu8AIC5PNtd>BLPX}-rz*Ht$J zn0kn+))j=sQGuSSB`X4^Vl_IrLoe(nn8%{P}D5jWJV2OtC;*v6(2ze3}+4Wl`Do zYg%#qIiX@(5_#vA?v(IoTUX*_-Tsd(NF2#-Zn z14HGFpCv}DiG5d{C7nw1d|Gz*P$G7bkR57R!CWC_=C%4^E9(B87jPccLlr~s*3pLY zKZ?$FZ`ZJEUdNCF(AkEB(!7|I?3)9;>Bb(W;qb1sZuu^z0os_Vhq-^Co*cp;G1{aF zsdls{+bL49Z;h$;^|8F;lZ5Ji3<1UVLg9D;!m1s|MN7x7j4txaOx4+4*=kROx6Sdf z53hM)#sp->tO*QQR)(_Ht&yDNc{*o%gch-{g%tBvLa`hP$#z2l3XqW9Peo<>AEL5z zUGPdN?2sRakYN2LE?I<-Y_-G+Rq%FNtKY+Fd;CJp59mQlF)mkqqg|}r)Gm~7Zs*FL ziRNlFVg62T;{8qFXN-U|)>VOwMF=vcV|dn(!83+VoHZT_iI$s`=-^2aJ5NdO_fbte zL&?q?VaawiEZUAE^y0kfT!1&+M76&U7Y#>3qMn{*W-RB{-?x0^T@AHY}XZ-xi zxGz_FF36SIeYq77;~RkLcLIIMS&XM`XK=>;)4fa$5E;YMfwcZwFl)$@q64QT*Ix9V zchaio$BDf6wWxw^4@njg{nxccWXmu7oSyOX`rqI}shZNn{gZy)Vb7fnC{IjPiRa;ESTA&8JKn{3Hh_s_0!5&IGAbi;|FEC)dfM-nK z@uv-t`eg0hb3&q85Rn{@28G6+K(67bYi;|Xm90DM;~QUS<);3>2Bb>V3sh?Ta@qU1 zQvE0)ltG9ub>c$lWjbHCFs9Z6omm6jnay)>#zhlZ*GZCf)#4f3wqVA3G0ZrgK)4%w zT!?18usyv5{MnkIpV6)jO8gK0v>95_cjaSh zUTn>1_XfCHosX+MNl3=|A<;C2o0KrX)n_53ROraTiesc&ewL8SBcxRQtuV?>@6`== z`LS#>#Ih}OP~WpK#(Rpx`C91A{X6e>iAeCXI`FZ&(pI**J1ErtJRs--JK1L-Cf!@} z4h&fUjsm1cbn|0_+LD-PoHO8Zy*-hl?4+dG? zo4dttqk4wT%HM3s9gG)tDo+B%n$09<>>~x^$E0BR2`L&EM8yB@-Y3?2puYw1YqgM+ z-Ngyn`AC;mi;1EEfFc55F>$MBaqHMJO?qsZ|1V=^t}tdU+{UeCg~BcRUqJF0 y!WZVk_*jCnRf$k2ECdfY5MDvBLkp~iiSDU#(!Iv`Z3eo}SbpbLWBe9G1OEg>TK_fx diff --git a/assets/icon.rc b/assets/icon.rc deleted file mode 100644 index 1fa8fd7..0000000 --- a/assets/icon.rc +++ /dev/null @@ -1 +0,0 @@ -IDI_ICON1 ICON "favicon.ico" \ No newline at end of file diff --git a/docs/AutoGGUF.py b/docs/AutoGGUF.py index 8bdc2be..4645430 100644 --- a/docs/AutoGGUF.py +++ b/docs/AutoGGUF.py @@ -1,29 +1,34 @@ +import importlib import json import re import shutil -import os - +from datetime import datetime from functools import partial +from typing import Any, Dict, List, Tuple + +import requests from PySide6.QtCore import * from PySide6.QtGui import * from PySide6.QtWidgets import * +from dotenv import load_dotenv +import lora_conversion +import presets +import ui_update +import utils +from CustomTitleBar import CustomTitleBar from GPUMonitor import GPUMonitor -from KVOverrideEntry import KVOverrideEntry +from Localizations import * from Logger import Logger -from ModelInfoDialog import ModelInfoDialog -from error_handling import show_error, handle_error +from QuantizationThread import QuantizationThread +from TaskListItem import TaskListItem +from error_handling import handle_error, show_error from imports_and_globals import ( + ensure_directory, open_file_safe, resource_path, show_about, - ensure_directory, ) -from Localizations import * -import presets -import ui_update -import lora_conversion -import utils class CustomTitleBar(QWidget): diff --git a/docs/DownloadThread.py b/docs/DownloadThread.py new file mode 100644 index 0000000..dbbd3c7 --- /dev/null +++ b/docs/DownloadThread.py @@ -0,0 +1,44 @@ +import os +import zipfile + +import requests +from PySide6.QtCore import QThread, Signal + + +class DownloadThread(QThread): + """ + A QThread subclass for downloading and extracting zip files. + + This thread downloads a file from a given URL, saves it to a specified path, + extracts its contents if it's a zip file, and then removes the original zip file. + + Signals: + progress_signal (int): Emits the download progress as a percentage. + finished_signal (str): Emits the path of the extracted directory upon successful completion. + error_signal (str): Emits an error message if an exception occurs during the process. + """ + + def __init__(self, url: str, save_path: str) -> None: + """ + Initialize the DownloadThread. + + Args: + url (str): The URL of the file to download. + save_path (str): The local path where the file will be saved. + """ + + def run(self) -> None: + """ + Execute the download, extraction, and cleanup process. + + This method performs the following steps: + 1. Downloads the file from the specified URL. + 2. Saves the file to the specified path. + 3. Extracts the contents if it's a zip file. + 4. Removes the original zip file after extraction. + 5. Emits signals for progress updates, completion, or errors. + + Raises: + Exception: Any exception that occurs during the process is caught + and emitted through the error_signal. + """ diff --git a/src/AutoGGUF.py b/src/AutoGGUF.py index 29429b6..e7ce8f4 100644 --- a/src/AutoGGUF.py +++ b/src/AutoGGUF.py @@ -1016,7 +1016,9 @@ def browse_hf_outfile(self) -> None: self.hf_outfile.setText(os.path.abspath(outfile)) def quantize_to_fp8_dynamic(self, model_dir: str, output_dir: str) -> None: - self.logger.info(f"Quantizing {os.path.basename(model_dir)} to {output_dir}") + self.logger.info( + QUANTIZING_TO_WITH_AUTOFP8.format(os.path.basename(model_dir), output_dir) + ) try: command = [ "python", @@ -1034,7 +1036,7 @@ def quantize_to_fp8_dynamic(self, model_dir: str, output_dir: str) -> None: thread = QuantizationThread(command, os.getcwd(), log_file) self.quant_threads.append(thread) - task_name = f"Quantizing {os.path.basename(model_dir)} with AutoFP8" + task_name = QUANTIZING_WITH_AUTOFP8.format(os.path.basename(model_dir)) task_item = TaskListItem( task_name, log_file, @@ -1057,12 +1059,12 @@ def quantize_to_fp8_dynamic(self, model_dir: str, output_dir: str) -> None: thread.start() except Exception as e: - show_error(self.logger, f"Error starting AutoFP8 quantization: {e}") - self.logger.info("AutoFP8 quantization task started") + show_error(self.logger, f"{ERROR_STARTING_AUTOFP8_QUANTIZATION}: {e}") + self.logger.info(AUTOFP8_QUANTIZATION_TASK_STARTED) def show_autofp8_window(self): dialog = QDialog(self) - dialog.setWindowTitle("Quantize to FP8 Dynamic") + dialog.setWindowTitle(QUANTIZE_TO_FP8_DYNAMIC) dialog.setFixedWidth(500) layout = QVBoxLayout() @@ -1072,10 +1074,10 @@ def show_autofp8_window(self): input_button = QPushButton(BROWSE) input_button.clicked.connect( lambda: self.fp8_input.setText( - QFileDialog.getExistingDirectory(self, "Open Model Folder") + QFileDialog.getExistingDirectory(self, OPEN_MODEL_FOLDER) ) ) - input_layout.addWidget(QLabel("Input Model:")) + input_layout.addWidget(QLabel(INPUT_MODEL)) input_layout.addWidget(self.fp8_input) input_layout.addWidget(input_button) layout.addLayout(input_layout) @@ -1086,16 +1088,16 @@ def show_autofp8_window(self): output_button = QPushButton(BROWSE) output_button.clicked.connect( lambda: self.fp8_output.setText( - QFileDialog.getExistingDirectory(self, "Open Model Folder") + QFileDialog.getExistingDirectory(self, OPEN_MODEL_FOLDER) ) ) - output_layout.addWidget(QLabel("Output Path:")) + output_layout.addWidget(QLabel(OUTPUT)) output_layout.addWidget(self.fp8_output) output_layout.addWidget(output_button) layout.addLayout(output_layout) # Quantize button - quantize_button = QPushButton("Quantize") + quantize_button = QPushButton(QUANTIZE) quantize_button.clicked.connect( lambda: self.quantize_to_fp8_dynamic( self.fp8_input.text(), self.fp8_output.text() diff --git a/src/Localizations.py b/src/Localizations.py index 2d460ba..9233061 100644 --- a/src/Localizations.py +++ b/src/Localizations.py @@ -1,6 +1,6 @@ import os -AUTOGGUF_VERSION = "v1.8.0" +AUTOGGUF_VERSION = "v1.8.1" class _Localization: @@ -34,6 +34,17 @@ def __init__(self): self.IMPORTING_MODEL = "Importing model" self.IMPORTED_MODEL_TOOLTIP = "Imported model: {}" + # AutoFP8 Quantization + self.AUTOFP8_QUANTIZATION_TASK_STARTED = "AutoFP8 quantization task started" + self.ERROR_STARTING_AUTOFP8_QUANTIZATION = "Error starting AutoFP8 quantization" + self.QUANTIZING_WITH_AUTOFP8 = "Quantizing {0} with AutoFP8" + self.QUANTIZING_TO_WITH_AUTOFP8 = "Quantizing {0} to {1}" + self.QUANTIZE_TO_FP8_DYNAMIC = "Quantize to FP8 Dynamic" + self.OPEN_MODEL_FOLDER = "Open Model Folder" + self.QUANTIZE = "Quantize" + self.OPEN_MODEL_FOLDER = "Open Model Folder" + self.INPUT_MODEL = "Input Model:" + # GGUF Verification self.INVALID_GGUF_FILE = "Invalid GGUF file: {}" self.SHARDED_MODEL_NAME = "{} (Sharded)"