noblebarkrr commited on
Commit
32f9199
·
verified ·
1 Parent(s): 1a43e1f

Upload 3 files

Browse files
Files changed (3) hide show
  1. Dockerfile +34 -0
  2. app.py +252 -0
  3. requirements.txt +156 -0
Dockerfile ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.10
2
+
3
+ # Установка системных зависимостей
4
+ RUN apt-get update && apt-get install -y \
5
+ libgirepository1.0-dev \
6
+ gobject-introspection \
7
+ pkg-config \
8
+ libdbus-1-dev \
9
+ libcairo2-dev \
10
+ && rm -rf /var/lib/apt/lists/*
11
+
12
+ # Создание пользователя
13
+ RUN useradd -m -u 1000 user
14
+ USER user
15
+ ENV PATH="/home/user/.local/bin:$PATH"
16
+ RUN pwd
17
+ # Установка рабочей директории
18
+ WORKDIR /content/PolGen
19
+
20
+ # Обновление pip
21
+ RUN pip install pip==23.1
22
+
23
+ # Копирование и установка зависимостей
24
+ COPY --chown=user ./requirements.txt requirements.txt
25
+ RUN pip install --ignore-installed --no-cache-dir --upgrade -r requirements.txt
26
+
27
+ # Клонирование репозитория
28
+ RUN rm -rf /content/PolGen
29
+ RUN git clone --depth 1 https://github.com/Bebra777228/PolGen-RVC --branch v1.2.0-fix --single-branch /content/PolGen
30
+ COPY --chown=user ./app.py /content/PolGen/app2.py
31
+ RUN ls /content/PolGen
32
+ RUN cd /content/PolGen
33
+ EXPOSE 7860
34
+ CMD ["python", "app2.py"]
app.py ADDED
@@ -0,0 +1,252 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import os
3
+ import asyncio
4
+ import shutil
5
+ from datetime import datetime
6
+ import urllib.request
7
+ import zipfile
8
+ import gdown
9
+ import requests
10
+ import logging
11
+
12
+ # Настройка логирования
13
+ logging.basicConfig(level=logging.INFO)
14
+
15
+ # Константы
16
+ f0_min = 50
17
+ f0_max = 1100
18
+ rvc_models_dir = './models'
19
+ input_folder = './input'
20
+ output_folder = './output'
21
+
22
+ # Создание необходимых директорий
23
+ os.makedirs(rvc_models_dir, exist_ok=True)
24
+ os.makedirs(input_folder, exist_ok=True)
25
+ os.makedirs(output_folder, exist_ok=True)
26
+
27
+ # Общие функции
28
+ async def run_command_async(command):
29
+ """Асинхронный запуск команд."""
30
+ process = await asyncio.create_subprocess_shell(
31
+ command,
32
+ stdout=asyncio.subprocess.PIPE,
33
+ stderr=asyncio.subprocess.PIPE
34
+ )
35
+ stdout, stderr = await process.communicate()
36
+ if process.returncode != 0:
37
+ logging.error(f"Error: {stderr.decode()}")
38
+ return stdout.decode()
39
+
40
+ def get_models_list():
41
+ """Получение списка моделей."""
42
+ models = []
43
+ if os.path.exists(rvc_models_dir):
44
+ models = [d for d in os.listdir(rvc_models_dir) if os.path.isdir(os.path.join(rvc_models_dir, d))]
45
+ return models
46
+
47
+ # Функции для первой вкладки
48
+ def process_uploaded_files(files):
49
+ """Обработка загруженных файлов."""
50
+ if os.path.exists(input_folder):
51
+ shutil.rmtree(input_folder)
52
+ os.makedirs(input_folder, exist_ok=True)
53
+
54
+ for file in files:
55
+ shutil.copy(file.name, input_folder)
56
+ return f"Uploaded {len(files)} files to {input_folder}"
57
+
58
+ async def convert_voice(
59
+ voicemodel_name,
60
+ pitch_vocal,
61
+ method_pitch,
62
+ hop_length,
63
+ index_rate,
64
+ filter_radius,
65
+ rms,
66
+ protect,
67
+ output_format
68
+ ):
69
+ """Конвертация голоса."""
70
+ current_time = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
71
+ output_ai_vocals_folder = os.path.join(output_folder, current_time)
72
+ os.makedirs(output_ai_vocals_folder, exist_ok=True)
73
+
74
+ output_test = {
75
+ "mp3": "-ab 320k",
76
+ "wav": "-c:a pcm_s32le",
77
+ "flac": "-c:a flac -af aformat=s16"
78
+ }[output_format]
79
+
80
+ for filename in os.listdir(input_folder):
81
+ if filename.endswith(("wav", "mp3", "flac")):
82
+ input_path = os.path.join(input_folder, filename)
83
+ base_name = os.path.splitext(filename)[0]
84
+
85
+ output_filename = f"mono_{base_name}_{current_time}_{method_pitch}_{pitch_vocal}.{output_format}"
86
+ output_path = os.path.join(output_ai_vocals_folder, output_filename)
87
+
88
+ # Выполнение команды RVC
89
+ await run_command_async(
90
+ f"python3 -m rvc.cli.rvc_cli -i \"{input_path}\" -m \"{voicemodel_name}\" -p {pitch_vocal} "
91
+ f"-ir {index_rate} -fr {filter_radius} -rms {rms} -f0 \"{method_pitch}\" "
92
+ f"-hop {hop_length} -pro {protect} -f0min {f0_min} -f0max {f0_max} -f \"wav\""
93
+ )
94
+
95
+ # Конвертация в нужный формат
96
+ await run_command_async(
97
+ f"ffmpeg -y -i ./output/Voice_Converted.wav "
98
+ f"-vn -ar 44100 -ac 1 {output_test} \"{output_path}\""
99
+ )
100
+
101
+ return [os.path.join(output_ai_vocals_folder, f) for f in os.listdir(output_ai_vocals_folder) if f.endswith(output_format)]
102
+
103
+ # Функции для второй вкладки
104
+ def extract_zip(extraction_folder, zip_name):
105
+ """Распаковка архива."""
106
+ os.makedirs(extraction_folder, exist_ok=True)
107
+ with zipfile.ZipFile(zip_name, 'r') as zip_ref:
108
+ zip_ref.extractall(extraction_folder)
109
+ os.remove(zip_name)
110
+
111
+ model_file = next((f for f in os.listdir(extraction_folder) if f.endswith('.pth')), None)
112
+ index_file = next((f for f in os.listdir(extraction_folder) if f.endswith('.index')), None)
113
+
114
+ if model_file:
115
+ os.rename(os.path.join(extraction_folder, model_file),
116
+ os.path.join(extraction_folder, model_file))
117
+ if index_file:
118
+ os.rename(os.path.join(extraction_folder, index_file),
119
+ os.path.join(extraction_folder, index_file))
120
+
121
+ async def download_model(url, dir_name):
122
+ """Скачивание модели."""
123
+ try:
124
+ zip_path = os.path.join(rvc_models_dir, f"{dir_name}.zip")
125
+ extraction_path = os.path.join(rvc_models_dir, dir_name)
126
+
127
+ if os.path.exists(extraction_path):
128
+ return f"Error: Directory {dir_name} already exists!"
129
+
130
+ if 'drive.google.com' in url:
131
+ file_id = url.split("file/d/")[1].split("/")[0] if "file/d/" in url else url.split("id=")[1].split("&")[0]
132
+ gdown.download(id=file_id, output=zip_path, quiet=False)
133
+ elif 'huggingface.co' in url:
134
+ urllib.request.urlretrieve(url, zip_path)
135
+ elif 'pixeldrain.com' in url:
136
+ file_id = url.split("pixeldrain.com/u/")[1]
137
+ response = requests.get(f"https://pixeldrain.com/api/file/{file_id}")
138
+ with open(zip_path, 'wb') as f:
139
+ f.write(response.content)
140
+
141
+ extract_zip(extraction_path, zip_path)
142
+ return f"Model {dir_name} successfully installed!"
143
+ except Exception as e:
144
+ return f"Error: {str(e)}"
145
+
146
+ # Создание интерфейса
147
+ with gr.Blocks() as demo:
148
+ gr.Markdown("# VBach Lite WEBUI")
149
+
150
+ with gr.Tabs():
151
+ # Первая вкладка
152
+ with gr.TabItem("Замена вокала"):
153
+ with gr.Row():
154
+ with gr.Column():
155
+ file_input = gr.File(file_count="multiple", label="Загрузить один или несколько файлов")
156
+ upload_status = gr.Textbox(label="Статус загрузки")
157
+ file_input.upload(
158
+ fn=process_uploaded_files,
159
+ inputs=file_input,
160
+ outputs=upload_status
161
+ )
162
+
163
+ with gr.Accordion("Настройки RVC:", open=True):
164
+ voicemodel_name = gr.Dropdown(
165
+ choices=get_models_list(),
166
+ label="Имя модели",
167
+ value="senko" if "senko" in get_models_list() else None
168
+ )
169
+ refresh_btn = gr.Button("Обновить")
170
+
171
+ pitch_vocal = gr.Slider(-48, 48, value=0, step=12, label="Высота тона")
172
+ method_pitch = gr.Dropdown(
173
+ ["fcpe", "rmvpe+", "mangio-crepe"],
174
+ value="rmvpe+",
175
+ label="Метод извлечения тона"
176
+ )
177
+ hop_length = gr.Slider(0, 255, value=73, step=1, label="Длина шага для mangio-crepe")
178
+ index_rate = gr.Slider(0, 1, value=1, step=0.05, label="ИИ-акцент")
179
+ filter_radius = gr.Slider(0, 7, value=7, step=1, label="Радиус фильтра")
180
+ rms = gr.Slider(0, 1, value=0, step=0.1, label="Нормализация")
181
+ protect = gr.Slider(0, 0.5, value=0.35, step=0.05, label="Защита согласных")
182
+ output_format = gr.Dropdown(
183
+ ["flac", "wav", "mp3"],
184
+ value="mp3",
185
+ label="Формат вывода"
186
+ )
187
+
188
+ convert_btn = gr.Button("Преобразовать!", variant="primary")
189
+
190
+ with gr.Column():
191
+ output_files = gr.Files(label="Аудио с преобразованным вокалом")
192
+
193
+ # Обработчики
194
+ refresh_btn.click(
195
+ fn=lambda: gr.update(choices=get_models_list()),
196
+ outputs=voicemodel_name
197
+ )
198
+
199
+ convert_btn.click(
200
+ fn=convert_voice,
201
+ inputs=[
202
+ voicemodel_name,
203
+ pitch_vocal,
204
+ method_pitch,
205
+ hop_length,
206
+ index_rate,
207
+ filter_radius,
208
+ rms,
209
+ protect,
210
+ output_format
211
+ ],
212
+ outputs=output_files
213
+ )
214
+
215
+ # Вторая вкладка
216
+ with gr.TabItem("Скачать модель"):
217
+ with gr.Row():
218
+ with gr.Column():
219
+ gr.Markdown("## Здесь можно скачать модель по ссылке на архив с нею")
220
+ url_input = gr.Textbox(
221
+ label="Ссылка на архив с моделью",
222
+ placeholder="хаггингфейс.ко/модель.zip"
223
+ )
224
+ dir_name_input = gr.Textbox(
225
+ label="Имя модели",
226
+ placeholder="Имя модели"
227
+ )
228
+ download_btn = gr.Button("Скачать модель", variant="primary")
229
+ install_status = gr.Textbox(label="Статус скачивания модели")
230
+
231
+ download_btn.click(
232
+ fn=download_model,
233
+ inputs=[url_input, dir_name_input],
234
+ outputs=install_status
235
+ )
236
+
237
+ with gr.Column():
238
+ gr.Markdown("## Проверить список моделей")
239
+ model_list = gr.Textbox(
240
+ value="\n".join(get_models_list()),
241
+ lines=10,
242
+ label="Установленные модели"
243
+ )
244
+ refresh_models_btn = gr.Button("Обновить")
245
+
246
+ refresh_models_btn.click(
247
+ fn=lambda: gr.update(value="\n".join(get_models_list())),
248
+ outputs=model_list
249
+ )
250
+
251
+ if __name__ == "__main__":
252
+ demo.launch()
requirements.txt ADDED
@@ -0,0 +1,156 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ aiofiles==23.2.1
2
+ aiohappyeyeballs==2.4.4
3
+ aiohttp==3.11.11
4
+ aiosignal==1.3.2
5
+ annotated-types==0.7.0
6
+ antlr4-python3-runtime==4.8
7
+ anyio==4.8.0
8
+ async-timeout==5.0.1
9
+ attrs==25.1.0
10
+ audioread==3.0.1
11
+ beautifulsoup4==4.12.3
12
+ bitarray==3.0.0
13
+ blinker==1.4
14
+ certifi==2024.12.14
15
+ cffi==1.17.1
16
+ charset-normalizer==3.4.1
17
+ click==8.1.8
18
+ colorama==0.4.6
19
+ contourpy==1.3.1
20
+ cryptography==3.4.8
21
+ cycler==0.12.1
22
+ Cython==3.0.11
23
+ dbus-python==1.2.18
24
+ decorator==5.1.1
25
+ distro==1.7.0
26
+ edge-tts==7.0.0
27
+ einops==0.8.0
28
+ exceptiongroup==1.2.2
29
+ fairseq==0.12.2
30
+ faiss-cpu==1.7.3
31
+ fastapi==0.112.4
32
+ ffmpeg-python==0.2.0
33
+ ffmpy==0.5.0
34
+ filelock==3.17.0
35
+ fonttools==4.55.7
36
+ frozenlist==1.5.0
37
+ fsspec==2024.12.0
38
+ future==1.0.0
39
+ gdown==5.2.0
40
+ gradio==4.43.0
41
+ gradio_client==1.3.0
42
+ h11==0.14.0
43
+ httpcore==1.0.7
44
+ httplib2==0.20.2
45
+ httpx==0.28.1
46
+ huggingface-hub==0.28.0
47
+ hydra-core==1.0.7
48
+ hyper-connections==0.1.9
49
+ idna==3.10
50
+ importlib-metadata==4.6.4
51
+ importlib_resources==6.5.2
52
+ jeepney==0.7.1
53
+ Jinja2==3.1.5
54
+ joblib==1.4.2
55
+ keyring==23.5.0
56
+ kiwisolver==1.4.8
57
+ launchpadlib==1.10.16
58
+ lazr.restfulclient==0.14.4
59
+ lazr.uri==1.0.6
60
+ lazy_loader==0.4
61
+ librosa==0.10.2.post1
62
+ llvmlite==0.43.0
63
+ local-attention==1.11.1
64
+ lxml==5.3.0
65
+ markdown-it-py==3.0.0
66
+ MarkupSafe==2.1.5
67
+ matplotlib==3.10.0
68
+ mdurl==0.1.2
69
+ mega.py==1.0.8
70
+ more-itertools==8.10.0
71
+ mpmath==1.3.0
72
+ msgpack==1.1.0
73
+ multidict==6.1.0
74
+ networkx==3.4.2
75
+ numba==0.60.0
76
+ numpy==1.23.5
77
+ nvidia-cublas-cu12==12.4.5.8
78
+ nvidia-cuda-cupti-cu12==12.4.127
79
+ nvidia-cuda-nvrtc-cu12==12.4.127
80
+ nvidia-cuda-runtime-cu12==12.4.127
81
+ nvidia-cudnn-cu12==9.1.0.70
82
+ nvidia-cufft-cu12==11.2.1.3
83
+ nvidia-curand-cu12==10.3.5.147
84
+ nvidia-cusolver-cu12==11.6.1.9
85
+ nvidia-cusparse-cu12==12.3.1.170
86
+ nvidia-nccl-cu12==2.21.5
87
+ nvidia-nvjitlink-cu12==12.4.127
88
+ nvidia-nvtx-cu12==12.4.127
89
+ oauthlib==3.2.0
90
+ omegaconf==2.0.6
91
+ orjson==3.10.15
92
+ packaging==24.2
93
+ pandas==2.2.3
94
+ pathlib==1.0.1
95
+ pedalboard==0.9.16
96
+ pillow==10.4.0
97
+ platformdirs==4.3.6
98
+ pooch==1.8.2
99
+ portalocker==3.1.1
100
+ praat-parselmouth==0.4.5
101
+ propcache==0.2.1
102
+ protobuf==5.29.3
103
+ pycparser==2.22
104
+ pycryptodome==3.21.0
105
+ pydantic==2.10.6
106
+ pydantic_core==2.27.2
107
+ pydub==0.25.1
108
+ Pygments==2.19.1
109
+ PyGObject==3.42.1
110
+ PyJWT==2.3.0
111
+ pyparsing==2.4.7
112
+ PySocks==1.7.1
113
+ python-dateutil==2.9.0.post0
114
+ python-multipart==0.0.20
115
+ pytz==2024.2
116
+ pyworld==0.3.4
117
+ PyYAML==6.0.2
118
+ regex==2024.11.6
119
+ requests==2.32.3
120
+ resampy==0.4.3
121
+ rich==13.9.4
122
+ ruff==0.9.3
123
+ sacrebleu==2.5.1
124
+ scikit-learn==1.6.1
125
+ scipy==1.15.1
126
+ SecretStorage==3.3.1
127
+ semantic-version==2.10.0
128
+ shellingham==1.5.4
129
+ six==1.16.0
130
+ sniffio==1.3.1
131
+ soundfile==0.13.1
132
+ soupsieve==2.6
133
+ soxr==0.5.0.post1
134
+ srt==3.5.3
135
+ starlette==0.38.6
136
+ sympy==1.13.1
137
+ tabulate==0.9.0
138
+ tenacity==5.1.5
139
+ tensorboardX==2.6.2.2
140
+ threadpoolctl==3.5.0
141
+ tomlkit==0.12.0
142
+ torch==2.5.1
143
+ torchaudio==2.5.1
144
+ torchcrepe==0.0.23
145
+ tqdm==4.67.1
146
+ triton==3.1.0
147
+ typer==0.15.1
148
+ typing_extensions==4.12.2
149
+ tzdata==2025.1
150
+ urllib3==2.3.0
151
+ uvicorn==0.34.0
152
+ wadllib==1.3.6
153
+ websockets==12.0
154
+ wget==3.2
155
+ yarl==1.18.3
156
+ zipp==1.0.0