Skip to content

Commit 81ca986

Browse files
committed
support pre-built local plugin
1 parent 5f9b990 commit 81ca986

File tree

9 files changed

+82
-32
lines changed

9 files changed

+82
-32
lines changed

README.md

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,16 @@ git clone https://github.com/tuneflow/so-vits-svc-plugin.git
1010

1111
## Installation
1212

13+
### (Option 1) Download Pre-Built Release
14+
15+
You can also download a prebuilt package with all dependencies included, from the below links:
16+
17+
[Download for Windows](https://plugin-dist.tuneflow.com/plugins/binary/svc_local/win-x64-1.0.0.zip)
18+
19+
[Download for macOS (Coming Soon)](#)
20+
21+
### (Option 2) Build from Source
22+
1323
It is recommended to install through python virtual environments, so that these dependencies won't conflict with your existing pip packages.
1424

1525
```bash
@@ -25,7 +35,7 @@ If you want the plugin to load models on start up, you can optionally place your
2535
The folder structure would look like this:
2636

2737
```
28-
-- so-vits-svc-plugin
38+
-- <root folder of the project>
2939
-- ......
3040
-- checkpoints
3141
-- G_XXX.pth
@@ -35,13 +45,19 @@ The folder structure would look like this:
3545

3646
## Run the Plugin
3747

48+
### If You Downloaded Pre-built Release
49+
50+
Unzip the app, and run the `local_app.exe` from the extracted folder.
51+
52+
### If You Built from Source
53+
3854
Once you installed the dependencies and prepared the models, you can start running the plugin using:
3955

4056
```bash
41-
python local_plugin.py
57+
python local_app.py
4258
```
4359

44-
You should see something like this in your console log:
60+
Once started, you should be able to see something like this:
4561

4662
```bash
4763
============= Plugin Info =============
@@ -57,7 +73,7 @@ Next, start TuneFlow Desktop, if you don't have it already, download from the ho
5773

5874
Create an empty song, or open an existing song.
5975

60-
Once the project is loaded, switch to the TuneFlow Plugin Library, at the top right corner, click on the "**Load a remotely hosted plugin**" button. And paste `http://127.0.0.1:8000/plugins/singing-voice-clone-local` into the address input. If everything is setup correctly our plugin should load successfully and show up in the plugin inventory.
76+
Once the project is loaded, switch to the TuneFlow Plugin Library, at the top right corner, click on the "Load a remotely hosted plugin" button. And paste http://127.0.0.1:8000/plugins/singing-voice-clone-local into the address input. If everything is setup correctly our plugin should load successfully and show up in the plugin inventory.
6177

6278
![Load local plugin](./images/load_plugin_en.jpg)
6379

README.zh.md

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,19 @@
88
git clone https://github.com/tuneflow/so-vits-svc-plugin.git
99
```
1010

11-
## 安装依赖
11+
## 安装
12+
13+
### (选项1)使用整合好的压缩包
14+
15+
首先下载安装包:
16+
17+
[Windows下载](https://plugin-dist.tuneflow.com/plugins/binary/svc_local/win-x64-1.0.0.zip)
18+
19+
[macOS下载(即将推出)](#)
20+
21+
随后解压下载好的安装包,其中的`local_app.exe`即为插件运行程序。
22+
23+
### (选项2)从源代码安装
1224

1325
注意:安装 python 依赖包时推荐使用 virtualenv,这样可以将插件所需依赖与系统其他依赖分离开来。
1426

@@ -23,26 +35,36 @@ pip install -r requirements.txt
2335
如果你想每次运行插件时都自动加载模型,你可以把模型和配置文件放到`checkpoints`目录下,这样整个目录结构看起来是这样的:
2436

2537
```
26-
-- so-vits-svc-plugin
38+
-- <项目根目录>
2739
-- ......
2840
-- checkpoints
2941
-- G_XXX.pth
3042
-- config.json
3143
-- ......
3244
```
3345

46+
该方法对于两种安装方式都适用。
47+
3448
## 训练自己的模型
3549

3650
参考 [炼丹百科全书](https://docs.qq.com/doc/DUWdxS1ZaV29vZnlV),有非常易用的网页版训练界面。
3751

3852
## 运行插件
3953

54+
### 如果你下载了打包好的压缩包
55+
56+
解压下载好的压缩包,运行其中的`local_app.exe`文件。
57+
58+
### 如果你是从源文件直接构建
59+
4060
当 python 依赖和模型文件准备完毕后,我们可以开始跑起来插件了。用以下命令运行插件:
4161

4262
```bash
43-
python local_plugin.py
63+
python local_app.py
4464
```
4565

66+
### 在 TuneFlow 中加载插件
67+
4668
插件正常运行的情况下,你可以看到类似下面的控制台输出:
4769

4870
```bash
@@ -59,7 +81,7 @@ Plugin Description: Sing a vocal clip with a new voice
5981

6082
打开桌面版后,我们可以创建一首空白曲目,或者打开一首已有的曲子。
6183

62-
曲目加载完成后,在界面右侧切换到 TuneFlow 插件库。在插件库面板的右上角点击"**加载远程插件**"按钮,并在地址框中输入`http://127.0.0.1:8000/plugins/singing-voice-clone-local`。如果所有东西配置正确的话,你应该可以看到插件被加载到了插件库中。
84+
曲目加载完成后,在界面右侧切换到 TuneFlow 插件库。在插件库面板的右上角点击"加载远程插件"按钮,并在地址框中输入http://127.0.0.1:8000/plugins/singing-voice-clone-local。如果所有东西配置正确的话,你应该可以看到插件被加载到了插件库中。
6385

6486
![加载本地插件](./images/load_plugin_zh.jpg)
6587

bundle_local.json

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
},
1818
"version": "1.0.0",
1919
"supportedPlatforms": ["desktop"],
20-
"minRequiredDesktopVersion": "1.9.1",
20+
"minRequiredDesktopVersion": "1.9.3",
2121
"options": {
2222
"allowReset": true,
2323
"allowManualApplyAdjust": true
@@ -74,11 +74,8 @@
7474
"categories": ["generate"],
7575
"localPlugin": {
7676
"binaryUrl": {
77-
"mac": {
78-
"x64": "https://s.tuneflow.com/plugins/binary/singing-voice-clone-local/mac-x64"
79-
},
8077
"win": {
81-
"x64": "https://s.tuneflow.com/plugins/binary/singing-voice-clone-local/win-x64"
78+
"x64": "https://plugin-dist.tuneflow.com/plugins/binary/svc_local/win-x64-1.0.0.zip"
8279
}
8380
},
8481
"servingPath": "/plugins/singing-voice-clone-local"

local_app.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
from local_plugin import SingingVoiceCloneLocal
2+
from tuneflow_devkit import Runner
3+
from pathlib import Path
4+
import uvicorn
5+
6+
if __name__ == "__main__":
7+
app = Runner(
8+
plugin_class_list=[SingingVoiceCloneLocal],
9+
bundle_file_path=str(Path(__file__).parent.joinpath('bundle_local.json').absolute())).start(
10+
path_prefix='/plugins/singing-voice-clone-local',
11+
config={
12+
"corsConfig":
13+
{"allowedOrigins": ["https://www.tuneflow.com", "https://tuneflow.com", "https://staging.tuneflow.com", "http://127.0.0.1:5173"],
14+
"addAllowCredentialsHeader": True}})
15+
uvicorn.run(app)

local_debug.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
from local_plugin import SingingVoiceCloneLocal
2+
from tuneflow_devkit import Debugger
3+
from pathlib import Path
4+
5+
if __name__ == "__main__":
6+
Debugger(plugin_class=SingingVoiceCloneLocal, bundle_file_path=str(
7+
Path(__file__).parent.joinpath('bundle_local.json').absolute())).start()

local_plugin.py

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,8 @@
55
import traceback
66
from inferencer import vc_fn_model, load_custom_model_func
77
from utils import trim_audio
8-
from tuneflow_devkit import Runner
98
from pathlib import Path
10-
import uvicorn
9+
1110

1211
class SingingVoiceCloneLocal(TuneflowPlugin):
1312
@staticmethod
@@ -155,9 +154,12 @@ def run(song: Song, params: dict[str, Any]):
155154

156155
try:
157156
model, spk = load_custom_model_func(config_path=config_file, ckpt_path=model_file)
158-
result = vc_fn_model(model, spk, trim_audio(
159-
clip_audio_data_list[0]["audioData"]["data"], song, clip), vc_transform=pitchOffset, auto_f0=False, cluster_ratio=0, slice_db=-40,
160-
noise_scale=0.4, pad_seconds=0.5, cl_num=0, lg_num=0, lgr_num=0.75, F0_mean_pooling=f0MeanPooling, enhancer_adaptive_key=0, cr_threshold=f0Threshold)
157+
result = vc_fn_model(
158+
model, spk, trim_audio(clip_audio_data_list[0]["audioData"]["data"],
159+
song, clip),
160+
vc_transform=pitchOffset, auto_f0=False, cluster_ratio=0, slice_db=-40, noise_scale=0.4,
161+
pad_seconds=0.5, cl_num=0, lg_num=0, lgr_num=0.75, F0_mean_pooling=f0MeanPooling,
162+
enhancer_adaptive_key=0, cr_threshold=f0Threshold)
161163
if not result:
162164
raise Exception("Failed to generate audio")
163165
status, generated_data = result
@@ -177,9 +179,4 @@ def run(song: Song, params: dict[str, Any]):
177179
}, clip_end_tick=clip.get_clip_end_tick(), insert_clip=True)
178180
except Exception as e:
179181
print(traceback.format_exc())
180-
raise e
181-
182-
if __name__ == "__main__":
183-
app = Runner(plugin_class_list=[SingingVoiceCloneLocal], bundle_file_path=str(
184-
Path(__file__).parent.joinpath('bundle_local.json').absolute())).start(path_prefix='/plugins/singing-voice-clone-local')
185-
uvicorn.run(app)
182+
raise e

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
tuneflow-devkit-py>=0.8.6
1+
tuneflow-devkit-py>=0.8.7
22
# Flask
33
# Flask_Cors
44
# gradio

requirements.win.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
tuneflow-devkit-py>=0.8.6
1+
tuneflow-devkit-py>=0.8.7
22
librosa==0.9.2
33
fairseq==0.12.2
44
Flask==2.1.2

utils.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,17 @@
77
import json
88
import subprocess
99
import warnings
10-
import random
1110
import functools
1211

13-
import librosa
1412
import numpy as np
1513
from scipy.io.wavfile import read
1614
import torch
1715
from torch.nn import functional as F
18-
from modules.commons import sequence_mask
19-
from hubert import hubert_model
2016
from pathlib import Path
2117
from tuneflow_py import Song, Clip
2218
from pydub import AudioSegment
2319
from io import BytesIO
20+
from fairseq.checkpoint_utils import load_model_ensemble_and_task
2421

2522
MATPLOTLIB_FLAG = False
2623

@@ -214,8 +211,7 @@ def f0_to_coarse(f0):
214211
def get_hubert_model():
215212
vec_path = str(Path(__file__).parent.joinpath('hubert').joinpath('checkpoint_best_legacy_500.pt'))
216213
print("load model(s) from {}".format(vec_path))
217-
from fairseq import checkpoint_utils
218-
models, saved_cfg, task = checkpoint_utils.load_model_ensemble_and_task(
214+
models, saved_cfg, task = load_model_ensemble_and_task(
219215
[vec_path],
220216
suffix="",
221217
)

0 commit comments

Comments
 (0)