generated from dellevin/template
111
This commit is contained in:
@@ -58,8 +58,9 @@ def _default_config():
|
|||||||
'top_k': 5, 'top_p': 1.0, 'temperature': 1.0,
|
'top_k': 5, 'top_p': 1.0, 'temperature': 1.0,
|
||||||
'batch_size': 1, 'speed_factor': 1.0, 'seed': -1,
|
'batch_size': 1, 'speed_factor': 1.0, 'seed': -1,
|
||||||
'gpt_model_dir': '', 'sovits_model_dir': '',
|
'gpt_model_dir': '', 'sovits_model_dir': '',
|
||||||
|
'gpt_model_dir_mode': 'absolute', 'sovits_model_dir_mode': 'absolute',
|
||||||
'last_gpt_model': '', 'last_sovits_model': '',
|
'last_gpt_model': '', 'last_sovits_model': '',
|
||||||
'refer_audio_folder': '',
|
'refer_audio_folder': '', 'refer_audio_folder_mode': 'absolute',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -230,12 +231,16 @@ def get_config():
|
|||||||
cfg = _load_config()
|
cfg = _load_config()
|
||||||
cfg['engine_status'] = _engine_status
|
cfg['engine_status'] = _engine_status
|
||||||
# 扫描模型列表
|
# 扫描模型列表
|
||||||
gpt_dir = cfg.get('gpt_model_dir', '')
|
sovits_path = cfg.get('sovits_project_path', '')
|
||||||
sovits_dir = cfg.get('sovits_model_dir', '')
|
gpt_dir_raw = cfg.get('gpt_model_dir', '')
|
||||||
|
gpt_dir = gpt_dir_raw if cfg.get('gpt_model_dir_mode') == 'absolute' else os.path.join(sovits_path, gpt_dir_raw)
|
||||||
|
sovits_dir_raw = cfg.get('sovits_model_dir', '')
|
||||||
|
sovits_dir = sovits_dir_raw if cfg.get('sovits_model_dir_mode') == 'absolute' else os.path.join(sovits_path, sovits_dir_raw)
|
||||||
cfg['gpt_models'] = _scan_models(gpt_dir, '*.ckpt')
|
cfg['gpt_models'] = _scan_models(gpt_dir, '*.ckpt')
|
||||||
cfg['sovits_models'] = _scan_models(sovits_dir, '*.pth')
|
cfg['sovits_models'] = _scan_models(sovits_dir, '*.pth')
|
||||||
# 扫描参考音频
|
# 扫描参考音频
|
||||||
refer_folder = cfg.get('refer_audio_folder', '')
|
refer_raw = cfg.get('refer_audio_folder', '')
|
||||||
|
refer_folder = refer_raw if cfg.get('refer_audio_folder_mode') == 'absolute' else os.path.join(sovits_path, refer_raw)
|
||||||
if refer_folder and os.path.isdir(refer_folder):
|
if refer_folder and os.path.isdir(refer_folder):
|
||||||
AUDIO_EXTS = ('.wav', '.mp3', '.flac', '.ogg', '.aac', '.m4a', '.wma')
|
AUDIO_EXTS = ('.wav', '.mp3', '.flac', '.ogg', '.aac', '.m4a', '.wma')
|
||||||
files = [os.path.join(refer_folder, f) for f in os.listdir(refer_folder)
|
files = [os.path.join(refer_folder, f) for f in os.listdir(refer_folder)
|
||||||
@@ -255,8 +260,9 @@ def save_config():
|
|||||||
'last_prompt_text', 'last_prompt_lang',
|
'last_prompt_text', 'last_prompt_lang',
|
||||||
'last_text_lang', 'last_text_split_method',
|
'last_text_lang', 'last_text_split_method',
|
||||||
'top_k', 'top_p', 'temperature', 'batch_size', 'speed_factor', 'seed',
|
'top_k', 'top_p', 'temperature', 'batch_size', 'speed_factor', 'seed',
|
||||||
'gpt_model_dir', 'sovits_model_dir',
|
'gpt_model_dir', 'sovits_model_dir', 'refer_audio_folder',
|
||||||
'last_gpt_model', 'last_sovits_model', 'refer_audio_folder'):
|
'gpt_model_dir_mode', 'sovits_model_dir_mode', 'refer_audio_folder_mode',
|
||||||
|
'last_gpt_model', 'last_sovits_model'):
|
||||||
if key in data:
|
if key in data:
|
||||||
cfg[key] = data[key]
|
cfg[key] = data[key]
|
||||||
_save_config(cfg)
|
_save_config(cfg)
|
||||||
@@ -329,8 +335,10 @@ def switch_model():
|
|||||||
return jsonify({'success': False, 'error': '缺少参数'}), 400
|
return jsonify({'success': False, 'error': '缺少参数'}), 400
|
||||||
|
|
||||||
cfg = _load_config()
|
cfg = _load_config()
|
||||||
|
sovits_path = cfg.get('sovits_project_path', '')
|
||||||
if model_type == 'gpt':
|
if model_type == 'gpt':
|
||||||
model_dir = cfg.get('gpt_model_dir', '')
|
model_dir_raw = cfg.get('gpt_model_dir', '')
|
||||||
|
model_dir = model_dir_raw if cfg.get('gpt_model_dir_mode') == 'absolute' else os.path.join(sovits_path, model_dir_raw)
|
||||||
full_path = os.path.join(model_dir, filename) if model_dir else filename
|
full_path = os.path.join(model_dir, filename) if model_dir else filename
|
||||||
ok, err = _reload_model('reload_gpt', full_path)
|
ok, err = _reload_model('reload_gpt', full_path)
|
||||||
if ok:
|
if ok:
|
||||||
@@ -339,7 +347,8 @@ def switch_model():
|
|||||||
return jsonify({'success': True, 'message': f'GPT 模型已切换: {filename}'})
|
return jsonify({'success': True, 'message': f'GPT 模型已切换: {filename}'})
|
||||||
return jsonify({'success': False, 'error': err})
|
return jsonify({'success': False, 'error': err})
|
||||||
elif model_type == 'sovits':
|
elif model_type == 'sovits':
|
||||||
model_dir = cfg.get('sovits_model_dir', '')
|
model_dir_raw = cfg.get('sovits_model_dir', '')
|
||||||
|
model_dir = model_dir_raw if cfg.get('sovits_model_dir_mode') == 'absolute' else os.path.join(sovits_path, model_dir_raw)
|
||||||
full_path = os.path.join(model_dir, filename) if model_dir else filename
|
full_path = os.path.join(model_dir, filename) if model_dir else filename
|
||||||
ok, err = _reload_model('reload_sovits', full_path)
|
ok, err = _reload_model('reload_sovits', full_path)
|
||||||
if ok:
|
if ok:
|
||||||
|
|||||||
@@ -13,8 +13,11 @@
|
|||||||
"seed": -1,
|
"seed": -1,
|
||||||
"gpt_model_dir": "E:\\AI\\GPT-SoVITS-v4\\GPT_weights_v2",
|
"gpt_model_dir": "E:\\AI\\GPT-SoVITS-v4\\GPT_weights_v2",
|
||||||
"sovits_model_dir": "E:\\AI\\GPT-SoVITS-v4\\SoVITS_weights_v2",
|
"sovits_model_dir": "E:\\AI\\GPT-SoVITS-v4\\SoVITS_weights_v2",
|
||||||
|
"gpt_model_dir_mode": "absolute",
|
||||||
|
"sovits_model_dir_mode": "absolute",
|
||||||
"last_gpt_model": "bubu-e15.ckpt",
|
"last_gpt_model": "bubu-e15.ckpt",
|
||||||
"last_sovits_model": "bubu_e4_s68.pth",
|
"last_sovits_model": "bubu_e8_s136.pth",
|
||||||
"refer_audio_folder": "D:\\UserData\\Desktop\\声音素材\\参考音频",
|
"refer_audio_folder": "E:\\AI\\GPT-SoVITS-v4\\参考音频",
|
||||||
|
"refer_audio_folder_mode": "absolute",
|
||||||
"config_yaml": "GPT_SoVITS/configs/tts_infer.yaml"
|
"config_yaml": "GPT_SoVITS/configs/tts_infer.yaml"
|
||||||
}
|
}
|
||||||
Binary file not shown.
@@ -60,6 +60,9 @@
|
|||||||
border-color: #0078d4; box-shadow: 0 0 0 2px rgba(0,120,212,0.06);
|
border-color: #0078d4; box-shadow: 0 0 0 2px rgba(0,120,212,0.06);
|
||||||
}
|
}
|
||||||
.input-group.no-icon input, .input-group.no-icon select { padding-left: 10px; }
|
.input-group.no-icon input, .input-group.no-icon select { padding-left: 10px; }
|
||||||
|
.path-row { display: flex; gap: 6px; align-items: flex-end; }
|
||||||
|
.path-row select { width: 90px; flex-shrink: 0; padding: 7px 6px; font-size: 12px; }
|
||||||
|
.path-row input { flex: 1; padding-left: 10px !important; }
|
||||||
|
|
||||||
.text-input {
|
.text-input {
|
||||||
width: 100%; padding: 10px 12px; border: 1px solid #e0e0e0; border-radius: 6px;
|
width: 100%; padding: 10px 12px; border: 1px solid #e0e0e0; border-radius: 6px;
|
||||||
@@ -301,7 +304,7 @@
|
|||||||
<select id="quickSwitch" style="flex:1;">
|
<select id="quickSwitch" style="flex:1;">
|
||||||
<option value="">选择模型组</option>
|
<option value="">选择模型组</option>
|
||||||
</select>
|
</select>
|
||||||
<button class="btn btn-outline btn-sm" onclick="quickSwitchRandom()" style="white-space:nowrap;"><i class="fas fa-refresh"></i> 随机</button>
|
<button class="btn btn-outline btn-sm" onclick="quickSwitchRandom()" style="white-space:nowrap;"><i class="fas fa-refresh"></i> 模型随机参数</button>
|
||||||
</div>
|
</div>
|
||||||
<div style="display:flex;gap:6px;margin-top:6px;">
|
<div style="display:flex;gap:6px;margin-top:6px;">
|
||||||
<button class="btn btn-outline btn-sm" onclick="quickSwitchPreset('rich_emotion')" style="flex:1;font-size:11px;">情感更丰富</button>
|
<button class="btn btn-outline btn-sm" onclick="quickSwitchPreset('rich_emotion')" style="flex:1;font-size:11px;">情感更丰富</button>
|
||||||
@@ -313,8 +316,8 @@
|
|||||||
<div class="section-title-row" style="margin-top:8px;">
|
<div class="section-title-row" style="margin-top:8px;">
|
||||||
<span class="title-left"><i class="fas fa-brain"></i> 模型切换</span>
|
<span class="title-left"><i class="fas fa-brain"></i> 模型切换</span>
|
||||||
<div style="display:flex;gap:4px;">
|
<div style="display:flex;gap:4px;">
|
||||||
<button class="btn btn-outline btn-sm" onclick="switchModels()"><i class="fas fa-refresh"></i> 切换</button>
|
<button class="btn btn-outline btn-sm" onclick="switchModels()"><i class="fas fa-refresh"></i> 切换模型(接口)</button>
|
||||||
<button class="btn btn-outline btn-sm" onclick="saveModelSelection()"><i class="fas fa-floppy-disk"></i> 保存</button>
|
<button class="btn btn-outline btn-sm" onclick="saveModelSelection()"><i class="fas fa-floppy-disk"></i> 保存配置</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
@@ -392,7 +395,7 @@
|
|||||||
<div class="section-card">
|
<div class="section-card">
|
||||||
<div class="section-title" style="display:flex;align-items:center;justify-content:space-between;">
|
<div class="section-title" style="display:flex;align-items:center;justify-content:space-between;">
|
||||||
<span><i class="fas fa-tags"></i> 推理参数</span>
|
<span><i class="fas fa-tags"></i> 推理参数</span>
|
||||||
<button class="btn btn-outline btn-sm" onclick="saveInferConfig()"><i class="fas fa-floppy-disk"></i> 保存</button>
|
<button class="btn btn-outline btn-sm" onclick="saveInferConfig()"><i class="fas fa-floppy-disk"></i> 保存推理配置</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="input-group no-icon">
|
<div class="input-group no-icon">
|
||||||
<label>文本分段</label>
|
<label>文本分段</label>
|
||||||
@@ -526,15 +529,21 @@
|
|||||||
<div class="section-title"><i class="fas fa-folder"></i> 模型文件夹</div>
|
<div class="section-title"><i class="fas fa-folder"></i> 模型文件夹</div>
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<label for="modalGptModelDir">GPT 模型文件夹</label>
|
<label for="modalGptModelDir">GPT 模型文件夹</label>
|
||||||
<div class="input-wrap">
|
<div class="path-row">
|
||||||
<i class="fas fa-folder-open"></i>
|
<select id="modalGptModelDirMode">
|
||||||
|
<option value="absolute">绝对路径</option>
|
||||||
|
<option value="relative">相对路径</option>
|
||||||
|
</select>
|
||||||
<input type="text" id="modalGptModelDir" placeholder="含 .ckpt 文件的文件夹路径">
|
<input type="text" id="modalGptModelDir" placeholder="含 .ckpt 文件的文件夹路径">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<label for="modalSovitsModelDir">SoVITS 模型文件夹</label>
|
<label for="modalSovitsModelDir">SoVITS 模型文件夹</label>
|
||||||
<div class="input-wrap">
|
<div class="path-row">
|
||||||
<i class="fas fa-folder-open"></i>
|
<select id="modalSovitsModelDirMode">
|
||||||
|
<option value="absolute">绝对路径</option>
|
||||||
|
<option value="relative">相对路径</option>
|
||||||
|
</select>
|
||||||
<input type="text" id="modalSovitsModelDir" placeholder="含 .pth 文件的文件夹路径">
|
<input type="text" id="modalSovitsModelDir" placeholder="含 .pth 文件的文件夹路径">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -547,8 +556,11 @@
|
|||||||
<div class="section-title"><i class="fas fa-folder-open"></i> 参考音频文件夹</div>
|
<div class="section-title"><i class="fas fa-folder-open"></i> 参考音频文件夹</div>
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<label for="modalAudioFolder">音频文件夹路径</label>
|
<label for="modalAudioFolder">音频文件夹路径</label>
|
||||||
<div class="input-wrap">
|
<div class="path-row">
|
||||||
<i class="fas fa-folder-open"></i>
|
<select id="modalAudioFolderMode">
|
||||||
|
<option value="absolute">绝对路径</option>
|
||||||
|
<option value="relative">相对路径</option>
|
||||||
|
</select>
|
||||||
<input type="text" id="modalAudioFolder" placeholder="例如 D:\声音素材\参考音频">
|
<input type="text" id="modalAudioFolder" placeholder="例如 D:\声音素材\参考音频">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -620,6 +632,9 @@
|
|||||||
if (cfg.gpt_model_dir) document.getElementById('modalGptModelDir').value = cfg.gpt_model_dir;
|
if (cfg.gpt_model_dir) document.getElementById('modalGptModelDir').value = cfg.gpt_model_dir;
|
||||||
if (cfg.sovits_model_dir) document.getElementById('modalSovitsModelDir').value = cfg.sovits_model_dir;
|
if (cfg.sovits_model_dir) document.getElementById('modalSovitsModelDir').value = cfg.sovits_model_dir;
|
||||||
if (cfg.refer_audio_folder) document.getElementById('modalAudioFolder').value = cfg.refer_audio_folder;
|
if (cfg.refer_audio_folder) document.getElementById('modalAudioFolder').value = cfg.refer_audio_folder;
|
||||||
|
document.getElementById('modalGptModelDirMode').value = cfg.gpt_model_dir_mode || 'absolute';
|
||||||
|
document.getElementById('modalSovitsModelDirMode').value = cfg.sovits_model_dir_mode || 'absolute';
|
||||||
|
document.getElementById('modalAudioFolderMode').value = cfg.refer_audio_folder_mode || 'absolute';
|
||||||
} catch (e) { showMessage('加载配置失败: ' + e.message, 'error'); }
|
} catch (e) { showMessage('加载配置失败: ' + e.message, 'error'); }
|
||||||
checkEngineStatus();
|
checkEngineStatus();
|
||||||
}
|
}
|
||||||
@@ -635,7 +650,10 @@
|
|||||||
method: 'POST', headers: { 'Content-Type': 'application/json' },
|
method: 'POST', headers: { 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
sovits_project_path: sovitsPath, sovits_config_yaml: configYaml,
|
sovits_project_path: sovitsPath, sovits_config_yaml: configYaml,
|
||||||
gpt_model_dir: gptDir, sovits_model_dir: sovitsDir, refer_audio_folder: audioFolder
|
gpt_model_dir: gptDir, sovits_model_dir: sovitsDir, refer_audio_folder: audioFolder,
|
||||||
|
gpt_model_dir_mode: document.getElementById('modalGptModelDirMode').value,
|
||||||
|
sovits_model_dir_mode: document.getElementById('modalSovitsModelDirMode').value,
|
||||||
|
refer_audio_folder_mode: document.getElementById('modalAudioFolderMode').value
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
showMessage('设置已保存', 'success');
|
showMessage('设置已保存', 'success');
|
||||||
@@ -662,7 +680,11 @@
|
|||||||
var sovitsDir = document.getElementById('modalSovitsModelDir').value.trim();
|
var sovitsDir = document.getElementById('modalSovitsModelDir').value.trim();
|
||||||
await fetch('/ai-dubbing/config', {
|
await fetch('/ai-dubbing/config', {
|
||||||
method: 'POST', headers: { 'Content-Type': 'application/json' },
|
method: 'POST', headers: { 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ gpt_model_dir: gptDir, sovits_model_dir: sovitsDir })
|
body: JSON.stringify({
|
||||||
|
gpt_model_dir: gptDir, sovits_model_dir: sovitsDir,
|
||||||
|
gpt_model_dir_mode: document.getElementById('modalGptModelDirMode').value,
|
||||||
|
sovits_model_dir_mode: document.getElementById('modalSovitsModelDirMode').value
|
||||||
|
})
|
||||||
});
|
});
|
||||||
showMessage('文件夹配置已保存', 'success');
|
showMessage('文件夹配置已保存', 'success');
|
||||||
refreshModels();
|
refreshModels();
|
||||||
@@ -672,7 +694,10 @@
|
|||||||
var folder = document.getElementById('modalAudioFolder').value.trim();
|
var folder = document.getElementById('modalAudioFolder').value.trim();
|
||||||
fetch('/ai-dubbing/config', {
|
fetch('/ai-dubbing/config', {
|
||||||
method: 'POST', headers: { 'Content-Type': 'application/json' },
|
method: 'POST', headers: { 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ refer_audio_folder: folder })
|
body: JSON.stringify({
|
||||||
|
refer_audio_folder: folder,
|
||||||
|
refer_audio_folder_mode: document.getElementById('modalAudioFolderMode').value
|
||||||
|
})
|
||||||
}).then(function() { showMessage('已保存', 'success'); });
|
}).then(function() { showMessage('已保存', 'success'); });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,9 @@ from config import JIEBA_DICT_FILE, TOKEN_FILE_PATH
|
|||||||
|
|
||||||
# 可选依赖
|
# 可选依赖
|
||||||
try:
|
try:
|
||||||
import jieba
|
import contextlib, io
|
||||||
|
with contextlib.redirect_stdout(io.StringIO()), contextlib.redirect_stderr(io.StringIO()):
|
||||||
|
import jieba
|
||||||
JIEBA_AVAILABLE = True
|
JIEBA_AVAILABLE = True
|
||||||
except ImportError:
|
except ImportError:
|
||||||
JIEBA_AVAILABLE = False
|
JIEBA_AVAILABLE = False
|
||||||
|
|||||||
Reference in New Issue
Block a user