Skip to content

Commit

Permalink
The final version
Browse files Browse the repository at this point in the history
- more Scheduler
- New painting interface
- New any model inpaiting support
- Variable Resolution
- etc.
  • Loading branch information
czkoko committed Feb 23, 2024
1 parent fb463dc commit 04633a3
Show file tree
Hide file tree
Showing 16 changed files with 461 additions and 85 deletions.
42 changes: 25 additions & 17 deletions Mochi Diffusion.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
03173C132999E2B500B03456 /* SDModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03173C122999E2B500B03456 /* SDModel.swift */; };
03173C152999F5C700B03456 /* ImageController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03173C142999F5C700B03456 /* ImageController.swift */; };
03173C18299B3C1300B03456 /* ImageStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03173C17299B3C1300B03456 /* ImageStore.swift */; };
0352E2A5294E2591003FBF25 /* Sparkle in Frameworks */ = {isa = PBXBuildFile; productRef = 0352E2A4294E2591003FBF25 /* Sparkle */; };
0352E2A7294E3148003FBF25 /* HelpCommands.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0352E2A6294E3148003FBF25 /* HelpCommands.swift */; };
0352E2AA294EA0E1003FBF25 /* AppView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0352E2A9294EA0E1003FBF25 /* AppView.swift */; };
0352E2AE294EA2B4003FBF25 /* MessageBanner.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0352E2AD294EA2B4003FBF25 /* MessageBanner.swift */; };
Expand Down Expand Up @@ -61,6 +60,9 @@
C1ADEC2C2B16957800E142CA /* FolderMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1ADEC2B2B16957800E142CA /* FolderMonitor.swift */; };
D7B03F2029D42F9900DF89DD /* SDModelAttentionType.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7B03F1F29D42F9900DF89DD /* SDModelAttentionType.swift */; };
E45FA5822B7F7E4B009E90F0 /* GuernikaKit in Frameworks */ = {isa = PBXBuildFile; productRef = E45FA5812B7F7E4B009E90F0 /* GuernikaKit */; };
E4EC46322B890B6D00351E8C /* Sparkle in Frameworks */ = {isa = PBXBuildFile; productRef = E4EC46312B890B6D00351E8C /* Sparkle */; };
E4F15B1D2B86720F00E1EC3C /* de-coremldata.bin in Resources */ = {isa = PBXBuildFile; fileRef = E4F15B1C2B86720F00E1EC3C /* de-coremldata.bin */; };
E4F15B1F2B8673DB00E1EC3C /* en-coremldata.bin in Resources */ = {isa = PBXBuildFile; fileRef = E4F15B1E2B8673DB00E1EC3C /* en-coremldata.bin */; };
/* End PBXBuildFile section */

