Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Building for MacOS and iOS #14

Open
jaocode opened this issue Sep 29, 2023 · 16 comments
Open

Building for MacOS and iOS #14

jaocode opened this issue Sep 29, 2023 · 16 comments

Comments

@jaocode
Copy link

jaocode commented Sep 29, 2023

I'm looking for instructions on how to build this for use with Python on MacOS. The piper-tts pip package exists for MacOS, but this dependency does not. I assume it is possible because there is a MacOS build of the library.

I'd also like to build this for use with iOS. Has this been attempted?

@nickolay
Copy link

nickolay commented Dec 3, 2023

I was curious about it too and saw #13, which motivated me to try and get it running. The following worked on my machine (Intel, Ventura, macports):

  1. The C++ build worked with no modification (assuming you have the common build prerequisites, such as XCode tools and cmake):
    $ git clone [email protected]:rhasspy/piper-phonemize.git pp
    $ cd pp
    $ git checkout fccd4f335aa68ac0b72600822f34d84363daa2bf -b my   # (tag: 2023.11.14-4, Date:   Tue Nov 14 11:54:34 2023 -0600)
    $ make
    
  2. To get the test binary working I had to override the default library and --espeak-data paths, as by default it was looking only in global folders (e.g. /usr)
    $ export DYLD_LIBRARY_PATH=`pwd`/install/lib/   # otherwise I got: dyld[82606]: Library not loaded: @rpath/libpiper_phonemize.1.dylib
    $ echo "testing one two three" | ./install/bin/piper_phonemize -l en-us --espeak-data ./install/share/espeak-ng-data/
    
  3. To build the python package, I needed to tweak the path to the C++ headers and libraries from step 1 again (I see that similar changes were needed for a Windows build), and also to change __version__ to the one piper-tts expects:
    $ python -m venv venv
    $ source venv/bin/activate
    $ pip install -U pip
    $ patch -p1 <<EOF
    --- a/setup.py
    +++ b/setup.py
    @@ -9 +9 @@ _DIR = Path(__file__).parent
    -_ESPEAK_DIR = _DIR / "espeak-ng" / "build"
    +_ESPEAK_DIR = _DIR / "install"
    @@ -13 +13 @@ _ONNXRUNTIME_DIR = _LIB_DIR / "onnxruntime"
    -__version__ = "1.2.0"
    +__version__ = "1.1.0"
    EOF
    $ pip install .
    $ cp -rp ./install/share/espeak-ng-data venv/lib/python3.10/site-packages/piper_phonemize/espeak-ng-data   # Otherwise I got Error processing file '/usr/share/espeak-ng-data/phontab': No such file or directory.
    
  4. Afterwards I was able to install and use piper-tts:
    $ pip install piper-tts
    $ echo 'Welcome to the world of speech synthesis!' |   venv/bin/piper --model en_US-lessac-medium --output_file welcome.wav
    $ afplay welcome.wav
    

@williamcorney
Copy link

Thanks @nickolay for posting that you got it working and the steps you had to take

I had prior to your post made further attempts but given up.

Can you clarify a few points ?

1.The test binary mentioned in second step is the one you built in first step I presume and which resides in the folder you did the build eg downloads.

2.are the exports commands in step 2 exactly what I would need to run , or is there any alteration I need to make depending where I built the piper-phonemize

  1. I’m not really clear what location pwd/install/lib/‘ refers to. It sounds like this is the equivalent of a command like ./foldername which appends the path of parent folder to make a complete path ?
  2. are the commands in step 3 to build the python modules exactly what anyone needs to copy paste to get this working? Do you have to be in a particular location or folder when you run ?

Thankyou

@nickolay
Copy link

nickolay commented Dec 3, 2023

Hey @williamcorney, I tested this specific sequence of commands from scratch before posting, but I can't guarantee it will work for everyone. (In addition to than what I have already mentioned, I was using bash and Python 3.10 for this.)

Re your first point: I cloned this repository to a local folder named pp in (1.1); all the other paths are relative to this directory. Both ./ and `pwd`/ refer to the current directory (so pp in my guide), so the location of the root (pp) folder shouldn't matter.

Yes, the ./install folder was created after I ran make. It has a bin subfolder, containing the test binary, also include, lib, and share.

Re your 2nd and 3rd questions: you should be able to re-use the commands with no modifications. You're right about the meaning of `pwd`/ — I used the absolute path for DYLD_LIBRARY_PATH to be able to invoke piper-tts after having changed the current directory. You will see that it resolves to the install/lib subdirectory of the git working directory, e.g.:

