"""Transcription par faster-whisper (CTranslate2) — tourne partout : Mac Intel, Windows avec ou sans GPU. Complement de moteur/mlx.py, qui lui est reserve a l'Apple Silicon. """ import numpy as np from core import clean_transcript class TranscripteurFasterWhisper: """Implementation du contrat Transcripteur pour faster-whisper. Le peripherique (`cpu`/`cuda`) et le type de calcul (`int8`/`float16`...) sont recus en parametres plutot que devines ici : cette classe ne sonde jamais le materiel elle-meme. C'est `moteur/__init__.py::choisir_transcripteur` qui tranche, d'apres `_cuda_disponible` — garder la decision hors de cette classe la rend testable sans machine CUDA ni GPU. """ def __init__(self, modele, langue, amorce, peripherique, type_calcul): self.modele = modele self.langue = langue self.amorce = amorce self.peripherique = peripherique self.type_calcul = type_calcul self._instance = None # modele CTranslate2 charge paresseusement def warmup(self): """Charge le modele une fois, sur une seconde de silence.""" self.transcrire(np.zeros(16000, dtype="float32")) def transcrire(self, audio): # Import differe dans la methode, jamais au niveau module : sinon toute # machine sans faster-whisper installe casserait a l'import de ce # fichier, y compris pour les tests qui n'exercent que la fabrique # (meme raison que moteur/mlx.py pour mlx_whisper). from faster_whisper import WhisperModel if self._instance is None: self._instance = WhisperModel( self.modele, device=self.peripherique, compute_type=self.type_calcul ) segments, _info = self._instance.transcribe( audio, language=self.langue, initial_prompt=self.amorce ) # faster-whisper rend un generateur de segments, pas un texte unique : # il faut le consommer entierement avant de pouvoir le joindre. return clean_transcript("".join(segment.text for segment in segments))