From 5e4d4172757d006edf7b07fdded7ad9da38c7e9c Mon Sep 17 00:00:00 2001 From: e-nord Date: Tue, 29 Sep 2026 21:25:32 -0700 Subject: [PATCH 1/3] feat: add Fizgig LoRA training studio package Fizgig (shootthesound/Fizgig) is an Apache-2.0 LoRA training studio for Flux 2 Klein 9B, Krea 2, MiniMax H3 and Qwen Image 2.1. It is a Tkinter desktop app rather than a web UI, so it follows the same shape as OneTrainer. Notes on the less obvious choices: - LaunchCommand is lora_trainer_gui.py, not launch.pyw. The latter re-spawns itself under venv/Scripts/pythonw.exe and exits, which would drop the process we track (no console output, no working Stop button) and leave the GUI orphaned. lora_trainer_gui.py has a standalone main() and is what upstream's run_fizgig.sh invokes directly. - VcBuildTools is a prerequisite so triton / torch.compile's inductor backend can compile kernels on Windows, which Fizgig's Compile Blocks speedup needs. - DISABLE_CUDA=1 is set around the requirements install. hqq ships as an sdist whose setup.py kicks off a CUDA kernel build during egg_info without it; Fizgig's own requirements.txt warns never to install that line otherwise. - The requirements exclude pattern spells out the version specifiers. The pattern is anchored against the whole entry, so the default "(torch|torchvision|...)" only catches bare, unpinned names and would let Fizgig's pinned torch==2.10.0 through - pulling multi-GB PyPI wheels right before the cu128 build force-reinstalls over them. - Torch pins carry the == operator ("==2.10.0"), since GetTorchPipArgs appends the version string directly to the package name. - CudaIndex is cu128; torch 2.10 has no wheels on SM's default cu130. Shared folders default to None, matching the other trainers. Symlink is offered as an opt-in (Package Manager -> Shared Model Strategy) that junctions output_loras into the shared Lora folder, so a freshly trained LoRA is immediately visible to ComfyUI and friends. Only output_loras is mapped: Fizgig flattens every weight it downloads into a single models/ directory, and junctions are directory-level, so DiffusionModels, TextEncoders and VAE would all collide on the same target path. ROCm is deliberately left out of this change and will follow separately. Co-Authored-By: Claude Opus 5.5 --- README.md | 2 + .../Services/DiscordRichPresenceService.cs | 1 + .../Helper/Factory/PackageFactory.cs | 8 + .../Models/Packages/Fizgig.cs | 171 ++++++++++++++++++ docs/advanced/hardware-support.md | 2 +- docs/package-manager/supported-packages.md | 3 +- 6 files changed, 185 insertions(+), 2 deletions(-) create mode 100644 StabilityMatrix.Core/Models/Packages/Fizgig.cs diff --git a/README.md b/README.md index e7d8cb099..ec20f9ac6 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,7 @@ [reforge]: https://github.com/Panchovix/stable-diffusion-webui-reForge [simplesdxl]: https://github.com/metercai/SimpleSDXL/ [fluxgym]: https://github.com/cocktailpeanut/fluxgym +[fizgig]: https://github.com/shootthesound/Fizgig [cogvideo]: https://github.com/THUDM/CogVideo [cogstudio]: https://github.com/pinokiofactory/cogstudio [amdforge]: https://github.com/lshqqytiger/stable-diffusion-webui-amdgpu-forge @@ -63,6 +64,7 @@ See the [documentation index](docs/README.md) for installation, package manageme - [Kohya's GUI][kohya-ss] - [OneTrainer][onetrainer] - [FluxGym][fluxgym] + - [Fizgig][fizgig] - [CogVideo][cogvideo] via [CogStudio][cogstudio] - Manage plugins / extensions for supported packages ([Automatic1111][auto1111], [Comfy UI][comfy], [SD Web UI-UX][webui-ux], and [SD.Next][sdnext]) - Easily install or update Python dependencies for each package diff --git a/StabilityMatrix.Avalonia/Services/DiscordRichPresenceService.cs b/StabilityMatrix.Avalonia/Services/DiscordRichPresenceService.cs index 19de6aed3..958ffc064 100644 --- a/StabilityMatrix.Avalonia/Services/DiscordRichPresenceService.cs +++ b/StabilityMatrix.Avalonia/Services/DiscordRichPresenceService.cs @@ -96,6 +96,7 @@ private void OnRunningPackageStatusChanged(object? sender, RunningPackageStatusC var packageTitle = args.CurrentPackagePair.BasePackage switch { + Fizgig => "Fizgig", FluxGym => "FluxGym", Fooocus => "Fooocus", Reforge => "SD WebUI reForge", diff --git a/StabilityMatrix.Core/Helper/Factory/PackageFactory.cs b/StabilityMatrix.Core/Helper/Factory/PackageFactory.cs index c23051fac..ca1b68828 100644 --- a/StabilityMatrix.Core/Helper/Factory/PackageFactory.cs +++ b/StabilityMatrix.Core/Helper/Factory/PackageFactory.cs @@ -278,6 +278,14 @@ public BasePackage GetNewBasePackage(InstalledPackage installedPackage) pyInstallationManager, pipWheelService ), + "Fizgig" => new Fizgig( + githubApiCache, + settingsManager, + downloadService, + prerequisiteHelper, + pyInstallationManager, + pipWheelService + ), "ai-toolkit" => new AiToolkit( githubApiCache, settingsManager, diff --git a/StabilityMatrix.Core/Models/Packages/Fizgig.cs b/StabilityMatrix.Core/Models/Packages/Fizgig.cs new file mode 100644 index 000000000..91cfcadc9 --- /dev/null +++ b/StabilityMatrix.Core/Models/Packages/Fizgig.cs @@ -0,0 +1,171 @@ +using Injectio.Attributes; +using StabilityMatrix.Core.Helper; +using StabilityMatrix.Core.Helper.Cache; +using StabilityMatrix.Core.Helper.HardwareInfo; +using StabilityMatrix.Core.Models.Progress; +using StabilityMatrix.Core.Processes; +using StabilityMatrix.Core.Python; +using StabilityMatrix.Core.Services; + +namespace StabilityMatrix.Core.Models.Packages; + +[RegisterSingleton(Duplicate = DuplicateStrategy.Append)] +public class Fizgig( + IGithubApiCache githubApi, + ISettingsManager settingsManager, + IDownloadService downloadService, + IPrerequisiteHelper prerequisiteHelper, + IPyInstallationManager pyInstallationManager, + IPipWheelService pipWheelService +) + : BaseGitPackage( + githubApi, + settingsManager, + downloadService, + prerequisiteHelper, + pyInstallationManager, + pipWheelService + ) +{ + public override string Name => "Fizgig"; + public override string DisplayName { get; set; } = "Fizgig"; + public override string Author => "shootthesound"; + + public override string Blurb => + "LoRA training studio for Flux 2 Klein 9B, Krea 2, MiniMax H3 and Qwen Image 2.1 — train, profile, repair and extract"; + + public override string LicenseType => "Apache-2.0"; + public override string LicenseUrl => "https://github.com/shootthesound/Fizgig/blob/master/LICENSE"; + + // NOT launch.pyw: that launcher re-spawns itself under venv/Scripts/pythonw.exe and exits, + // which would drop the process we track (no console output, no working Stop button) and + // leave the GUI orphaned. lora_trainer_gui.py has a standalone main() and is what upstream's + // run_fizgig.sh invokes directly. + public override string LaunchCommand => "lora_trainer_gui.py"; + + public override Uri PreviewImageUri => + new("https://github.com/shootthesound/Fizgig/blob/master/icon.png?raw=true"); + + public override string MainBranch => "master"; + public override PackageType PackageType => PackageType.SdTraining; + public override PackageDifficulty InstallerSortOrder => PackageDifficulty.Advanced; + public override bool OfferInOneClickInstaller => false; + public override bool IsCompatible => HardwareHelper.HasNvidiaGpu(); + public override IEnumerable AvailableTorchIndices => [TorchIndex.Cuda]; + + public override TorchIndex GetRecommendedTorchVersion() => TorchIndex.Cuda; + + public override PyVersion RecommendedPythonVersion => Python.PyInstallationManager.Python_3_12_10; + + // Tkinter for the GUI itself; VcBuildTools for triton / torch.compile's inductor backend, + // which the Compile Blocks speedup needs on Windows. + public override IEnumerable Prerequisites => + base.Prerequisites.Concat([PackagePrerequisite.Tkinter, PackagePrerequisite.VcBuildTools]); + + public override List LaunchOptions => [LaunchOptionDefinition.Extras]; + + // Trained LoRAs, not images. + public override string OutputFolderName => string.Empty; + public override Dictionary>? SharedOutputFolders => null; + + /// + /// Defaults to None, matching the other trainers. Opting in to Symlink (Package Manager -> + /// ... -> Shared Model Strategy) junctions output_loras into the shared Lora folder, so a + /// freshly trained LoRA is immediately visible to ComfyUI and friends. + /// + public override SharedFolderMethod RecommendedSharedFolderMethod => SharedFolderMethod.None; + + public override IEnumerable AvailableSharedFolderMethods => + [SharedFolderMethod.None, SharedFolderMethod.Symlink]; + + /// + /// Only output_loras is mapped. Fizgig's models/ directory deliberately flattens every + /// weight it downloads into one folder — DiTs, text encoders, VAEs, turbo LoRAs and training + /// adapters all land there as bare filenames (see src/fizgig/scripts/fetch_models.py) — and + /// junctions are directory-level, so there is no way to fan that single directory out to + /// DiffusionModels/TextEncoders/VAE without them colliding on the same target path. + /// + public override SharedFolderLayout SharedFolderLayout => + new() + { + Rules = + [ + new SharedFolderLayoutRule + { + SourceTypes = [SharedFolderType.Lora], + TargetRelativePaths = ["output_loras"], + }, + ], + }; + + public override async Task InstallPackage( + string installLocation, + InstalledPackage installedPackage, + InstallPackageOptions options, + IProgress? progress = null, + Action? onConsoleOutput = null, + CancellationToken cancellationToken = default + ) + { + progress?.Report(new ProgressReport(-1f, "Setting up venv", isIndeterminate: true)); + + await using var venvRunner = await SetupVenvPure( + installLocation, + pythonVersion: options.PythonOptions.PythonVersion + ) + .ConfigureAwait(false); + + // hqq ships as an sdist whose setup.py kicks off a CUDA kernel build during egg_info + // unless DISABLE_CUDA is set. Fizgig only uses its pure-PyTorch path, and its own + // requirements.txt warns never to install that line without this. + venvRunner.UpdateEnvironmentVariables(env => env.SetItem("DISABLE_CUDA", "1")); + + var config = new PipInstallConfig + { + RequirementsFilePaths = ["requirements.txt"], + // Drop the torch pins and the cu128 index line from the file so the torch install + // below is the single source of truth for which build lands in the venv. The pattern + // is anchored against the whole entry by the caller, so the version specifier has to + // be matched too - the default pattern only catches bare, unpinned names. + RequirementsExcludePattern = + @"(--extra-index-url.*|(torch|torchvision|torchaudio|xformers)([=<>!~].*)?)", + TorchVersion = "==2.10.0", + TorchvisionVersion = "==0.25.0", + // torch 2.10 pairs with cu128 here; SM's default cu130 has no matching wheels. + CudaIndex = "cu128", + }; + + await StandardPipInstallProcessAsync( + venvRunner, + options, + installedPackage, + config, + onConsoleOutput, + progress, + cancellationToken + ) + .ConfigureAwait(false); + + venvRunner.UpdateEnvironmentVariables(env => env.Remove("DISABLE_CUDA")); + } + + public override async Task RunPackage( + string installLocation, + InstalledPackage installedPackage, + RunPackageOptions options, + Action? onConsoleOutput = null, + CancellationToken cancellationToken = default + ) + { + await SetupVenv(installLocation, pythonVersion: PyVersion.Parse(installedPackage.PythonVersion)) + .ConfigureAwait(false); + + // Desktop Tkinter app - there is no local URL to wait for, so startup is complete + // as soon as the process is up. + VenvRunner.RunDetached( + [Path.Combine(installLocation, options.Command ?? LaunchCommand), .. options.Arguments], + onConsoleOutput, + OnExit + ); + } +} diff --git a/docs/advanced/hardware-support.md b/docs/advanced/hardware-support.md index ad74692cb..87b3621f3 100644 --- a/docs/advanced/hardware-support.md +++ b/docs/advanced/hardware-support.md @@ -36,7 +36,7 @@ The lists below describe what the code checks for. Because hardware detection wo - **Caveats:** - The `cu130` wheels require an NVIDIA driver of version 580 or newer. ComfyUI checks the installed driver on launch and warns if it is older than 580.x while `cu130` torch is installed, suggesting either a driver update or manually downgrading to an older torch index such as `cu128`. - Turing (RTX 2000-series) or newer is the practical recommendation; older cards may still work but are treated as legacy. -- **Packages:** CUDA is the most broadly supported backend. Every inference package that lists a GPU backend supports CUDA, and CUDA-only packages include Fooocus, SimpleSDXL, ForgeClassic, FramePack, and the training tools (Kohya's GUI, OneTrainer, FluxGym, AI Toolkit). +- **Packages:** CUDA is the most broadly supported backend. Every inference package that lists a GPU backend supports CUDA, and CUDA-only packages include Fooocus, SimpleSDXL, ForgeClassic, FramePack, and the training tools (Kohya's GUI, OneTrainer, FluxGym, AI Toolkit, Fizgig). ## AMD on Windows diff --git a/docs/package-manager/supported-packages.md b/docs/package-manager/supported-packages.md index 0a244d23b..540729246 100644 --- a/docs/package-manager/supported-packages.md +++ b/docs/package-manager/supported-packages.md @@ -40,8 +40,9 @@ Training packages are used to fine-tune or train AI models such as LoRAs, checkp |---|---| | **AI-Toolkit** | An all-in-one training suite for diffusion models supporting LoRA, full fine-tune, and more. | | **OneTrainer** | A comprehensive one-stop solution for Stable Diffusion model training with a graphical interface. | -| **kohya_ss** | A Windows-focused Gradio GUI wrapping Kohya's popular Stable Diffusion trainer scripts. Windows only.| +| **kohya_ss** | A Windows-focused Gradio GUI wrapping Kohya's popular Stable Diffusion trainer scripts. Windows only. | | **FluxGym** | A simple, low-VRAM Flux LoRA training UI designed for quick fine-tuning workflows. | +| **Fizgig** | A LoRA training studio for Flux 2 Klein 9B, Krea 2, MiniMax H3 and Qwen Image 2.1, with block profiling, repair and extraction tools. NVIDIA only. | --- From ed47e1f4f025900c252eaf54de29c977b8bd11a7 Mon Sep 17 00:00:00 2001 From: e-nord Date: Wed, 30 Sep 2026 23:00:54 -0700 Subject: [PATCH 2/3] fix(fizgig): install CUDA torch before requirements, disclose VS Build Tools Address review feedback on the Fizgig package: - Install torch 2.10.0 / torchvision 0.25.0 from cu128 via PrePipInstallArgs, so it lands before the requirements, and skip the standard torch step. accelerate (and others) depend on torch transitively; previously that pulled a PyPI torch build during the requirements step which the cu128 install then had to force-reinstall over. - Re-state the torch/torchvision pins alongside the requirements. The installed +cu128 build satisfies them, and a conflicting requirement fails loudly instead of swapping torch. - Add a Windows-only Disclaimer, shown in the install browser before installing, stating that VS Build Tools are installed system-wide and remain after Fizgig is uninstalled. The change is Fizgig-specific; shared install code is untouched. Co-Authored-By: Claude Opus 5.5 --- .../Models/Packages/Fizgig.cs | 31 ++++++++++++++++--- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/StabilityMatrix.Core/Models/Packages/Fizgig.cs b/StabilityMatrix.Core/Models/Packages/Fizgig.cs index 91cfcadc9..6163173c2 100644 --- a/StabilityMatrix.Core/Models/Packages/Fizgig.cs +++ b/StabilityMatrix.Core/Models/Packages/Fizgig.cs @@ -34,6 +34,13 @@ IPipWheelService pipWheelService public override string Blurb => "LoRA training studio for Flux 2 Klein 9B, Krea 2, MiniMax H3 and Qwen Image 2.1 — train, profile, repair and extract"; + // Shown in the install browser before the user commits to installing. + public override string Disclaimer => + Compat.IsWindows + ? "Visual Studio Build Tools for C++ Desktop Development will be installed system-wide if not already present (may require admin privileges). " + + "They are shared with other software and remain installed after Fizgig is uninstalled." + : string.Empty; + public override string LicenseType => "Apache-2.0"; public override string LicenseUrl => "https://github.com/shootthesound/Fizgig/blob/master/LICENSE"; @@ -120,19 +127,35 @@ public override async Task InstallPackage( // requirements.txt warns never to install that line without this. venvRunner.UpdateEnvironmentVariables(env => env.SetItem("DISABLE_CUDA", "1")); + const string torchVersion = "==2.10.0"; + const string torchvisionVersion = "==0.25.0"; + var config = new PipInstallConfig { RequirementsFilePaths = ["requirements.txt"], - // Drop the torch pins and the cu128 index line from the file so the torch install + // Drop the torch pins and the cu128 index line from the file so the pre-install step // below is the single source of truth for which build lands in the venv. The pattern // is anchored against the whole entry by the caller, so the version specifier has to // be matched too - the default pattern only catches bare, unpinned names. RequirementsExcludePattern = @"(--extra-index-url.*|(torch|torchvision|torchaudio|xformers)([=<>!~].*)?)", - TorchVersion = "==2.10.0", - TorchvisionVersion = "==0.25.0", + // Install the cu128 build before the requirements. accelerate (and friends) depend on + // torch transitively, so installing it afterwards would let the requirements step + // pull a default PyPI build that then has to be force-reinstalled over. // torch 2.10 pairs with cu128 here; SM's default cu130 has no matching wheels. - CudaIndex = "cu128", + PrePipInstallArgs = + [ + $"torch{torchVersion}", + $"torchvision{torchvisionVersion}", + "--extra-index-url", + "https://download.pytorch.org/whl/cu128", + "--force-reinstall", + ], + // Re-state the pins alongside the requirements: pip then treats the installed + // 2.10.0+cu128 as satisfying them instead of resolving its own torch from PyPI, and + // fails loudly rather than swapping it if anything conflicts. + ExtraPipArgs = [$"torch{torchVersion}", $"torchvision{torchvisionVersion}"], + SkipTorchInstall = true, }; await StandardPipInstallProcessAsync( From 128e8e95bc8e112b2c4034d7390d5e2e67702c15 Mon Sep 17 00:00:00 2001 From: e-nord Date: Fri, 2 Oct 2026 18:49:22 -0700 Subject: [PATCH 3/3] docs(fizgig): note Linux support for the NVIDIA/CUDA path Fizgig already works on Linux with NVIDIA GPUs; no code change is needed. The package is CUDA-only and gated on HasNvidiaGpu on every platform, and the CUDA install carries over unchanged: requirements.txt scopes triton-windows to win32, pytorch.org publishes Linux cu128 wheels for torch 2.10.0, insightface ships a pure-Python wheel, and the Unix prerequisite helper skips the Windows-only Tkinter / VS Build Tools prerequisites. The VS Build Tools disclaimer is already gated on Windows. Linux ROCm is left out. Upstream labels it highly experimental and installs it from AMD's TheRock wheels, which do not fit Stability Matrix's existing Linux ROCm path. Co-Authored-By: Claude Opus 5.5 --- docs/package-manager/supported-packages.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/package-manager/supported-packages.md b/docs/package-manager/supported-packages.md index 540729246..49d65167e 100644 --- a/docs/package-manager/supported-packages.md +++ b/docs/package-manager/supported-packages.md @@ -42,7 +42,7 @@ Training packages are used to fine-tune or train AI models such as LoRAs, checkp | **OneTrainer** | A comprehensive one-stop solution for Stable Diffusion model training with a graphical interface. | | **kohya_ss** | A Windows-focused Gradio GUI wrapping Kohya's popular Stable Diffusion trainer scripts. Windows only. | | **FluxGym** | A simple, low-VRAM Flux LoRA training UI designed for quick fine-tuning workflows. | -| **Fizgig** | A LoRA training studio for Flux 2 Klein 9B, Krea 2, MiniMax H3 and Qwen Image 2.1, with block profiling, repair and extraction tools. NVIDIA only. | +| **Fizgig** | A LoRA training studio for Flux 2 Klein 9B, Krea 2, MiniMax H3 and Qwen Image 2.1, with block profiling, repair and extraction tools. NVIDIA only, on Windows and Linux. | ---