Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
14 changes: 14 additions & 0 deletions Packages/ContinuityKit/Sources/Ingest/MemoryFootprint.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import Foundation
import os

/// Jetsam-debugging breadcrumbs. `os_proc_available_memory` reports how much of the process's
/// memory allowance remains before the OS kills it — logging it at each pipeline stage turns a
/// silent jetsam into a console trace that names the eater. Cheap enough to leave in release.
enum MemoryFootprint {
private static let logger = Logger(subsystem: "com.continuity.app", category: "mem")

static func breadcrumb(_ label: String) {
let remainingMB = Int(os_proc_available_memory() / 1_048_576)
logger.info("mem[\(label, privacy: .public)] \(remainingMB, privacy: .public) MB headroom")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,9 @@ extension PreparationQueue {
return
}
do {
MemoryFootprint.breadcrumb("separation task begin")
let modelURL = try await StemModelStore.ensureModel()
MemoryFootprint.breadcrumb("model ensured")
let separator = OnnxStemSeparator(modelURL: modelURL)
_ = try separator.separate(inputURL: inputURL, vocalsOut: vocalsOut, accompanimentOut: accompanimentOut)
await MainActor.run {
Expand Down
2 changes: 2 additions & 0 deletions Packages/ContinuityKit/Sources/Ingest/PreparationQueue.swift
Original file line number Diff line number Diff line change
Expand Up @@ -274,9 +274,11 @@ public final class PreparationQueue {
if needsReanalysis, track.modelContext != nil, let relativePath = track.localRelativePath {
let url = AudioCache.url(forRelativePath: relativePath)
await ingestLimiter.acquire()
MemoryFootprint.breadcrumb("analysis begin")
let analysis = try? await Task.detached(priority: .utility) {
try TrackAnalyzer.analyze(fileURL: url)
}.value
MemoryFootprint.breadcrumb("analysis end")
await ingestLimiter.release()
if let analysis, track.modelContext != nil {
track.bpm = analysis.bpm > 0 ? analysis.bpm : nil
Expand Down
6 changes: 6 additions & 0 deletions Packages/ContinuityKit/Sources/Ingest/StemSeparator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ final class OnnxStemSeparator: StemSeparating {
defer { sessionLock.unlock() }
if let cached = cachedSession, cached.path == modelURL.path { return cached.session }
do {
MemoryFootprint.breadcrumb("ort session load begin")
let env = try ORTEnv(loggingLevel: .warning)
let options = try ORTSessionOptions()
// Cap thread fan-out: default parallel arenas on a phone balloon RSS toward the
Expand All @@ -121,6 +122,7 @@ final class OnnxStemSeparator: StemSeparating {
try options.addConfigEntry(withKey: "session.disable_prepacking", value: "1")
let session = try ORTSession(env: env, modelPath: modelURL.path, sessionOptions: options)
cachedSession = (modelURL.path, session)
MemoryFootprint.breadcrumb("ort session ready")
return session
} catch {
throw StemSeparationError.inference("session: \(error)")
Expand Down Expand Up @@ -164,6 +166,7 @@ final class OnnxStemSeparator: StemSeparating {
try? FileManager.default.removeItem(at: accompanimentOut)
throw error
}
MemoryFootprint.breadcrumb("separation done")
return StemPaths(vocals: vocalsOut, accompaniment: accompanimentOut)
}

Expand All @@ -184,6 +187,7 @@ final class OnnxStemSeparator: StemSeparating {
var input = [Float](repeating: 0, count: channels * segment)

var start = 0
var windowCount = 0
while true {
// Decode ahead through the end of this window (or EOF / the length cap).
while !atEOF && decodedEnd < start + segment {
Expand Down Expand Up @@ -215,6 +219,8 @@ final class OnnxStemSeparator: StemSeparating {
input[segment + i] = 0
}

if windowCount % 10 == 0 { MemoryFootprint.breadcrumb("window \(windowCount)") }
windowCount += 1
let vocals = try runWindow(input)
guard vocals.count >= channels * segment else {
throw StemSeparationError.inference("short vocals output: \(vocals.count)")
Expand Down
Loading