Skip to content

Commit

Permalink
Merge pull request LykosAI#513 from ionite34/forge
Browse files Browse the repository at this point in the history
Added SDWebUi Forge by lllyasviel
  • Loading branch information
mohnjiles authored Feb 10, 2024
2 parents a423483 + f2f8e67 commit 89f0545
Show file tree
Hide file tree
Showing 5 changed files with 257 additions and 24 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ All notable changes to Stability Matrix will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning 2.0](https://semver.org/spec/v2.0.0.html).

## v2.9.0-dev.1
### Added
- Added new package: [StableSwarmUI](https://github.com/Stability-AI/StableSwarmUI) by Stability AI
- Added new package: [Stable Diffusion WebUI Forge](https://github.com/lllyasviel/stable-diffusion-webui-forge) by lllyasviel
- Added extension management for SD.Next and Stable Diffusion WebUI-UX

## v2.8.2
### Added
- Added missing GFPGAN link to Automatic1111 packages
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace StabilityMatrix.Core.Models.Packages.Extensions;

public class VladExtensionItem
{
public required string Name { get; set; }
public required Uri Url { get; set; }
public string? Long { get; set; }
public string? Description { get; set; }
}
129 changes: 129 additions & 0 deletions StabilityMatrix.Core/Models/Packages/SDWebForge.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
using System.Text.Json.Nodes;
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.Packages.Extensions;
using StabilityMatrix.Core.Models.Progress;
using StabilityMatrix.Core.Processes;
using StabilityMatrix.Core.Python;
using StabilityMatrix.Core.Services;

namespace StabilityMatrix.Core.Models.Packages;

[Singleton(typeof(BasePackage))]
public class SDWebForge(
IGithubApiCache githubApi,
ISettingsManager settingsManager,
IDownloadService downloadService,
IPrerequisiteHelper prerequisiteHelper
) : A3WebUI(githubApi, settingsManager, downloadService, prerequisiteHelper)
{
public override string Name => "stable-diffusion-webui-forge";
public override string DisplayName { get; set; } = "Stable Diffusion WebUI Forge";
public override string Author => "lllyasviel";

public override string Blurb =>
"Stable Diffusion WebUI Forge is a platform on top of Stable Diffusion WebUI (based on Gradio) to make development easier, optimize resource management, and speed up inference.";

public override string LicenseUrl =>
"https://github.com/lllyasviel/stable-diffusion-webui-forge/blob/main/LICENSE.txt";

public override Uri PreviewImageUri =>
new(
"https://github.com/lllyasviel/stable-diffusion-webui-forge/assets/19834515/ca5e05ed-bd86-4ced-8662-f41034648e8c"
);

public override string MainBranch => "main";
public override bool ShouldIgnoreReleases => true;
public override IPackageExtensionManager ExtensionManager => null;

public override List<LaunchOptionDefinition> LaunchOptions =>
[
new LaunchOptionDefinition
{
Name = "Always Offload from VRAM",
Type = LaunchOptionType.Bool,
Options = ["--always-offload-from-vram"]
},
new LaunchOptionDefinition
{
Name = "Always GPU",
Type = LaunchOptionType.Bool,
Options = ["--always-gpu"]
},
new LaunchOptionDefinition
{
Name = "Always CPU",
Type = LaunchOptionType.Bool,
Options = ["--always-cpu"]
},
new LaunchOptionDefinition
{
Name = "Use DirectML",
Type = LaunchOptionType.Bool,
InitialValue = HardwareHelper.PreferDirectML(),
Options = ["--directml"]
},
LaunchOptionDefinition.Extras
];

public override IEnumerable<TorchVersion> AvailableTorchVersions =>
new[]
{
TorchVersion.Cpu,
TorchVersion.Cuda,
TorchVersion.DirectMl,
TorchVersion.Rocm,
TorchVersion.Mps
};

public override async Task InstallPackage(
string installLocation,
TorchVersion torchVersion,
SharedFolderMethod selectedSharedFolderMethod,
DownloadPackageVersionOptions versionOptions,
IProgress<ProgressReport>? progress = null,
Action<ProcessOutput>? onConsoleOutput = null
)
{
progress?.Report(new ProgressReport(-1f, "Setting up venv", isIndeterminate: true));

var venvRunner = await SetupVenv(installLocation, forceRecreate: true).ConfigureAwait(false);
await venvRunner.PipInstall("--upgrade pip wheel", onConsoleOutput).ConfigureAwait(false);

progress?.Report(new ProgressReport(-1f, "Installing requirements...", isIndeterminate: true));

var requirements = new FilePath(installLocation, "requirements_versions.txt");
var pipArgs = new PipInstallArgs();
if (torchVersion is TorchVersion.DirectMl)
{
pipArgs = pipArgs.WithTorchDirectML();
}
else
{
pipArgs = pipArgs
.WithTorch("==2.1.2")
.WithTorchVision("==0.16.2")
.WithTorchExtraIndex(
torchVersion switch
{
TorchVersion.Cpu => "cpu",
TorchVersion.Cuda => "cu121",
TorchVersion.Rocm => "rocm5.6",
TorchVersion.Mps => "nightly/cpu",
_ => throw new ArgumentOutOfRangeException(nameof(torchVersion), torchVersion, null)
}
);
}

pipArgs = pipArgs.WithParsedFromRequirementsTxt(
await requirements.ReadAllTextAsync().ConfigureAwait(false),
excludePattern: "torch"
);

await venvRunner.PipInstall(pipArgs, onConsoleOutput).ConfigureAwait(false);
progress?.Report(new ProgressReport(1f, "Install complete", isIndeterminate: false));
}
}
47 changes: 46 additions & 1 deletion StabilityMatrix.Core/Models/Packages/StableDiffusionUx.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
using System.Diagnostics.CodeAnalysis;
using System.Text.Json.Nodes;
using System.Text.Json;
using System.Text.RegularExpressions;
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.Packages.Extensions;
using StabilityMatrix.Core.Models.Progress;
using StabilityMatrix.Core.Processes;
using StabilityMatrix.Core.Python;
Expand Down Expand Up @@ -41,6 +42,8 @@ IPrerequisiteHelper prerequisiteHelper

public override PackageDifficulty InstallerSortOrder => PackageDifficulty.Advanced;

public override IPackageExtensionManager? ExtensionManager => new A3WebUiExtensionManager(this);

public override Dictionary<SharedFolderType, IReadOnlyList<string>> SharedFolders =>
new()
{
Expand Down Expand Up @@ -272,4 +275,46 @@ await venvRunner
)
.ConfigureAwait(false);
}

private class A3WebUiExtensionManager(StableDiffusionUx package)
: GitPackageExtensionManager(package.PrerequisiteHelper)
{
public override string RelativeInstallDirectory => "extensions";

public override IEnumerable<ExtensionManifest> DefaultManifests =>
[
new ExtensionManifest(
new Uri(
"https://raw.githubusercontent.com/AUTOMATIC1111/stable-diffusion-webui-extensions/master/index.json"
)
)
];

public override async Task<IEnumerable<PackageExtension>> GetManifestExtensionsAsync(
ExtensionManifest manifest,
CancellationToken cancellationToken = default
)
{
try
{
// Get json
var content = await package
.DownloadService.GetContentAsync(manifest.Uri.ToString(), cancellationToken)
.ConfigureAwait(false);

// Parse json
var jsonManifest = JsonSerializer.Deserialize<A1111ExtensionManifest>(
content,
A1111ExtensionManifestSerializerContext.Default.Options
);

return jsonManifest?.GetPackageExtensions() ?? Enumerable.Empty<PackageExtension>();
}
catch (Exception e)
{
Logger.Error(e, "Failed to get extensions from manifest");
return Enumerable.Empty<PackageExtension>();
}
}
}
}
90 changes: 67 additions & 23 deletions StabilityMatrix.Core/Models/Packages/VladAutomatic.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using StabilityMatrix.Core.Helper.Cache;
using StabilityMatrix.Core.Helper.HardwareInfo;
using StabilityMatrix.Core.Models.FileInterfaces;
using StabilityMatrix.Core.Models.Packages.Extensions;
using StabilityMatrix.Core.Models.Progress;
using StabilityMatrix.Core.Processes;
using StabilityMatrix.Core.Python;
Expand Down Expand Up @@ -79,6 +80,7 @@ IPrerequisiteHelper prerequisiteHelper
};