$ echo $DYLD_LIBRARY_PATH
/Users/nickolay/pp/install/lib/

Re 4th question: the step 3 continues the commands from steps 1 and 2, so is executed inside the same git checkout (named pp in my example).

If you have trouble with the multiline-heredoc patch -p0 <<EOF, you can instead edit setup.py by hand. The last command might need updating if the location of site-packages in your python virtual environment created via python -m venv venv is different. I'm just putting the espeak data to the folder that piper-phonemize expects.

@williamcorney
Copy link

williamcorney commented Dec 3, 2023

Thankyou @nickolay :)

Great work

I have been able to get through all the steps and replicate your success.

Notes from my own experience

  1. I had to run 'git clone https://github.com/rhasspy/piper-phonemize.git pp' instead
  2. I had in my case to modify the line with python 3.10 to 3.11
  3. I had already prior to attempting your steps installed piper-tts by overriding dependencies and it was necessary for me to remove piper-tts then rebuild/reinstall after run the patches to setup.py.

I wasn't familiar with the patch function you used to patch the setup.py file so confused at first. Handy little feature thanks for introducing me to that.

@jaocode
Copy link
Author

jaocode commented Dec 8, 2023

Thank you @nickolay and @williamcorney. Following your responses I was able to build and install it on my M1 MacBook.

@phillipeloher
Copy link

Thank you @nickolay , your steps worked perfectly.

@williamcorney
Copy link

another step I found to be necessary after reinstalling recently

Error
[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1000)>

Cause
It seems that, for some reason, Brew has not run the Install Certificates.command that comes in the Python3 bundle for Mac.

Solution

The solution to this issue is to run the following script (copied from Install Certificates.command) after brew install python3. I havent pasted here to not spam this post but you can see the full post here.

https://stackoverflow.com/questions/44649449/brew-installation-of-python-3-6-1-ssl-certificate-verify-failed-certificate/44649450#44649450

@williamcorney
Copy link

williamcorney commented Mar 8, 2024

I have created wheels for python 3.10 and 3.12 which makes this work much smoother now :)

It was a sharp learning curve to understand what needed to be done as barely understood what a wheel was before let alone how to make one lol

download and extract the whl file and install by running the command

pip3 install -f /REPLACE/WITH/PATH/WHERE/YOU/DOWNLOADED/WHEEL/FILE piper-phonemize

piper_phonemize-1.1.0-cp310-cp310-macosx_13_0_x86_64.whl.zip
piper_phonemize-1.1.0-cp311-cp311-macosx_13_0_x86_64.whl.zip
piper_phonemize-1.1.0-cp312-cp312-macosx_13_0_x86_64.whl.zip
piper_phonemize-1.1.0-cp311-cp311-macosx_10_14_x86_64.whl.zip
piper_phonemize-1.1.0-cp312-cp312-macosx_10_14_universal2.whl.zip

These of course are intended for Intel based Mac.

image

@williamcorney
Copy link

@synesthesiam

Can these wheels be added to pypi for macos ? I haven't done before so not sure the process

Thank you

@synesthesiam
Copy link
Contributor

I've uploaded the wheels above to PyPI 👍

@brainiakk
Copy link

Thanks alot @nickolay & @williamcorney 💆🏼‍♂️ my head aches from trying to install this for weeks, but this fixed it. I don't know why espeak-ng is not available for mac or on brew and I honestly don't understand why some great py libraries installation process on mac is just horrific, it's like mac is an afterthought for some devs 😂

@bluevisor
Copy link

Can someone point me to the right direction of how to make this work on an ARM Mac please?

@williamcorney
Copy link

williamcorney commented May 4, 2024

