feat(models): memory-aware whisper.cpp ladder with conditional backend order
Free memory picks the load-time rung (large-v3-turbo-q8_0 default, q5_0 under 1086 MiB free, small/small.en floor) for unpinned default configs; thresholds derive from catalog sizes plus the protocol's 512 MiB headroom. A manual pin is never overridden, and a failed load steps one rung down and retries exactly once before surfacing. CUDA ranks before Vulkan only with a complete architecture-matching toolkit (nvidia-smi GPU, nvcc, compute capability >= 7.0); otherwise Vulkan, then CPU. The driver-only CUDA recommendation now demotes to CPU logic instead of naming an unreachable VRAM ladder. Refs #20
This commit is contained in:
@@ -999,9 +999,13 @@ class TestGetRecommendedModel(unittest.TestCase):
|
||||
) as mock_backend:
|
||||
mock_backend.return_value = ("vulkan", "Intel Arc A770")
|
||||
|
||||
from vocalinux.utils.whispercpp_model_info import get_recommended_model
|
||||
with patch(
|
||||
"vocalinux.speech_recognition.model_ladder.cuda_toolkit_ready",
|
||||
return_value=True,
|
||||
):
|
||||
from vocalinux.utils.whispercpp_model_info import get_recommended_model
|
||||
|
||||
model, reason = get_recommended_model()
|
||||
model, reason = get_recommended_model()
|
||||
|
||||
self.assertEqual(model, "small")
|
||||
|
||||
@@ -1018,13 +1022,41 @@ class TestGetRecommendedModel(unittest.TestCase):
|
||||
) as mock_backend:
|
||||
mock_backend.return_value = ("cuda", "NVIDIA RTX 4090 (24GB)")
|
||||
|
||||
from vocalinux.utils.whispercpp_model_info import get_recommended_model
|
||||
with patch(
|
||||
"vocalinux.speech_recognition.model_ladder.cuda_toolkit_ready",
|
||||
return_value=True,
|
||||
):
|
||||
from vocalinux.utils.whispercpp_model_info import get_recommended_model
|
||||
|
||||
model, reason = get_recommended_model()
|
||||
model, reason = get_recommended_model()
|
||||
|
||||
# High VRAM should recommend medium or higher
|
||||
self.assertIn(model, ["medium", "large", "small"])
|
||||
|
||||
def test_get_recommended_model_with_driver_only_cuda_demotes(self):
|
||||
"""A CUDA driver without the toolkit cannot run the build: CPU logic."""
|
||||
import sys
|
||||
|
||||
mock_psutil = MagicMock()
|
||||
mock_psutil.virtual_memory.return_value = MagicMock(total=16 * (1024**3))
|
||||
|
||||
with patch.dict("sys.modules", {"psutil": mock_psutil}):
|
||||
with patch(
|
||||
"vocalinux.utils.whispercpp_model_info.detect_compute_backend"
|
||||
) as mock_backend:
|
||||
mock_backend.return_value = ("cuda", "NVIDIA RTX 4090 (24GB)")
|
||||
|
||||
with patch(
|
||||
"vocalinux.speech_recognition.model_ladder.cuda_toolkit_ready",
|
||||
return_value=False,
|
||||
):
|
||||
from vocalinux.utils.whispercpp_model_info import get_recommended_model
|
||||
|
||||
model, _reason = get_recommended_model()
|
||||
|
||||
# 16 GB system RAM under CPU logic recommends base.
|
||||
self.assertEqual(model, "base")
|
||||
|
||||
def test_get_recommended_model_with_cpu_high_ram(self):
|
||||
"""Test model recommendation with CPU and 16GB+ RAM."""
|
||||
import sys
|
||||
@@ -1038,9 +1070,13 @@ class TestGetRecommendedModel(unittest.TestCase):
|
||||
) as mock_backend:
|
||||
mock_backend.return_value = ("cpu", "Intel Core i7")
|
||||
|
||||
from vocalinux.utils.whispercpp_model_info import get_recommended_model
|
||||
with patch(
|
||||
"vocalinux.speech_recognition.model_ladder.cuda_toolkit_ready",
|
||||
return_value=True,
|
||||
):
|
||||
from vocalinux.utils.whispercpp_model_info import get_recommended_model
|
||||
|
||||
model, reason = get_recommended_model()
|
||||
model, reason = get_recommended_model()
|
||||
|
||||
self.assertEqual(model, "base")
|
||||
|
||||
@@ -1057,9 +1093,13 @@ class TestGetRecommendedModel(unittest.TestCase):
|
||||
) as mock_backend:
|
||||
mock_backend.return_value = ("cpu", "AMD Ryzen 5")
|
||||
|
||||
from vocalinux.utils.whispercpp_model_info import get_recommended_model
|
||||
with patch(
|
||||
"vocalinux.speech_recognition.model_ladder.cuda_toolkit_ready",
|
||||
return_value=True,
|
||||
):
|
||||
from vocalinux.utils.whispercpp_model_info import get_recommended_model
|
||||
|
||||
model, reason = get_recommended_model()
|
||||
model, reason = get_recommended_model()
|
||||
|
||||
self.assertEqual(model, "tiny")
|
||||
|
||||
@@ -1076,9 +1116,13 @@ class TestGetRecommendedModel(unittest.TestCase):
|
||||
) as mock_backend:
|
||||
mock_backend.return_value = ("cpu", "Intel Atom")
|
||||
|
||||
from vocalinux.utils.whispercpp_model_info import get_recommended_model
|
||||
with patch(
|
||||
"vocalinux.speech_recognition.model_ladder.cuda_toolkit_ready",
|
||||
return_value=True,
|
||||
):
|
||||
from vocalinux.utils.whispercpp_model_info import get_recommended_model
|
||||
|
||||
model, reason = get_recommended_model()
|
||||
model, reason = get_recommended_model()
|
||||
|
||||
self.assertEqual(model, "tiny")
|
||||
|
||||
@@ -1141,9 +1185,13 @@ class TestGetRecommendedModel(unittest.TestCase):
|
||||
) as mock_backend:
|
||||
mock_backend.return_value = ("cuda", "NVIDIA GeForce RTX 3070 (8192 MiB)")
|
||||
|
||||
from vocalinux.utils.whispercpp_model_info import get_recommended_model
|
||||
with patch(
|
||||
"vocalinux.speech_recognition.model_ladder.cuda_toolkit_ready",
|
||||
return_value=True,
|
||||
):
|
||||
from vocalinux.utils.whispercpp_model_info import get_recommended_model
|
||||
|
||||
model, reason = get_recommended_model()
|
||||
model, reason = get_recommended_model()
|
||||
|
||||
self.assertEqual(model, "medium")
|
||||
self.assertIn("VRAM", reason)
|
||||
@@ -1159,9 +1207,13 @@ class TestGetRecommendedModel(unittest.TestCase):
|
||||
) as mock_backend:
|
||||
mock_backend.return_value = ("cuda", "NVIDIA GeForce RTX 3060 (6144 MiB)")
|
||||
|
||||
from vocalinux.utils.whispercpp_model_info import get_recommended_model
|
||||
with patch(
|
||||
"vocalinux.speech_recognition.model_ladder.cuda_toolkit_ready",
|
||||
return_value=True,
|
||||
):
|
||||
from vocalinux.utils.whispercpp_model_info import get_recommended_model
|
||||
|
||||
model, reason = get_recommended_model()
|
||||
model, reason = get_recommended_model()
|
||||
|
||||
self.assertEqual(model, "small")
|
||||
|
||||
@@ -1176,9 +1228,13 @@ class TestGetRecommendedModel(unittest.TestCase):
|
||||
) as mock_backend:
|
||||
mock_backend.return_value = ("cuda", "NVIDIA GeForce GTX 1050 (2048 MiB)")
|
||||
|
||||
from vocalinux.utils.whispercpp_model_info import get_recommended_model
|
||||
with patch(
|
||||
"vocalinux.speech_recognition.model_ladder.cuda_toolkit_ready",
|
||||
return_value=True,
|
||||
):
|
||||
from vocalinux.utils.whispercpp_model_info import get_recommended_model
|
||||
|
||||
model, reason = get_recommended_model()
|
||||
model, reason = get_recommended_model()
|
||||
|
||||
self.assertEqual(model, "base")
|
||||
|
||||
@@ -1192,9 +1248,13 @@ class TestGetRecommendedModel(unittest.TestCase):
|
||||
) as mock_backend:
|
||||
mock_backend.return_value = ("cuda", "NVIDIA GPU")
|
||||
|
||||
from vocalinux.utils.whispercpp_model_info import get_recommended_model
|
||||
with patch(
|
||||
"vocalinux.speech_recognition.model_ladder.cuda_toolkit_ready",
|
||||
return_value=True,
|
||||
):
|
||||
from vocalinux.utils.whispercpp_model_info import get_recommended_model
|
||||
|
||||
model, reason = get_recommended_model()
|
||||
model, reason = get_recommended_model()
|
||||
|
||||
self.assertEqual(model, "small")
|
||||
self.assertIn("CUDA GPU detected", reason)
|
||||
@@ -1210,9 +1270,13 @@ class TestGetRecommendedModel(unittest.TestCase):
|
||||
) as mock_backend:
|
||||
mock_backend.return_value = ("vulkan", "Intel Arc A770")
|
||||
|
||||
from vocalinux.utils.whispercpp_model_info import get_recommended_model
|
||||
with patch(
|
||||
"vocalinux.speech_recognition.model_ladder.cuda_toolkit_ready",
|
||||
return_value=True,
|
||||
):
|
||||
from vocalinux.utils.whispercpp_model_info import get_recommended_model
|
||||
|
||||
model, reason = get_recommended_model()
|
||||
model, reason = get_recommended_model()
|
||||
|
||||
self.assertEqual(model, "small")
|
||||
self.assertIn("8GB", reason)
|
||||
|
||||
Reference in New Issue
Block a user