Spaces:
Sleeping
Sleeping
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 | |
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 | |
""") |