Skip to content

Commit 8cb975d

Browse files
committed
Refactor ASR service configuration and enhance user prompts
- Updated `wizard.py` to remove the `http://` prefix requirement for ASR service URLs, improving user experience during setup. - Enhanced `ChronicleSetup` in `init.py` to prompt users for Parakeet ASR and VibeVoice ASR URLs without the `http://` prefix, ensuring clarity in input expectations. - Introduced a new prompt for embedding dimensions in `ChronicleSetup`, allowing users to specify dimensions with validation for better configuration management.
1 parent 134faf5 commit 8cb975d

3 files changed

Lines changed: 72 additions & 43 deletions

File tree

backends/advanced/init.py

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,7 @@ def setup_transcription(self):
326326
elif choice == "2":
327327
self.console.print("[blue][INFO][/blue] Offline Parakeet ASR selected")
328328
parakeet_url = self.prompt_value(
329-
"Parakeet ASR URL", "http://host.docker.internal:8767"
329+
"Parakeet ASR URL (without http:// prefix)", "host.docker.internal:8767"
330330
)
331331

332332
# Write URL to .env for ${PARAKEET_ASR_URL} placeholder in config.yml
@@ -350,7 +350,8 @@ def setup_transcription(self):
350350
"[blue][INFO][/blue] Offline VibeVoice ASR selected (built-in speaker diarization)"
351351
)
352352
vibevoice_url = self.prompt_value(
353-
"VibeVoice ASR URL", "http://host.docker.internal:8767"
353+
"VibeVoice ASR URL (without http:// prefix)",
354+
"host.docker.internal:8767",
354355
)
355356

356357
# Write URL to .env for ${VIBEVOICE_ASR_URL} placeholder in config.yml
@@ -654,6 +655,18 @@ def setup_llm(self):
654655
)
655656

656657
if embedding_model_name:
658+
embed_dim_str = self.prompt_value(
659+
"Embedding dimensions (e.g. 1536 for text-embedding-3-small, 3072 for text-embedding-3-large)",
660+
"1536",
661+
)
662+
try:
663+
embedding_dimensions = int(embed_dim_str)
664+
except ValueError:
665+
self.console.print(
666+
f"[yellow][WARNING][/yellow] Invalid dimensions '{embed_dim_str}', using default 1536"
667+
)
668+
raise ValueError(f"Invalid dimensions '{embed_dim_str}'")
669+
657670
embed_model = {
658671
"name": "custom-embed",
659672
"description": "Custom OpenAI-compatible embeddings",
@@ -663,7 +676,7 @@ def setup_llm(self):
663676
"model_name": embedding_model_name,
664677
"model_url": base_url,
665678
"api_key": "${oc.env:CUSTOM_LLM_API_KEY,''}",
666-
"embedding_dimensions": 1536,
679+
"embedding_dimensions": embedding_dimensions,
667680
"model_output": "vector",
668681
}
669682
self.config_manager.add_or_update_model(embed_model)

extras/asr-services/tests/test_cuda_version_config.py

Lines changed: 55 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,10 @@
77

88
import os
99
import re
10-
import pytest
1110
from pathlib import Path
1211

12+
import pytest
13+
1314

1415
class TestDockerfileCUDASupport:
1516
"""Test that Dockerfiles support configurable CUDA versions."""
@@ -34,56 +35,63 @@ def test_vibevoice_dockerfile_has_cuda_arg(self, vibevoice_dockerfile_path):
3435
content = vibevoice_dockerfile_path.read_text()
3536

3637
# Should have ARG declaration
37-
assert re.search(r"ARG\s+PYTORCH_CUDA_VERSION", content), \
38-
"Dockerfile must declare PYTORCH_CUDA_VERSION build arg"
38+
assert re.search(
39+
r"ARG\s+PYTORCH_CUDA_VERSION", content
40+
), "Dockerfile must declare PYTORCH_CUDA_VERSION build arg"
3941

4042
# Should have default value
4143
arg_match = re.search(r"ARG\s+PYTORCH_CUDA_VERSION=(\w+)", content)
4244
assert arg_match, "PYTORCH_CUDA_VERSION should have default value"
4345
default_version = arg_match.group(1)
44-
assert default_version in ["cu121", "cu126", "cu128"], \
45-
f"Default CUDA version {default_version} should be cu121, cu126, or cu128"
46-
47-
def test_vibevoice_dockerfile_uses_cuda_arg_in_uv_sync(self, vibevoice_dockerfile_path):
46+
assert default_version in [
47+
"cu121",
48+
"cu126",
49+
"cu128",
50+
], f"Default CUDA version {default_version} should be cu121, cu126, or cu128"
51+
52+
def test_vibevoice_dockerfile_uses_cuda_arg_in_uv_sync(
53+
self, vibevoice_dockerfile_path
54+
):
4855
"""Test that VibeVoice Dockerfile uses CUDA arg in uv sync command."""
4956
content = vibevoice_dockerfile_path.read_text()
5057

