Repository: voicepaw/so-vits-svc-fork

Issue:
Can't stop voice changer (3.9.3)
**Describe the bug**
With 3.9.3 switching to using the ThreadPool instead of the ProcessPool the voice changer can't be stopped anymore.

Additionally, this change also causes #359 .

**To Reproduce**
Start the voice changer on 3.9.3, then try to stop it. The console will say it was stopped but the logs about the inference will continue.



Discussion:
Reading through people having similar issues, it seems setting `torch.multiprocessing.set_start_method('spawn')` in the `__main__` class at the bottom should fix it?

https://stackoverflow.com/questions/72779926/gunicorn-cuda-cannot-re-initialize-cuda-in-forked-subprocess
https://github.com/pytorch/pytorch/issues/40403
does not context=spawn work?
You mean context=spawn for the Thread Pool? I'll give that a go.

I saw you tried that with the Process Pool before but commented it out
i didnt try it
ThreadPool doesn't seem to have an argument called `context`. Do you mean you haven't tried it for ProcessPool?

Edit:
Opening the GUI with ProcessPool and context=spawn just makes it crash.

```
E:\Development\so-vits-svc-4.0\Kurzgesagt>..\__env\Scripts\svcg
Traceback (most recent call last):
  File "c:\program files\python310\lib\runpy.py", line 196, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "c:\program files\python310\lib\runpy.py", line 86, in _run_code
    exec(code, run_globals)
  File "E:\Development\so-vits-svc-4.0\__env\Scripts\svcg.exe\__main__.py", line 7, in <module>
  File "E:\Development\so-vits-svc-4.0\__env\lib\site-packages\so_vits_svc_fork\gui.py", line 517, in main
    with ProcessPool(max_workers=1, context="spawn") as pool:
  File "E:\Development\so-vits-svc-4.0\__env\lib\site-packages\pebble\pool\process.py", line 60, in __init__
    self._pool_manager = PoolManager(self._context, mp_context)
  File "E:\Development\so-vits-svc-4.0\__env\lib\site-packages\pebble\pool\process.py", line 202, in __init__
    self.worker_manager = WorkerManager(context.workers,
  File "E:\Development\so-vits-svc-4.0\__env\lib\site-packages\pebble\pool\process.py", line 344, in __init__
    self.pool_channel, self.workers_channel = channels(mp_context)
  File "E:\Development\so-vits-svc-4.0\__env\lib\site-packages\pebble\pool\channel.py", line 31, in channels
    read0, write0 = mp_context.Pipe(duplex=False)
AttributeError: 'str' object has no attribute 'Pipe'
```
Maybe multiprocessing.get_context('spawn')
> Maybe multiprocessing.get_context('spawn')

Oh it could be I left that in as well and that'd what caused it, yes.

I should mention that since I'm on Windows I didn't encounter any issues with ProcessPool before - I can't test it on Linux unfortunately :(
#359 seems nothing to do with this

Resolving patch:
diff --git a/src/so_vits_svc_fork/gui.py b/src/so_vits_svc_fork/gui.py
--- a/src/so_vits_svc_fork/gui.py
+++ b/src/so_vits_svc_fork/gui.py
@@ -1,6 +1,7 @@
 from __future__ import annotations
 
 import json
+import multiprocessing
 from copy import copy
 from logging import getLogger
 from pathlib import Path
@@ -9,7 +10,7 @@
 import sounddevice as sd
 import soundfile as sf
 import torch
-from pebble import ProcessFuture, ThreadPool
+from pebble import ProcessFuture, ProcessPool
 from tqdm.tk import tqdm_tk
 
 from .utils import ensure_pretrained_model, get_optimal_device
@@ -514,8 +515,11 @@ def apply_preset(name: str) -> None:
     update_speaker()
     update_devices()
     # with ProcessPool(max_workers=1) as pool:
-    # with ProcessPool(max_workers=1, context="spawn") as pool:
-    with ThreadPool(max_workers=1) as pool:
+    # to support Linux
+    with ProcessPool(
+        max_workers=min(2, multiprocessing.cpu_count()),
+        context=multiprocessing.get_context("spawn"),
+    ) as pool:
         future: None | ProcessFuture = None
         infer_futures: set[ProcessFuture] = set()
         while True:


Test patch: