diff --git a/CHANGELOG.md b/CHANGELOG.md index 44c7e891..ed41a71c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,12 @@ and this project adheres to [Semantic Versioning 2.0](https://semver.org/spec/v2 ## v2.8.0-dev.4 ### Added - Auto-update support for macOS +- New package installation flow +- Added `--use-directml` launch argument for SDWebUI DirectML fork +### Changed +- Changed default Period to "AllTime" in the Model Browser +### Fixed +- Fixed SDTurboScheduler's missing denoise parameter ## v2.8.0-dev.3 ### Added diff --git a/StabilityMatrix.Avalonia/ViewModels/CheckpointBrowser/CivitAiBrowserViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/CheckpointBrowser/CivitAiBrowserViewModel.cs index 2d9cef4b..2911dc6b 100644 --- a/StabilityMatrix.Avalonia/ViewModels/CheckpointBrowser/CivitAiBrowserViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/CheckpointBrowser/CivitAiBrowserViewModel.cs @@ -72,7 +72,7 @@ public partial class CivitAiBrowserViewModel : TabViewModelBase private bool showMainLoadingSpinner; [ObservableProperty] - private CivitPeriod selectedPeriod = CivitPeriod.Month; + private CivitPeriod selectedPeriod = CivitPeriod.AllTime; [ObservableProperty] private CivitSortMode sortMode = CivitSortMode.HighestRated; @@ -118,8 +118,10 @@ public partial class CivitAiBrowserViewModel : TabViewModelBase private List allModelCards = new(); - public IEnumerable AllCivitPeriods => Enum.GetValues(typeof(CivitPeriod)).Cast(); - public IEnumerable AllSortModes => Enum.GetValues(typeof(CivitSortMode)).Cast(); + public IEnumerable AllCivitPeriods => + Enum.GetValues(typeof(CivitPeriod)).Cast(); + public IEnumerable AllSortModes => + Enum.GetValues(typeof(CivitSortMode)).Cast(); public IEnumerable AllModelTypes => Enum.GetValues(typeof(CivitModelType)) @@ -128,7 +130,17 @@ public partial class CivitAiBrowserViewModel : TabViewModelBase .OrderBy(t => t.ToString()); public List BaseModelOptions => - ["All", "SD 1.5", "SD 1.5 LCM", "SD 2.1", "SDXL 0.9", "SDXL 1.0", "SDXL 1.0 LCM", "SDXL Turbo", "Other"]; + [ + "All", + "SD 1.5", + "SD 1.5 LCM", + "SD 2.1", + "SDXL 0.9", + "SDXL 1.0", + "SDXL 1.0 LCM", + "SDXL Turbo", + "Other" + ]; public CivitAiBrowserViewModel( ICivitApi civitApi, @@ -189,7 +201,11 @@ public partial class CivitAiBrowserViewModel : TabViewModelBase ShowNsfw = settingsManager.Settings.ModelBrowserNsfwEnabled; - settingsManager.RelayPropertyFor(this, model => model.ShowNsfw, settings => settings.ModelBrowserNsfwEnabled); + settingsManager.RelayPropertyFor( + this, + model => model.ShowNsfw, + settings => settings.ModelBrowserNsfwEnabled + ); } /// @@ -238,7 +254,10 @@ public partial class CivitAiBrowserViewModel : TabViewModelBase } // Filter out unknown model types and archived/taken-down models - models = models.Where(m => m.Type.ConvertTo() > 0).Where(m => m.Mode == null).ToList(); + models = models + .Where(m => m.Type.ConvertTo() > 0) + .Where(m => m.Mode == null) + .ToList(); // Database update calls will invoke `OnModelsUpdated` // Add to database @@ -451,8 +470,7 @@ public partial class CivitAiBrowserViewModel : TabViewModelBase try { cachedQuery = await liteDbContext - .CivitModelQueryCache - .IncludeAll() + .CivitModelQueryCache.IncludeAll() .FindByIdAsync(ObjectHash.GetMd5Guid(modelRequest)); } catch (Exception e) @@ -556,7 +574,12 @@ public partial class CivitAiBrowserViewModel : TabViewModelBase TrySearchAgain().SafeFireAndForget(); settingsManager.Transaction( s => - s.ModelSearchOptions = new ModelSearchOptions(value, SortMode, SelectedModelType, SelectedBaseModelType) + s.ModelSearchOptions = new ModelSearchOptions( + value, + SortMode, + SelectedModelType, + SelectedBaseModelType + ) ); } @@ -578,7 +601,13 @@ public partial class CivitAiBrowserViewModel : TabViewModelBase { TrySearchAgain().SafeFireAndForget(); settingsManager.Transaction( - s => s.ModelSearchOptions = new ModelSearchOptions(SelectedPeriod, SortMode, value, SelectedBaseModelType) + s => + s.ModelSearchOptions = new ModelSearchOptions( + SelectedPeriod, + SortMode, + value, + SelectedBaseModelType + ) ); } @@ -586,7 +615,13 @@ public partial class CivitAiBrowserViewModel : TabViewModelBase { TrySearchAgain().SafeFireAndForget(); settingsManager.Transaction( - s => s.ModelSearchOptions = new ModelSearchOptions(SelectedPeriod, SortMode, SelectedModelType, value) + s => + s.ModelSearchOptions = new ModelSearchOptions( + SelectedPeriod, + SortMode, + SelectedModelType, + value + ) ); } diff --git a/StabilityMatrix.Avalonia/ViewModels/Inference/InferenceTextToImageViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/Inference/InferenceTextToImageViewModel.cs index 1c0caa13..052986be 100644 --- a/StabilityMatrix.Avalonia/ViewModels/Inference/InferenceTextToImageViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/Inference/InferenceTextToImageViewModel.cs @@ -114,6 +114,14 @@ public class InferenceTextToImageViewModel : InferenceGenerationViewModelBase, I SamplerCardViewModel.IsRefinerStepsEnabled = e.Sender is { IsRefinerSelectionEnabled: true, SelectedRefiner: not null }; }); + + SamplerCardViewModel + .WhenPropertyChanged(x => x.SelectedScheduler) + .Subscribe(e => + { + e.Sender.IsDenoiseStrengthEnabled = + e.Sender.SelectedScheduler?.DisplayName.Equals("SD Turbo") ?? false; + }); } /// diff --git a/StabilityMatrix.Avalonia/ViewModels/Inference/SamplerCardViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/Inference/SamplerCardViewModel.cs index a129696f..96b9de36 100644 --- a/StabilityMatrix.Avalonia/ViewModels/Inference/SamplerCardViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/Inference/SamplerCardViewModel.cs @@ -88,7 +88,10 @@ public partial class SamplerCardViewModel : LoadableViewModelBase, IParametersLo private int TotalSteps => Steps + RefinerSteps; - public SamplerCardViewModel(IInferenceClientManager clientManager, ServiceManager vmFactory) + public SamplerCardViewModel( + IInferenceClientManager clientManager, + ServiceManager vmFactory + ) { ClientManager = clientManager; ModulesCardViewModel = vmFactory.Get(modulesCard => @@ -102,7 +105,10 @@ public partial class SamplerCardViewModel : LoadableViewModelBase, IParametersLo public void ApplyStep(ModuleApplyStepEventArgs e) { // Resample the current primary if size does not match the selected size - if (e.Builder.Connections.PrimarySize.Width != Width || e.Builder.Connections.PrimarySize.Height != Height) + if ( + e.Builder.Connections.PrimarySize.Width != Width + || e.Builder.Connections.PrimarySize.Height != Height + ) { e.Builder.Connections.Primary = e.Builder.Group_Upscale( e.Nodes.GetUniqueName("Sampler_ScalePrimary"), @@ -170,7 +176,8 @@ public partial class SamplerCardViewModel : LoadableViewModelBase, IParametersLo { Name = "SDTurboScheduler", Model = e.Builder.Connections.Base.Model.Unwrap(), - Steps = Steps + Steps = Steps, + Denoise = DenoiseStrength } ); @@ -297,7 +304,10 @@ public partial class SamplerCardViewModel : LoadableViewModelBase, IParametersLo if ( !string.IsNullOrEmpty(parameters.Sampler) - && GenerationParametersConverter.TryGetSamplerScheduler(parameters.Sampler, out var samplerScheduler) + && GenerationParametersConverter.TryGetSamplerScheduler( + parameters.Sampler, + out var samplerScheduler + ) ) { SelectedSampler = ClientManager.Samplers.FirstOrDefault(s => s == samplerScheduler.Sampler); diff --git a/StabilityMatrix.Core/Models/Api/Comfy/Nodes/ComfyNodeBuilder.cs b/StabilityMatrix.Core/Models/Api/Comfy/Nodes/ComfyNodeBuilder.cs index 45f847fb..874397ef 100644 --- a/StabilityMatrix.Core/Models/Api/Comfy/Nodes/ComfyNodeBuilder.cs +++ b/StabilityMatrix.Core/Models/Api/Comfy/Nodes/ComfyNodeBuilder.cs @@ -110,6 +110,9 @@ public class ComfyNodeBuilder [Range(1, 10)] public required int Steps { get; init; } + + [Range(0, 1.0)] + public required double Denoise { get; init; } } public record EmptyLatentImage : ComfyTypedNodeBase @@ -155,7 +158,11 @@ public class ComfyNodeBuilder return new NamedComfyNode(name) { ClassType = "ImageUpscaleWithModel", - Inputs = new Dictionary { ["upscale_model"] = upscaleModel.Data, ["image"] = image.Data } + Inputs = new Dictionary + { + ["upscale_model"] = upscaleModel.Data, + ["image"] = image.Data + } }; } @@ -286,7 +293,8 @@ public class ComfyNodeBuilder public required string ControlNetName { get; init; } } - public record ControlNetApplyAdvanced : ComfyTypedNodeBase + public record ControlNetApplyAdvanced + : ComfyTypedNodeBase { public required ConditioningNodeConnection Positive { get; init; } public required ConditioningNodeConnection Negative { get; init; } @@ -409,7 +417,9 @@ public class ComfyNodeBuilder .Output, image => Nodes - .AddNamedNode(ImageScale($"{name}_ImageUpscale", image, upscaleInfo.Name, height, width, false)) + .AddNamedNode( + ImageScale($"{name}_ImageUpscale", image, upscaleInfo.Name, height, width, false) + ) .Output ); } @@ -420,7 +430,11 @@ public class ComfyNodeBuilder var samplerImage = GetPrimaryAsImage(primary, vae); // Do group upscale - var modelUpscaler = Group_UpscaleWithModel($"{name}_ModelUpscale", upscaleInfo.Name, samplerImage); + var modelUpscaler = Group_UpscaleWithModel( + $"{name}_ModelUpscale", + upscaleInfo.Name, + samplerImage + ); // Since the model upscale is fixed to model (2x/4x), scale it again to the requested size var resizedScaled = Nodes.AddNamedNode( @@ -476,7 +490,11 @@ public class ComfyNodeBuilder ); // Do group upscale - var modelUpscaler = Group_UpscaleWithModel($"{name}_ModelUpscale", upscaleInfo.Name, samplerImage.Output); + var modelUpscaler = Group_UpscaleWithModel( + $"{name}_ModelUpscale", + upscaleInfo.Name, + samplerImage.Output + ); // Since the model upscale is fixed to model (2x/4x), scale it again to the requested size var resizedScaled = Nodes.AddNamedNode( @@ -550,7 +568,11 @@ public class ComfyNodeBuilder ); // Do group upscale - var modelUpscaler = Group_UpscaleWithModel($"{name}_ModelUpscale", upscaleInfo.Name, samplerImage.Output); + var modelUpscaler = Group_UpscaleWithModel( + $"{name}_ModelUpscale", + upscaleInfo.Name, + samplerImage.Output + ); // Since the model upscale is fixed to model (2x/4x), scale it again to the requested size var resizedScaled = Nodes.AddNamedNode( @@ -750,7 +772,10 @@ public class ComfyNodeBuilder return Connections.Primary.AsT1; } - return GetPrimaryAsImage(Connections.Primary ?? throw new NullReferenceException("No primary connection"), vae); + return GetPrimaryAsImage( + Connections.Primary ?? throw new NullReferenceException("No primary connection"), + vae + ); } /// @@ -771,7 +796,7 @@ public class ComfyNodeBuilder public ClipNodeConnection? BaseClip { get; set; } public ClipVisionNodeConnection? BaseClipVision { get; set; } - + public Dictionary Models { get; } = new() { ["Base"] = new ModelConnections("Base"), ["Refiner"] = new ModelConnections("Refiner") }; @@ -796,7 +821,9 @@ public class ComfyNodeBuilder public ModelNodeConnection GetRefinerOrBaseModel() { - return Refiner.Model ?? Base.Model ?? throw new NullReferenceException("No Refiner or Base Model"); + return Refiner.Model + ?? Base.Model + ?? throw new NullReferenceException("No Refiner or Base Model"); } public ConditioningConnections GetRefinerOrBaseConditioning() diff --git a/StabilityMatrix.Core/Models/Packages/StableDiffusionDirectMl.cs b/StabilityMatrix.Core/Models/Packages/StableDiffusionDirectMl.cs index 34321d04..b1687c33 100644 --- a/StabilityMatrix.Core/Models/Packages/StableDiffusionDirectMl.cs +++ b/StabilityMatrix.Core/Models/Packages/StableDiffusionDirectMl.cs @@ -1,10 +1,8 @@ -using System.Diagnostics.CodeAnalysis; -using System.Text.Json.Nodes; -using System.Text.RegularExpressions; -using NLog; +using NLog; using StabilityMatrix.Core.Attributes; using StabilityMatrix.Core.Helper; using StabilityMatrix.Core.Helper.Cache; +using StabilityMatrix.Core.Helper.HardwareInfo; using StabilityMatrix.Core.Models.FileInterfaces; using StabilityMatrix.Core.Models.Progress; using StabilityMatrix.Core.Processes; @@ -38,9 +36,31 @@ public class StableDiffusionDirectMl( public override PackageDifficulty InstallerSortOrder => PackageDifficulty.Recommended; + public override List LaunchOptions + { + get + { + var baseLaunchOptions = base.LaunchOptions; + baseLaunchOptions.Insert( + 0, + new LaunchOptionDefinition + { + Name = "Use DirectML", + Type = LaunchOptionType.Bool, + InitialValue = HardwareHelper.PreferDirectML(), + Options = ["--use-directml"] + } + ); + + return baseLaunchOptions; + } + } + public override IEnumerable AvailableTorchVersions => new[] { TorchVersion.Cpu, TorchVersion.DirectMl }; + public override TorchVersion GetRecommendedTorchVersion() => TorchVersion.DirectMl; + public override bool ShouldIgnoreReleases => true; public override async Task InstallPackage(