From c7d2ed1920e4c6d68632976abc779e710122d04b Mon Sep 17 00:00:00 2001 From: Daniel Han Date: Wed, 3 Jun 2026 07:29:18 -0700 Subject: [PATCH] Fix macOS Apple Silicon installs resolving torch against x86_64 (#5976) * Fix macOS Apple Silicon installs that resolve torch against x86_64 On Apple Silicon, `uv venv --python 3.13` can reuse a cached x86_64 (Rosetta) CPython, often because uv itself is an x86_64 build. The resulting venv reports macosx_*_x86_64 to the wheel resolver, but PyTorch has shipped no macOS x86_64 wheels since 2.2.2, so the torch install fails with "no wheels with a matching platform tag (macosx_..._x86_64)". Two changes, both scoped to macOS arm64 and additive (no other install path is affected): - Create the venv with an arch-explicit `cpython-X.Y-macos-aarch64-none` request on Apple Silicon (no --python override), so uv cannot fall back to a cached x86_64 interpreter. - Harden the existing x86_64 venv guard: when the venv python cannot be executed (x86_64 binary on a Mac without Rosetta), the platform.machine() probe returns empty and the recreate was silently skipped. Fall back to reading the binary's Mach-O arch via lipo/file so migrated or pre-existing x86_64 venvs are still recreated as arm64. * Harden arm64 static-arch fallback: file -L and set -e safety Address review feedback on the lipo/file fallback: - uv symlinks the venv's bin/python to the base interpreter; plain `file` reports the symlink ("symbolic link to ...") and the arch substring never matches. Use `file -L` to dereference (lipo already follows the link). - Append `|| true` so the command substitution cannot abort the installer under set -e on a Mac that has neither lipo nor file. --------- Co-authored-by: danielhanchen --- install.sh | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/install.sh b/install.sh index 1d4d9067c1..d35d370313 100755 --- a/install.sh +++ b/install.sh @@ -1529,7 +1529,17 @@ fi if [ ! -x "$VENV_DIR/bin/python" ]; then step "venv" "creating Python ${PYTHON_VERSION} virtual environment" substep "$VENV_DIR" - run_install_cmd "create venv" uv venv "$VENV_DIR" --python "$PYTHON_VERSION" + if [ "$OS" = "macos" ] && [ "$_ARCH" = "arm64" ] && [ -z "$_USER_PYTHON" ]; then + # Apple Silicon: request an arch-explicit arm64 CPython so uv cannot + # reuse a cached x86_64 (Rosetta) build. torch ships no macOS x86_64 + # wheels since 2.2.2, so an x86_64 venv makes the torch install + # unresolvable. The arm64 guard below is kept as a backstop for + # migrated / pre-existing venvs. + run_install_cmd "create venv" uv venv "$VENV_DIR" \ + --python "cpython-${PYTHON_VERSION}-macos-aarch64-none" + else + run_install_cmd "create venv" uv venv "$VENV_DIR" --python "$PYTHON_VERSION" + fi fi # Mark the freshly-created venv as Studio-owned so a partial install can be @@ -1561,6 +1571,21 @@ if [ -z "$_USER_PYTHON" ] && [ "$OS" = "macos" ] && [ "$_ARCH" = "arm64" ]; then _info=$(_inspect_venv) _VENV_ARCH=${_info%% *} _PY_VER=${_info##* } + # If the interpreter could not be executed (an x86_64 venv python on a Mac + # without Rosetta installed), the probe above yields an empty arch. Fall + # back to reading the binary's Mach-O arch statically so the x86_64 + # recreate below still triggers instead of letting uv fail later. + if [ -z "$_VENV_ARCH" ] && [ -x "$VENV_DIR/bin/python" ]; then + # uv symlinks bin/python to the base interpreter, so dereference with + # file -L (lipo already follows the link). Trailing || true keeps the + # installer alive under set -e when neither tool is present. + _archs=$(lipo -archs "$VENV_DIR/bin/python" 2>/dev/null \ + || file -L "$VENV_DIR/bin/python" 2>/dev/null || true) + case "$_archs" in + *arm64*) _VENV_ARCH=arm64 ;; + *x86_64*) _VENV_ARCH=x86_64 ;; + esac + fi if [ "$_VENV_ARCH" = "x86_64" ]; then echo " WARNING: venv was created with an x86_64 (Rosetta) Python on Apple Silicon."