public override string OutputFolderName => "outputs";
public override IPackageExtensionManager ExtensionManager => new VladExtensionManager(this);

[SuppressMessage("ReSharper", "ArrangeObjectCreationWhenTypeNotEvident")]
public override List<LaunchOptionDefinition> LaunchOptions =>
Expand Down Expand Up @@ -231,33 +233,28 @@ public override async Task DownloadPackage(
var installDir = new DirectoryPath(installLocation);
installDir.Create();

if (!string.IsNullOrWhiteSpace(downloadOptions.CommitHash))
if (string.IsNullOrWhiteSpace(downloadOptions.BranchName))
{
await PrerequisiteHelper
.RunGit(
new[] { "clone", "https://github.com/vladmandic/automatic", installDir.Name },
installDir.Parent?.FullPath ?? ""
)
.ConfigureAwait(false);

await PrerequisiteHelper
.RunGit(new[] { "checkout", downloadOptions.CommitHash }, installLocation)
.ConfigureAwait(false);
throw new ArgumentNullException(nameof(downloadOptions));
}
else if (!string.IsNullOrWhiteSpace(downloadOptions.BranchName))

await PrerequisiteHelper
.RunGit(
new[]
{
"clone",
"-b",
downloadOptions.BranchName,
"https://github.com/vladmandic/automatic",
installDir.Name
},
installDir.Parent?.FullPath ?? ""
)
.ConfigureAwait(false);
if (!string.IsNullOrWhiteSpace(downloadOptions.CommitHash) && !downloadOptions.IsLatest)
{
await PrerequisiteHelper
.RunGit(
new[]
{
"clone",
"-b",
downloadOptions.BranchName,
"https://github.com/vladmandic/automatic",
installDir.Name
},
installDir.Parent?.FullPath ?? ""
)
.RunGit(new[] { "checkout", downloadOptions.CommitHash }, installLocation)
.ConfigureAwait(false);
}
}
Expand Down Expand Up @@ -496,4 +493,51 @@ private Task RemoveConfigSettings(string installDirectory)

