Skip to content

ci: add macOS arm64 build + fix release upload permissions - #4

Merged
superm1 merged 3 commits into
lemonade-sdk:mainfrom
Geramy:geramy/macos-arm64-ci
May 1, 2026
Merged

superm1 merged 3 commits into
lemonade-sdk:mainfrom
Geramy:geramy/macos-arm64-ci

Conversation

@Geramy

@Geramy Geramy commented Apr 30, 2026

Copy link
Copy Markdown
Member

Two related fixes in this branch:

1. macOS arm64 build (kokoros-darwin-arm64.tar.gz)

Adds [macos-14, macos-latest] matrix entries targeting aarch64-apple-darwin. Both produce tarballs named kokoros-darwin-arm64.tar.gz (and …-latest.tar.gz), shaped identically to the existing Linux/Windows ones. fail-fast: false so a flake on one platform doesn't cancel the others.

audiopus_sys requires cmake and libopus at build time; Linux runners get these via apt but macOS runners don't, so a brew install cmake opus step is added gated on startsWith(matrix.os, 'macos').

2. permissions: contents: write at workflow level

This is a fix for a pre-existing issue I hit when running the workflow on my fork — every release-asset upload step (Linux, Windows, and now macOS) fails with RequestError [HttpError]: Resource not accessible by integration because the default GITHUB_TOKEN is read-only without an explicit permissions: block. With this added, all four matrix entries can publish to the b{run_number} release.

End-to-end verification (Apple Silicon)

Tested on a real M-series Mac:

```
$ tar -xzf kokoros-darwin-arm64.tar.gz
$ ./darwin-arm64/koko text "test" -o out.wav
$ afinfo out.wav
Data format: 2 ch, 24000 Hz, Float32, interleaved
estimated duration: 1.500000 sec
```

Round-tripped through whisper.cpp Metal — the WAV transcribed back as "Test." Release artifacts here: https://github.com/Geramy/Kokoros/releases/tag/b2

Worth noting: the macOS tarball also bundles the model + voices files (checkpoints/kokoro-v1.0.onnx, data/voices-v1.0.bin), so koko text … works out-of-the-box with no extra downloads.

Geramy added 2 commits April 27, 2026 21:43
Adds two macOS arm64 matrix entries (macos-14 + macos-latest) targeting
aarch64-apple-darwin, producing kokoros-darwin-arm64.tar.gz and
kokoros-darwin-arm64-latest.tar.gz. Both attach to the same b<run_number>
release as the existing Linux/Windows builds. fail-fast disabled so a flake
on one platform doesn't cancel the others.
Two fixes bundled:

1. macOS build was failing in audiopus_sys's CMake step because cmake +
   libopus aren't preinstalled on macos-14/macos-latest runners (Linux
   runners have them via apt). Add a 'brew install cmake opus' step gated
   on macOS runners.

2. The Linux + Windows builds succeeded but couldn't attach assets to a
   release (HTTP 'Resource not accessible by integration') because the
   workflow-level GITHUB_TOKEN defaulted to read-only. Add
   permissions.contents: write so all four matrix entries can publish.
@Geramy
Geramy requested a review from superm1 April 30, 2026 20:17
…ith backend ID