5158
# Should use --extra ${PYTORCH_CUDA_VERSION}
52-
assert re.search(r"uv\s+sync.*--extra\s+\$\{PYTORCH_CUDA_VERSION\}", content), \
53-
"uv sync command must include --extra ${PYTORCH_CUDA_VERSION}"
59+
assert re.search(
60+
r"uv\s+sync.*--extra\s+\$\{PYTORCH_CUDA_VERSION\}", content
61+
), "uv sync command must include --extra ${PYTORCH_CUDA_VERSION}"
5462

5563
def test_nemo_dockerfile_has_cuda_support(self, nemo_dockerfile_path):
5664
"""Test that NeMo Dockerfile (reference implementation) has CUDA support."""
5765
content = nemo_dockerfile_path.read_text()
5866

59-
assert re.search(r"ARG\s+PYTORCH_CUDA_VERSION", content), \
60-
"NeMo Dockerfile should have PYTORCH_CUDA_VERSION arg"
67+
assert re.search(
68+
r"ARG\s+PYTORCH_CUDA_VERSION", content
69+
), "NeMo Dockerfile should have PYTORCH_CUDA_VERSION arg"
6170

62-
assert re.search(r"uv\s+sync.*--extra\s+\$\{PYTORCH_CUDA_VERSION\}", content), \
63-
"NeMo Dockerfile should use CUDA version in uv sync"
71+
assert re.search(
72+
r"uv\s+sync.*--extra\s+\$\{PYTORCH_CUDA_VERSION\}", content
73+
), "NeMo Dockerfile should use CUDA version in uv sync"
6474

6575
def test_docker_compose_passes_cuda_arg_to_vibevoice(self, docker_compose_path):
6676
"""Test that docker-compose.yml passes PYTORCH_CUDA_VERSION to vibevoice service."""
6777
content = docker_compose_path.read_text()
6878

6979
# Find vibevoice-asr service section
7080
vibevoice_section = re.search(
71-
r"vibevoice-asr:.*?(?=^\S|\Z)",
72-
content,
73-
re.MULTILINE | re.DOTALL
81+
r"vibevoice-asr:.*?(?=^\S|\Z)", content, re.MULTILINE | re.DOTALL
7482
)
7583
assert vibevoice_section, "docker-compose.yml must have vibevoice-asr service"
7684

7785
section_text = vibevoice_section.group(0)
7886

7987
# Should have build args section
80-
assert re.search(r"args:", section_text), \
81-
"vibevoice-asr service should have build args section"
88+
assert re.search(
89+
r"args:", section_text
90+
), "vibevoice-asr service should have build args section"
8291

8392
# Should pass PYTORCH_CUDA_VERSION
8493
assert re.search(
85-
r"PYTORCH_CUDA_VERSION:\s*\$\{PYTORCH_CUDA_VERSION:-cu126\}",
86-
section_text
94+
r"PYTORCH_CUDA_VERSION:\s*\$\{PYTORCH_CUDA_VERSION:-cu126\}", section_text
8795
), "vibevoice-asr should pass PYTORCH_CUDA_VERSION build arg with cu126 default"
8896

8997
def test_docker_compose_cuda_arg_consistency(self, docker_compose_path):
@@ -95,9 +103,7 @@ def test_docker_compose_cuda_arg_consistency(self, docker_compose_path):
95103

96104
for service_name in gpu_services:
97105
service_match = re.search(
98-
rf"{service_name}:.*?(?=^\S|\Z)",
99-
content,
100-
re.MULTILINE | re.DOTALL
106+
rf"{service_name}:.*?(?=^\S|\Z)", content, re.MULTILINE | re.DOTALL
101107
)
102108

103109
if service_match:
@@ -108,7 +114,7 @@ def test_docker_compose_cuda_arg_consistency(self, docker_compose_path):
108114
# Should have PYTORCH_CUDA_VERSION arg
109115
assert re.search(
110116
r"PYTORCH_CUDA_VERSION:\s*\$\{PYTORCH_CUDA_VERSION:-cu\d+\}",
111-
service_text
117+
service_text,
112118
), f"{service_name} with GPU should have PYTORCH_CUDA_VERSION build arg"
113119

114120

@@ -120,8 +126,9 @@ def test_cuda_version_env_var_format(self):
120126
valid_versions = ["cu121", "cu126", "cu128"]
121127

122128
for version in valid_versions:
123-
assert re.match(r"^cu\d{3}$", version), \
124-
f"{version} should match pattern cu### (e.g., cu121, cu126)"
129+
assert re.match(
130+
r"^cu\d{3}$", version
131+
), f"{version} should match pattern cu### (e.g., cu121, cu126)"
125132

126133
def test_cuda_version_from_env(self):
127134
"""Test reading CUDA version from environment."""
@@ -161,22 +168,30 @@ def test_rtx_5090_requires_cu128(self):
161168
# Map GPU architecture to minimum CUDA version
162169
arch_to_cuda = {
163170
"sm_120": "cu128", # RTX 5090, RTX 50 series
164-
"sm_90": "cu126", # RTX 4090, H100
165-
"sm_89": "cu121", # RTX 4090
166-
"sm_86": "cu121", # RTX 3090, A6000
171+
"sm_90": "cu126", # RTX 4090, H100
172+
"sm_89": "cu121", # RTX 4090
173+
"sm_86": "cu121", # RTX 3090, A6000
167174
}
168175

169-
assert arch_to_cuda.get(gpu_arch) == required_cuda, \
170-
f"GPU architecture {gpu_arch} requires CUDA version {required_cuda}"
176+
assert (
177+
arch_to_cuda.get(gpu_arch) == required_cuda
178+
), f"GPU architecture {gpu_arch} requires CUDA version {required_cuda}"
179+
180+
# Architectures supported by each CUDA version (minimum cu version that supports them)
181+
# Used as authoritative reference for architecture-to-CUDA mapping tests.
182+
CUDA_ARCH_SUPPORT = {
183+
"cu121": {"sm_75", "sm_80", "sm_86", "sm_89"},
184+
"cu126": {"sm_75", "sm_80", "sm_86", "sm_89", "sm_90"},
185+
"cu128": {"sm_75", "sm_80", "sm_86", "sm_89", "sm_90", "sm_120"},
186+
}
171187

172188
def test_older_gpus_work_with_cu121(self):
173189
"""Test that older GPUs (sm_86, sm_80) work with cu121."""
174190
older_archs = ["sm_86", "sm_80", "sm_75"] # RTX 3090, A100, RTX 2080
191+
cu121_supported = self.CUDA_ARCH_SUPPORT["cu121"]
175192

176193
for arch in older_archs:
177-
# cu121 supports these architectures
178-
assert arch in ["sm_75", "sm_80", "sm_86"], \
179-
f"{arch} should be supported by CUDA 12.1"
194+
assert arch in cu121_supported, f"{arch} should be supported by CUDA 12.1"
180195

181196

182197
class TestPyProjectCUDAExtras:
@@ -199,8 +214,9 @@ def test_pyproject_has_cuda_extras(self, pyproject_path):
199214

200215
for version in cuda_versions:
201216
# Look for the CUDA version as an extra
202-
assert re.search(rf'["\']?{version}["\']?\s*=', content), \
203-
f"pyproject.toml should define {version} extra"
217+
assert re.search(
218+
rf'["\']?{version}["\']?\s*=', content
219+
), f"pyproject.toml should define {version} extra"
204220

205221
def test_pyproject_cuda_extras_have_pytorch(self, pyproject_path):
206222
"""Test that CUDA extras include torch/torchaudio dependencies."""
@@ -211,9 +227,9 @@ def test_pyproject_cuda_extras_have_pytorch(self, pyproject_path):
211227

212228
# Each CUDA extra should reference torch with the appropriate index
213229
# e.g., { extra = "cu128" } or { index = "pytorch-cu128" }
214-
assert re.search(r'extra\s*=\s*["\']cu\d{3}["\']', content) or \
215-
re.search(r'index\s*=\s*["\']pytorch-cu\d{3}["\']', content), \
216-
"CUDA extras should reference PyTorch with CUDA version"
230+
assert re.search(r'extra\s*=\s*["\']cu\d{3}["\']', content) or re.search(
231+
r'index\s*=\s*["\']pytorch-cu\d{3}["\']', content
232+
), "CUDA extras should reference PyTorch with CUDA version"
217233

218234

219235
if __name__ == "__main__":

wizard.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ def run_service_setup(
258258
if "speaker-recognition" in selected_services:
259259
cmd.extend(["--speaker-service-url", "http://speaker-service:8085"])
260260
if "asr-services" in selected_services:
261-
cmd.extend(["--parakeet-asr-url", "http://host.docker.internal:8767"])
261+
cmd.extend(["--parakeet-asr-url", "host.docker.internal:8767"])
262262

263263
# Pass transcription provider choice from wizard
264264
if transcription_provider:

0 commit comments

Comments
 (0)