/* Begin PBXFileReference section */
Expand Down Expand Up @@ -132,6 +134,8 @@
C1220FBF2AFB122F007E5055 /* ImageWellView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageWellView.swift; sourceTree = "<group>"; };
C1ADEC2B2B16957800E142CA /* FolderMonitor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FolderMonitor.swift; sourceTree = "<group>"; };
D7B03F1F29D42F9900DF89DD /* SDModelAttentionType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SDModelAttentionType.swift; sourceTree = "<group>"; };
E4F15B1C2B86720F00E1EC3C /* de-coremldata.bin */ = {isa = PBXFileReference; lastKnownFileType = archive.macbinary; path = "de-coremldata.bin"; sourceTree = "<group>"; };
E4F15B1E2B8673DB00E1EC3C /* en-coremldata.bin */ = {isa = PBXFileReference; lastKnownFileType = archive.macbinary; path = "en-coremldata.bin"; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand All @@ -140,8 +144,8 @@
buildActionMask = 2147483647;
files = (
036BFC4E294B9FDB00D8AD04 /* Path in Frameworks */,
E4EC46322B890B6D00351E8C /* Sparkle in Frameworks */,
E45FA5822B7F7E4B009E90F0 /* GuernikaKit in Frameworks */,
0352E2A5294E2591003FBF25 /* Sparkle in Frameworks */,
0388DEB0297B00FC008B1C1C /* CompactSlider in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down Expand Up @@ -275,6 +279,8 @@
isa = PBXGroup;
children = (
036BFC25294B9F7600D8AD04 /* Assets.xcassets */,
E4F15B1E2B8673DB00E1EC3C /* en-coremldata.bin */,
E4F15B1C2B86720F00E1EC3C /* de-coremldata.bin */,
03FD2318295F74B6006EEEE2 /* RealESRGAN.mlmodel */,
);
path = Resources;
Expand All @@ -298,9 +304,9 @@
name = "Mochi Diffusion";
packageProductDependencies = (
036BFC4D294B9FDB00D8AD04 /* Path */,
0352E2A4294E2591003FBF25 /* Sparkle */,
0388DEAF297B00FC008B1C1C /* CompactSlider */,
E45FA5812B7F7E4B009E90F0 /* GuernikaKit */,
E4EC46312B890B6D00351E8C /* Sparkle */,
);
productName = "Mochi Diffusion";
productReference = 036BFC1E294B9F7500D8AD04 /* Mochi Diffusion.app */;
Expand Down Expand Up @@ -367,9 +373,9 @@
mainGroup = 036BFC15294B9F7500D8AD04;
packageReferences = (
036BFC4C294B9FDB00D8AD04 /* XCRemoteSwiftPackageReference "Path.swift" */,
0352E2A3294E2591003FBF25 /* XCRemoteSwiftPackageReference "Sparkle" */,
0388DEAE297B00FC008B1C1C /* XCRemoteSwiftPackageReference "CompactSlider" */,
E45FA5802B7F7E4B009E90F0 /* XCRemoteSwiftPackageReference "GuernikaKit" */,
E4EC46302B890B6D00351E8C /* XCRemoteSwiftPackageReference "Sparkle" */,
);
productRefGroup = 036BFC1F294B9F7500D8AD04 /* Products */;
projectDirPath = "";
Expand All @@ -389,6 +395,8 @@
03F578642967CE9A003A815F /* Localizable.strings in Resources */,
0311C6BD2989E3EF0074BCAE /* Localizable.stringsdict in Resources */,
036BFC26294B9F7600D8AD04 /* Assets.xcassets in Resources */,
E4F15B1F2B8673DB00E1EC3C /* en-coremldata.bin in Resources */,
E4F15B1D2B86720F00E1EC3C /* de-coremldata.bin in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -700,14 +708,6 @@
/* End XCConfigurationList section */

/* Begin XCRemoteSwiftPackageReference section */
0352E2A3294E2591003FBF25 /* XCRemoteSwiftPackageReference "Sparkle" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/sparkle-project/Sparkle";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = 2.0.0;
};
};
036BFC4C294B9FDB00D8AD04 /* XCRemoteSwiftPackageReference "Path.swift" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/mxcl/Path.swift.git";
Expand All @@ -732,14 +732,17 @@
minimumVersion = 1.5.0;
};
};
E4EC46302B890B6D00351E8C /* XCRemoteSwiftPackageReference "Sparkle" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/sparkle-project/Sparkle.git";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = 2.5.2;
};
};
/* End XCRemoteSwiftPackageReference section */

/* Begin XCSwiftPackageProductDependency section */
0352E2A4294E2591003FBF25 /* Sparkle */ = {
isa = XCSwiftPackageProductDependency;
package = 0352E2A3294E2591003FBF25 /* XCRemoteSwiftPackageReference "Sparkle" */;
productName = Sparkle;
};
036BFC4D294B9FDB00D8AD04 /* Path */ = {
isa = XCSwiftPackageProductDependency;
package = 036BFC4C294B9FDB00D8AD04 /* XCRemoteSwiftPackageReference "Path.swift" */;
Expand All @@ -755,6 +758,11 @@
package = E45FA5802B7F7E4B009E90F0 /* XCRemoteSwiftPackageReference "GuernikaKit" */;
productName = GuernikaKit;
};
E4EC46312B890B6D00351E8C /* Sparkle */ = {
isa = XCSwiftPackageProductDependency;
package = E4EC46302B890B6D00351E8C /* XCRemoteSwiftPackageReference "Sparkle" */;
productName = Sparkle;
};
/* End XCSwiftPackageProductDependency section */
};
rootObject = 036BFC16294B9F7500D8AD04 /* Project object */;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/GuernikaCore/GuernikaKit.git",
"state" : {
"revision" : "2c1ce26535279b309149acba47ae65e6a9394cb5",
"version" : "1.5.0"
"revision" : "dae44bf061ffa84df7f882cb563070d484488e44",
"version" : "1.6.0"
}
},
{
Expand All @@ -41,14 +41,14 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/GuernikaCore/Schedulers.git",
"state" : {
"revision" : "5e6ab9fa91aa56fc34edc6bae9de1caa7f13deb8",
"version" : "1.2.0"
"revision" : "1f517514d679e38bb9915c3a74bf04f75d5b5875",
"version" : "1.4.0"
}
},
{
"identity" : "sparkle",
"kind" : "remoteSourceControl",
"location" : "https://github.com/sparkle-project/Sparkle",
"location" : "https://github.com/sparkle-project/Sparkle.git",
"state" : {
"revision" : "47d3d90aee3c52b6f61d04ceae426e607df62347",
"version" : "2.5.2"
Expand Down
9 changes: 4 additions & 5 deletions Mochi Diffusion/Model/SDModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ struct SDModel: Identifiable {
let attention: SDModelAttentionType
let controlNet: [String]
let isXL: Bool
let inputSize: CGSize?
var inputSize: CGSize?

var id: URL { url }

Expand Down Expand Up @@ -103,8 +103,7 @@ private func identifyIfXL(_ url: URL) -> Bool {
private func unetMetadataURL(from url: URL) -> URL? {
let potentialMetadataURLs = [
url.appending(components: "Unet.mlmodelc", "metadata.json"),
url.appending(components: "UnetChunk1.mlmodelc", "metadata.json"),
url.appending(components: "ControlledUnet.mlmodelc", "metadata.json")
url.appending(components: "UnetChunk1.mlmodelc", "metadata.json")
]

return potentialMetadataURLs.first {
Expand All @@ -113,11 +112,11 @@ private func unetMetadataURL(from url: URL) -> URL? {
}

private func identifyInputSize(_ url: URL) -> CGSize? {
let encoderMetadataURL = url.appending(path: "VAEEncoder.mlmodelc").appending(path: "metadata.json")
let encoderMetadataURL = url.appending(path: "VAEDecoder.mlmodelc").appending(path: "metadata.json")
if let jsonData = try? Data(contentsOf: encoderMetadataURL),
let jsonArray = try? JSONSerialization.jsonObject(with: jsonData) as? [[String: Any]],
let jsonItem = jsonArray.first,
let inputSchema = jsonItem["inputSchema"] as? [[String: Any]],
let inputSchema = jsonItem["outputSchema"] as? [[String: Any]],
let controlnetCond = inputSchema.first,
let shapeString = controlnetCond["shape"] as? String {
let shapeIntArray = shapeString.trimmingCharacters(in: CharacterSet(charactersIn: "[]"))
Expand Down
25 changes: 20 additions & 5 deletions Mochi Diffusion/Model/Scheduler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,29 +9,44 @@ import Schedulers

/// Schedulers compatible with StableDiffusionPipeline
enum Scheduler: String, CaseIterable {
/// Scheduler that uses a pseudo-linear multi-step (PLMS) method
case lcm = "LCM"
/// Scheduler that uses a second order DPM-Solver++ algorithm
case ddim = "DDIM"

case dpmSolverMultistep = "DPM++ 2M"

case dpmSolverMultistepKarras = "DPM++ 2M Karras"

case dpmSolverSinglestep = "DPM++ SDE"

case dpmSolverSinglestepKarras = "DPM++ SDE Karras"

case eulerDiscrete = "Euler"

case eulerDiscreteKarras = "Euler Karras"

case eulerAncenstralDiscrete = "Euler Ancenstral"

case lcm = "LCM"
}

func convertScheduler(_ scheduler: Scheduler) -> Schedulers {
switch scheduler {
case .lcm:
return Schedulers.lcm
case .ddim:
return Schedulers.ddim
case .dpmSolverMultistep:
return Schedulers.dpmSolverMultistep
case .dpmSolverMultistepKarras:
return Schedulers.dpmSolverMultistepKarras
case .dpmSolverSinglestep:
return Schedulers.dpmSolverSinglestep
case .dpmSolverSinglestepKarras:
return Schedulers.dpmSolverSinglestepKarras
case .eulerDiscrete:
return Schedulers.eulerDiscrete
case .eulerDiscreteKarras:
return Schedulers.eulerDiscreteKarras
case .eulerAncenstralDiscrete:
return Schedulers.eulerAncenstralDiscrete
case .lcm:
return .lcm
}
}
Binary file added Mochi Diffusion/Resources/de-coremldata.bin
Binary file not shown.
Binary file added Mochi Diffusion/Resources/en-coremldata.bin
Binary file not shown.
1 change: 0 additions & 1 deletion Mochi Diffusion/Support/Extensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

import CompactSlider
import CoreML
import GuernikaKit
import SwiftUI
import UniformTypeIdentifiers

Expand Down
13 changes: 10 additions & 3 deletions Mochi Diffusion/Support/ImageController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ final class ImageController: ObservableObject {

@Published
var startingImage: CGImage?

@Published
var maskImage: CGImage?

@Published
var numberOfImages = 1.0
Expand Down Expand Up @@ -257,20 +260,24 @@ final class ImageController: ObservableObject {

var pipelineConfig = SampleInput(prompt: prompt)
pipelineConfig.negativePrompt = negativePrompt
if let size = currentModel?.inputSize {
pipelineConfig.initImage = startingImage?.scaledAndCroppedTo(size: size)
pipelineConfig.size = CGSize(width: ImageController.shared.width, height: ImageController.shared.height)

if let size = pipelineConfig.size, startingImage != nil{
pipelineConfig.initImage = startingImage?.scaledAndCroppedTo(size: size)
pipelineConfig.inpaintMask = maskImage?.scaledAndCroppedTo(size: size)
}
if startingImage == nil && currentControlNets.isEmpty{
strength = 1.0
}

pipelineConfig.strength = Float(strength)
pipelineConfig.stepCount = Int(steps)
pipelineConfig.seed = seed
pipelineConfig.originalStepCount = 50
pipelineConfig.guidanceScale = Float(guidanceScale)
pipelineConfig.scheduler = convertScheduler(scheduler)
for controlNet in currentControlNets {
if controlNet.name != nil, let size = model.inputSize, let image = controlNet.image?.scaledAndCroppedTo(size: size) {
if controlNet.name != nil, let size = pipelineConfig.size, let image = controlNet.image?.scaledAndCroppedTo(size: size) {
if ImageGenerator.shared.pipeline?.supportsControlNet == true{
let c = try? ControlNet(modelAt: URL(fileURLWithPath: controlNetDir + controlNet.name! + ".mlmodelc"))
let cinput = ConditioningInput.init(module: c!)
Expand Down

0 comments on commit 04633a3

Please sign in to comment.