SimpleFrog's picture
Update app.py
7e7072c verified
import streamlit as st
import torch
import tempfile
import os
import librosa
import numpy as np
from transformers import WhisperProcessor, WhisperForConditionalGeneration
from peft import PeftModel
import psutil
# Configuration de l'interface Streamlit
st.title("🔊 Transcription Audio avec Whisper Fine-tuné (LoRA)")
st.write("Upload un fichier audio et laisse ton modèle fine-tuné faire le travail !")
# 🔹 Charger le modèle Whisper Large et appliquer l’adaptateur LoRA
@st.cache_resource # Permet de ne charger qu'une seule fois le modèle
def load_model():
base_model_name = "openai/whisper-large" # Modèle de base
adapter_model_name = "SimpleFrog/whisper_finetuned" # Adaptateur LoRA
# Récupérer le token Hugging Face depuis une variable d'environnement
hf_token = os.environ.get("HF_TOKEN")
if not hf_token:
raise ValueError("Aucun token Hugging Face trouvé dans l'environnement. Ajoute 'HF_TOKEN'.")
# Charger le modèle de base
model = WhisperForConditionalGeneration.from_pretrained(base_model_name)
# Charger l'adaptateur LoRA (avec le token car modèle privé)
model = PeftModel.from_pretrained(model, adapter_model_name, token=hf_token)
# Charger le processeur audio
processor = WhisperProcessor.from_pretrained(base_model_name)
model.eval() # Mode évaluation
return processor, model
processor, model = load_model()
memory_used = psutil.Process(os.getpid()).memory_info().rss / (1024 * 1024) # Convertir en MB
st.write(f"🖥️ Mémoire utilisée par le modèle : {memory_used:.2f} MB")
# Vérifier que les poids LoRA sont bien appliqués
if hasattr(model, "peft_config"):
st.write("✅ Adaptateur LoRA chargé avec succès !")
st.write("📂 Couches LoRA appliquées :", model.peft_config)
else:
st.write("❌ Aucun adaptateur LoRA détecté, le modèle utilisé est Whisper Large standard.")
# 🔹 Upload d'un fichier audio
uploaded_file = st.file_uploader("Upload un fichier audio", type=["mp3", "wav", "m4a"])
if uploaded_file is not None:
# Sauvegarder temporairement l'audio
with tempfile.NamedTemporaryFile(delete=False, suffix=".wav") as temp_audio:
temp_audio.write(uploaded_file.read())
temp_audio_path = temp_audio.name
# Charger et traiter l'audio
st.write("📄 **Transcription en cours...**")
# 🔹 Charger l'audio et convertir en waveform
audio, sr = librosa.load(temp_audio_path, sr=16000) # Whisper attend du 16kHz
audio = np.expand_dims(audio, axis=0) # Ajouter une dimension batch
# 🔹 Préparer les entrées pour Whisper
inputs = processor(audio, sampling_rate=16000, return_tensors="pt", language="fr", task="transcribe")
# 🔹 Générer la transcription
with torch.no_grad():
predicted_ids = model.generate(input_features=inputs.input_features)
# 🔹 Décoder la sortie
transcription = processor.batch_decode(predicted_ids, skip_special_tokens=True)[0]
# 🔹 Afficher la transcription
st.subheader("📝 Transcription :")
st.text_area("", transcription, height=200)
# Supprimer le fichier temporaire après l'affichage
os.remove(temp_audio_path)
st.write("🔹 Modèle utilisé :", "Whisper Large + Adaptateur LoRA (SimpleFrog/whisper_finetuned)")