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

Reduce memory usage of forced alignment on CPU #3787

Open
wants to merge 8 commits into
base: main
Choose a base branch
from

Conversation

MahmoudAshraf97
Copy link

@MahmoudAshraf97 MahmoudAshraf97 commented May 11, 2024

In the forced alignment c++ code, backPtr is an int8 tensor while only storing the values 0,1, and 2 which can be effectively stored using only 2 bits instead of 8, and since the backPtr tensor size is log_probs_len * (targets_length * 2 + 1), it can grow to unmanageable sizes in audio files that exceed 2 hours.
By using two std::vector<bool> to represent the two bits needed for backPtr we guarantee that the results are exactly the same while lowering memory usage since std::vector<bool> should use 1 bit to represent a boolean.
Best case scenario is memory usage drops to 25%, worst case scenario memory usage doubles if a boolean is represented using 1 byte.

From my experiments, the new code can handle longer audio files without running out of memory. I also noticed that on average, only 1-targets_length/log_probs_length of the backPtr array is used (depending on the inputs) so further memory savings can be gained if we used a shape that reduces unused elements.

log_probs.shape (1,50000,32)
targets.shape (1,25000)
# new code
12.2 s ± 63 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
# original
12.3 s ± 170 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

edit:
I implemented a better structure for the backPtr tensor that still uses two boolean vectors but the numbers of elements are greatly reduced to achieve better memory efficiency.
The new structure is similar to a sparse matrix or a list of lists, instead of initializing a complete trellis matrix, we initialize the elements which are only going to be used which is approximated by the formula in the code (deduced empirically and tested thorougly). We also create two new arrays for indexing purposes.

@MahmoudAshraf97 MahmoudAshraf97 requested a review from a team as a code owner May 11, 2024 13:38
Copy link

pytorch-bot bot commented May 11, 2024

🔗 Helpful Links

🧪 See artifacts and rendered test results at hud.pytorch.org/pr/pytorch/audio/3787

Note: Links to docs will display an error until the docs builds have been completed.

This comment was automatically generated by Dr. CI and updates every 15 minutes.

@facebook-github-bot
Copy link
Contributor

Hi @MahmoudAshraf97!

Thank you for your pull request and welcome to our community.

Action Required

In order to merge any pull request (code, docs, etc.), we require contributors to sign our Contributor License Agreement, and we don't seem to have one on file for you.

Process

In order for us to review and merge your suggested changes, please sign at https://code.facebook.com/cla. If you are contributing on behalf of someone else (eg your employer), the individual CLA may not be sufficient and your employer may need to sign the corporate CLA.

Once the CLA is signed, our tooling will perform checks and validations. Afterwards, the pull request will be tagged with CLA signed. The tagging process may take up to 1 hour after signing. Please give it that time before contacting us about it.

If you have received this in error or have any questions, please contact us at cla@meta.com. Thanks!

@facebook-github-bot
Copy link
Contributor

Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Meta Open Source project. Thanks!

@vadimkantorov
Copy link

vadimkantorov commented Jun 17, 2024

I used this compression trick in my Python CTC-based forced alignment: https://github.com/vadimkantorov/ctc/blob/master/ctc.py

And this compression indeed works and helps

* initial code

* .

* back to origins

* final

* reduce the `backPtr` size because the first row is always unused

* dynamic vectors

* fix casting

* .

* preallocation

* fix casting

* missin ;

* prevent redundant setting

* missing ;

* fixed backPtr indexing

* fixed initial size

* fix seek update

* wrap up

* implement better trellis matrix structure

* avoid seek overflow

* fix building on mac and windows
@MahmoudAshraf97
Copy link
Author

MahmoudAshraf97 commented Jun 19, 2024

since torchaudio is no longer maintained, I've created a library that builds upon this code and improves it here
it's around 50% faster with 5x less memory usage, it also supports all CTC models from hugging face. The MMS alignment model used by torch audio is hosted here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants