File size: 5,565 Bytes
c20202b
 
 
 
 
575d0b2
e6aeca8
 
c2fcead
 
 
 
 
 
e6aeca8
c2fcead
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e6aeca8
c20202b
 
e6aeca8
c2fcead
 
 
 
 
 
 
c20202b
c2fcead
c20202b
 
c2fcead
 
 
 
 
 
 
 
 
 
 
c20202b
 
 
c2fcead
c20202b
c2fcead
c20202b
 
 
19c391c
 
c2fcead
c20202b
 
 
 
c2fcead
c20202b
 
19c391c
 
c2fcead
c20202b
c2fcead
c20202b
c2fcead
 
 
 
 
 
 
 
 
 
 
c20202b
c2fcead
 
 
c20202b
c2fcead
 
 
c20202b
c2fcead
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c20202b
c2fcead
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c20202b
c2fcead
 
c20202b
c2fcead
 
 
 
 
996027d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
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
""")