diff --git a/pandrator_installer/cli.py b/pandrator_installer/cli.py index ba0bccd..0287a7e 100644 --- a/pandrator_installer/cli.py +++ b/pandrator_installer/cli.py @@ -62,7 +62,7 @@ def parse_launcher_cli_args(argv=None): ) parser.add_argument('--crispasr-model-quantization', choices=('f16', 'q8_0', 'q5_0', 'q4_k')) parser.add_argument('--qwen-backend', choices=('auto', 'cpu', 'cuda', 'vulkan', 'metal'), default='auto') - parser.add_argument('--qwen-model-size', choices=('0.6b', '1.7b'), default='0.6b') + parser.add_argument('--qwen-model-size', choices=('0.6b', '1.7b'), default='1.7b') parser.add_argument('--qwen-quantization', choices=('f16', 'q8_0'), default='f16') parser.add_argument( '--qwen-initial-model', diff --git a/pandrator_installer/components.py b/pandrator_installer/components.py index a8c5dcc..ed45cea 100644 --- a/pandrator_installer/components.py +++ b/pandrator_installer/components.py @@ -951,7 +951,7 @@ def build_kobold_qwen_launcher_command( use_cpu=False, pixi_path=None, backend=None, - model_size="0.6b", + model_size="1.7b", quantization="f16", initial_model="base", ): @@ -1457,7 +1457,7 @@ def install_kobold_qwen_api_server( use_cpu=False, pixi_path=None, backend=None, - model_size="0.6b", + model_size="1.7b", quantization="f16", initial_model="base", ): diff --git a/pandrator_installer/gui/main_window.py b/pandrator_installer/gui/main_window.py index 7a80c94..cf8bd54 100644 --- a/pandrator_installer/gui/main_window.py +++ b/pandrator_installer/gui/main_window.py @@ -115,7 +115,7 @@ def __init__(self, headless=False, working_dir=None, skip_space_warning=False): self.kobold_qwen_var = False self.kobold_qwen_cpu_var = False self.kobold_qwen_backend = "auto" - self.kobold_qwen_model_size = "0.6b" + self.kobold_qwen_model_size = "1.7b" self.kobold_qwen_quantization = "f16" self.kobold_qwen_initial_model = "base" self.kobold_qwen_settings_manually_set = False @@ -1227,7 +1227,7 @@ def set_widget_state(widget, state, value=None): self.kobold_qwen_initial_model = stored_qwen_selection self.kobold_qwen_model_size = qwen_effective_model_size( stored_qwen_selection, - config.get('kobold_qwen_model_size', '0.6b'), + config.get('kobold_qwen_model_size', '1.7b'), ) self.kobold_qwen_quantization = config.get('kobold_qwen_quantization', 'f16') set_widget_state(self.kobold_qwen_checkbox, not kobold_qwen_support, False) @@ -1530,7 +1530,7 @@ def apply_install_selection(self, selection): self.crispasr_engine = getattr(selection, "crispasr_engine", "whisper-large-v3") self.crispasr_model_quantization = getattr(selection, "crispasr_model_quantization", "f16") self.kobold_qwen_backend = getattr(selection, "kobold_qwen_backend", "auto") - self.kobold_qwen_model_size = getattr(selection, "kobold_qwen_model_size", "0.6b") + self.kobold_qwen_model_size = getattr(selection, "kobold_qwen_model_size", "1.7b") self.kobold_qwen_quantization = getattr(selection, "kobold_qwen_quantization", "f16") self.kobold_qwen_initial_model = getattr(selection, "kobold_qwen_initial_model", "base") @@ -1914,7 +1914,7 @@ def __init__(self, parent=None): self.model_size_combo = QComboBox() self.model_size_combo.addItem("0.6B — lower memory, Base only", "0.6b") self.model_size_combo.addItem("1.7B — higher capacity", "1.7b") - self.model_size_combo.setCurrentIndex(max(0, self.model_size_combo.findData(getattr(parent, "kobold_qwen_model_size", "0.6b")))) + self.model_size_combo.setCurrentIndex(max(0, self.model_size_combo.findData(getattr(parent, "kobold_qwen_model_size", "1.7b")))) self.quantization_combo = QComboBox() self.quantization_combo.addItem("FP16 — full precision (default)", "f16") self.quantization_combo.addItem("Q8_0 — lower memory", "q8_0") @@ -1956,7 +1956,7 @@ def get_selected_backend(self): return str(self.backend_combo.currentData() or "auto") def get_selected_model_size(self): - return str(self.model_size_combo.currentData() or "0.6b") + return str(self.model_size_combo.currentData() or "1.7b") def get_selected_quantization(self): return str(self.quantization_combo.currentData() or "f16") diff --git a/pandrator_installer/lifecycle.py b/pandrator_installer/lifecycle.py index 37ed70b..eb817dd 100644 --- a/pandrator_installer/lifecycle.py +++ b/pandrator_installer/lifecycle.py @@ -172,7 +172,7 @@ def _selection(args) -> InstallSelection: crispasr_engine=str(getattr(args, "crispasr_engine", "whisper-large-v3") or "whisper-large-v3"), crispasr_model_quantization=getattr(args, "crispasr_model_quantization", None), kobold_qwen_backend=str(getattr(args, "qwen_backend", "auto") or "auto"), - kobold_qwen_model_size=str(getattr(args, "qwen_model_size", "0.6b") or "0.6b"), + kobold_qwen_model_size=str(getattr(args, "qwen_model_size", "1.7b") or "1.7b"), kobold_qwen_quantization=str(getattr(args, "qwen_quantization", "f16") or "f16"), kobold_qwen_initial_model=str(getattr(args, "qwen_initial_model", "base") or "base"), ) @@ -736,7 +736,7 @@ def build_parser() -> argparse.ArgumentParser: ) command.add_argument("--crispasr-model-quantization", choices=("f16", "q8_0", "q5_0", "q4_k")) command.add_argument("--qwen-backend", choices=("auto", "cpu", "cuda", "vulkan", "metal"), default="auto") - command.add_argument("--qwen-model-size", choices=("0.6b", "1.7b"), default="0.6b") + command.add_argument("--qwen-model-size", choices=("0.6b", "1.7b"), default="1.7b") command.add_argument("--qwen-quantization", choices=("f16", "q8_0"), default="f16") command.add_argument("--qwen-initial-model", choices=("base", "customvoice", "both"), default="base") command.set_defaults(handler=handler) diff --git a/pandrator_installer/models.py b/pandrator_installer/models.py index 37f413e..0aba803 100644 --- a/pandrator_installer/models.py +++ b/pandrator_installer/models.py @@ -6,6 +6,12 @@ from pathlib import Path from typing import Iterable + +# Match the manager catalogue default. An explicit 0.6B selection remains +# supported for Base-model voice cloning; this value is only for legacy +# configurations that predate the persisted model-size setting. +DEFAULT_QWEN_MODEL_SIZE = "1.7b" + from .catalog import INSTALL_COMPONENT_KEYS, resolve_dependencies @@ -71,7 +77,7 @@ class InstallSelection: kobold_qwen: bool = False kobold_qwen_cpu: bool = False kobold_qwen_backend: str = "auto" - kobold_qwen_model_size: str = "0.6b" + kobold_qwen_model_size: str = DEFAULT_QWEN_MODEL_SIZE kobold_qwen_quantization: str = "f16" kobold_qwen_initial_model: str = "base" magpie: bool = False @@ -90,7 +96,7 @@ def from_components( crispasr_engine: str = "whisper-large-v3", crispasr_model_quantization: str | None = None, kobold_qwen_backend: str = "auto", - kobold_qwen_model_size: str = "0.6b", + kobold_qwen_model_size: str = DEFAULT_QWEN_MODEL_SIZE, kobold_qwen_quantization: str = "f16", kobold_qwen_initial_model: str = "base", ) -> "InstallSelection": @@ -127,7 +133,9 @@ def from_components( crispasr_engine=selected_crispasr_engine, crispasr_model_quantization=selected_crispasr_quantization, kobold_qwen_backend=str(kobold_qwen_backend or "auto").lower(), - kobold_qwen_model_size=str(kobold_qwen_model_size or "0.6b").lower(), + kobold_qwen_model_size=str( + kobold_qwen_model_size or DEFAULT_QWEN_MODEL_SIZE + ).lower(), kobold_qwen_quantization=str(kobold_qwen_quantization or "f16").lower(), kobold_qwen_initial_model=str(kobold_qwen_initial_model or "base").lower(), **{field.name: field.name in selected for field in fields(cls) if field.name not in ( @@ -209,8 +217,12 @@ def qwen_effective_model_size(selection: str, model_size: str) -> str: variants = qwen_model_variants(selection) if "customvoice" in variants: return "1.7b" - normalized = str(model_size or "0.6b").strip().lower() - return normalized if normalized in {"0.6b", "1.7b"} else "0.6b" + normalized = str(model_size or DEFAULT_QWEN_MODEL_SIZE).strip().lower() + return ( + normalized + if normalized in {"0.6b", "1.7b"} + else DEFAULT_QWEN_MODEL_SIZE + ) @dataclass(frozen=True) diff --git a/pandrator_installer/runtime.py b/pandrator_installer/runtime.py index 11befef..9c5fcbf 100644 --- a/pandrator_installer/runtime.py +++ b/pandrator_installer/runtime.py @@ -690,7 +690,7 @@ def launch_process(self, selection=None): self.kobold_qwen_process = self.run_kobold_qwen_api_server( kobold_qwen_server_path, backend=configured_backend, - model_size=install_config.get('kobold_qwen_model_size', '0.6b'), + model_size=install_config.get('kobold_qwen_model_size', '1.7b'), quantization=install_config.get('kobold_qwen_quantization', 'f16'), initial_model=install_config.get('kobold_qwen_initial_model', 'base'), pixi_path=shared_pixi_path, @@ -1232,7 +1232,7 @@ def run_kobold_qwen_api_server( use_cpu=False, pixi_path=None, backend=None, - model_size="0.6b", + model_size="1.7b", quantization="f16", initial_model="base", ): diff --git a/pandrator_installer/workflows.py b/pandrator_installer/workflows.py index 6654299..406e887 100644 --- a/pandrator_installer/workflows.py +++ b/pandrator_installer/workflows.py @@ -146,7 +146,7 @@ def run_headless_install( crispasr_engine="whisper-large-v3", crispasr_model_quantization=None, kobold_qwen_backend="auto", - kobold_qwen_model_size="0.6b", + kobold_qwen_model_size="1.7b", kobold_qwen_quantization="f16", kobold_qwen_initial_model="base", ): @@ -879,7 +879,7 @@ def kokoro_update_bootstrap_task(): self.install_kobold_qwen_api_server( kobold_qwen_repo_path, backend=config.get('kobold_qwen_backend', 'auto') if kobold_qwen_gpu_support else 'cpu', - model_size=config.get('kobold_qwen_model_size', '0.6b'), + model_size=config.get('kobold_qwen_model_size', '1.7b'), quantization=config.get('kobold_qwen_quantization', 'f16'), initial_model=model_variant, pixi_path=shared_pixi_path, diff --git a/tests/test_installer_architecture.py b/tests/test_installer_architecture.py index b56d799..19acadd 100644 --- a/tests/test_installer_architecture.py +++ b/tests/test_installer_architecture.py @@ -271,6 +271,7 @@ def test_qwen_defaults_to_fp16_and_supports_both_1_7b_variants(self): ) self.assertEqual(default_selection.kobold_qwen_quantization, "f16") + self.assertEqual(default_selection.kobold_qwen_model_size, "1.7b") self.assertEqual( qwen_model_variants(both_selection.kobold_qwen_initial_model), ("base", "customvoice"), @@ -290,6 +291,7 @@ def test_qwen_defaults_to_fp16_and_supports_both_1_7b_variants(self): ["--qwen-model-size", "1.7b", "--qwen-initial-model", "both"] ) self.assertEqual(cli_defaults.qwen_quantization, "f16") + self.assertEqual(cli_defaults.qwen_model_size, "1.7b") self.assertEqual(cli_both.qwen_initial_model, "both") def test_external_subprocess_environment_restores_pre_bundle_library_path(self): @@ -1159,7 +1161,7 @@ def test_kobold_qwen_launcher_uses_auto_backend_and_port(self): "--port", "8042", "--model-size", - "0.6b", + "1.7b", "--quantization", "f16", "--initial-model", diff --git a/tests/test_installer_launcher_chatterbox.py b/tests/test_installer_launcher_chatterbox.py index 59e11f2..7a5cadc 100644 --- a/tests/test_installer_launcher_chatterbox.py +++ b/tests/test_installer_launcher_chatterbox.py @@ -44,7 +44,7 @@ def test_kobold_qwen_cpu_option_maps_to_cpu_install_variant(self): selection = installer.snapshot_install_selection() self.assertFalse(selection.kobold_qwen) self.assertTrue(selection.kobold_qwen_cpu) - self.assertEqual(selection.kobold_qwen_model_size, "0.6b") + self.assertEqual(selection.kobold_qwen_model_size, "1.7b") self.assertEqual(selection.kobold_qwen_quantization, "f16") installer.launch_kobold_qwen_checkbox.setChecked(True) @@ -158,6 +158,39 @@ def test_qwen_snapshot_keeps_both_models_on_1_7b_if_state_is_stale(self): self.assertEqual(selection.kobold_qwen_initial_model, "both") self.assertEqual(selection.kobold_qwen_model_size, "1.7b") + def test_qwen_model_size_survives_repeated_legacy_configuration_refreshes(self): + installer = PandratorInstaller(headless=True) + config = { + "kobold_qwen_support": True, + "kobold_qwen_gpu_support": True, + "kobold_qwen_backend": "cuda", + "kobold_qwen_model_size": "1.7b", + "kobold_qwen_quantization": "f16", + "kobold_qwen_initial_model": "base", + } + with patch.object(installer, "load_install_config", return_value=config): + installer.refresh_ui_state() + first = installer.snapshot_install_selection() + installer.refresh_ui_state() + second = installer.snapshot_install_selection() + + self.assertEqual(first.kobold_qwen_model_size, "1.7b") + self.assertEqual(second.kobold_qwen_model_size, "1.7b") + + def test_qwen_missing_legacy_model_size_uses_the_manager_default(self): + installer = PandratorInstaller(headless=True) + with patch.object( + installer, + "load_install_config", + return_value={"kobold_qwen_support": True}, + ): + installer.refresh_ui_state() + + self.assertEqual( + installer.snapshot_install_selection().kobold_qwen_model_size, + "1.7b", + ) + def test_rvc_cpu_option_maps_to_cpu_install_and_launch_variants(self): installer = PandratorInstaller(headless=True) diff --git a/tests/test_manager_guided_setup.py b/tests/test_manager_guided_setup.py index 0474b8e..f2b63a6 100644 --- a/tests/test_manager_guided_setup.py +++ b/tests/test_manager_guided_setup.py @@ -338,6 +338,29 @@ def test_frozen_manager_uses_pixi_for_python_backend_bootstrappers(self): self.assertIn("run.py", spec.arguments) self.assertIn("1.7b", spec.arguments) + def test_qwen_runtime_spec_keeps_an_explicit_model_size(self): + from pandrator_manager.models import ResolvedComponentState + from pandrator_manager.runtime_specs import component_runtime_spec + + with tempfile.TemporaryDirectory() as directory: + layout = WorkspaceLayout.from_value(directory) + layout.ensure_base_directories() + self._activate_fixture(layout, "qwen_tts") + spec = component_runtime_spec( + layout, + "qwen_tts", + ResolvedComponentState( + compute=ComputeVariant.CUDA, + platform="test", + quantization="f16", + options={"initial_model": "base", "model_size": "1.7b"}, + ), + ) + + self.assertIsNotNone(spec) + model_size_index = spec.arguments.index("--model-size") + self.assertEqual("1.7b", spec.arguments[model_size_index + 1]) + def test_kokoro_and_voxcpm_have_manager_owned_runtime_contracts(self): from pandrator_manager.models import ResolvedComponentState from pandrator_manager.runtime_specs import component_runtime_spec