Building piper-phonemize from source

  1. Open a terminal window

  2. Install Xcode command line tools xcode-select --install

  3. Install homebrew /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

  4. Install cmake with homebrew brew install cmake

  5. Run these commands
    git clone https://github.com/rhasspy/piper-phonemize.git pp
    cd pp
    git checkout fccd4f335aa68ac0b72600822f34d84363daa2bf -b my
    make

  6. Run export command to include location in DYLD_LIBRARY_PATH
    export DYLD_LIBRARY_PATH=`pwd`/install/lib/

  7. Test piper-phonemize
    echo "testing one two three" | ./install/bin/piper_phonemize -l en-us --espeak-data ./install/share/espeak-ng-data/

  8. Create a new python virtual environment
    python -m venv venv

  9. Activate environment
    source venv/bin/activate

  10. Use the following command to patch the setup.py with necessary changes
    patch -p1 <<EOF --- a/setup.py +++ b/setup.py @@ -9 +9 @@ _DIR = Path(__file__).parent -_ESPEAK_DIR = _DIR / "espeak-ng" / "build" +_ESPEAK_DIR = _DIR / "install" @@ -13 +13 @@ _ONNXRUNTIME_DIR = _LIB_DIR / "onnxruntime" -__version__ = "1.2.0" +__version__ = "1.1.0" EOF
    If any issue with the above long command, there is a copy earlier in thread which I know works.

  11. Install package locally
    pip install .

  12. Copy espeak-ng data to necessary folder ( amend if you have different python version)
    cp -rp ./install/share/espeak-ng-data venv/lib/python3.12/site-packages/piper_phonemize/espeak-ng-data

  13. Install piper-tts
    pip install piper-tts

  14. Test piper-tts
    echo 'Welcome to the world of speech synthesis!' | venv/bin/piper --model en_US-lessac-medium --output_file welcome.wav

Creating a wheel

These are optional but recommended steps.
If you dont then you will have to run step (2) above each and every time you open a terminal AND always give the absolute path to piper when you call it. I also found that I couldn't use the module properly in pycharm until I had installed it from my newly created wheel. Note the wheel is linked to the version of python and the architecture. You may find you need to create a separate wheel for pycharm as it may use a different version of python interpreter than terminal is using
If you create the wheel you can then uninstall piper-phonemize and reinstall from the wheel
You could share the wheel here for anyone else. There is a command you can run to make a more universal wheel.
I'll leave that as homework :)

  1. Install necessary packages
    pip install wheel setuptools pybind11 delocate
  2. Create wheel
    python3 setup.py bdist_wheel
  3. List dependencies of piper-phonemize.
    delocate-listdeps /example/location/of/wheel/file
    e.g. /Users/myname/pp/dist/piper_phonemize-1.1.0-cp312-cp312-macosx_10_14_universal2.whl
  4. Update wheel with the dependencies. Size of wheel will grow accordingly
    delocate-listdeps /example/location/of/wheel/file

@bluevisor
Copy link

bluevisor commented May 4, 2024

Building piper-phonemize from source

  1. Open a terminal window
  2. Install Xcode command line tools xcode-select --install
  3. Install homebrew /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
  4. Install cmake with homebrew brew install cmake
  5. Run these commands
    git clone https://github.com/rhasspy/piper-phonemize.git pp
    cd pp
    git checkout fccd4f335aa68ac0b72600822f34d84363daa2bf -b my
    make
  6. Run export command to include location in DYLD_LIBRARY_PATH
    export DYLD_LIBRARY_PATH=`pwd`/install/lib/
  7. Test piper-phonemize
    echo "testing one two three" | ./install/bin/piper_phonemize -l en-us --espeak-data ./install/share/espeak-ng-data/
  8. Create a new python virtual environment
    python -m venv venv
  9. Activate environment
    source venv/bin/activate
  10. Use the following command to patch the setup.py with necessary changes
    patch -p1 <<EOF --- a/setup.py +++ b/setup.py @@ -9 +9 @@ _DIR = Path(__file__).parent -_ESPEAK_DIR = _DIR / "espeak-ng" / "build" +_ESPEAK_DIR = _DIR / "install" @@ -13 +13 @@ _ONNXRUNTIME_DIR = _LIB_DIR / "onnxruntime" -__version__ = "1.2.0" +__version__ = "1.1.0" EOF
    If any issue with the above long command, there is a copy earlier in thread which I know works.
  11. Install package locally
    pip install .
  12. Copy espeak-ng data to necessary folder ( amend if you have different python version)
    cp -rp ./install/share/espeak-ng-data venv/lib/python3.12/site-packages/piper_phonemize/espeak-ng-data
  13. Install piper-tts
    pip install piper-tts
  14. Test piper-tts
    echo 'Welcome to the world of speech synthesis!' | venv/bin/piper --model en_US-lessac-medium --output_file welcome.wav

Creating a wheel

