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..7e6483e14 --- /dev/null +++ b/StabilityMatrix.Core/Models/Packages/Fizgig.cs @@ -0,0 +1,214 @@ +using System.Text.RegularExpressions; +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 partial 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"; + + // 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"; + + // 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; + + /// + /// None only, like the other trainers. output_loras also receives sample images and multi-GB + /// resume-state folders, so linking it into the shared Lora folder would leak those into other + /// packages. Users who want trained LoRAs there can point Fizgig's Output Directory at it. + /// models/ can't be shared either: Fizgig flattens every weight it downloads into that one + /// directory, which doesn't map onto the per-type shared folders. + /// + public override SharedFolderMethod RecommendedSharedFolderMethod => SharedFolderMethod.None; + + public override IEnumerable AvailableSharedFolderMethods => [SharedFolderMethod.None]; + + 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")); + + // Mirrors upstream's uv_install_deps.py: torch goes in first from the CUDA index, then + // the rest of requirements.txt without that index. The torch pins stay in the second + // step so nothing can swap the CUDA build for a PyPI one. + var (extraIndexUrl, torchSpecs) = await ParseRequirementsAsync( + Path.Combine(installLocation, "requirements.txt"), + cancellationToken + ) + .ConfigureAwait(false); + + var config = new PipInstallConfig + { + RequirementsFilePaths = ["requirements.txt"], + RequirementsExcludePattern = "--extra-index-url.*", + PrePipInstallArgs = + extraIndexUrl is not null && torchSpecs.Count > 0 + ? [.. torchSpecs, "--extra-index-url", extraIndexUrl] + : [], + SkipTorchInstall = true, + }; + + await StandardPipInstallProcessAsync( + venvRunner, + options, + installedPackage, + config, + onConsoleOutput, + progress, + cancellationToken + ) + .ConfigureAwait(false); + } + + private static readonly string[] TorchEcosystem = ["torch", "torchvision", "torchaudio"]; + + /// + /// Port of _parse_requirements in upstream's uv_install_deps.py: returns the single + /// --extra-index-url and the torch-ecosystem requirement lines. + /// + private static async Task<(string? ExtraIndexUrl, List TorchSpecs)> ParseRequirementsAsync( + string requirementsPath, + CancellationToken cancellationToken + ) + { + string? extraIndexUrl = null; + var torchSpecs = new List(); + + var lines = await File.ReadAllLinesAsync(requirementsPath, cancellationToken).ConfigureAwait(false); + foreach (var raw in lines) + { + var code = raw.Split('#', 2)[0].Trim(); + if (code.StartsWith("--extra-index-url", StringComparison.Ordinal)) + { + if (extraIndexUrl is not null) + { + throw new InvalidOperationException( + "Fizgig's requirements.txt declares more than one --extra-index-url" + ); + } + + var parts = code.Split((char[]?)null, 2, StringSplitOptions.RemoveEmptyEntries); + if (parts.Length == 2) + { + extraIndexUrl = parts[1]; + } + continue; + } + + if (code.Length > 0) + { + var pkg = RequirementNameEndRegex().Split(code, 2)[0]; + if (TorchEcosystem.Contains(pkg)) + { + torchSpecs.Add(code); + } + } + } + + return (extraIndexUrl, torchSpecs); + } + + [GeneratedRegex(@"[=<>!~\s\[;]")] + private static partial Regex RequirementNameEndRegex(); + + 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..49d65167e 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, on Windows and Linux. | ---