"""FasterWhisperEngine 단위 테스트 — CTranslate2 호출 계약 (device 분리). faster-whisper/CTranslate2는 ``device`` 문자열로 "cuda"만 허용하며 인덱스는 별도 ``device_index`` 인자로 받는다. DeviceManager가 내려주는 "cuda:N"을 제대로 분리해 전달하는지 mock으로 검증한다 (GPU 환경에서만 재현되는 버그 — Colab 실전 테스트에서 ``unsupported device cuda:0``으로 확인됨). """ from __future__ import annotations import sys import types from luke_scribe.engine.base import TranscriptionOptions from luke_scribe.engine.faster_whisper_engine import FasterWhisperEngine class FakeWhisperModel: """faster_whisper.WhisperModel 대체 — 생성 인자만 기록한다.""" calls: list[dict] = [] def __init__(self, *args, **kwargs) -> None: self.kwargs = kwargs self.__class__.calls.append(kwargs) def transcribe(self, audio_path, **kwargs): return iter([]), {} def _install_fake(monkeypatch) -> None: mod = types.ModuleType("faster_whisper") mod.WhisperModel = FakeWhisperModel monkeypatch.setitem(sys.modules, "faster_whisper", mod) FakeWhisperModel.calls.clear() def _opts(**kw) -> TranscriptionOptions: kw.setdefault("model", "large-v3-turbo") kw.setdefault("device", "cuda:0") kw.setdefault("compute_type", "float16") return TranscriptionOptions(**kw) def test_cuda_device_index_split(monkeypatch): """'cuda:0' → device='cuda', device_index=0 (Colab A100 첫 GPU).""" _install_fake(monkeypatch) FasterWhisperEngine().transcribe("/tmp/x.wav", _opts()) kwargs = FakeWhisperModel.calls[-1] assert kwargs["device"] == "cuda" assert kwargs["device_index"] == 0 assert kwargs["compute_type"] == "float16" def test_cuda_second_device_index(monkeypatch): """'cuda:1' → device='cuda', device_index=1.""" _install_fake(monkeypatch) FasterWhisperEngine().transcribe("/tmp/x.wav", _opts(device="cuda:1")) kwargs = FakeWhisperModel.calls[-1] assert kwargs["device"] == "cuda" assert kwargs["device_index"] == 1 def test_cpu_passthrough(monkeypatch): """'cpu' → 그대로 device='cpu', device_index=0.""" _install_fake(monkeypatch) FasterWhisperEngine().transcribe("/tmp/x.wav", _opts(device="cpu", compute_type="int8")) kwargs = FakeWhisperModel.calls[-1] assert kwargs["device"] == "cpu" assert kwargs["device_index"] == 0 assert kwargs["compute_type"] == "int8" def test_split_device_helper(): assert FasterWhisperEngine._split_device("cuda:0") == ("cuda", 0) assert FasterWhisperEngine._split_device("cuda:3") == ("cuda", 3) assert FasterWhisperEngine._split_device("cpu") == ("cpu", 0) assert FasterWhisperEngine._split_device("cuda") == ("cuda", 0) # 파싱 불가 인덱스는 그대로 전달 (모델 로드 시 명시적 오류로 fail-explicit) assert FasterWhisperEngine._split_device("cuda:xx") == ("cuda:xx", 0)