diff --git a/buzz/model_loader.py b/buzz/model_loader.py index 87531189..5d4061e9 100644 --- a/buzz/model_loader.py +++ b/buzz/model_loader.py @@ -624,9 +624,41 @@ class ModelDownloader(QRunnable): ) if self.is_coreml_supported: - with zipfile.ZipFile( - os.path.join(model_path, f"ggml-{model_name}-encoder.mlmodelc.zip"), 'r') as zip_ref: - zip_ref.extractall(model_path) + import tempfile + + target_dir = os.path.join(model_path, f"ggml-{model_name}-encoder.mlmodelc") + zip_path = os.path.join(model_path, f"ggml-{model_name}-encoder.mlmodelc.zip") + + # Remove target directory if it exists + if os.path.exists(target_dir): + shutil.rmtree(target_dir) + + # Extract to a temporary directory first + with tempfile.TemporaryDirectory() as temp_dir: + with zipfile.ZipFile(zip_path, 'r') as zip_ref: + zip_ref.extractall(temp_dir) + + # Remove __MACOSX metadata folders if present + macosx_path = os.path.join(temp_dir, "__MACOSX") + if os.path.exists(macosx_path): + shutil.rmtree(macosx_path) + + # Check if there's a single top-level directory + temp_contents = os.listdir(temp_dir) + if len(temp_contents) == 1 and os.path.isdir(os.path.join(temp_dir, temp_contents[0])): + # Single directory - move its contents to target + nested_dir = os.path.join(temp_dir, temp_contents[0]) + shutil.move(nested_dir, target_dir) + else: + # Multiple items or files - copy everything to target + os.makedirs(target_dir, exist_ok=True) + for item in temp_contents: + src = os.path.join(temp_dir, item) + dst = os.path.join(target_dir, item) + if os.path.isdir(src): + shutil.copytree(src, dst) + else: + shutil.copy2(src, dst) self.signals.finished.emit(os.path.join( model_path, f"ggml-{model_name}.bin")) diff --git a/buzz/transcriber/whisper_cpp.py b/buzz/transcriber/whisper_cpp.py index 7bea69fb..8b2195ee 100644 --- a/buzz/transcriber/whisper_cpp.py +++ b/buzz/transcriber/whisper_cpp.py @@ -100,7 +100,12 @@ class WhisperCpp: "-l", language, "--print-progress", "--suppress-nst", + # Protections against hallucinated repetition. Seems to be problem on macOS + # https://github.com/ggml-org/whisper.cpp/issues/1507 + "--max-context", "64", + "--entropy-thold", "2.8", "--output-json-full", + "-t", str(os.getenv("BUZZ_WHISPERCPP_N_THREADS", (os.cpu_count() or 8) // 2)), "-f", file_to_process, ] @@ -110,9 +115,8 @@ class WhisperCpp: # Force CPU if specified force_cpu = os.getenv("BUZZ_FORCE_CPU", "false") - if force_cpu != "false" or not IS_VULKAN_SUPPORTED: + if force_cpu != "false" or (not IS_VULKAN_SUPPORTED and platform.system() != "Darwin"): cmd.extend(["--no-gpu"]) - cmd.extend(["-t", str(os.getenv("BUZZ_WHISPERCPP_N_THREADS", (os.cpu_count() or 8) // 2))]) print(f"Running Whisper CLI: {' '.join(cmd)}")