RustAudio / deepspeech-rs

Rust bindings for the deepspeech library
Other
295 stars 24 forks source link

memory management #21

Open jeremyandrews opened 4 years ago

jeremyandrews commented 4 years ago

I'm using deepspeech-rs in a personal project and I've run into a memory-related problem.

At a high level, I have an Actix server that accepts audio files (currently from a watchOS client) uses deepspeech-rs to convert the audio to text, then returns the result. The problem I'm seeing is memory grows by ~250MB each time I process an audio file.

I suspect the problem is that I'm loading the model into memory each time I process a new audio file. However, in trying to solve this I've run into two problems:

  1. I don't understand how to properly free the memory after loading the model -- I'm used to Rust doing this for me, and trying to clear the Model and/or Audio Buffer doesn't solve the leak
  2. I'd prefer to load the models one time, and then share it with all the Actix threads -- however, I'm unable to wrap it in a Mutex and share it, as deepspeech::Model doesn't implement Copy() or Clone().

I do see there was recent discussion of a memory leak in the upstream deepspeech repo, but offhand that doesn't look related.

I'm currently doing development on an Ubuntu-based Linux distribution, with the 5.3 Linux kernel. I set things up and build as documented in my project's README.

I'd appreciate any suggestions!

est31 commented 4 years ago

In theory, the Rust wrapper is supposed to do the resource deallocation for you. As in, we specifically override the drop constructor to deallocate the model.

In general, it would be best for performance to load one (or multiple) models into memory at the start and then to reuse them. Otherwise you have the overhead of loading models each time you process a file.

deepspeech::Model doesn't implement Copy() or Clone().

I think neither is implemented upstream, so we can't implement them in the wrapper. std::sync::Mutex only requires Sized which we do implement. Why does Actix require Copy/Clone?

jeremyandrews commented 4 years ago

In theory, the Rust wrapper is supposed to do the resource deallocation for you. As in, we specifically override the drop constructor to deallocate the model.

So is there a bug here? It does not appear to be happening, though the problem could certainly be on my end.

I think neither is implemented upstream, so we can't implement them in the wrapper. std::sync::Mutex only requires Sized which we do implement. Why does Actix require Copy/Clone?

It seems I had confused myself, you are completely correct. I added send to my struct and now I am able to compile and reuse the model object. Actix does not require Copy/Clone.

Thank you!