In my previous post (the first-ever post on here) I said I was going to start publishing today I learned (TIL) posts, where I share small things I learn throughout my day. I'm excited to say this is the first of the series, yay!
Today I want to share how I tried running Coqui-ai's text-to-speech (TTS) library on my M2 MacBook, failed, and how I fixed it. The issue was present for me with version 0.13.3 of the library. I hope it will be of use for those having the same issue, while at the same time showcasing a very simple but powerful strategy for debugging (other people's) Python code.
If you're here for the solution, check it out here:
Run
brew install mecab
to get rid of the installation error “[Errno 2] No such file or directory: 'mecab-config'“
(see this issue)Go to the TTS package source file
your_virtualenv/lib/python3.X/site-packages/TTS/utils/audio/processor.py
If you don’t know where to find the site-packages folder, try runningpython -m site
.On line 219,
self.inv_mel_basis = np.linalg.pinv(self._build_mel_basis())
,
replace thenp.linalg.pinv
withlinalg.pinv
, after importingfrom scipy import linalg
somewhere at the top of the file.
Obviously this is not really a sustainable solution, but at least it allows us to run the program on our machines. I might open up a pull request for this, so hopefully no one will have these issues after it's fixed.
Coqui-ai’s TTS is a free and open source library for running and training TTS models (amazing!). Since it is quite a popular library, with currently 10.9k stars on GitHub, I expected the most common usecase, running the TTS inference, to work without issue. Unfortunately this wasn't the case. After running tts-server --model_name "tts_models/nl/css10/vits"
, the program would crash with the following (rather cryptic) error: bus error tts-server --model_name "tts_models/nl/css10/vits"
. This turns out to be something like a segfault.
Now for the fun part: finding the issue. Let's put our bug hunter hats on 🪲.
I immediately suspected it was due to the M2 chip on my laptop. Apple's M1 and M2 chips are quite new CPU architectures, and proper support for them is still lacking in many cases.
As the program crashed on a memory error, it didn't even generate a stack trace, making it a lot harder to find the place where the program actually crashed.
Luckily we can debug any Python code using Python's built-in debugger pdb
. Just insert from pdb import set_trace; set_trace()
on any line you wish to break on, and you're good to go.
When you install a Python package, Python always stores its source in a specific location relative to the Python binary: .../site_packages/<package_name>
. As python is an interpreted language, we can debug any line of the 3rd party code we want. A very simple technique is simply dropping the set_trace
on program start, continuing line by line until the error is hit and the program crashes.
After an hour of trial and error, following import statements, and moving around the set_trace statement, I found the line where the program crashed:
self.inv_mel_basis = np.linalg.pinv(self._build_mel_basis())
The error was due to some NumPy linear algebra function. I figured that NumPy and SciPy probably have an indentical implementation of this function. So, by replacing the above with:
from scipy import linalg
...
self.inv_mel_basis = linalg.pinv(self._build_mel_basis())
The program actually ran!
It's such a satisfying feeling getting something like this to work! If you're still here, thanks for reading! See you in the next one ;)
Damn. Nice job finding the error and resolving it moving to a related library. Does this mean the NumPy dependancy (version) 'linarg' function doesn't work on M2?