Lemonade is adopting a 'metal' backend identifier for macOS arm64
recipes (mirroring llamacpp/metal). Renaming the macOS archives to
include the -metal suffix keeps the naming consistent across all 3
macOS builds (whisper-bin-darwin-arm64-metal.zip,
sd-…-Darwin-arm64-metal.zip, kokoros-darwin-arm64-metal.tar.gz). On
macOS the koko binary uses ONNX Runtime which has CoreML / Metal
execution providers available, so the label is not purely cosmetic.
@superm1
superm1 merged commit d122b52 into lemonade-sdk:main May 1, 2026
meghsat pushed a commit to lemonade-sdk/lemonade that referenced this pull request Jul 10, 2026
…-cpp (#1777)

* feat(macos): add macOS arm64 (Metal) backends for whisper, kokoros, sd-cpp

Introduces a 'metal' backend identifier for whispercpp, kokoro, and
sd-cpp that mirrors the existing llamacpp/metal pattern: macOS arm64
gets its own row in the recipe matrix, its own arm in each backend's
get_install_params, and its own version pin in backend_versions.json.
No more conflating macOS arm64 with the existing windows/linux cpu
backends.

Source repos for the new artifacts:
  - whispercpp/metal -> lemonade-sdk/whisper.cpp-builds
                       (whisper-bin-darwin-arm64-metal.zip)
  - kokoro/metal     -> lemonade-sdk/Kokoros
                       (kokoros-darwin-arm64-metal.tar.gz)
  - sd-cpp/metal     -> lemonade-sdk/stable-diffusion.cpp
                       (sd-{ver}-bin-Darwin-arm64-metal.zip)

The previous code paths for macOS were dead in two of three cases:
  - whisper_server.cpp pointed at ggml-org/whisper.cpp's
    'whisper-bin-arm64.zip', which has never existed in any of the
    upstream's 32 releases.
  - kokoro_server.cpp threw 'Unsupported platform for kokoros'.
  - sd_server.cpp pointed at a hardcoded 'Darwin-macOS-15.7.2-arm64.zip'
    name that did exist in lemonade-sdk releases master-494..master-555
    but stopped being published around master-585.

Cleanup:
  - whisper_server.cpp: drop dead __APPLE__ arm in cpu branch (which
    referenced the never-published upstream artifact). cpu now only
    targets windows + linux as the matrix says.
  - sd_server.cpp: drop dead __APPLE__ arm in cpu branch (matched a
    moving runner-version filename that hasn't shipped recently).
    cpu now only targets windows + linux.
  - kokoro_server.cpp: switch from hardcoded 'cpu' to a platform-resolved
    backend so the load() flow picks 'metal' on Apple Silicon and 'cpu'
    elsewhere. kokoro doesn't have user-selectable backends through
    RuntimeConfig so this stays implicit.
  - whisper_server.cpp / sd_server.cpp: include 'metal' in the
    DEVICE_GPU branch of the device-type detection.

Blocked on three companion build-farm PRs that publish the artifacts
this code references:
  - lemonade-sdk/stable-diffusion.cpp#2
  - lemonade-sdk/Kokoros#4
  - lemonade-sdk/whisper.cpp-builds#5

backend_versions.json placeholder pins reuse the current cpu/etc.
versions; they need bumping to whatever new release tags are cut after
the build-farm PRs merge, before this PR can be marked ready for
review and tested end-to-end on macOS.

* fix(whisper): use whisper-{ver}-darwin-metal-arm64.tar.gz on macOS

Aligns the macOS Metal download path with the established
whisper-{tag}-{plat}-{backend}-{arch}.{ext} convention used by the
linux-cpu, linux-vulkan, and windows-npu pins. Pairs with
lemonade-sdk/whisper.cpp-builds#5 which renames the published
artifact to match.

* fix(sd-cpp): pin metal to master-593-7f65f2a (Darwin-arm64 asset)

The previously pinned master-569-ab6afe8 release does not publish a
sd-*-bin-Darwin-arm64-metal.zip asset, so macOS install fails.
master-593-7f65f2a includes the Darwin-arm64-metal build.

* fix(kokoro): pin metal to b17 (Darwin-arm64 asset)

* Resolved review comments, removing redundant checks and dummy code.

* ci: capture server logs from Linux test-cli-endpoints jobs

The Test ollama (ubuntu-latest) failure on this branch returns 404 from
/api/generate but no server log is uploaded for diagnosis. Add the same
capture-server-logs step the Windows/macOS jobs and the deb test jobs
already use, so the next run produces a downloadable artifact.

* deps: bump sd-cpp pins to master-596-b6f38cd (portable AVX2 baseline)

The master-593 release of sd-cpp was built with -march=native on a runner
with AVX-512, baking 5,396 zmm + 1,582 k-mask AVX-512 instructions into
libstable-diffusion.so. That binary SIGILLed on AVX-512-less GitHub-hosted
ubuntu-latest runners — surfaced as Test ollama (ubuntu-latest) failing
test_022_generate_image_output with sd-server "exit code: -1" within 200ms.

master-596 is the first release after lemonade-sdk/stable-diffusion.cpp#3,
which pins the Linux x86_64 cpu and rocm builds to GGML_NATIVE=OFF +
AVX2/FMA/F16C. Verified: 0 zmm refs, 0 k-mask refs, 12,720 ymm refs.

* This code was filtering out ALL sdcpp, kokoro, whispercpp, flm, and other non-llamacpp models from `get_supported_models()` on macOS. Since the Model Manager UI fetches models via `/models?show_all=true` which calls `get_supported_models()`, the categories appeared empty even after downloading backends.

* re-enable macos CI

* added macos guards to tests.

* add ci tests to macos

* running lemonade as non system service for whisper ci process, since a non signed binary cant run as a service.

* additional test.

* bump whisper.cpp backend versions to v1.8.3

* fix: run macOS unsigned builds directly from build/ with artifact sharing

- Replace /usr/local/bin/ system install with direct build/ execution for unsigned paths
- Upload built binaries as GitHub Actions artifact from build-lemonade-macos-dmg job
- Download artifacts in test-dmg-inference (fresh runner) and verify binaries
- Start lemond once before matrix tests, keep running for all inference tests
- Avoids race conditions from per-test server restarts

* fix: restore execute permissions on downloaded macOS binaries

GitHub Actions artifacts strip executable permissions on download.
Add chmod +x both before upload and after download to fix
'Permission denied' errors when running binaries.

* bump whisper.cpp backend versions to v1.8.4

Picks up the fix-release-archive-format release on
lemonade-sdk/whisper.cpp-builds, which produces correctly formatted
Linux tarballs and Windows zips. v1.8.3 archives failed to extract
in CI (tar: Error is not recoverable / executable not found).

* fix(ci): include build/resources/ in unsigned macOS test artifact

The unsigned-path test-dmg-inference job downloads the
lemonade-unsigned-binaries artifact into build/ on a fresh runner,
but the artifact only contained the three binaries. lemond then
failed to start with 'Failed to open build/resources/defaults.json'
because get_resource_path resolves relative to the executable.

Add build/resources/ to the upload so defaults.json,
backend_versions.json, server_models.json and the static/web-app
trees are available alongside the binaries.

* test(sd-cpp): use smaller GGUF variant on macos-latest CI

The sd-cpp-metal matrix test on GitHub-hosted macos-latest (M1, 14 GB
RAM) consistently has sd-server die mid-load with SD-Turbo's 2.7 GB
safetensors checkpoint. Replace it with a quantized GGUF variant for
this matrix entry to reduce peak memory during load.

- Register SD-Turbo-GGUF (Green-Sky/SD-Turbo-GGUF, Q8_0, ~2 GB) with
  the same image_defaults so test_007's assertions still hold.
- Let SD_MODEL be overridden via LEMONADE_TEST_SD_MODEL so the rest
  of the test surface (local runs, other CI) keeps using SD-Turbo.
- Wire the override only into the sd-cpp-metal matrix entry via a new
  matrix.sd_model field.

* Disable sdcpp metal ci test

---------

Co-authored-by: Jeremy Fowers <80718789+jeremyfowers@users.noreply.github.com>
Co-authored-by: Jeremy Fowers <jeremy.fowers@amd.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants