Nechba's picture
Update app.py
c2fcead verified
import streamlit as st
import whisper
from transformers import pipeline
from tempfile import NamedTemporaryFile
import torch
import os
from huggingface_hub import login
# Configuration and setup
st.set_page_config(
page_title="Médical SOAP Transcription",
page_icon="🩺",
layout="wide"
)
# App title and introduction
st.title("🩺 MédiScribe: Transcription Médicale SOAP")
st.markdown("""
Convertissez vos dictées médicales en notes structurées au format SOAP
(Subjectif, Objectif, Analyse, Plan) en quelques clics.
Fonctionne entièrement hors ligne pour préserver la confidentialité des données patients.
""")
# Sidebar for app information and configuration
with st.sidebar:
st.header("À propos")
st.info("""
**MédiScribe** transforme vos enregistrements audio en notes médicales structurées.
**Fonctionnalités:**
- Transcription audio → texte
- Structuration automatique SOAP
- Traitement 100% local et sécurisé
- Compatible avec le vocabulaire médical français
""")
st.header("Configuration")
st.markdown("**Statut des modèles:**")
device_info = "GPU 🚀" if torch.cuda.is_available() else "CPU 💻"
st.code(f"Appareil: {device_info}")
# Check for GPU availability
DEVICE = "cuda" if torch.cuda.is_available() else "cpu"
# Authentication for Hugging Face (if token available)
token = os.getenv("HF_AUTH_TOKEN")
if token:
login(token=token)
st.sidebar.success("✅ Authentifié avec Hugging Face")
else:
st.sidebar.warning("⚠️ Token Hugging Face non configuré")
# Load models with caching
@st.cache_resource
def load_models():
with st.spinner("Chargement des modèles..."):
# Speech-to-text model
stt_model = whisper.load_model("medium")
# Text structuring model
struct_model = pipeline(
"text-generation",
model="meta-llama/Llama-3.2-3B-Instruct",
device=DEVICE,
)
return stt_model, struct_model
# Function to structure text using local model
def structure_text_local(text):
prompt = f"""Transforme ce texte médical en format SOAP de manière concise et stricte.:
Texte: {text}
Format de sortie attendu:
- S (Subjectif) :
- O (Objectif) :
- A (Analyse) :
- P (Plan) :
Ne rien ajouter d'autre que ce format exact."""
response = struct_model(
prompt,
max_length=512,
num_return_sequences=1,
temperature=0.4,
repetition_penalty=1.2
)
text = response[0]['generated_text']
text = text.replace(prompt, "")
text = text.replace("Réponse:", "")
return text.strip()
# Main app flow
try:
stt_model, struct_model = load_models()
# File uploader section
st.header("1. Importer un fichier audio")
uploaded_file = st.file_uploader(
"Télécharger un enregistrement audio",
type=["wav", "mp3", "m4a"],
help="Formats supportés: WAV, MP3, M4A"
)
# Processing section
if uploaded_file is not None:
st.header("2. Écouter l'enregistrement")
with NamedTemporaryFile(delete=False, suffix=".wav") as temp_file:
temp_file.write(uploaded_file.getvalue())
st.audio(temp_file.name, format='audio/wav')
col1, col2 = st.columns(2)
process_button = col1.button("🔄 Transcrire et Structurer", use_container_width=True)
if process_button:
st.toast("Démarrage du traitement...")
# Transcription step
with st.spinner("🎙️ Transcription en cours..."):
result = stt_model.transcribe(temp_file.name, language='fr')
transcription = result["text"]
st.toast("Structuration en cours...")
# Structuring step
with st.spinner("🔄 Structuration en format SOAP..."):
soap_output = structure_text_local(transcription)
st.toast("Traitement terminé!")
# Display results
st.header("3. Résultats")
tabs = st.tabs(["Note SOAP Structurée", "Transcription Brute"])
with tabs[0]:
st.subheader("Note Médicale Structurée (SOAP)")
st.code(soap_output)
st.download_button(
"💾 Télécharger la note SOAP",
soap_output,
file_name="note_medicale_soap.txt",
mime="text/plain"
)
with tabs[1]:
st.subheader("Transcription Brute")
st.text_area("Texte transcrit", transcription, height=200)
# Instructions section
else:
st.info("👆 Commencez par importer un fichier audio pour générer une note médicale SOAP")
except Exception as e:
st.error(f"Une erreur s'est produite: {str(e)}")
st.info("Veuillez vérifier que tous les modèles et dépendances sont correctement installés.")
# Footer
st.divider()
st.markdown("""
**Configuration système recommandée:**
- CPU: 8+ cœurs (pour traitement rapide)
- RAM: 16GB+ (pour les modèles locaux)
- GPU: Recommandé pour performances optimales
- Stockage: 10GB+ d'espace libre
""")