Support the legacy single-function SpeechDecoder and MultiCodeDecoder assets - #520
Merged
Merged
Conversation
Support both the multifunction and legacy single-function assets by probing the model's functions and update-mask rank instead of assuming a layout.
Eight matrix jobs compile the same sources, so each compiler warning was posted eight times on the PR diff.
EduardoPach
requested review from
ZachNagengast and
a2they
and removed request for
a2they
August 5, 2026 21:49
Contributor
Author
|
This PR will allow people to do the following in case they have the previous import TTSKit
Task {
let config = TTSKitConfig(
multiCodeDecoderVariant: "W8A16",
speechDecoderVariant: "W8A16"
)
let tts = try await TTSKit(config)
let result = try await tts.generate(text: "Hello from TTSKit!")
print("Generated \(result.audioDuration)s of audio at \(result.sampleRate)Hz")
} |
ZachNagengast
approved these changes
Aug 5, 2026
Probe the asset's CoreML functions instead of always setting a functionName, so the legacy single-function W8A16 asset loads and runs the stepped path. Requesting fused against it now reports a clear configuration error.
setupModels built a fresh TTSKitConfig for the download that dropped versionDir and the six component variants. downloadPatterns is derived from those, so any pinned variant was ignored: the downloader fetched the preset defaults and the load then failed on the variant actually asked for. Without this, the legacy assets restored here are unreachable through TTSKit(config:) -- and a user who already has W8A16 and pins it pulls the ~1.1GB multifunction assets they do not need before failing to load.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
#494 and #513 moved the SpeechDecoder and the MultiCodeDecoder onto multifunction
assets, which dropped support for the legacy single-function
W8A16ones. Thisrestores both by detecting the layout at load time instead of assuming it.
SpeechDecoder
MLModelAsset.functionNames; empty → load without afunctionName.Requesting
throughputOptimizedagainst it errors instead of silentlyproducing latency-mode audio.
kv_cache_update_maskrank from the model (2 = legacy, 3 =multifunction). Not derivable from
codesPerStep— both ranks exist atcodesPerStep == 1, soSpeechDecoderCachetakes it as a parameter.ModelUtilitiesdimension reads are now bounds-safe; probing anunexpected-rank input used to trap.
MultiCodeDecoder
Same probe: the legacy asset is schema-identical to the multifunction
steppedgraph, so it loads without a
functionNameand drives the same decode path..fusedhas no counterpart in a single-function asset, so asking for it reportsa configuration error naming the multifunction variant rather than quietly
running stepped.
.steppedstays the default; both variants are supported.Downloader
setupModelsbuilt a freshTTSKitConfigfor the download that droppedversionDirand the six component variants.downloadPatternsis derived fromthose, so any pinned variant was ignored — the downloader fetched the preset
defaults and the load then failed on the variant actually requested.
This is pre-existing (it reproduces on
main), but it makes the legacy supportabove unreachable through
TTSKit(config:), so it is fixed here. It also means auser who already has
W8A16and pins it currently pulls the ~1.1 GBmultifunction assets they don't need before failing to load; after the fix that
run downloads nothing.
Validation
Cache deleted and re-downloaded from scratch: all 40 files match their original
SHA-256. Same text/seed at
--temperature 0, vsmain:mainW8A16vs multifunction steppedW8A16against a cache that already has itBoth guards fire: legacy +
fusedand legacy +throughputOptimizedeach reportthe single-function configuration error. 4 tests added for rank-2 geometry. The
macOS 14 path stays deleted — both layouts need the macOS 15 / iOS 18
MLTensorfloor.
One commit is unrelated to the decoders: it gates
xcbeautify --renderer github-actionsto a single matrix job, since eight jobs were annotating the samewarning eight times.