Skip to content
Merged

v2.15.1 #1412

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
e369fe4
Fixed AI Toolkit error on job start, show at least 30 results in civi…
mohnjiles Sep 23, 2025
e1b752e
Request more than TargetItemCount
mohnjiles Sep 23, 2025
27b30f1
Merge pull request #1140 from ionite34/fixes-n-stuff
mohnjiles Sep 23, 2025
771bc04
Update HIP SDK to 6.4.2 for zluda packages and update comfyzluda to j…
mohnjiles Sep 24, 2025
837f79b
Merge pull request #1141 from ionite34/update-zluda-stuffs
mohnjiles Sep 25, 2025
f4f7547
Fix incorrect zipFolderName parsing for gfx1103
mohnjiles Sep 25, 2025
2d2ca5a
Merge pull request #1145 from ionite34/fix-gfx1103-zip-name
mohnjiles Sep 25, 2025
d9ad7df
Merge branch 'main' into dev-to-main
mohnjiles Sep 25, 2025
1a31edc
Merge pull request #1146 from ionite34/dev-to-main
mohnjiles Sep 27, 2025
4964aed
Merge pull request #1147 from ionite34/update-sage-and-nunchaku
mohnjiles Oct 2, 2025
749da3c
Merge pull request #1148 from ionite34/backport/main/pr-1147
mohnjiles Oct 2, 2025
cfd6f2b
Merge pull request #1149 from ionite34/fix-python-special-character-p…
mohnjiles Oct 2, 2025
3d2667f
Merge pull request #1150 from ionite34/backport/main/pr-1149
mohnjiles Oct 2, 2025
a845630
Merge pull request #1151 from ionite34/fix-format-crashes
mohnjiles Oct 7, 2025
9a7e665
Merge pull request #1153 from ionite34/backport/main/pr-1151
mohnjiles Oct 7, 2025
cd142ce
Merge pull request #1152 from ionite34/fix-sdnext
mohnjiles Oct 7, 2025
66319fd
Merge pull request #1154 from ionite34/backport/main/pr-1152
mohnjiles Oct 7, 2025
3093966
Merge pull request #1155 from ionite34/shoutout-chagenlog
mohnjiles Oct 7, 2025
4aa2625
Merge pull request #1156 from ionite34/backport/main/pr-1155
mohnjiles Oct 7, 2025
a9fc2f8
Merge branch 'main' of https://github.com/LykosAI/StabilityMatrix-Dev
mohnjiles Oct 7, 2025
a29d932
Merge branch 'LykosAI:main' into main
mohnjiles Oct 7, 2025
265e67b
Merge pull request #1157 from ionite34/comfy-rocm-env-vars
mohnjiles Oct 7, 2025
4ed952d
Merge pull request #1158 from ionite34/backport/main/pr-1157
mohnjiles Oct 7, 2025
dac3f3a
Merge branch 'main' of https://github.com/LykosAI/StabilityMatrix-Dev
mohnjiles Oct 7, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,29 @@ 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.15.1
### Changed
- Upgraded ComfyUI-Zluda and Stable Diffusion WebUI AMDGPU Forge packages to install and use HIP SDK 6.4.2
- Changed ComfyUI torch index from `cu129` back to `cu128` for better compatibility with custom nodes
- Updated SageAttention installer to install v2.2.0-windows.post3
- Updated Nunchaku installer to install v1.0.1
- Updated Windows ROCm ComfyUI installs to use recommended environment variables by default
### Fixed
- Fixed [#1372](https://github.com/LykosAI/StabilityMatrix/issues/1372), [#1399](https://github.com/LykosAI/StabilityMatrix/issues/1399) - LiteAsyncException upon starting Stability Matrix v2.15.0
- Fixed [#1391](https://github.com/LykosAI/StabilityMatrix/issues/1391) - "Failed to parse" error when upgrading pip packages with extra index url
- Fixed [#1401](https://github.com/LykosAI/StabilityMatrix/issues/1401) - "Python <version> was not found and/or failed to install" errors when path contains special characters
- Fixed [#1403](https://github.com/LykosAI/StabilityMatrix/issues/1403) - Checkpoint Manager filters not being saved correctly
- Fixed [#1411](https://github.com/LykosAI/StabilityMatrix/issues/1411) - SD.Next installs not using correct torch version
- Fixed "cannot access local variable 'job' where it is not associated with a value" error when running jobs in AI Toolkit
- Fixed Civitai browser not always returning at least 30 results when possible on initial search
- Fixed model browser crashing when downloading a file with invalid characters in the name
- Fixed model browser crashing when no author exists for a model
### Supporters
#### 🌟 Visionaries
To our guiding stars, the Visionaries! Thank you **Waterclouds**, **JungleDragon**, **bluepopsicle**, **Bob S**, **Ibixat**, and **whudunit**! While this release is focused on fixes and stability, your foundational support is what empowers us to build a reliable and robust platform for everyone.
#### 🚀 Pioneers
A huge round of applause for our fantastic Pioneers! Your steady support helps us smooth out the rough edges and deliver a better experience with every update. Our deepest thanks to: **Szir777**, **Tigon**, **Noah M**, **USATechDude**, **Thom**, **SeraphOfSalem**, **Desert Viber**, **Tundra Everquill**, **Adam**, and **Droolguy**. We're also thrilled to welcome our newest Pioneers to the crew: **Philip R.**, **ACTUALLY_the_Real_Willem_Dafoe**, and **takyamtom**!

## v2.15.0
### Added
- Added new package - [AI Toolkit](https://github.com/ostris/ai-toolkit/)
Expand Down
58 changes: 28 additions & 30 deletions StabilityMatrix.Avalonia/Helpers/WindowsPrerequisiteHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ IPyInstallationManager pyInstallationManager
private const string CppBuildToolsUrl = "https://aka.ms/vs/17/release/vs_BuildTools.exe";

private const string HipSdkDownloadUrl =
"https://download.amd.com/developer/eula/rocm-hub/AMD-Software-PRO-Edition-24.Q4-Win10-Win11-For-HIP.exe";
"https://download.amd.com/developer/eula/rocm-hub/AMD-Software-PRO-Edition-25.Q3-Win10-Win11-For-HIP.exe";
private const string PythonLibsDownloadUrl = "https://cdn.lykos.ai/python_libs_for_sage.zip";

private const string UvWindowsDownloadUrl =
Expand Down Expand Up @@ -110,7 +110,7 @@ private string GetPythonLibraryZipPath(PyVersion version) =>
private string HipSdkDownloadPath => Path.Combine(AssetsDir, "AMD-HIP-SDK.exe");

private string HipInstalledPath =>
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), "AMD", "ROCm", "6.2");
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), "AMD", "ROCm", "6.4");
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The HIP SDK version "6.4" is hardcoded. This version string is used in multiple places (WindowsPrerequisiteHelper.cs, ComfyZluda.cs, ForgeAmdGpu.cs). To improve maintainability, consider defining it as a public constant in a shared location within the StabilityMatrix.Core project, so it only needs to be updated in one place in the future.


private string UvDownloadPath => Path.Combine(AssetsDir, "uv.zip");
private string UvExtractPath => Path.Combine(AssetsDir, "uv");
Expand Down Expand Up @@ -189,7 +189,7 @@ private async Task<string> RunNode(

result.EnsureSuccessExitCode();
return result.StandardOutput ?? result.StandardError ?? string.Empty;
}
}

public async Task RunNpm(
ProcessArgs args,
Expand Down Expand Up @@ -997,15 +997,11 @@ private async Task PatchHipSdkIfNecessary(IProgress<ProgressReport>? progress)

var zipFolderName = downloadUrl switch
{
_ when downloadUrl.Contains("gfx1201") => null,
_ when downloadUrl.Contains("gfx1150") => "rocm gfx1150 for hip skd 6.2.4",
_ when downloadUrl.Contains("gfx1103.AMD") =>
"rocm gfx1103 AMD 780M phoenix V5.0 for hip skd 6.2.4",
_ when downloadUrl.Contains("gfx1034") => "rocm gfx1034-gfx1035-gfx1036 for hip sdk 6.2.4",
_ when downloadUrl.Contains("gfx1032") => "rocm gfx1032 for hip skd 6.2.4(navi21 logic)",
_ when downloadUrl.Contains("gfx1031") => "rocm gfx1031 for hip skd 6.2.4 (littlewu's logic)",
_ when downloadUrl.Contains("gfx1010") =>
"rocm gfx1010-xnack-gfx1011-xnack-gfx1012-xnack- for hip sdk 6.2.4",
_ when downloadUrl.Contains("gfx1103.for.hip") => "rocm gfx1103 for hip 6.4.2",
_ when downloadUrl.Contains("gfx1034") => "rocm gfx1034.gfx1035.gfx1036 for hip 6.4.2",
_ when downloadUrl.Contains("gfx1032") => "rocm gfx1032 for hip 6.4.2",
_ when downloadUrl.Contains("gfx1031") => "rocm gfx1031 for hip 6.4.2",
_ when downloadUrl.Contains("gfx1010") => "rocm gfx1010-xnack-gfx1012-xnack-.for.hip6.4.2",
_ => null,
};

Expand Down Expand Up @@ -1035,27 +1031,29 @@ _ when downloadUrl.Contains("gfx1010") =>

private string? GetDownloadUrlFromGpuName(string name)
{
// not used anymore but good to know for gfx -> name reference
// gfx1201
if (name.Contains("9060") || name.Contains("9070"))
{
return "https://github.com/likelovewant/ROCmLibs-for-gfx1103-AMD780M-APU/releases/download/v0.6.2.4/rocm.gfx1201.for.hip.skd.6.2.4-no-optimized.7z";
}
// if (name.Contains("9060") || name.Contains("9070"))
// {
// return "https://github.com/likelovewant/ROCmLibs-for-gfx1103-AMD780M-APU/releases/download/v0.6.2.4/rocm.gfx1201.for.hip.skd.6.2.4-no-optimized.7z";
// }

// not used anymore but good to know for gfx -> name reference
// gfx1150
if (
name.Contains("8050S")
|| name.Contains("8060S")
|| name.Contains("880M")
|| name.Contains("890M")
)
{
return "https://github.com/likelovewant/ROCmLibs-for-gfx1103-AMD780M-APU/releases/download/v0.6.2.4/rocm.gfx1150.for.hip.skd.6.2.4.7z";
}
// if (
// name.Contains("8050S")
// || name.Contains("8060S")
// || name.Contains("880M")
// || name.Contains("890M")
// )
// {
// return "https://github.com/likelovewant/ROCmLibs-for-gfx1103-AMD780M-APU/releases/download/v0.6.2.4/rocm.gfx1150.for.hip.skd.6.2.4.7z";
// }

// gfx1103
if (name.Contains("740M") || name.Contains("760M") || name.Contains("780M") || name.Contains("Z1"))
{
return "https://github.com/likelovewant/ROCmLibs-for-gfx1103-AMD780M-APU/releases/download/v0.6.2.4/rocm.gfx1103.AMD.780M.phoenix.V5.0.for.hip.sdk.6.2.4.7z";
return "https://github.com/likelovewant/ROCmLibs-for-gfx1103-AMD780M-APU/releases/download/v0.6.4.2/rocm.gfx1103.for.hip.6.4.2.7z";
}

// gfx1034, gfx1035, gfx1036
Expand All @@ -1070,7 +1068,7 @@ _ when downloadUrl.Contains("gfx1010") =>
|| name.Contains("Graphics 128SP")
)
{
return "https://github.com/likelovewant/ROCmLibs-for-gfx1103-AMD780M-APU/releases/download/v0.6.2.4/rocm.gfx1034-gfx1035-gfx1036.for.hip.sdk.6.2.4.7z";
return "https://github.com/likelovewant/ROCmLibs-for-gfx1103-AMD780M-APU/releases/download/v0.6.4.2/rocm.gfx1034.gfx1035.gfx1036.for.hip.6.4.2.7z";
}

// gfx1032
Expand All @@ -1081,7 +1079,7 @@ _ when downloadUrl.Contains("gfx1010") =>
|| name.Contains("6650")
)
{
return "https://github.com/likelovewant/ROCmLibs-for-gfx1103-AMD780M-APU/releases/download/v0.6.2.4/rocm.gfx1032.for.hip.sdk.6.2.4.navi21.logic.7z";
return "https://github.com/likelovewant/ROCmLibs-for-gfx1103-AMD780M-APU/releases/download/v0.6.4.2/rocm.gfx1032.for.hip.6.4.2.7z";
}

// gfx1031
Expand All @@ -1092,13 +1090,13 @@ _ when downloadUrl.Contains("gfx1010") =>
|| name.Contains("6850M")
)
{
return "https://github.com/likelovewant/ROCmLibs-for-gfx1103-AMD780M-APU/releases/download/v0.6.2.4/rocm.gfx1031.for.hip.sdk.6.2.4.littlewu.s.logic.7z";
return "https://github.com/likelovewant/ROCmLibs-for-gfx1103-AMD780M-APU/releases/download/v0.6.4.2/rocm.gfx1031.for.hip.6.4.2.7z";
}

// gfx1010/1012
if (name.Contains("5700") || name.Contains("5600") || name.Contains("5300") || name.Contains("5500"))
{
return "https://github.com/likelovewant/ROCmLibs-for-gfx1103-AMD780M-APU/releases/download/v0.6.2.4/rocm.gfx1010-xnack-gfx1011-xnack-gfx1012-xnack-.for.hip.sdk.6.2.4.7z";
return "https://github.com/likelovewant/ROCmLibs-for-gfx1103-AMD780M-APU/releases/download/v0.6.4.2/rocm.gfx1010-xnack-gfx1012-xnack-.for.hip6.4.2.7z";
}

return null;
Expand Down
15 changes: 14 additions & 1 deletion StabilityMatrix.Avalonia/Models/Inference/FileNameFormat.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,20 @@ public string GetFileName()
return Prefix
+ string.Join(
"",
Parts.Select(part => part.Match(constant => constant, substitution => substitution.Invoke()))
Parts.Select(part =>
part.Match(
constant => constant,
substitution =>
{
// Filter invalid path chars
var result = substitution.Invoke();
return result is null
? null
: Path.GetInvalidFileNameChars()
.Aggregate(result, (current, c) => current.Replace(c, '_'));
}
)
)
)
+ Postfix;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public partial class FileNameFormatProvider
{ "project_name", () => ProjectName },
{ "date", () => DateTime.Now.ToString("yyyy-MM-dd") },
{ "time", () => DateTime.Now.ToString("HH-mm-ss") },
{ "author", () => CivitModel?.Creator.Username },
{ "author", () => CivitModel?.Creator?.Username },
{ "base_model", () => CivitModelVersion?.BaseModel },
{ "file_name", () => Path.GetFileNameWithoutExtension(CivitFile?.Name) },
{ "file_id", () => CivitFile?.Id.ToString() },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ private void ToggleFavorite()
[RelayCommand]
public void SearchAuthor()
{
EventManager.Instance.OnNavigateAndFindCivitAuthorRequested(CivitModel.Creator.Username);
EventManager.Instance.OnNavigateAndFindCivitAuthorRequested(CivitModel.Creator?.Username);
}

