@ -17,12 +17,12 @@ namespace StabilityMatrix.Core.Models.Packages;
public class VladAutomatic : BaseGitPackage
{
private static readonly Logger Logger = LogManager . GetCurrentClassLogger ( ) ;
public override string Name = > "automatic" ;
public override string DisplayName { get ; set ; } = "SD.Next Web UI" ;
public override string Author = > "vladmandic" ;
public override string LicenseType = > "AGPL-3.0" ;
public override string LicenseUrl = >
public override string LicenseUrl = >
"https://github.com/vladmandic/automatic/blob/master/LICENSE.txt" ;
public override string Blurb = > "Stable Diffusion implementation with advanced features" ;
public override string LaunchCommand = > "launch.py" ;
@ -30,129 +30,133 @@ public class VladAutomatic : BaseGitPackage
public override Uri PreviewImageUri = >
new ( "https://github.com/vladmandic/automatic/raw/master/html/black-orange.jpg" ) ;
public override bool ShouldIgnoreReleases = > true ;
public override SharedFolderMethod RecommendedSharedFolderMethod = >
SharedFolderMethod . Symlink ;
public override IEnumerable < TorchVersion > AvailableTorchVersions = > new [ ]
{
TorchVersion . Cpu ,
TorchVersion . Rocm ,
TorchVersion . DirectMl ,
TorchVersion . Cuda
} ;
public VladAutomatic ( IGithubApiCache githubApi , ISettingsManager settingsManager , IDownloadService downloadService ,
IPrerequisiteHelper prerequisiteHelper ) :
base ( githubApi , settingsManager , downloadService , prerequisiteHelper )
{
}
public override SharedFolderMethod RecommendedSharedFolderMethod = > SharedFolderMethod . Symlink ;
// https://github.com/vladmandic/automatic/blob/master/modules/shared.py#L324
public override Dictionary < SharedFolderType , IReadOnlyList < string > > SharedFolders = > new ( )
{
[SharedFolderType.StableDiffusion] = new [ ] { "models/Stable-diffusion" } ,
[SharedFolderType.Diffusers] = new [ ] { "models/Diffusers" } ,
[SharedFolderType.VAE] = new [ ] { "models/VAE" } ,
[SharedFolderType.TextualInversion] = new [ ] { "models/embeddings" } ,
[SharedFolderType.Hypernetwork] = new [ ] { "models/hypernetworks" } ,
[SharedFolderType.Codeformer] = new [ ] { "models/Codeformer" } ,
[SharedFolderType.GFPGAN] = new [ ] { "models/GFPGAN" } ,
[SharedFolderType.BSRGAN] = new [ ] { "models/BSRGAN" } ,
[SharedFolderType.ESRGAN] = new [ ] { "models/ESRGAN" } ,
[SharedFolderType.RealESRGAN] = new [ ] { "models/RealESRGAN" } ,
[SharedFolderType.ScuNET] = new [ ] { "models/ScuNET" } ,
[SharedFolderType.SwinIR] = new [ ] { "models/SwinIR" } ,
[SharedFolderType.LDSR] = new [ ] { "models/LDSR" } ,
[SharedFolderType.CLIP] = new [ ] { "models/CLIP" } ,
[SharedFolderType.Lora] = new [ ] { "models/Lora" } ,
[SharedFolderType.LyCORIS] = new [ ] { "models/LyCORIS" } ,
[SharedFolderType.ControlNet] = new [ ] { "models/ControlNet" }
} ;
public override IEnumerable < TorchVersion > AvailableTorchVersions = >
new [ ] { TorchVersion . Cpu , TorchVersion . Rocm , TorchVersion . DirectMl , TorchVersion . Cuda } ;
[SuppressMessage("ReSharper", "ArrangeObjectCreationWhenTypeNotEvident")]
public override List < LaunchOptionDefinition > LaunchOptions = > new ( )
{
new ( )
{
Name = "Host" ,
Type = LaunchOptionType . String ,
DefaultValue = "localhost" ,
Options = new ( ) { "--server-name" }
} ,
public VladAutomatic (
IGithubApiCache githubApi ,
ISettingsManager settingsManager ,
IDownloadService downloadService ,
IPrerequisiteHelper prerequisiteHelper
)
: base ( githubApi , settingsManager , downloadService , prerequisiteHelper ) { }
// https://github.com/vladmandic/automatic/blob/master/modules/shared.py#L324
public override Dictionary < SharedFolderType , IReadOnlyList < string > > SharedFolders = >
new ( )
{
Name = "Port" ,
Type = LaunchOptionType . String ,
DefaultValue = "7860" ,
Options = new ( ) { "--port" }
} ,
[SharedFolderType.StableDiffusion] = new [ ] { "models/Stable-diffusion" } ,
[SharedFolderType.Diffusers] = new [ ] { "models/Diffusers" } ,
[SharedFolderType.VAE] = new [ ] { "models/VAE" } ,
[SharedFolderType.TextualInversion] = new [ ] { "models/embeddings" } ,
[SharedFolderType.Hypernetwork] = new [ ] { "models/hypernetworks" } ,
[SharedFolderType.Codeformer] = new [ ] { "models/Codeformer" } ,
[SharedFolderType.GFPGAN] = new [ ] { "models/GFPGAN" } ,
[SharedFolderType.BSRGAN] = new [ ] { "models/BSRGAN" } ,
[SharedFolderType.ESRGAN] = new [ ] { "models/ESRGAN" } ,
[SharedFolderType.RealESRGAN] = new [ ] { "models/RealESRGAN" } ,
[SharedFolderType.ScuNET] = new [ ] { "models/ScuNET" } ,
[SharedFolderType.SwinIR] = new [ ] { "models/SwinIR" } ,
[SharedFolderType.LDSR] = new [ ] { "models/LDSR" } ,
[SharedFolderType.CLIP] = new [ ] { "models/CLIP" } ,
[SharedFolderType.Lora] = new [ ] { "models/Lora" } ,
[SharedFolderType.LyCORIS] = new [ ] { "models/LyCORIS" } ,
[SharedFolderType.ControlNet] = new [ ] { "models/ControlNet" }
} ;
[SuppressMessage("ReSharper", "ArrangeObjectCreationWhenTypeNotEvident")]
public override List < LaunchOptionDefinition > LaunchOptions = >
new ( )
{
Name = "VRAM" ,
Type = LaunchOptionType . Bool ,
InitialValue = HardwareHelper . IterGpuInfo ( ) . Select ( gpu = > gpu . MemoryLevel ) . Max ( ) switch
new ( )
{
Level . Low = > "--lowvram" ,
Level . Medium = > "--medvram" ,
_ = > null
Name = "Host" ,
Type = LaunchOptionType . String ,
DefaultValue = "localhost" ,
Options = new ( ) { "--server-name" }
} ,
Options = new ( ) { "--lowvram" , "--medvram" }
} ,
new ( )
{
Name = "Force use of Intel OneAPI XPU backend" ,
Type = LaunchOptionType . Bool ,
Options = new ( ) { "--use-ipex" }
} ,
new ( )
{
Name = "Use DirectML if no compatible GPU is detected" ,
Type = LaunchOptionType . Bool ,
InitialValue = HardwareHelper . PreferDirectML ( ) ,
Options = new ( ) { "--use-directml" }
} ,
new ( )
{
Name = "Force use of Nvidia CUDA backend" ,
Type = LaunchOptionType . Bool ,
InitialValue = HardwareHelper . HasNvidiaGpu ( ) ,
Options = new ( ) { "--use-cuda" }
} ,
new ( )
{
Name = "Force use of AMD ROCm backend" ,
Type = LaunchOptionType . Bool ,
InitialValue = HardwareHelper . PreferRocm ( ) ,
Options = new ( ) { "--use-rocm" }
} ,
new ( )
{
Name = "CUDA Device ID" ,
Type = LaunchOptionType . String ,
Options = new ( ) { "--device-id" }
} ,
new ( )
{
Name = "API" ,
Type = LaunchOptionType . Bool ,
Options = new ( ) { "--api" }
} ,
new ( )
{
Name = "Debug Logging" ,
Type = LaunchOptionType . Bool ,
Options = new ( ) { "--debug" }
} ,
LaunchOptionDefinition . Extras
} ;
new ( )
{
Name = "Port" ,
Type = LaunchOptionType . String ,
DefaultValue = "7860" ,
Options = new ( ) { "--port" }
} ,
new ( )
{
Name = "VRAM" ,
Type = LaunchOptionType . Bool ,
InitialValue = HardwareHelper
. IterGpuInfo ( )
. Select ( gpu = > gpu . MemoryLevel )
. Max ( ) switch
{
Level . Low = > "--lowvram" ,
Level . Medium = > "--medvram" ,
_ = > null
} ,
Options = new ( ) { "--lowvram" , "--medvram" }
} ,
new ( )
{
Name = "Force use of Intel OneAPI XPU backend" ,
Type = LaunchOptionType . Bool ,
Options = new ( ) { "--use-ipex" }
} ,
new ( )
{
Name = "Use DirectML if no compatible GPU is detected" ,
Type = LaunchOptionType . Bool ,
InitialValue = HardwareHelper . PreferDirectML ( ) ,
Options = new ( ) { "--use-directml" }
} ,
new ( )
{
Name = "Force use of Nvidia CUDA backend" ,
Type = LaunchOptionType . Bool ,
InitialValue = HardwareHelper . HasNvidiaGpu ( ) ,
Options = new ( ) { "--use-cuda" }
} ,
new ( )
{
Name = "Force use of AMD ROCm backend" ,
Type = LaunchOptionType . Bool ,
InitialValue = HardwareHelper . PreferRocm ( ) ,
Options = new ( ) { "--use-rocm" }
} ,
new ( )
{
Name = "CUDA Device ID" ,
Type = LaunchOptionType . String ,
Options = new ( ) { "--device-id" }
} ,
new ( )
{
Name = "API" ,
Type = LaunchOptionType . Bool ,
Options = new ( ) { "--api" }
} ,
new ( )
{
Name = "Debug Logging" ,
Type = LaunchOptionType . Bool ,
Options = new ( ) { "--debug" }
} ,
LaunchOptionDefinition . Extras
} ;
public override string ExtraLaunchArguments = > "" ;
public override Task < string > GetLatestVersion ( ) = > Task . FromResult ( "master" ) ;
public override async Task InstallPackage ( string installLocation , TorchVersion torchVersion ,
IProgress < ProgressReport > ? progress = null )
public override async Task InstallPackage (
string installLocation ,
TorchVersion torchVersion ,
IProgress < ProgressReport > ? progress = null
)
{
progress ? . Report ( new ProgressReport ( - 1f , "Installing package..." , isIndeterminate : true ) ) ;
// Setup venv
@ -166,11 +170,13 @@ public class VladAutomatic : BaseGitPackage
{
// Run initial install
case TorchVersion . Cuda :
await venvRunner . CustomInstall ( "launch.py --use-cuda --debug --test" , OnConsoleOutput )
await venvRunner
. CustomInstall ( "launch.py --use-cuda --debug --test" , OnConsoleOutput )
. ConfigureAwait ( false ) ;
break ;
case TorchVersion . Rocm :
await venvRunner . CustomInstall ( "launch.py --use-rocm --debug --test" , OnConsoleOutput )
await venvRunner
. CustomInstall ( "launch.py --use-rocm --debug --test" , OnConsoleOutput )
. ConfigureAwait ( false ) ;
break ;
case TorchVersion . DirectMl :
@ -180,7 +186,8 @@ public class VladAutomatic : BaseGitPackage
break ;
default :
// CPU
await venvRunner . CustomInstall ( "launch.py --debug --test" , OnConsoleOutput )
await venvRunner
. CustomInstall ( "launch.py --debug --test" , OnConsoleOutput )
. ConfigureAwait ( false ) ;
break ;
}
@ -188,11 +195,20 @@ public class VladAutomatic : BaseGitPackage
progress ? . Report ( new ProgressReport ( 1f , isIndeterminate : false ) ) ;
}
public override async Task DownloadPackage ( string installLocation ,
DownloadPackageVersionOptions downloadOptions , IProgress < ProgressReport > ? progress = null )
public override async Task DownloadPackage (
string installLocation ,
DownloadPackageVersionOptions downloadOptions ,
IProgress < ProgressReport > ? progress = null
)
{
progress ? . Report ( new ProgressReport ( - 1f , message : "Downloading package..." ,
isIndeterminate : true , type : ProgressType . Download ) ) ;
progress ? . Report (
new ProgressReport (
- 1f ,
message : "Downloading package..." ,
isIndeterminate : true ,
type : ProgressType . Download
)
) ;
var installDir = new DirectoryPath ( installLocation ) ;
installDir . Create ( ) ;
@ -200,22 +216,38 @@ public class VladAutomatic : BaseGitPackage
if ( ! string . IsNullOrWhiteSpace ( downloadOptions . CommitHash ) )
{
await PrerequisiteHelper
. RunGit ( installDir . Parent ? ? "" , "clone" , "https://github.com/vladmandic/automatic" ,
installDir . Name ) . ConfigureAwait ( false ) ;
. RunGit (
installDir . Parent ? ? "" ,
"clone" ,
"https://github.com/vladmandic/automatic" ,
installDir . Name
)
. ConfigureAwait ( false ) ;
await PrerequisiteHelper . RunGit ( installLocation , "checkout" , downloadOptions . CommitHash )
await PrerequisiteHelper
. RunGit ( installLocation , "checkout" , downloadOptions . CommitHash )
. ConfigureAwait ( false ) ;
}
else if ( ! string . IsNullOrWhiteSpace ( downloadOptions . BranchName ) )
{
await PrerequisiteHelper
. RunGit ( installDir . Parent ? ? "" , "clone" , "-b" , downloadOptions . BranchName ,
"https://github.com/vladmandic/automatic" , installDir . Name )
. RunGit (
installDir . Parent ? ? "" ,
"clone" ,
"-b" ,
downloadOptions . BranchName ,
"https://github.com/vladmandic/automatic" ,
installDir . Name
)
. ConfigureAwait ( false ) ;
}
}
public override async Task RunPackage ( string installedPackagePath , string command , string arguments )
public override async Task RunPackage (
string installedPackagePath ,
string command ,
string arguments
)
{
await SetupVenv ( installedPackagePath ) . ConfigureAwait ( false ) ;
@ -245,35 +277,44 @@ public class VladAutomatic : BaseGitPackage
VenvRunner . RunDetached ( args . TrimEnd ( ) , HandleConsoleOutput , HandleExit ) ;
}
public override async Task < InstalledPackageVersion > Update ( InstalledPackage installedPackage ,
TorchVersion torchVersion , IProgress < ProgressReport > ? progress = null ,
bool includePrerelease = false )
public override async Task < InstalledPackageVersion > Update (
InstalledPackage installedPackage ,
TorchVersion torchVersion ,
IProgress < ProgressReport > ? progress = null ,
bool includePrerelease = false
)
{
if ( installedPackage . Version is null )
{
throw new Exception ( "Version is null" ) ;
}
progress ? . Report ( new ProgressReport ( - 1f , message : "Downloading package update..." ,
isIndeterminate : true , type : ProgressType . Update ) ) ;
await PrerequisiteHelper . RunGit ( installedPackage . FullPath , "checkout" ,
installedPackage . Version . InstalledBranch ) . ConfigureAwait ( false ) ;
progress ? . Report (
new ProgressReport (
- 1f ,
message : "Downloading package update..." ,
isIndeterminate : true ,
type : ProgressType . Update
)
) ;
await PrerequisiteHelper
. RunGit ( installedPackage . FullPath , "checkout" , installedPackage . Version . InstalledBranch )
. ConfigureAwait ( false ) ;
var venvRunner = new PyVenvRunner ( Path . Combine ( installedPackage . FullPath ! , "venv" ) ) ;
venvRunner . WorkingDirectory = installedPackage . FullPath ! ;
venvRunner . EnvironmentVariables = SettingsManager . Settings . EnvironmentVariables ;
await venvRunner . CustomInstall ( "launch.py --upgrade --test" , OnConsoleOutput )
await venvRunner
. CustomInstall ( "launch.py --upgrade --test" , OnConsoleOutput )
. ConfigureAwait ( false ) ;
try
{
var output =
await PrerequisiteHelper
. GetGitOutput ( installedPackage . FullPath , "rev-parse" , "HEAD" )
. ConfigureAwait ( false ) ;
var output = await PrerequisiteHelper
. GetGitOutput ( installedPackage . FullPath , "rev-parse" , "HEAD" )
. ConfigureAwait ( false ) ;
return new InstalledPackageVersion
{
@ -287,9 +328,14 @@ public class VladAutomatic : BaseGitPackage
}
finally
{
progress ? . Report ( new ProgressReport ( 1f , message : "Update Complete" ,
isIndeterminate : false ,
type : ProgressType . Update ) ) ;
progress ? . Report (
new ProgressReport (
1f ,
message : "Update Complete" ,
isIndeterminate : false ,
type : ProgressType . Update
)
) ;
}
return new InstalledPackageVersion
@ -298,7 +344,10 @@ public class VladAutomatic : BaseGitPackage
} ;
}
public override Task SetupModelFolders ( DirectoryPath installDirectory , SharedFolderMethod sharedFolderMethod )
public override Task SetupModelFolders (
DirectoryPath installDirectory ,
SharedFolderMethod sharedFolderMethod
)
{
switch ( sharedFolderMethod )
{
@ -335,38 +384,56 @@ public class VladAutomatic : BaseGitPackage
configRoot [ "vae_dir" ] = Path . Combine ( SettingsManager . ModelsDirectory , "VAE" ) ;
configRoot [ "lora_dir" ] = Path . Combine ( SettingsManager . ModelsDirectory , "Lora" ) ;
configRoot [ "lyco_dir" ] = Path . Combine ( SettingsManager . ModelsDirectory , "LyCORIS" ) ;
configRoot [ "embeddings_dir" ] = Path . Combine ( SettingsManager . ModelsDirectory , "TextualInversion" ) ;
configRoot [ "hypernetwork_dir" ] = Path . Combine ( SettingsManager . ModelsDirectory , "Hypernetwork" ) ;
configRoot [ "codeformer_models_path" ] = Path . Combine ( SettingsManager . ModelsDirectory , "Codeformer" ) ;
configRoot [ "embeddings_dir" ] = Path . Combine (
SettingsManager . ModelsDirectory ,
"TextualInversion"
) ;
configRoot [ "hypernetwork_dir" ] = Path . Combine (
SettingsManager . ModelsDirectory ,
"Hypernetwork"
) ;
configRoot [ "codeformer_models_path" ] = Path . Combine (
SettingsManager . ModelsDirectory ,
"Codeformer"
) ;
configRoot [ "gfpgan_models_path" ] = Path . Combine ( SettingsManager . ModelsDirectory , "GFPGAN" ) ;
configRoot [ "bsrgan_models_path" ] = Path . Combine ( SettingsManager . ModelsDirectory , "BSRGAN" ) ;
configRoot [ "esrgan_models_path" ] = Path . Combine ( SettingsManager . ModelsDirectory , "ESRGAN" ) ;
configRoot [ "realesrgan_models_path" ] = Path . Combine ( SettingsManager . ModelsDirectory , "RealESRGAN" ) ;
configRoot [ "realesrgan_models_path" ] = Path . Combine (
SettingsManager . ModelsDirectory ,
"RealESRGAN"
) ;
configRoot [ "scunet_models_path" ] = Path . Combine ( SettingsManager . ModelsDirectory , "ScuNET" ) ;
configRoot [ "swinir_models_path" ] = Path . Combine ( SettingsManager . ModelsDirectory , "SwinIR" ) ;
configRoot [ "ldsr_models_path" ] = Path . Combine ( SettingsManager . ModelsDirectory , "LDSR" ) ;
configRoot [ "clip_models_path" ] = Path . Combine ( SettingsManager . ModelsDirectory , "CLIP" ) ;
configRoot [ "control_net_models_path" ] = Path . Combine ( SettingsManager . ModelsDirectory , "ControlNet" ) ;
var configJsonStr = JsonSerializer . Serialize ( configRoot , new JsonSerializerOptions
{
WriteIndented = true
} ) ;
configRoot [ "control_net_models_path" ] = Path . Combine (
SettingsManager . ModelsDirectory ,
"ControlNet"
) ;
var configJsonStr = JsonSerializer . Serialize (
configRoot ,
new JsonSerializerOptions { WriteIndented = true }
) ;
File . WriteAllText ( configJsonPath , configJsonStr ) ;
return Task . CompletedTask ;
}
public override Task UpdateModelFolders ( DirectoryPath installDirectory ,
SharedFolderMethod sharedFolderMethod ) = >
SetupModelFolders ( installDirectory , sharedFolderMethod ) ;
public override Task UpdateModelFolders (
DirectoryPath installDirectory ,
SharedFolderMethod sharedFolderMethod
) = > SetupModelFolders ( installDirectory , sharedFolderMethod ) ;
public override Task RemoveModelFolderLinks ( DirectoryPath installDirectory ,
SharedFolderMethod sharedFolderMethod ) = >
public override Task RemoveModelFolderLinks (
DirectoryPath installDirectory ,
SharedFolderMethod sharedFolderMethod
) = >
sharedFolderMethod switch
{
SharedFolderMethod . Symlink = > base . RemoveModelFolderLinks ( installDirectory ,
sharedFolderMethod ) ,
SharedFolderMethod . Symlink
= > base . RemoveModelFolderLinks ( installDirectory , sharedFolderMethod ) ,
SharedFolderMethod . None = > Task . CompletedTask ,
_ = > Task . CompletedTask
} ;