Update app.py
Browse files
app.py
CHANGED
|
@@ -6,7 +6,6 @@ import shutil
|
|
| 6 |
from pathlib import Path
|
| 7 |
import zipfile
|
| 8 |
import json
|
| 9 |
-
import time
|
| 10 |
|
| 11 |
class RealRVCTrainer:
|
| 12 |
def __init__(self):
|
|
@@ -116,7 +115,7 @@ class RealRVCTrainer:
|
|
| 116 |
|
| 117 |
progress(0.3, desc="Preprocessing audio...")
|
| 118 |
cmd = [sys.executable, str(preprocess_script), str(dataset_path), str(sample_rate), "2"]
|
| 119 |
-
result = subprocess.run(cmd, capture_output=True, text=True
|
| 120 |
|
| 121 |
progress(1.0, desc="Preprocessing complete!")
|
| 122 |
return f"β
Preprocessing Complete!\n\nπ΅ Sample Rate: {sample_rate}Hz\nπ Features extracted\nπ Ready for training!"
|
|
@@ -131,148 +130,83 @@ class RealRVCTrainer:
|
|
| 131 |
log_dir = self.rvc_dir / "logs" / model_name
|
| 132 |
log_dir.mkdir(parents=True, exist_ok=True)
|
| 133 |
|
| 134 |
-
# Create weights directory explicitly
|
| 135 |
-
weights_dir = log_dir / "weights"
|
| 136 |
-
weights_dir.mkdir(exist_ok=True)
|
| 137 |
-
|
| 138 |
progress(0.1, desc="Starting RVC training...")
|
| 139 |
train_script = self.rvc_dir / "infer" / "modules" / "train" / "train.py"
|
| 140 |
if not train_script.exists():
|
| 141 |
train_script = self.rvc_dir / "train_nsf_sim_cache_sid_load_pretrain.py"
|
| 142 |
|
| 143 |
-
if not train_script.exists():
|
| 144 |
-
return f"β Training script not found. Searched:\n- {self.rvc_dir / 'infer' / 'modules' / 'train' / 'train.py'}\n- {self.rvc_dir / 'train_nsf_sim_cache_sid_load_pretrain.py'}"
|
| 145 |
-
|
| 146 |
cmd = [
|
| 147 |
sys.executable, str(train_script),
|
| 148 |
-
"-e", model_name,
|
| 149 |
-
"-
|
| 150 |
-
"-
|
| 151 |
-
"-bs", str(batch_size),
|
| 152 |
-
"-g", "0",
|
| 153 |
-
"-te", str(epochs),
|
| 154 |
-
"-se", "10",
|
| 155 |
"-pg", str(self.rvc_dir / "pretrained" / "f0G40k.pth"),
|
| 156 |
"-pd", str(self.rvc_dir / "pretrained" / "f0D40k.pth"),
|
| 157 |
-
"-l", "0",
|
| 158 |
-
"-c", "0"
|
| 159 |
]
|
| 160 |
|
| 161 |
progress(0.2, desc=f"Training {model_name}...")
|
| 162 |
|
| 163 |
-
#
|
| 164 |
-
|
| 165 |
-
env['PYTHONPATH'] = str(self.rvc_dir) + (f":{env.get('PYTHONPATH', '')}" if env.get('PYTHONPATH') else "")
|
| 166 |
-
|
| 167 |
-
# Run training from RVC directory and capture output
|
| 168 |
-
process = subprocess.Popen(
|
| 169 |
-
cmd,
|
| 170 |
-
stdout=subprocess.PIPE,
|
| 171 |
-
stderr=subprocess.STDOUT,
|
| 172 |
-
text=True,
|
| 173 |
-
bufsize=1,
|
| 174 |
-
cwd=str(self.rvc_dir),
|
| 175 |
-
env=env
|
| 176 |
-
)
|
| 177 |
-
|
| 178 |
-
last_output = []
|
| 179 |
-
while True:
|
| 180 |
-
line = process.stdout.readline()
|
| 181 |
-
if not line and process.poll() is not None:
|
| 182 |
-
break
|
| 183 |
-
if line:
|
| 184 |
-
last_output.append(line.strip())
|
| 185 |
-
if len(last_output) > 10:
|
| 186 |
-
last_output.pop(0)
|
| 187 |
-
if "epoch" in line.lower() or "step" in line.lower():
|
| 188 |
-
progress(0.2, desc=f"Training: {line.strip()[:60]}")
|
| 189 |
-
|
| 190 |
-
return_code = process.wait()
|
| 191 |
|
| 192 |
-
|
| 193 |
-
|
|
|
|
|
|
|
|
|
|
| 194 |
|
| 195 |
-
|
| 196 |
-
time.sleep(2)
|
| 197 |
|
| 198 |
progress(0.9, desc="Searching for model files...")
|
| 199 |
|
| 200 |
-
#
|
| 201 |
-
|
| 202 |
-
|
| 203 |
-
|
| 204 |
-
|
| 205 |
-
|
| 206 |
-
|
| 207 |
-
|
| 208 |
-
|
| 209 |
-
|
|
|
|
| 210 |
|
| 211 |
-
|
| 212 |
-
model_files = []
|
| 213 |
-
index_files = []
|
| 214 |
-
|
| 215 |
-
for path in possible_paths:
|
| 216 |
-
if path.exists():
|
| 217 |
-
if path.is_dir():
|
| 218 |
-
model_files.extend(list(path.glob("**/*.pth")))
|
| 219 |
-
index_files.extend(list(path.glob("**/*.index")))
|
| 220 |
-
elif path.suffix == '.pth':
|
| 221 |
-
model_files.append(path)
|
| 222 |
-
|
| 223 |
-
# Search for G_*.pth and D_*.pth checkpoint files
|
| 224 |
-
if log_dir.exists():
|
| 225 |
-
g_checkpoints = list(log_dir.glob("G_*.pth"))
|
| 226 |
-
d_checkpoints = list(log_dir.glob("D_*.pth"))
|
| 227 |
-
model_files.extend(g_checkpoints)
|
| 228 |
-
model_files.extend(list(log_dir.rglob("*.index")))
|
| 229 |
-
index_files.extend(list(log_dir.rglob("*.index")))
|
| 230 |
-
|
| 231 |
-
# Remove duplicates
|
| 232 |
-
model_files = list(set(model_files))
|
| 233 |
-
index_files = list(set(index_files))
|
| 234 |
-
|
| 235 |
-
if model_files or index_files:
|
| 236 |
output_dir = self.workspace / model_name
|
| 237 |
output_dir.mkdir(exist_ok=True)
|
| 238 |
|
| 239 |
files_info = []
|
| 240 |
|
| 241 |
-
#
|
| 242 |
-
g_files = [f for f in model_files if f.name.startswith('G_')]
|
| 243 |
if g_files:
|
| 244 |
-
latest_g = max(g_files, key=lambda
|
| 245 |
shutil.copy2(latest_g, output_dir / f"{model_name}.pth")
|
| 246 |
model_size = latest_g.stat().st_size / (1024*1024)
|
| 247 |
-
files_info.append(f"- {model_name}.pth (
|
| 248 |
|
| 249 |
-
|
| 250 |
-
|
| 251 |
-
shutil.copy2(
|
| 252 |
-
files_info.append(f"- {
|
| 253 |
|
| 254 |
progress(1.0, desc="Training complete!")
|
| 255 |
-
return f"β
Training Complete!\n\nπ Model: {model_name}\nπ Epochs: {epochs}\n\nπΎ
|
| 256 |
else:
|
| 257 |
-
|
| 258 |
-
debug_info
|
| 259 |
-
for p in possible_paths:
|
| 260 |
-
debug_info.append(f" - {p} (exists: {p.exists()})")
|
| 261 |
-
|
| 262 |
-
debug_info.append(f"\nLog directory contents:")
|
| 263 |
if log_dir.exists():
|
| 264 |
for item in log_dir.rglob("*"):
|
| 265 |
-
|
| 266 |
-
|
| 267 |
|
| 268 |
-
debug_info.append(
|
| 269 |
-
debug_info.extend(
|
| 270 |
|
| 271 |
-
return f"β οΈ Training completed but model files not found.\n\n{chr(10).join(debug_info)}\n\nπ‘
|
| 272 |
|
| 273 |
except Exception as e:
|
| 274 |
-
|
| 275 |
-
return f"β Training failed: {str(e)}\n\nTraceback:\n{traceback.format_exc()}"
|
| 276 |
|
| 277 |
def package_model(self, model_name):
|
| 278 |
"""Package model for download"""
|
|
@@ -281,8 +215,8 @@ class RealRVCTrainer:
|
|
| 281 |
if not output_dir.exists():
|
| 282 |
output_dir = self.rvc_dir / "logs" / model_name / "weights"
|
| 283 |
|
| 284 |
-
if not output_dir.exists()
|
| 285 |
-
return None, "β Model not found
|
| 286 |
|
| 287 |
zip_path = self.workspace / f"{model_name}_RVC.zip"
|
| 288 |
with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zipf:
|
|
@@ -290,8 +224,7 @@ class RealRVCTrainer:
|
|
| 290 |
if file.is_file() and (file.suffix in ['.pth', '.index', '.json']):
|
| 291 |
zipf.write(file, file.name)
|
| 292 |
|
| 293 |
-
|
| 294 |
-
return str(zip_path), f"β
Model packaged: {zip_path.name} ({zip_size:.1f}MB)"
|
| 295 |
except Exception as e:
|
| 296 |
return None, f"β Error: {str(e)}"
|
| 297 |
|
|
|
|
| 6 |
from pathlib import Path
|
| 7 |
import zipfile
|
| 8 |
import json
|
|
|
|
| 9 |
|
| 10 |
class RealRVCTrainer:
|
| 11 |
def __init__(self):
|
|
|
|
| 115 |
|
| 116 |
progress(0.3, desc="Preprocessing audio...")
|
| 117 |
cmd = [sys.executable, str(preprocess_script), str(dataset_path), str(sample_rate), "2"]
|
| 118 |
+
result = subprocess.run(cmd, capture_output=True, text=True)
|
| 119 |
|
| 120 |
progress(1.0, desc="Preprocessing complete!")
|
| 121 |
return f"β
Preprocessing Complete!\n\nπ΅ Sample Rate: {sample_rate}Hz\nπ Features extracted\nπ Ready for training!"
|
|
|
|
| 130 |
log_dir = self.rvc_dir / "logs" / model_name
|
| 131 |
log_dir.mkdir(parents=True, exist_ok=True)
|
| 132 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 133 |
progress(0.1, desc="Starting RVC training...")
|
| 134 |
train_script = self.rvc_dir / "infer" / "modules" / "train" / "train.py"
|
| 135 |
if not train_script.exists():
|
| 136 |
train_script = self.rvc_dir / "train_nsf_sim_cache_sid_load_pretrain.py"
|
| 137 |
|
|
|
|
|
|
|
|
|
|
| 138 |
cmd = [
|
| 139 |
sys.executable, str(train_script),
|
| 140 |
+
"-e", model_name, "-sr", str(sample_rate),
|
| 141 |
+
"-f0", "1", "-bs", str(batch_size),
|
| 142 |
+
"-g", "0", "-te", str(epochs), "-se", "10",
|
|
|
|
|
|
|
|
|
|
|
|
|
| 143 |
"-pg", str(self.rvc_dir / "pretrained" / "f0G40k.pth"),
|
| 144 |
"-pd", str(self.rvc_dir / "pretrained" / "f0D40k.pth"),
|
| 145 |
+
"-l", "0", "-c", "0"
|
|
|
|
| 146 |
]
|
| 147 |
|
| 148 |
progress(0.2, desc=f"Training {model_name}...")
|
| 149 |
|
| 150 |
+
# Capture both stdout and stderr
|
| 151 |
+
process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 152 |
|
| 153 |
+
training_output = []
|
| 154 |
+
for line in process.stdout:
|
| 155 |
+
training_output.append(line.strip())
|
| 156 |
+
if "epoch" in line.lower():
|
| 157 |
+
progress(0.2 + 0.6, desc=f"Training: {line.strip()[:50]}")
|
| 158 |
|
| 159 |
+
return_code = process.wait()
|
|
|
|
| 160 |
|
| 161 |
progress(0.9, desc="Searching for model files...")
|
| 162 |
|
| 163 |
+
# Search for G_*.pth (generator checkpoints) and D_*.pth (discriminator)
|
| 164 |
+
g_files = list(log_dir.glob("G_*.pth"))
|
| 165 |
+
d_files = list(log_dir.glob("D_*.pth"))
|
| 166 |
+
index_files = list(log_dir.rglob("*.index"))
|
| 167 |
+
|
| 168 |
+
# Also check in added_* subfolders
|
| 169 |
+
added_folders = list(log_dir.glob("added_*"))
|
| 170 |
+
for folder in added_folders:
|
| 171 |
+
g_files.extend(list(folder.glob("G_*.pth")))
|
| 172 |
+
d_files.extend(list(folder.glob("D_*.pth")))
|
| 173 |
+
index_files.extend(list(folder.glob("*.index")))
|
| 174 |
|
| 175 |
+
if g_files or index_files:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 176 |
output_dir = self.workspace / model_name
|
| 177 |
output_dir.mkdir(exist_ok=True)
|
| 178 |
|
| 179 |
files_info = []
|
| 180 |
|
| 181 |
+
# Get the latest G file (highest epoch number)
|
|
|
|
| 182 |
if g_files:
|
| 183 |
+
latest_g = max(g_files, key=lambda f: int(f.stem.split('_')[1]) if f.stem.split('_')[1].isdigit() else 0)
|
| 184 |
shutil.copy2(latest_g, output_dir / f"{model_name}.pth")
|
| 185 |
model_size = latest_g.stat().st_size / (1024*1024)
|
| 186 |
+
files_info.append(f"- {model_name}.pth ({model_size:.1f}MB) [from {latest_g.name}]")
|
| 187 |
|
| 188 |
+
if index_files:
|
| 189 |
+
latest_index = max(index_files, key=lambda p: p.stat().st_mtime)
|
| 190 |
+
shutil.copy2(latest_index, output_dir / latest_index.name)
|
| 191 |
+
files_info.append(f"- {latest_index.name}")
|
| 192 |
|
| 193 |
progress(1.0, desc="Training complete!")
|
| 194 |
+
return f"β
Training Complete!\n\nπ Model: {model_name}\nπ Epochs: {epochs}\n\nπΎ Model Files:\n{chr(10).join(files_info)}\n\nπ Location: {output_dir}\n\nπ Ready to download!"
|
| 195 |
else:
|
| 196 |
+
debug_info = [f"Return code: {return_code}", ""]
|
| 197 |
+
debug_info.append("Files in log directory:")
|
|
|
|
|
|
|
|
|
|
|
|
|
| 198 |
if log_dir.exists():
|
| 199 |
for item in log_dir.rglob("*"):
|
| 200 |
+
if item.is_file():
|
| 201 |
+
debug_info.append(f" - {item.relative_to(log_dir)} ({item.stat().st_size} bytes)")
|
| 202 |
|
| 203 |
+
debug_info.append("\nLast 10 lines of training output:")
|
| 204 |
+
debug_info.extend(training_output[-10:])
|
| 205 |
|
| 206 |
+
return f"β οΈ Training completed but model files not found.\n\nπ Debug:\n{chr(10).join(debug_info)}\n\nπ‘ Check if training actually ran or failed silently."
|
| 207 |
|
| 208 |
except Exception as e:
|
| 209 |
+
return f"β Training failed: {str(e)}"
|
|
|
|
| 210 |
|
| 211 |
def package_model(self, model_name):
|
| 212 |
"""Package model for download"""
|
|
|
|
| 215 |
if not output_dir.exists():
|
| 216 |
output_dir = self.rvc_dir / "logs" / model_name / "weights"
|
| 217 |
|
| 218 |
+
if not output_dir.exists():
|
| 219 |
+
return None, "β Model not found"
|
| 220 |
|
| 221 |
zip_path = self.workspace / f"{model_name}_RVC.zip"
|
| 222 |
with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zipf:
|
|
|
|
| 224 |
if file.is_file() and (file.suffix in ['.pth', '.index', '.json']):
|
| 225 |
zipf.write(file, file.name)
|
| 226 |
|
| 227 |
+
return str(zip_path), f"β
Model packaged: {zip_path.name}"
|
|
|
|
| 228 |
except Exception as e:
|
| 229 |
return None, f"β Error: {str(e)}"
|
| 230 |
|