From 1b14c26b7b774ac3e96d53533ca5474240180c8a Mon Sep 17 00:00:00 2001 From: Andres Marafioti Date: Fri, 25 Sep 2026 09:39:08 +0200 Subject: [PATCH] Publish macOS Metal wheels alongside Linux wheels on PyPI --- .github/workflows/metal-wheel.yml | 10 ++++++++-- .github/workflows/publish.yml | 8 +++++++- AGENTS.md | 11 +++++++---- 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/.github/workflows/metal-wheel.yml b/.github/workflows/metal-wheel.yml index f8bde95..e0971a5 100644 --- a/.github/workflows/metal-wheel.yml +++ b/.github/workflows/metal-wheel.yml @@ -10,6 +10,10 @@ name: Apple Silicon Metal wheel default: 7df559a8ca25f66fee02970514ebe5f01dee9055 workflow_call: inputs: + pypi: + description: Build a public version for PyPI instead of a Hugging Face local version + type: boolean + default: false qwentts_ref: type: string default: 7df559a8ca25f66fee02970514ebe5f01dee9055 @@ -39,10 +43,12 @@ jobs: git -C third_party/qwentts.cpp fetch --depth 1 origin "$QWENTTS_REF" git -C third_party/qwentts.cpp checkout --detach FETCH_HEAD git -C third_party/qwentts.cpp submodule update --init --recursive --depth 1 + - name: Set Hugging Face local version + if: ${{ !inputs.pypi }} + run: python scripts/set_local_version.py metal - name: Build and repair Metal wheel run: | test "$(uname -m)" = arm64 - python scripts/set_local_version.py metal python scripts/build_native.py --backend metal --clean # setup-python may provide universal2 Python; the bundled dylibs are arm64 only. python -m build --wheel --config-setting=--build-option=--plat-name=macosx_14_0_arm64 @@ -67,5 +73,5 @@ jobs: "from qwentts_cpp import QwenLibrary; lib = QwenLibrary(); print(lib.path); print(lib.version())" - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: - name: hf-wheel-metal-macosx-arm64 + name: ${{ inputs.pypi && 'wheel-metal-macosx-arm64' || 'hf-wheel-metal-macosx-arm64' }} path: wheelhouse/*.whl diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 7a70b04..e637e2c 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -15,6 +15,12 @@ permissions: contents: read jobs: + build-metal-wheel: + uses: ./.github/workflows/metal-wheel.yml + with: + pypi: true + qwentts_ref: ${{ inputs.qwentts_ref || '7df559a8ca25f66fee02970514ebe5f01dee9055' }} + build-wheels: name: Linux ${{ matrix.arch }} CUDA 12.8 wheel runs-on: ${{ matrix.runner }} @@ -110,7 +116,7 @@ jobs: check: name: Check distributions - needs: build-wheels + needs: [build-wheels, build-metal-wheel] runs-on: ubuntu-latest steps: - uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0 diff --git a/AGENTS.md b/AGENTS.md index 271d8be..f8288fe 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -8,11 +8,13 @@ PyPI publishing is handled by GitHub Actions in `.github/workflows/publish.yml`. The workflow runs on pushed tags that match `v*`, builds the public Linux CUDA -12.8 wheels, checks the artifacts with `twine check --strict`, and publishes +12.8 and macOS Metal wheels, checks the artifacts with `twine check --strict`, and publishes through the configured `pypi` environment. -The public `qwentts-cpp-python` package currently publishes CUDA 12.8 wheels -only. Publishing multiple backend flavors under the same package name, version, +The public `qwentts-cpp-python` package publishes CUDA 12.8 wheels for Linux +and Metal wheels for macOS 14+ arm64, using plain public versions for both. +Their platform tags let pip select the appropriate wheel automatically. +Publishing multiple backend flavors under the same package name, version, and platform tag would leave pip with no reliable way to choose the intended runtime. @@ -31,7 +33,8 @@ PyPI. The `+metal` flavor is a macOS 14+ arm64 wheel with embedded Metal shaders and bundled native dylibs. The reusable `.github/workflows/metal-wheel.yml` builds, repairs, validates ABI layouts, and tests a clean wheel install. It runs for PRs -and is also called by validation and Hugging Face publishing. GPU synthesis is +and is also called by validation, PyPI publishing (with `pypi: true` to omit +the local version suffix), and Hugging Face publishing. GPU synthesis is tested locally with `scripts/smoke_stream.py --require-metal` and local weights. Pull requests do not run the Linux wheel matrix. Do not run the validation