mirror of
https://github.com/Pakobbix/StartUI-oobabooga-webui
synced 2026-01-02 08:50:33 +00:00
Compare commits
30 Commits
5e40ae8456
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| adbb97ecc2 | |||
| b10c023810 | |||
| 757debce3a | |||
| a8f033ac5b | |||
| a32aff730e | |||
| 0cd44016f5 | |||
| 21930ba8e9 | |||
| b96c0914ed | |||
| a07146e879 | |||
| 807dad51dd | |||
| 395c347020 | |||
| a75a8f42bc | |||
| 24e5876eff | |||
| c87e12d75a | |||
| 1ffd11eb5b | |||
| 311cbfed75 | |||
| 646b7419a5 | |||
| 0fb9a42cc6 | |||
| b2f2a894c9 | |||
| ce9ef8f419 | |||
| db6ed71594 | |||
| 86171f84d7 | |||
| 077669ea2e | |||
| 25087b1e2d | |||
| 5d755a302c | |||
| cc485f5342 | |||
| 20c847a532 | |||
| ab514acc40 | |||
| f28f1f21f9 | |||
| c3696284fa |
65
.github/workflows/package.yml
vendored
65
.github/workflows/package.yml
vendored
@@ -6,11 +6,8 @@ on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
package:
|
||||
runs-on: self-hosted
|
||||
strategy:
|
||||
matrix:
|
||||
os: [windows-latest, ubuntu-latest]
|
||||
package_on_ubuntu:
|
||||
runs-on: ubuntu-selfhosted
|
||||
steps:
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v3
|
||||
@@ -20,19 +17,67 @@ jobs:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Upgrade Pip
|
||||
run: python -m pip install --upgrade pip
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
sudo apt-get update
|
||||
sudo apt-get upgrade -y
|
||||
sudo apt-get install patchelf -y
|
||||
pip install -r requirements.txt
|
||||
pip install pyinstaller
|
||||
pip install nuitka
|
||||
sudo apt install patchelf
|
||||
|
||||
- name: Build and package
|
||||
run: python3 -m nuitka StartUI.py --onefile --enable-plugin=pyqt5 --product-version=1.6.0 --disable-console --include-data-files=webuiGUI.py=webuiGUI.py --output-dir=./dist --noinclude-pytest-mode=nofollow --noinclude-setuptools-mode=nofollow
|
||||
|
||||
- name: remove build folders
|
||||
run: |
|
||||
pyinstaller --noconfirm --onefile --windowed StartUI.py
|
||||
cp webuiGUI.py dist/ # Copy webuiGUI.py to the dist directory
|
||||
rm -rf dist/StartUI.build
|
||||
rm -rf dist/StartUI.dist
|
||||
rm -rf dist/StartUI.onefile-build
|
||||
|
||||
- name: Executive permission
|
||||
run: |
|
||||
chmod +x dist/StartUI
|
||||
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: ${{ matrix.os }}-binary-v1.5.1
|
||||
name: ubuntu-binary-v1.6
|
||||
path: dist
|
||||
|
||||
package_on_windows:
|
||||
runs-on: windows-selfhosted
|
||||
steps:
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v3
|
||||
with:
|
||||
python-version: 3.x
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Upgrade Pip
|
||||
run: python -m pip install --upgrade pip
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
pip install -r requirements.txt
|
||||
pip install nuitka
|
||||
|
||||
- name: Build and package
|
||||
run: nuitka StartUI.py --onefile --enable-plugin=pyqt5 --product-version=1.6.0 --disable-console --include-data-files=webuiGUI.py=webuiGUI.py --output-dir=./dist --noinclude-pytest-mode=nofollow --noinclude-setuptools-mode=nofollow
|
||||
|
||||
- name: remove build folders
|
||||
run: |
|
||||
Remove-Item -Recurse -Force ./dist/StartUI.build
|
||||
Remove-Item -Recurse -Force ./dist/StartUI.dist
|
||||
Remove-Item -Recurse -Force ./dist/StartUI.onefile-build
|
||||
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: windows-binary-v1.6
|
||||
path: dist
|
||||
56
StartUI.py
56
StartUI.py
@@ -1,16 +1,18 @@
|
||||
import sys, os, gpustat, json, subprocess, platform, psutil, re, requests, darkdetect, qdarkstyle, time
|
||||
from PyQt5.QtWidgets import QApplication, QHBoxLayout, QToolBar, QMessageBox, QAction, QMainWindow, QSpinBox, QLabel, QVBoxLayout, QComboBox, QSlider, QCheckBox, QLineEdit, QFileDialog, QPushButton, QWidget, QListWidget, QListWidgetItem, QGridLayout, QRadioButton, QFrame
|
||||
|
||||
from PyQt5.QtCore import Qt
|
||||
from PyQt5.QtGui import QDoubleValidator, QIntValidator
|
||||
from PyQt5.QtWidgets import QAction, QApplication, QCheckBox, QComboBox, QFileDialog, QFrame, QGridLayout, QHBoxLayout, QLabel, QLineEdit, QListWidget, QListWidgetItem, QMainWindow, QMessageBox, QPushButton, QRadioButton, QSlider, QSpinBox, QToolBar, QVBoxLayout, QWidget
|
||||
|
||||
# For showing the current version and checking for updates
|
||||
version = "1.5.1"
|
||||
version = "1.6"
|
||||
|
||||
# Profile folder for loading and saving profiles.
|
||||
profiles_folder = "./profiles"
|
||||
# Create the profile folder if it doesn't exist
|
||||
os.makedirs(profiles_folder, exist_ok=True)
|
||||
|
||||
repo_path = "./text-generation-webui"
|
||||
model_folder = "./text-generation-webui/models"
|
||||
extensions_folder = "./text-generation-webui/extensions"
|
||||
loras_folder = "./text-generation-webui/loras"
|
||||
@@ -221,6 +223,7 @@ class MainWindow(QMainWindow):
|
||||
# |_| |_|\__,_|_|_| |_| \_/\_/ |_|_| |_|\__,_|\___/ \_/\_/ #
|
||||
# #
|
||||
###################################################################
|
||||
|
||||
layout = QGridLayout()
|
||||
layout.setColumnMinimumWidth(0, 350)
|
||||
layout.setColumnMinimumWidth(3, 30)
|
||||
@@ -418,21 +421,22 @@ class MainWindow(QMainWindow):
|
||||
self.pre_layer_slider_value = []
|
||||
self.pre_layer_amount_max = 100
|
||||
# Don't get confused. With the latest changes, each GPU can have it's own pre_layer value. So we check again gpu_stats for the amount.
|
||||
for i, gpu in enumerate(gpu_stats):
|
||||
pre_layer_labels = QLabel(f"{gpu.name} Pre_Layer:")
|
||||
pre_layer_labels.setToolTip(f"The number of layers to allocate to the GPU.\nSetting this parameter enables CPU offloading for 4-bit models.\nFor multi-gpu, write the numbers separated by spaces, eg --pre_layer 30 60.")
|
||||
layout.addWidget(pre_layer_labels, 11 + (len(gpu_stats) * 2) + i, 0)
|
||||
self.pre_layer_labels.append(pre_layer_labels)
|
||||
if nvidia_gpu:
|
||||
for i, gpu in enumerate(gpu_stats):
|
||||
pre_layer_labels = QLabel(f"{gpu.name} Pre_Layer:")
|
||||
pre_layer_labels.setToolTip(f"The number of layers to allocate to the GPU.\nSetting this parameter enables CPU offloading for 4-bit models.\nFor multi-gpu, write the numbers separated by spaces, eg --pre_layer 30 60.")
|
||||
layout.addWidget(pre_layer_labels, 11 + (len(gpu_stats) * 2) + i, 0)
|
||||
self.pre_layer_labels.append(pre_layer_labels)
|
||||
|
||||
pre_layer_sliders = QSlider(Qt.Horizontal)
|
||||
pre_layer_sliders.setMaximum(100)
|
||||
pre_layer_sliders.valueChanged.connect(lambda value, idx=i: self.on_pre_layer_slider_changed(value, idx))
|
||||
layout.addWidget(pre_layer_sliders, 11 + (len(gpu_stats) * 2) + i, 1)
|
||||
self.pre_layer_slider.append(pre_layer_sliders)
|
||||
pre_layer_sliders = QSlider(Qt.Horizontal)
|
||||
pre_layer_sliders.setMaximum(100)
|
||||
pre_layer_sliders.valueChanged.connect(lambda value, idx=i: self.on_pre_layer_slider_changed(value, idx))
|
||||
layout.addWidget(pre_layer_sliders, 11 + (len(gpu_stats) * 2) + i, 1)
|
||||
self.pre_layer_slider.append(pre_layer_sliders)
|
||||
|
||||
pre_layer_sliders_value = QLabel("0")
|
||||
layout.addWidget(pre_layer_sliders_value, 11 + (len(gpu_stats) * 2) + i, 2)
|
||||
self.pre_layer_slider_value.append(pre_layer_sliders_value)
|
||||
pre_layer_sliders_value = QLabel("0")
|
||||
layout.addWidget(pre_layer_sliders_value, 11 + (len(gpu_stats) * 2) + i, 2)
|
||||
self.pre_layer_slider_value.append(pre_layer_sliders_value)
|
||||
|
||||
# Add horizontal line to seperate the Checkboxes
|
||||
line = QFrame()
|
||||
@@ -448,7 +452,7 @@ class MainWindow(QMainWindow):
|
||||
# Deactivate Streaming Output
|
||||
self.use_nostream_checkbox = QCheckBox("No Stream")
|
||||
self.use_nostream_checkbox.setToolTip("Don't stream the text output in real time. Increases Token/s by ~ 50%")
|
||||
layout.addWidget(self.use_nostream_checkbox, 15 + (len(gpu_stats) * 2), 1)
|
||||
layout.addWidget(self.use_nostream_checkbox, 14 + (len(gpu_stats) * 2), 1)
|
||||
|
||||
# Load in full 16bit precision
|
||||
self.use_16bit_checkbox = QCheckBox("Load in 16bit")
|
||||
@@ -539,11 +543,16 @@ class MainWindow(QMainWindow):
|
||||
self.use_triton_checkbox.setToolTip("Use Triton for inference.")
|
||||
layout.addWidget(self.use_triton_checkbox, 22 + (len(gpu_stats) * 2), 1)
|
||||
|
||||
# Add desc_act option Checkbox
|
||||
self.use_desc_act_checkbox = QCheckBox("Use desc_act")
|
||||
self.use_desc_act_checkbox.setToolTip("For models that don\'t have a quantize_config.json, this parameter is used to define whether to set desc_act or not in BaseQuantizeConfig.")
|
||||
layout.addWidget(self.use_desc_act_checkbox, 23 + (len(gpu_stats) * 2), 0)
|
||||
|
||||
# Add horizontal line to seperate the Checkboxes
|
||||
line = QFrame()
|
||||
line.setFrameShape(QFrame.HLine)
|
||||
line.setFrameShadow(QFrame.Sunken)
|
||||
layout.addWidget(line, 23 + (len(gpu_stats) * 2), 0, 1, 3)
|
||||
layout.addWidget(line, 29 + (len(gpu_stats) * 2), 0, 1, 3)
|
||||
|
||||
# New GUI Options based on Toolbox Checkboxes.
|
||||
|
||||
@@ -1858,6 +1867,10 @@ class MainWindow(QMainWindow):
|
||||
if self.use_triton_checkbox.isChecked():
|
||||
command += " --triton"
|
||||
|
||||
# if desc_act is checked
|
||||
if self.use_desc_act_checkbox.isChecked():
|
||||
command += " --desc_act"
|
||||
|
||||
# Adds the chosen extensions to the list of the command.
|
||||
extensions = [self.extensions_list.item(i).text() for i in range(self.extensions_list.count()) if self.extensions_list.item(i).checkState() == Qt.Checked]
|
||||
if self.use_extensions_checkbox.isChecked():
|
||||
@@ -1905,15 +1918,6 @@ class MainWindow(QMainWindow):
|
||||
def on_update_button_clicked(self):
|
||||
run_cmd_with_conda(f"python {webui_file} --update && exit")
|
||||
|
||||
def load_profile(self, profile_file):
|
||||
with open(profile_file, "r") as file:
|
||||
try:
|
||||
settings = json.load(file)
|
||||
# Set the GUI elements based on the loaded settings...
|
||||
except json.JSONDecodeError:
|
||||
# Handle the case when the file is empty or not in valid JSON format
|
||||
pass
|
||||
|
||||
def populate_profiles_dropdown(self):
|
||||
self.profiles_dropdown.clear()
|
||||
profiles = [name for name in os.listdir(profiles_folder) if name.endswith(".json")]
|
||||
|
||||
Reference in New Issue
Block a user