private async Task DoImport(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ public sealed partial class CivitAiBrowserViewModel : TabViewModelBase, IInfinit

private readonly SourceCache<OrderedValue<CivitModel>, int> modelCache = new(static ov => ov.Value.Id);

private const int TargetPageItemCount = 30;

[ObservableProperty]
private IObservableCollection<CheckpointBrowserCardViewModel> modelCards =
new ObservableCollectionExtended<CheckpointBrowserCardViewModel>();
Expand Down Expand Up @@ -453,8 +455,46 @@ private async Task CivitModelQuery(CivitModelsRequest request, bool isInfiniteSc
}
else
{
modelsResponse = await civitApi.GetModels(request);
models = modelsResponse.Items;
// Auto-paginate via cursor until we fill the target page size or run out
var collectedById = new HashSet<int>();
var targetCount = request.Limit ?? TargetPageItemCount;
var safetyGuard = 0;

while (true)
{
var resp = await civitApi.GetModels(request);
modelsResponse = resp;

if (resp.Items != null)
{
foreach (var item in resp.Items)
{
if (collectedById.Add(item.Id))
{
models.Add(item);
}
}
}

// Check how many items survive local filtering
var filteredCount = models
.Where(m => m.Type.ConvertTo<SharedFolderType>() > 0)
.Count(m => m.Mode == null);

var next = resp.Metadata?.NextCursor;
if (filteredCount >= targetCount || string.IsNullOrEmpty(next))
{
break;
}

request.Cursor = next;

if (++safetyGuard >= 10)
{
// Avoid unbounded looping on unexpected cursors
break;
}
}
}

if (models is null)
Expand Down Expand Up @@ -513,7 +553,7 @@ private async Task CivitModelQuery(CivitModelsRequest request, bool isInfiniteSc
var doesBaseModelTypeMatch =
SelectedBaseModels.Count == 0
? request.BaseModels == null || request.BaseModels.Length == 0
: SelectedBaseModels.SequenceEqual(request.BaseModels);
: SelectedBaseModels.SequenceEqual(request.BaseModels ?? []);
var doesModelTypeMatch =
SelectedModelType == CivitModelType.All
? request.Types == null || request.Types.Length == 0
Expand Down Expand Up @@ -634,6 +674,7 @@ private async Task SearchModels(bool isInfiniteScroll = false)
// Build request
var modelRequest = new CivitModelsRequest
{
Limit = TargetPageItemCount + 20, // Fetch a few extra to account for local filtering
Nsfw = "true", // Handled by local view filter
Sort = SortMode,
Period = SelectedPeriod,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -651,7 +651,7 @@ private async Task ShowImageDialog(ImageSource? image)
private void SearchByAuthor()
{
navigationService.GoBack();
EventManager.Instance.OnNavigateAndFindCivitAuthorRequested(CivitModel.Creator.Username);
EventManager.Instance.OnNavigateAndFindCivitAuthorRequested(CivitModel.Creator?.Username);
}

[RelayCommand]
Expand Down
18 changes: 11 additions & 7 deletions StabilityMatrix.Avalonia/ViewModels/CheckpointsPageViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -160,16 +160,14 @@ protected override async Task OnInitialLoadedAsync()

await base.OnInitialLoadedAsync();

var settingsSelectedBaseModels = settingsManager.Settings.SelectedBaseModels;

AddDisposable(
BaseModelCache
.Connect()
.DeferUntilLoaded()
.Transform(baseModel => new BaseModelOptionViewModel
{
ModelType = baseModel,
IsSelected = settingsSelectedBaseModels.Contains(baseModel),
IsSelected = settingsManager.Settings.SelectedBaseModels.Contains(baseModel),
})
.SortAndBind(
BaseModelOptions,
Expand All @@ -179,10 +177,15 @@ protected override async Task OnInitialLoadedAsync()
.ObserveOn(SynchronizationContext.Current)
.Subscribe(next =>
{
if (next.Sender.IsSelected)
SelectedBaseModels.Add(next.Sender.ModelType);
else
SelectedBaseModels.Remove(next.Sender.ModelType);
switch (next.Sender.IsSelected)
{
case true when !SelectedBaseModels.Contains(next.Sender.ModelType):
SelectedBaseModels.Add(next.Sender.ModelType);
break;
case false when SelectedBaseModels.Contains(next.Sender.ModelType):
SelectedBaseModels.Remove(next.Sender.ModelType);
break;
}

OnPropertyChanged(nameof(ClearButtonText));
OnPropertyChanged(nameof(SelectedBaseModels));
Expand All @@ -191,6 +194,7 @@ protected override async Task OnInitialLoadedAsync()

var settingsTransactionObservable = this.WhenPropertyChanged(x => x.SelectedBaseModels)
.Throttle(TimeSpan.FromMilliseconds(50))
.Skip(1)
.ObserveOn(SynchronizationContext.Current)
.Subscribe(_ =>
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ private async Task UpgradePackageVersion(

if (extraIndexUrl != null)
{
args = args.AddArg(("--extra-index-url", extraIndexUrl));
args = args.AddArgs("--extra-index-url", extraIndexUrl);
}

var steps = new List<IPackageStep>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ public override void LoadStateFromJsonObject(JsonObject state)
? HybridModelFile.None
: ClientManager.ClipModels.FirstOrDefault(x => x.RelativePath == model.SelectedClip3Name);

SelectedClip4 = model.SelectedClip3Name is null
SelectedClip4 = model.SelectedClip4Name is null
? HybridModelFile.None
: ClientManager.ClipModels.FirstOrDefault(x => x.RelativePath == model.SelectedClip4Name);

Expand Down
Loading
Loading