return Task.CompletedTask;
}

private class VladExtensionManager(VladAutomatic package)
: GitPackageExtensionManager(package.PrerequisiteHelper)
{
public override string RelativeInstallDirectory => "extensions";

public override IEnumerable<ExtensionManifest> DefaultManifests =>
[new ExtensionManifest(new Uri("https://vladmandic.github.io/sd-data/pages/extensions.json"))];

public override async Task<IEnumerable<PackageExtension>> GetManifestExtensionsAsync(
ExtensionManifest manifest,
CancellationToken cancellationToken = default
)
{
try
{
// Get json
var content = await package
.DownloadService.GetContentAsync(manifest.Uri.ToString(), cancellationToken)
.ConfigureAwait(false);

// Parse json
var jsonManifest = JsonSerializer.Deserialize<IEnumerable<VladExtensionItem>>(
content,
new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }
);

return jsonManifest?.Select(
entry =>
new PackageExtension
{
Title = entry.Name,
Author = entry.Long?.Split('/').FirstOrDefault() ?? "Unknown",
Reference = entry.Url,
Files = [entry.Url],
Description = entry.Description,
InstallType = "git-clone"
}
) ?? Enumerable.Empty<PackageExtension>();
}
catch (Exception e)
{
Logger.Error(e, "Failed to get extensions from manifest");
return Enumerable.Empty<PackageExtension>();
}
}
}
}

0 comments on commit 89f0545

Please sign in to comment.