Skip to content

KokoroAne: vocoder fails on macOS 14 under every compute-unit preset #836

Description

@drakulavich

Summary

On macOS 14 (Apple M1 (Virtual), a GitHub-hosted macos-14 runner), KokoroAneManager.synthesize fails at the vocoder stage under every KokoroAneComputeUnits setting. The package declares .macOS(.v14) and KokoroAne carries no @available gate, so this reads as a supported configuration that nothing currently exercises — every workflow in .github/workflows runs on macos-15.

The compute-unit setting does change CoreML's behaviour; it just moves the failure rather than clearing it. The four presets split cleanly into two groups.

ANE-targeting presetsdefault, all-ane:

predictionFailed(stage: "vocoder", underlying: Error Domain=com.apple.CoreML Code=0
  "Failed to prepare the model for predictions. ML program was KokoroVocoder and the
   function name was main."
  NSUnderlyingError=... Error Domain=com.apple.CoreML Code=0
  "E5RT: Output rank has changed after reshaping espresso network for
   blob = anchor_classic_cpu (11)")

Non-ANE presetscpu-and-gpu, cpu-only:

predictionFailed(stage: "vocoder", underlying: Error Domain=com.apple.CoreML Code=1
  "Invalid shape for output feature 'anchor'."
  NSUnderlyingError=... Error Domain=com.apple.CoreML Code=1
  "According to model description, feature 'anchor' must be of rank 1, instead got a
   multi-array value of rank 2.")

cpu-only fails identically to cpu-and-gpu, so the rank mismatch is not GPU-specific — it is on the CPU path of the vocoder.

Environment

FluidAudio 0.14.8 (pinned exactly)
OS macOS 14.8.7, build 23J520
Arch arm64, Apple M1 (Virtual)
Runner GitHub-hosted macos-14
Toolchain Xcode 16.2 (Swift 6)
Variant .english, voice af_heart

For contrast, the same code path with the same staged model bundle synthesizes fine on a physical M2 (macOS 26.5.2) under all four presets.

Why this looks like a gap rather than misuse

  • Package.swift at v0.14.8 declares platforms: [.macOS(.v14), .iOS(.v17)].
  • KokoroAne has no @available annotation anywhere under Sources/FluidAudio/TTS/. Qwen3 does — @available(macOS 15, iOS 18, *) on Qwen3AsrManager, Qwen3AsrModels, Qwen3StreamingManager — so per-feature OS gating is clearly the established pattern when a feature needs macOS 15. Its absence on KokoroAne reads as intentional.
  • Documentation/TTS/ makes no macOS 15 claim.
  • Every workflow under .github/workflows/ runs on macos-15, so nothing exercises the declared floor.

If macOS 14 is in fact not supported for KokoroAne, an @available(macOS 15, ...) gate would turn this runtime failure into a compile-time one and answer the question at the API surface. That would be a perfectly good resolution — it just is not the current state.

Possibly related

On the physical M2, cpu-and-gpu emits E5RT "Data-dependent shapes were disabled" diagnostics to stdout and recovers internally; synthesis succeeds. The rank-2-instead-of-rank-1 result on the virtual M1 may be the same data-dependent-shape path failing to recover rather than a separate defect — but I have not established that link and am flagging it only as a lead.

Separately, those diagnostics going to stdout is awkward for any caller streaming WAV bytes there; that may deserve its own issue if it is not already known.

Reproduction

Honest caveat up front: I hit this through fluidaudio-rs, a Rust binding, not from pure Swift. The bridge is thin at the failing point — it calls manager.synthesize(text:voice:speed:) directly, and the thrown value is FluidAudio's own KokoroAneError.predictionFailed, raised in KokoroAneSynthesizer.predict around model.prediction(from:). I do not have a macOS 14 host to run a Swift-only case on, so I have not confirmed the binding is irrelevant, only that it does nothing between the call and the error.

The Swift equivalent should be:

let manager = KokoroAneManager(
    variant: .english,
    defaultVoice: "af_heart",
    computeUnits: KokoroAneComputeUnits(preset: .cpuOnly))
try await manager.initialize(preloadVoices: ["af_heart"])
let audio = try await manager.synthesize(text: "Hello world", voice: "af_heart", speed: 1.0)

initialize succeeds — it only downloads and loads the mlmodelcs, and issues no prediction. The failure lands on the first synthesize.

To reproduce in CI, add a macos-14 job and select Xcode 16 explicitly: that image's default toolchain is Swift 5.10, which cannot build a Swift-tools-6.0 package, and it ships no plain Xcode_16.app — only Xcode_16.1 / Xcode_16.2.

Full run with all four presets, per-preset stderr and host details:
https://github.com/FluidInference/fluidaudio-rs/actions/runs/31007985381

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions