ci: add macOS arm64 (Metal) build - #5
Merged
Conversation
Adds a darwin-arm64-metal job covering [macos-14, macos-latest] that builds upstream whisper.cpp with Metal enabled and produces whisper-bin-darwin-arm64-metal.zip plus -latest variant. Wired into release.needs so the .zip lands in the same draft release as the existing Linux/Windows artifacts.
Same rationale as the sd.cpp fix: without this, binaries that link to shared libs would carry the runner's absolute build path in rpath and fail at runtime when the .zip is unpacked elsewhere.
superm1
previously approved these changes
May 1, 2026
Geramy
added a commit
to Geramy/lemonade
that referenced
this pull request
May 1, 2026
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.
Aligns the macOS arm64 Metal artifact's filename with the established
versioned pattern that v1.8.2 already uses for linux-cpu, linux-vulkan,
windows-npu (e.g. whisper-v1.8.2-linux-cpu-x86_64.tar.gz). The macOS
artifact now ships as:
whisper-{tag}-darwin-metal-arm64.tar.gz
whisper-{tag}-darwin-metal-arm64-latest.tar.gz (macos-latest)
Switched packaging from zip to tar.gz to match the linux artifacts'
extension (better for preserving Unix file modes and dylib symlinks
during extraction). The release-job's 'Move artifacts' and
'Upload release' steps now also accept *.tar.gz alongside *.zip so the
new files actually make it into the published release.
Member
Author
|
@superm1 I had renamed the output file to the correct formatting. |
Member
Check the ci failure |
Member
Author
looks like a transient issue, due to qemu I might re-arrange the jobs or adjust them to no longer use emu for linux on arm64 since GitHub has arm64 linux runners, there is no need to use qemu in fact it is just Suboptimal. |
… jobs
This fork has no self-hosted runners, so the upstream ggml-ci-* jobs that
target [self-hosted, ...] runner labels queued indefinitely on PRs.
- Retarget ggml-ci-mac-metal to macos-14. Move output paths from ~/results
and ~/mnt to ./tmp/ (home dir is wiped per run on hosted) and add
GG_BUILD_LOW_PERF=1 so the model set fits in macos-14's ~14GB free disk.
- Retarget ggml-ci-mac-vulkan to macos-14 with brew-installed MoltenVK,
vulkan-loader, vulkan-headers, vulkan-tools, glslang, shaderc. Set
VK_ICD_FILENAMES to MoltenVK's ICD JSON and CMAKE_PREFIX_PATH so CMake
finds the brew Vulkan. Same ./tmp/ + GG_BUILD_LOW_PERF=1 as mac-metal.
- Comment out (with re-enablement notes) the four jobs that need hardware
no GitHub-hosted runner provides:
- ggml-ci-x64-nvidia-cuda (NVIDIA GPU)
- ggml-ci-x64-nvidia-vulkan-cm (NVIDIA GPU)
- ggml-ci-x64-nvidia-vulkan-cm2 (Ada/Hopper NV w/ COOPMAT2)
- ggml-ci-x64-cpu-amx (Sapphire Rapids+ Xeon)
superm1
reviewed
May 4, 2026
superm1
previously approved these changes
May 4, 2026
superm1
left a comment
Member
There was a problem hiding this comment.
just a question on adding pointless commented out jobs. decide on that and then fine
First run failed at vulkaninfo with:
loader_get_json: Failed to open JSON file
/opt/homebrew/opt/molten-vk/share/vulkan/icd.d/MoltenVK_icd.json
Brew's molten-vk 1.4.1 no longer ships the ICD JSON at that path.
Find it dynamically under $(brew --prefix molten-vk); if absent, write
a minimal ICD JSON pointing at libMoltenVK.dylib (same approach
vulkan-tools uses for its mock ICD). set -euo pipefail to fail loudly
on future env changes.
None of these jobs are runnable on free GitHub-hosted runners and this
fork has no self-hosted runners. Removing entirely (previously commented
out, but now deleting the dead config too):
- ggml-ci-x64-nvidia-cuda (no NVIDIA GPU on hosted runners)
- ggml-ci-x64-nvidia-vulkan-cm (no NVIDIA GPU on hosted runners)
- ggml-ci-x64-nvidia-vulkan-cm2 (Ada/Hopper + COOPMAT2 unavailable)
- ggml-ci-x64-cpu-amx (Sapphire Rapids+ unavailable)
- ggml-ci-mac-vulkan (MoltenVK crashes on AppleParavirt-
Device - hosted Macs are virtualized
and lack the Metal API surface
MoltenVK requires)
ggml-ci-mac-metal stays - Metal works on the paravirt device.
superm1
approved these changes
May 5, 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>
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.
Adds a
darwin-arm64-metaljob covering[macos-14, macos-latest]that builds upstream whisper.cpp with Metal enabled and produceswhisper-bin-darwin-arm64-metal.zip(plus a…-latest.zipvariant). Wired intorelease.needs:so the new.ziplands in the same draft release as the existing Linux/Windows artifacts.Mirrors the flag set used by
ggml-org/llama.cpp'srelease.yml:-DGGML_METAL=ON -DGGML_METAL_USE_BF16=ON -DGGML_METAL_EMBED_LIBRARY=ON-DCMAKE_INSTALL_RPATH='@loader_path' -DCMAKE_BUILD_WITH_INSTALL_RPATH=ONso the produced binaries find their*.dylibsiblings via@loader_pathrather than the GitHub runner's absolute build directory (without this, downloaded archives crash withdyld: Library not loaded: @rpath/libwhisper.…dylib).End-to-end verification (Apple Silicon)
```
$ otool -l whisper-cli | grep -A2 LC_RPATH
cmd LC_RPATH
path @loader_path
$ ./whisper-cli -m ggml-tiny.en.bin -f samples/jfk.wav -np
[00:00:00.000 --> 00:00:07.960] And so my fellow Americans ask not what your country can do for you
[00:00:07.960 --> 00:00:10.760] ask what you can do for your country.
```
Real Metal-accelerated inference works. Round-trip with Kokoros TTS also passes (TTS-generated WAV → whisper-cli transcribes back the original text).
Release artifacts: https://github.com/Geramy/whisper.cpp-builds/releases/tag/b4078
Companion PRs to lemonade-sdk/stable-diffusion.cpp and lemonade-sdk/Kokoros add the same macOS arm64 coverage to the other two backends.