Fix sidecar crash: torch circular import under PyInstaller
- Exclude ctranslate2.converters from PyInstaller bundle — these modules import torch at module level causing circular import crashes, and are only needed for model conversion (never used at runtime) - Defer all heavy ML imports to first handler call instead of startup, so the sidecar can send its ready message without loading torch/whisper Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -33,7 +33,13 @@ a = Analysis(
|
|||||||
hookspath=[],
|
hookspath=[],
|
||||||
hooksconfig={},
|
hooksconfig={},
|
||||||
runtime_hooks=[],
|
runtime_hooks=[],
|
||||||
excludes=["tkinter", "test", "unittest", "pip", "setuptools"],
|
excludes=[
|
||||||
|
"tkinter", "test", "unittest", "pip", "setuptools",
|
||||||
|
# ctranslate2.converters imports torch at module level and causes
|
||||||
|
# circular import crashes under PyInstaller. These modules are only
|
||||||
|
# needed for model format conversion, never for inference.
|
||||||
|
"ctranslate2.converters",
|
||||||
|
],
|
||||||
win_no_prefer_redirects=False,
|
win_no_prefer_redirects=False,
|
||||||
win_private_assemblies=False,
|
win_private_assemblies=False,
|
||||||
cipher=block_cipher,
|
cipher=block_cipher,
|
||||||
|
|||||||
@@ -41,11 +41,15 @@ def ping_handler(msg: IPCMessage) -> IPCMessage:
|
|||||||
|
|
||||||
def make_transcribe_handler() -> HandlerFunc:
|
def make_transcribe_handler() -> HandlerFunc:
|
||||||
"""Create a transcription handler with a persistent TranscribeService."""
|
"""Create a transcription handler with a persistent TranscribeService."""
|
||||||
from voice_to_notes.services.transcribe import TranscribeService, result_to_payload
|
service = None
|
||||||
|
|
||||||
service = TranscribeService()
|
|
||||||
|
|
||||||
def handler(msg: IPCMessage) -> IPCMessage:
|
def handler(msg: IPCMessage) -> IPCMessage:
|
||||||
|
nonlocal service
|
||||||
|
if service is None:
|
||||||
|
from voice_to_notes.services.transcribe import TranscribeService
|
||||||
|
service = TranscribeService()
|
||||||
|
from voice_to_notes.services.transcribe import result_to_payload
|
||||||
|
|
||||||
payload = msg.payload
|
payload = msg.payload
|
||||||
result = service.transcribe(
|
result = service.transcribe(
|
||||||
request_id=msg.id,
|
request_id=msg.id,
|
||||||
@@ -66,11 +70,15 @@ def make_transcribe_handler() -> HandlerFunc:
|
|||||||
|
|
||||||
def make_diarize_handler() -> HandlerFunc:
|
def make_diarize_handler() -> HandlerFunc:
|
||||||
"""Create a diarization handler with a persistent DiarizeService."""
|
"""Create a diarization handler with a persistent DiarizeService."""
|
||||||
from voice_to_notes.services.diarize import DiarizeService, diarization_to_payload
|
service = None
|
||||||
|
|
||||||
service = DiarizeService()
|
|
||||||
|
|
||||||
def handler(msg: IPCMessage) -> IPCMessage:
|
def handler(msg: IPCMessage) -> IPCMessage:
|
||||||
|
nonlocal service
|
||||||
|
if service is None:
|
||||||
|
from voice_to_notes.services.diarize import DiarizeService
|
||||||
|
service = DiarizeService()
|
||||||
|
from voice_to_notes.services.diarize import diarization_to_payload
|
||||||
|
|
||||||
payload = msg.payload
|
payload = msg.payload
|
||||||
result = service.diarize(
|
result = service.diarize(
|
||||||
request_id=msg.id,
|
request_id=msg.id,
|
||||||
@@ -163,11 +171,15 @@ def make_diarize_download_handler() -> HandlerFunc:
|
|||||||
|
|
||||||
def make_pipeline_handler() -> HandlerFunc:
|
def make_pipeline_handler() -> HandlerFunc:
|
||||||
"""Create a full pipeline handler (transcribe + diarize + merge)."""
|
"""Create a full pipeline handler (transcribe + diarize + merge)."""
|
||||||
from voice_to_notes.services.pipeline import PipelineService, pipeline_result_to_payload
|
service = None
|
||||||
|
|
||||||
service = PipelineService()
|
|
||||||
|
|
||||||
def handler(msg: IPCMessage) -> IPCMessage:
|
def handler(msg: IPCMessage) -> IPCMessage:
|
||||||
|
nonlocal service
|
||||||
|
if service is None:
|
||||||
|
from voice_to_notes.services.pipeline import PipelineService
|
||||||
|
service = PipelineService()
|
||||||
|
from voice_to_notes.services.pipeline import pipeline_result_to_payload
|
||||||
|
|
||||||
payload = msg.payload
|
payload = msg.payload
|
||||||
result = service.run(
|
result = service.run(
|
||||||
request_id=msg.id,
|
request_id=msg.id,
|
||||||
@@ -193,11 +205,15 @@ def make_pipeline_handler() -> HandlerFunc:
|
|||||||
|
|
||||||
def make_export_handler() -> HandlerFunc:
|
def make_export_handler() -> HandlerFunc:
|
||||||
"""Create an export handler."""
|
"""Create an export handler."""
|
||||||
from voice_to_notes.services.export import ExportService, make_export_request
|
service = None
|
||||||
|
|
||||||
service = ExportService()
|
|
||||||
|
|
||||||
def handler(msg: IPCMessage) -> IPCMessage:
|
def handler(msg: IPCMessage) -> IPCMessage:
|
||||||
|
nonlocal service
|
||||||
|
if service is None:
|
||||||
|
from voice_to_notes.services.export import ExportService
|
||||||
|
service = ExportService()
|
||||||
|
from voice_to_notes.services.export import make_export_request
|
||||||
|
|
||||||
request = make_export_request(msg.payload)
|
request = make_export_request(msg.payload)
|
||||||
output_path = service.export(request)
|
output_path = service.export(request)
|
||||||
return IPCMessage(
|
return IPCMessage(
|
||||||
@@ -211,11 +227,14 @@ def make_export_handler() -> HandlerFunc:
|
|||||||
|
|
||||||
def make_ai_chat_handler() -> HandlerFunc:
|
def make_ai_chat_handler() -> HandlerFunc:
|
||||||
"""Create an AI chat handler with persistent AIProviderService."""
|
"""Create an AI chat handler with persistent AIProviderService."""
|
||||||
from voice_to_notes.services.ai_provider import create_default_service
|
service = None
|
||||||
|
|
||||||
service = create_default_service()
|
|
||||||
|
|
||||||
def handler(msg: IPCMessage) -> IPCMessage:
|
def handler(msg: IPCMessage) -> IPCMessage:
|
||||||
|
nonlocal service
|
||||||
|
if service is None:
|
||||||
|
from voice_to_notes.services.ai_provider import create_default_service
|
||||||
|
service = create_default_service()
|
||||||
|
|
||||||
payload = msg.payload
|
payload = msg.payload
|
||||||
action = payload.get("action", "chat")
|
action = payload.get("action", "chat")
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user