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

Memory Leak / Утечка памяти #282

Open
Freeeeeet opened this issue Jul 9, 2024 · 6 comments
Open

Memory Leak / Утечка памяти #282

Freeeeeet opened this issue Jul 9, 2024 · 6 comments
Assignees
Labels
help wanted Extra attention is needed

Comments

@Freeeeeet
Copy link

Freeeeeet commented Jul 9, 2024

Столкнулся с проблемой утечки памяти на модели tts. При каждом обращении к модели занятая оперативка растет на ~100МБ.

Вызывается сразу несколько инстансов, работает через FastAPI, но я думаю, можно обойтись без деталей и оставил только то, что связано с моделью(если что-то ещё нужно будет докинуть - докину)
вызываю примерно вот таким образом, чтобы получить итоговое аудио:

model = get_model()
    file_path = generate_audio_file(model, query.id, query.text_to_speech)
    return_model(model)

А вот тут в различных файликах описано, что я, собственно, вызываю:

device = 'cpu'
model_pool = ModelPool(size=2, device=device)



def get_model():
    return model_pool.get_model()


def return_model(model):
    model_pool.return_model(model)
class ModelPool:
    def __init__(self, size, device='cpu'):
        self.pool = queue.Queue()
        self.device = torch.device(device)  # Устройство, на котором будет выполняться модель
        self.load_models(size)

    def load_models(self, size):
        for _ in range(size):
            model, __ = torch.hub.load(repo_or_dir='snakers4/silero-models',
                                   model='silero_tts',
                                   language='ru',
                                   speaker='v3_1_ru')
            model.to(self.device)
            self.pool.put(model)

    def get_model(self):
        return self.pool.get()

    def return_model(self, model):
        self.pool.put(model)
def generate_audio_file(model, id, text: str, speaker='xenia', sample_rate=24000) -> str:
    file_path = f"some_filename--{id}.wav"
    model.save_wav(text=text, speaker=speaker, sample_rate=sample_rate, audio_path=file_path)
    return file_path

Не сталкивались с таким?
torch.no_grad() пробовал добавлять в различные места кода, не помогло

@Freeeeeet Freeeeeet added the help wanted Extra attention is needed label Jul 9, 2024
@Freeeeeet Freeeeeet changed the title ❓ Questions / Help / Support Memory Leak / Утечка памяти Jul 10, 2024
@dumonten
Copy link

Привет! У меня было точно так же, когда я использовала v2, RAM выедалась до 1 ГБ и выше. Не понимала в чем проблема, использовала и torch._C._jit_set_profiling_mode(False), и torch.set_grad_enabled(False), вызывала и gc.collect(), и torch.cuda.empty_cache() - ничего не помогало. С этим, видимо, все сталкиваются, так именно моделька написана - и, как я понимаю, это не исправить. Поставила v4 - и все стало ок

@MrYNikita
Copy link

@dumonten, приветствую! Ознакомился с Вашим кодом, для Вас проблема была решена и утечка памяти устранена?

@Freeeeeet
Copy link
Author

Нет же, все описал, как выглядят примеры моего кода
Все это крутится в докере и дёргается через фастапи
И каждый раз, когда дёргается модель таким образом, как описано выше - начинает течь память.
Принципиально использовать версию модели v3.1

@dumonten

This comment was marked as spam.

@dumonten
Copy link

dumonten commented Aug 1, 2024

Нет же, все описал, как выглядят примеры моего кода Все это крутится в докере и дёргается через фастапи И каждый раз, когда дёргается модель таким образом, как описано выше - начинает течь память. Принципиально использовать версию модели v3.1

Может попробуй еще позапускать код с apply_tts, а не через save_wav? Вот пример:

audio = model.apply_tts(ssml_text=ssml_sample,
speaker=speaker,
sample_rate=sample_rate)

Только подчищай тензор, который он генерит после сохранения.

Я лично, v3 не использовала, только v2 и v4. Поэтому и порекомендовала то решение, где у меня все исправилось.

@VitalyPetrov
Copy link

VitalyPetrov commented Nov 7, 2024

Можно использовать io.BytesIO объект для сохранения wav в него и перезаписывать его при каждом обращении к tts

import io

bts = io.BytesIO()

model.save_wav(
    ssml_text=ssml,
    sample_rate=48000
    speaker='<some-speaker-name>',
    put_accent=True,
    put_yo=True,
    audio_path=bts,
)

Соответственно, при каждом вызове метода .save_wav() bts будет ссылаться на новую область памяти, а старую сборщик мусора будет удалять.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

5 participants