Skip to content

fix: fall back to onnxruntime/coremltools on Python 3.12+ - #204

Open
bodapatisaikrishna wants to merge 1 commit into
spotify:mainfrom
bodapatisaikrishna:fix/python-3.12-tensorflow-wheel-gap
Open

bodapatisaikrishna wants to merge 1 commit into
spotify:mainfrom
bodapatisaikrishna:fix/python-3.12-tensorflow-wheel-gap

Conversation

@bodapatisaikrishna

Copy link
Copy Markdown

Description

Fixes #203 (and the same root cause behind #159 and #188): on Python 3.12,
pip install basic-pitch fails to resolve at all, on any platform.

tensorflow/tensorflow-macos never published a cp312 wheel below version
2.16 (verified against PyPI's release metadata), but the dependency markers
cap both at <2.15.1 while still activating for python_version >= '3.11'
(non-Darwin) / python_version > '3.11' (Darwin) -- an unsatisfiable
constraint on 3.12.

Simply raising the version cap is not a safe fix. I installed
tensorflow-macos==2.16.2 and confirmed the bundled saved_models/icassp_2022/nmp
SavedModel fails to load:

AttributeError: '_UserObject' object has no attribute 'add_slot'

This is Keras 3 (TF 2.16's default) being unable to reconstruct the old
optimizer's object graph inside the SavedModel checkpoint. So relaxing the pin
would trade an install-time failure for a worse runtime one.

Fix

basic_pitch already bundles the model in three other formats
(nmp.onnx, nmp.tflite, nmp.mlpackage) and already has fallback logic in
basic_pitch/__init__.py (TF_PRESENT → CT_PRESENT → TFLITE_PRESENT →
ONNX_PRESENT) to pick whichever backend is installed. On Python 3.12+:

  • Darwin: coremltools is already an unconditional dependency there, so no
    new dependency is needed -- it becomes the default backend automatically.
  • Non-Darwin (Linux/Windows): added onnxruntime (has cp312+ wheels) as the
    dependency, so onnxruntime becomes the default backend.

tensorflow/tensorflow-macos (both in dependencies and the [tf] extra)
are now excluded on python_version >= '3.12' instead of installing something
that can't load the model. Added the Python :: 3.12 classifier.

Testing Instructions

Verified with real inference, not just pip install --dry-run:

  1. Confirmed the vulnerability/bug is real: tensorflow-macos==2.16.2
    raises the add_slot error above when loading the bundled model.

  2. Confirmed ONNX and CoreML produce matching output to the current
    TensorFlow 2.15.0 path, by running basic_pitch.inference.predict() on
    tests/resources/vocadito_10.wav against all three backends directly:

    backend note events note sum
    tensorflow-macos 2.15.0 (current) 28 7604.52099609375
    onnxruntime (nmp.onnx) 28 7604.51904296875
    coremltools (nmp.mlpackage) 28 7604.52099609375
  3. Confirmed the fix end-to-end on real Python 3.12.0, macOS arm64 (the
    exact environment from macOS Python 3.12 dependency marker selects TensorFlow-macOS without cp312 wheels #203's repro): uv pip install --dry-run now
    resolves cleanly (installs coremltools, no tensorflow-macos attempted);
    a real install correctly reports TF_PRESENT: False, CT_PRESENT: True,
    auto-selects the .mlpackage model, and predict() produces the same 28
    note events with matching output sums as the TensorFlow 2.15.0 baseline.

  4. Ran tests/test_inference.py on both the existing Python 3.11 (TF) path
    and the new Python 3.12 (CoreML) path: 8/9 pass on 3.12. The one failure
    (test_predict) is a pre-existing, unrelated issue -- librosa.get_duration(filename=...)
    was deprecated in librosa 0.10.0 and removed in 1.0.0, which is what a
    fresh librosa>=0.8.0 install now resolves to. I did not fix it here
    since path= (the replacement kwarg) doesn't exist before librosa 0.10.0,
    and basic-pitch supports librosa>=0.8.0 with no upper bound -- a
    version-safe fix is a separate, unrelated piece of work. Verified this
    failure is unrelated to this PR by reproducing it on the current Python
    3.11/TensorFlow path too (same error, same cause, present on main).

Additional Information

tensorflow/tensorflow-macos never published a cp312 wheel below
version 2.16 (verified against PyPI release metadata), but the
dependency markers cap both at <2.15.1 while still activating for
python_version >= 3.11 (non-Darwin) / > 3.11 (Darwin) -- an
unsatisfiable constraint on Python 3.12. Fixes spotify#203 (same root cause
as spotify#159, spotify#188).

Simply raising the version cap is not safe: tensorflow-macos==2.16.2
fails to load the bundled SavedModel with
AttributeError("'_UserObject' object has no attribute 'add_slot'"),
Keras 3's optimizer object graph being incompatible with the old
checkpoint. Verified this empirically before choosing the fix below.

basic_pitch already bundles the model in ONNX/TFLite/CoreML formats
and already has fallback backend-selection logic. On Python 3.12+:
exclude tensorflow(-macos) (both in `dependencies` and the `[tf]`
extra) so it isn't attempted where it can't work; add onnxruntime
(has cp312+ wheels) for non-Darwin, since coremltools is already an
unconditional Darwin dependency and becomes the default there for
free. Added the Python :: 3.12 classifier.

Verified ONNX and CoreML backends produce output matching the current
TensorFlow 2.15.0 path (28 note events, matching sums) via direct
predict() calls, and verified the full fix end-to-end on real Python
3.12.0 macOS arm64: install resolves cleanly, auto-selects coremltools,
and produces matching inference output.
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.

macOS Python 3.12 dependency marker selects TensorFlow-macOS without cp312 wheels

1 participant