Skip to content

Commit

Permalink
Fix memory leak from non-async MLModel prediction (#56)
Browse files Browse the repository at this point in the history
  • Loading branch information
finnvoor authored Mar 7, 2024
1 parent 20c9001 commit df15f89
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 4 deletions.
2 changes: 1 addition & 1 deletion Sources/WhisperKit/Core/AudioEncoder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public class AudioEncoder: AudioEncoding, WhisperMLModel {

try Task.checkCancellation()

let outputFeatures = try await model.prediction(from: modelInputs, options: MLPredictionOptions())
let outputFeatures = try await model.asyncPrediction(from: modelInputs, options: MLPredictionOptions())

let output = AudioEncoderOutput(features: outputFeatures)

Expand Down
2 changes: 1 addition & 1 deletion Sources/WhisperKit/Core/FeatureExtractor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public class FeatureExtractor: FeatureExtracting, WhisperMLModel {

try Task.checkCancellation()

let outputFeatures = try await model.prediction(from: modelInputs, options: MLPredictionOptions())
let outputFeatures = try await model.asyncPrediction(from: modelInputs, options: MLPredictionOptions())

let output = MelSpectrogramOutput(features: outputFeatures)

Expand Down
4 changes: 2 additions & 2 deletions Sources/WhisperKit/Core/TextDecoder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ public extension TextDecoding {

try Task.checkCancellation()

let outputFeatures = try await prefillModel.prediction(from: modelInputs, options: MLPredictionOptions())
let outputFeatures = try await prefillModel.asyncPrediction(from: modelInputs, options: MLPredictionOptions())

let output = TextDecoderCachePrefillOutput(features: outputFeatures)

Expand Down Expand Up @@ -291,7 +291,7 @@ public class TextDecoder: TextDecoding, WhisperMLModel {

try Task.checkCancellation()

let outputFeatures = try await model.prediction(from: modelInputs, options: MLPredictionOptions())
let outputFeatures = try await model.asyncPrediction(from: modelInputs, options: MLPredictionOptions())

let output = TextDecoderOutput(features: outputFeatures)

Expand Down
15 changes: 15 additions & 0 deletions Sources/WhisperKit/Core/Utils.swift
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,21 @@ extension MLMultiArray {
}
}

extension MLModel {
func asyncPrediction(
from input: MLFeatureProvider,
options: MLPredictionOptions
) async throws -> MLFeatureProvider {
if #available(macOS 14, iOS 17, watchOS 10, visionOS 1, *) {
return try await prediction(from: input, options: options)
} else {
return try await Task {
try prediction(from: input, options: options)
}.value
}
}
}

@available(macOS 13, iOS 16, watchOS 10, visionOS 1, *)
func initMLMultiArray(shape: [NSNumber], dataType: MLMultiArrayDataType, initialValue: Any) -> MLMultiArray {
let multiArray = try! MLMultiArray(shape: shape, dataType: dataType)
Expand Down

0 comments on commit df15f89

Please sign in to comment.