Ajoute le moteur faster-whisper, pour les machines sans Apple Silicon

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-23 18:38:09 +02:00
co-authored by Claude Opus 5
parent 5cf8f448ed
commit 6974a3406c
4 changed files with 81 additions and 0 deletions
+8
View File
@@ -59,4 +59,12 @@ def choisir_transcripteur(nom, modele, langue, amorce):
if nom == "mlx":
from moteur.mlx import TranscripteurMLX
return TranscripteurMLX(modele, langue, amorce)
if nom in ("faster-cpu", "faster-gpu"):
# C'est ICI, et nulle part dans TranscripteurFasterWhisper, que le
# peripherique et le type de calcul sont decides : la classe reste
# testable sans jamais sonder de vrai materiel.
from moteur.faster import TranscripteurFasterWhisper
peripherique = "cuda" if nom == "faster-gpu" else "cpu"
type_calcul = "float16" if nom == "faster-gpu" else "int8"
return TranscripteurFasterWhisper(modele, langue, amorce, peripherique, type_calcul)
raise NotImplementedError(f"Moteur non pris en charge à cette étape : {nom}")
+48
View File
@@ -0,0 +1,48 @@
"""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))