From c21f61f7509d8a604a0b342033992b63590a1599 Mon Sep 17 00:00:00 2001 From: Felix IntegrIT Solutions Date: Thu, 16 Apr 2026 04:20:35 +0200 Subject: [PATCH] feat: add dictionaryOnly mode for background-safe G2P MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When `dictionaryOnly = true`, the MLX BART OOV fallback is skipped. Pure Swift dictionary lookups (179K entries) still run, covering virtually all English words. Only rare OOV words miss — those pass through with nil phonemes for the caller to handle. Use case: iOS background mode where Metal GPU is unavailable. MLX crashes with SIGABRT ("Insufficient Permission to submit GPU work from background") when the BART fallback runs. Dictionary-only mode prevents this while maintaining near-full pronunciation quality. --- Sources/MisakiSwift/English/EnglishG2P.swift | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Sources/MisakiSwift/English/EnglishG2P.swift b/Sources/MisakiSwift/English/EnglishG2P.swift index 48631b5..f20d050 100644 --- a/Sources/MisakiSwift/English/EnglishG2P.swift +++ b/Sources/MisakiSwift/English/EnglishG2P.swift @@ -9,6 +9,11 @@ final public class EnglishG2P { private let lexicon: Lexicon private let fallback: EnglishFallbackNetwork private let unk: String + + /// When `true`, skips MLX BART fallback for OOV words. Pure Swift dictionary + /// lookups (179K entries) still run. Use in iOS background mode where Metal + /// GPU is unavailable. OOV words will have nil phonemes. + public var dictionaryOnly: Bool = false static let punctuationTags: Set = Set([.openQuote, .closeQuote, .openParenthesis, .closeParenthesis, .punctuation, .sentenceTerminator, .otherPunctuation]) static let punctuactions: Set = Set(";:,.!?—…\"“”") @@ -416,7 +421,7 @@ final public class EnglishG2P { w.`_`.rating = out.1 } - if w.phonemes == nil { + if w.phonemes == nil && !dictionaryOnly { let out = fallback(w) w.phonemes = out.0 w.`_`.rating = out.1 @@ -461,7 +466,7 @@ final public class EnglishG2P { } } - if shouldFallback { + if shouldFallback && !dictionaryOnly { let token = mergeTokens(arr) let first = arr[0] let out = fallback(token)