These are optional but recommended steps. If you dont then you will have to run step (2) above each and every time you open a terminal AND always give the absolute path to piper when you call it. I also found that I couldn't use the module properly in pycharm until I had installed it from my newly created wheel. Note the wheel is linked to the version of python and the architecture. You may find you need to create a separate wheel for pycharm as it may use a different version of python interpreter than terminal is using If you create the wheel you can then uninstall piper-phonemize and reinstall from the wheel You could share the wheel here for anyone else. There is a command you can run to make a more universal wheel. I'll leave that as homework :)

  1. Install necessary packages
    pip install wheel setuptools pybind11 delocate
  2. Create wheel
    python3 setup.py bdist_wheel
  3. List dependencies of piper-phonemize.
    delocate-listdeps /example/location/of/wheel/file
    e.g. /Users/myname/pp/dist/piper_phonemize-1.1.0-cp312-cp312-macosx_10_14_universal2.whl
  4. Update wheel with the dependencies. Size of wheel will grow accordingly
    delocate-listdeps /example/location/of/wheel/file

Thank you so much for the detailed instruction, I finally got it working!

A few things to note hope it helps others:
1, Above instruction assumes bash or zsh shell, if you are using fish shell like me, switch to bash first.
2, For step 10, copy and paste doesn't work, just enter these line by line:

$ patch -p1 <<EOF
--- a/setup.py
+++ b/setup.py
@@ -9 +9 @@ _DIR = Path(__file__).parent
-_ESPEAK_DIR = _DIR / "espeak-ng" / "build"
+_ESPEAK_DIR = _DIR / "install"
@@ -13 +13 @@ _ONNXRUNTIME_DIR = _LIB_DIR / "onnxruntime"
-__version__ = "1.2.0"
+__version__ = "1.1.0"
EOF

3, I'm attaching my wheel file here, don't know why it says osx11, I'm on 14.5.
piper_phonemize-1.1.0-cp311-cp311-macosx_11_0_arm64.whl.zip

@williamcorney
Copy link

I'm glad you got it sorted and good to know same steps works for arm64 too.

Great job :). Good to see the wheel there too.

@cverrier
Copy link

The solution given by @williamcorney does not work for me (macOS 14.6.1, Apple M1 Pro chip, Python 3.11.9, ZSH shell). First, I had to update Makefile (see below) due to an error with cd build && ctest --config Release:

.PHONY: all clean

all:
	cmake -Bbuild -DCMAKE_INSTALL_PREFIX=install -DCMAKE_BUILD_TYPE=Release
	cmake --build build
	cd build && ctest
	cmake --install build

clean:
	rm -rf build install

Then everything seemed to work, until I started building the wheel (step 3, 'List dependencies of piper-phonemize'): running

delocate-listdeps /Users/clementverrier/repos/piper-phonemize/dist/piper_phonemize-1.1.0-cp311-cp311-macosx_14_0_arm64.whl

led to the following output error:

ERROR:delocate.libsana:
@rpath/libespeak-ng.1.dylib not found:
  Needed by: /private/var/folders/2x/XXXXXXXX/T/tmpitpfjjp4/piper_phonemize_cpp.cpython-311-darwin.so
  Search path:

ERROR:delocate.libsana:
@rpath/libonnxruntime.1.14.1.dylib not found:
  Needed by: /private/var/folders/2x/XXXXXXXX/T/tmpitpfjjp4/piper_phonemize_cpp.cpython-311-darwin.so
  Search path:

ERROR:delocate.libsana:
@rpath/libespeak-ng.1.dylib not found:
  Needed by: /private/var/folders/2x/XXXXXXXX/T/tmpitpfjjp4/piper_phonemize_cpp.cpython-311-darwin.so
  Search path:

ERROR:delocate.libsana:@rpath/libespeak-ng.1.dylib not found, requested by /private/var/folders/2x/XXXXXXXX/T/tmpitpfjjp4/piper_phonemize_cpp.cpython-311-darwin.so
ERROR:delocate.libsana:
@rpath/libonnxruntime.1.14.1.dylib not found:
  Needed by: /private/var/folders/2x/XXXXXXXX/T/tmpitpfjjp4/piper_phonemize_cpp.cpython-311-darwin.so
  Search path:

ERROR:delocate.libsana:@rpath/libonnxruntime.1.14.1.dylib not found, requested by /private/var/folders/2x/XXXXXXXX/T/tmpitpfjjp4/piper_phonemize_cpp.cpython-311-darwin.so
/opt/homebrew/Cellar/llvm/18.1.8/lib/libunwind.1.0.dylib

I spent a consequent amount of time with an LLM trying to debug this stuff, but couldn't find a working solution so far. @bluevisor have you encountered other problems except those you mentioned?

@synesthesiam could you provide more information regarding the installation of piper via pip, including all its dependencies?

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

No branches or pull requests

8 participants