From 7b4c89114758aa8aa3be0dcb624a9fee958c1c7f Mon Sep 17 00:00:00 2001 From: Pedro Cuenca Date: Sun, 11 Dec 2022 16:58:05 +0100 Subject: [PATCH] Make weightedSum common. --- .../DPMSolverMultistepScheduler.swift | 15 ------- .../StableDiffusion/pipeline/Scheduler.swift | 44 ++++++++++--------- 2 files changed, 23 insertions(+), 36 deletions(-) diff --git a/swift/StableDiffusion/pipeline/DPMSolverMultistepScheduler.swift b/swift/StableDiffusion/pipeline/DPMSolverMultistepScheduler.swift index 9ad075d..26f3854 100644 --- a/swift/StableDiffusion/pipeline/DPMSolverMultistepScheduler.swift +++ b/swift/StableDiffusion/pipeline/DPMSolverMultistepScheduler.swift @@ -78,21 +78,6 @@ public final class DPMSolverMultistepScheduler: Scheduler { self.timeSteps = linspace(0, Float(self.trainStepCount-1), stepCount).reversed().map { Int(round($0)) } } - func weightedSum(_ weights: [Double], _ values: [MLShapedArray]) -> MLShapedArray { - assert(weights.count > 1 && values.count == weights.count) - assert(values.allSatisfy({$0.scalarCount == values.first!.scalarCount})) - var w = Float(weights.first!) - var scalars = values.first!.scalars.map({ $0 * w }) - for next in 1 ..< values.count { - w = Float(weights[next]) - let nextScalars = values[next].scalars - for i in 0 ..< scalars.count { - scalars[i] += w * nextScalars[i] - } - } - return MLShapedArray(scalars: scalars, shape: values.first!.shape) - } - /// Convert the model output to the corresponding type the algorithm needs. /// This implementation is for second-order DPM-Solver++ assuming epsilon prediction. func convertModelOutput(modelOutput: MLShapedArray, timestep: Int, sample: MLShapedArray) -> MLShapedArray { diff --git a/swift/StableDiffusion/pipeline/Scheduler.swift b/swift/StableDiffusion/pipeline/Scheduler.swift index 1dbb92f..6658b85 100644 --- a/swift/StableDiffusion/pipeline/Scheduler.swift +++ b/swift/StableDiffusion/pipeline/Scheduler.swift @@ -46,6 +46,29 @@ public extension Scheduler { var initNoiseSigma: Float { 1 } } +public extension Scheduler { + /// Compute weighted sum of shaped arrays of equal shapes + /// + /// - Parameters: + /// - weights: The weights each array is multiplied by + /// - values: The arrays to be weighted and summed + /// - Returns: sum_i weights[i]*values[i] + func weightedSum(_ weights: [Double], _ values: [MLShapedArray]) -> MLShapedArray { + assert(weights.count > 1 && values.count == weights.count) + assert(values.allSatisfy({$0.scalarCount == values.first!.scalarCount})) + var w = Float(weights.first!) + var scalars = values.first!.scalars.map({ $0 * w }) + for next in 1 ..< values.count { + w = Float(weights[next]) + let nextScalars = values[next].scalars + for i in 0 ..< scalars.count { + scalars[i] += w * nextScalars[i] + } + } + return MLShapedArray(scalars: scalars, shape: values.first!.shape) + } +} + /// How to map a beta range to a sequence of betas to step over public enum BetaSchedule { /// Linear stepping between start and end @@ -188,27 +211,6 @@ public final class PNDMScheduler: Scheduler { return prevSample } - /// Compute weighted sum of shaped arrays of equal shapes - /// - /// - Parameters: - /// - weights: The weights each array is multiplied by - /// - values: The arrays to be weighted and summed - /// - Returns: sum_i weights[i]*values[i] - func weightedSum(_ weights: [Double], _ values: [MLShapedArray]) -> MLShapedArray { - assert(weights.count > 1 && values.count == weights.count) - assert(values.allSatisfy({$0.scalarCount == values.first!.scalarCount})) - var w = Float(weights.first!) - var scalars = values.first!.scalars.map({ $0 * w }) - for next in 1 ..< values.count { - w = Float(weights[next]) - let nextScalars = values[next].scalars - for i in 0 ..< scalars.count { - scalars[i] += w * nextScalars[i] - } - } - return MLShapedArray(scalars: scalars, shape: values.first!.shape) - } - /// Compute sample (denoised image) at previous step given a current time step /// /// - Parameters: