Seicas commited on
Commit
02eb251
·
verified ·
1 Parent(s): 3dcdeae

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +185 -105
app.py CHANGED
@@ -1,132 +1,212 @@
1
- from fastapi import FastAPI, Depends, HTTPException, status, UploadFile, File
2
- from fastapi.middleware.cors import CORSMiddleware
3
- import gradio as gr
4
  import os
5
  import tempfile
6
  import json
7
- from typing import Optional
 
8
  import spacy
9
  from preprocessing import clean_audio
10
- from asr import transcribe_file, MedicalASR
11
  from diarization import diarize_segments
12
  from privacy import MedicalPrivacyProcessor
13
  from config import settings
14
 
15
- # HuggingFace token'ını ayarla (kullanıcının kendi token'ını eklemesini sağla)
16
- os.environ["HF_TOKEN"] = os.environ.get("HF_TOKEN", "")
17
- os.environ["ENVIRONMENT"] = "production"
 
18
 
19
- # Arayüz konfigürasyonu
20
- THEME = gr.themes.Soft(
21
- primary_hue="indigo",
22
- secondary_hue="blue",
23
- )
24
- LOGO = "assets/pediatric_logo.png" # Logo ekleyin (opsiyonel)
 
 
 
 
 
 
 
 
 
 
 
 
 
25
 
26
  # SpaCy modelini yükle
27
- try:
28
- nlp = spacy.load("tr_core_news_sm")
29
- except OSError:
30
- nlp = spacy.blank("tr")
31
 
32
- # Gradio arayüzü
33
- def create_gradio_app():
34
- def transcribe_gr(audio_file, diarize=True, enhance_audio=True, anonymize=True):
35
- try:
36
- if audio_file is None:
37
- return "Lütfen bir ses dosyası yükleyin."
38
-
39
- asr_model = get_asr_model()
40
- result = asr_model.transcribe(
41
- audio_file,
42
- speaker_diarization=diarize,
43
- enhance_audio=enhance_audio
44
- )
45
-
46
- output = "📝 Transkripsiyon:\n\n"
47
-
48
- if "diarization" in result:
49
- for segment in result["diarization"]:
50
- output += f"🗣️ {segment['speaker']} ({segment['start']:.1f}s - {segment['end']:.1f}s):\n"
51
- output += f"{segment['text']}\n\n"
52
- else:
53
- output += result["text"]
54
-
55
- if result.get("anonymized"):
56
- output += "\n🔒 Kişisel veriler anonimleştirildi."
57
-
58
- return output
59
- except Exception as e:
60
- return f"Bir hata oluştu: {str(e)}"
61
 
62
- demo = gr.Interface(
63
- fn=transcribe_gr,
64
- inputs=[
65
- gr.Audio(type="filepath", label="Ses Dosyası"),
66
- gr.Checkbox(label="Konuşmacı Ayrımı", value=True),
67
- gr.Checkbox(label="Ses İyileştirme", value=True),
68
- gr.Checkbox(label="Kişisel Verileri Anonimleştir", value=True)
69
- ],
70
- outputs=gr.Textbox(label="Transkripsiyon Sonucu", lines=10),
71
- title="🏥 Tıbbi Konuşma Transkripsiyon Servisi",
72
- description="Bu servis, doktor vizitelerindeki konuşmaları yazıya döker ve konuşmacıları ayırt eder.",
73
- theme=gr.themes.Soft(primary_hue="indigo", secondary_hue="blue"),
74
- allow_flagging="never"
75
- )
76
- return demo
77
 
78
- # FastAPI uygulaması
79
- app = FastAPI(title="Pediatrik ASR API")
80
 
81
- # CORS ayarları
82
- app.add_middleware(
83
- CORSMiddleware,
84
- allow_origins=["*"],
85
- allow_credentials=True,
86
- allow_methods=["*"],
87
- allow_headers=["*"],
88
- )
89
 
90
- # ASR modeli için bağımlılık
91
- def get_asr_model():
92
- config = {
93
- "language": "tr",
94
- "model": settings.ASR_MODEL,
95
- "domain": "medical"
96
- }
97
- return MedicalASR(config)
 
 
 
98
 
99
- # API endpoint'i
100
- @app.post("/api/v1/transcribe")
101
- async def transcribe_audio_api(
102
- file: UploadFile = File(...),
103
- diarize: bool = True,
104
- enhance_audio: bool = True,
105
- anonymize: Optional[bool] = None,
106
- asr_model: MedicalASR = Depends(get_asr_model)
107
- ):
108
  try:
109
- with tempfile.NamedTemporaryFile(delete=False, suffix=".wav") as temp_file:
110
- temp_file.write(await file.read())
111
- temp_file_path = temp_file.name
 
112
 
113
- result = asr_model.transcribe(
114
- temp_file_path,
115
- speaker_diarization=diarize,
116
- enhance_audio=enhance_audio
 
 
 
 
 
 
 
117
  )
118
 
119
- os.unlink(temp_file_path)
120
- return result
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
121
 
122
  except Exception as e:
123
- raise HTTPException(status_code=500, detail=str(e))
 
124
 
125
- # Gradio uygulamasını oluştur ve mount et
126
- gradio_app = create_gradio_app()
127
- app = gr.mount_gradio_app(app, gradio_app, path="/")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
128
 
129
- # Uygulamayı başlat
130
  if __name__ == "__main__":
131
- import uvicorn
132
- uvicorn.run(app, host="0.0.0.0", port=7860)
 
 
 
 
1
  import os
2
  import tempfile
3
  import json
4
+ import time
5
+ import gradio as gr
6
  import spacy
7
  from preprocessing import clean_audio
8
+ from asr import transcribe_file
9
  from diarization import diarize_segments
10
  from privacy import MedicalPrivacyProcessor
11
  from config import settings
12
 
13
+ # HuggingFace token'ını ayarla
14
+ HF_TOKEN = os.getenv("HF_TOKEN", "")
15
+ if not HF_TOKEN:
16
+ print("Warning: HF_TOKEN not set!")
17
 
18
+ def load_spacy_model():
19
+ """SpaCy modelini yükle veya indir"""
20
+ try:
21
+ # Önce mevcut modelleri kontrol et
22
+ available_models = spacy.util.get_installed_models()
23
+ if "tr_core_news_md" in available_models:
24
+ print("Türkçe SpaCy modeli bulundu, yükleniyor...")
25
+ return spacy.load("tr_core_news_md")
26
+ elif "tr_core_news_sm" in available_models:
27
+ print("Küçük Türkçe SpaCy modeli bulundu, yükleniyor...")
28
+ return spacy.load("tr_core_news_sm")
29
+ else:
30
+ print("Türkçe SpaCy modeli bulunamadı, indiriliyor...")
31
+ os.system("python -m spacy download tr_core_news_md")
32
+ return spacy.load("tr_core_news_md")
33
+ except Exception as e:
34
+ print(f"SpaCy model yükleme hatası: {str(e)}")
35
+ print("Boş Türkçe model oluşturuluyor...")
36
+ return spacy.blank("tr")
37
 
38
  # SpaCy modelini yükle
39
+ nlp = load_spacy_model()
 
 
 
40
 
41
+ # Yardım metni
42
+ usage_tips = """
43
+ ## Kullanım İpuçları
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44
 
45
+ 1. **Dosya formatı**: WAV formatında ses dosyaları en iyi sonuçları verir.
46
+ 2. **Ses kalitesi**: Gürültüsüz ortamlarda kaydedilen sesler daha iyi sonuç verir.
47
+ 3. **Konuşmacı ayrımı**: Konuşmacı sayısı arttıkça tanıma doğruluğu düşebilir.
48
+ 4. **Hata durumlarında**: Sistem hata verirse, ses dosyasının formatını ve boyutunu kontrol edin.
 
 
 
 
 
 
 
 
 
 
 
49
 
50
+ ## Pediatrik Uzmanlar İçin
 
51
 
52
+ Sistem, çocuk hastalıkları, aşılar, ilaçlar ve muayene terimleri içeren
53
+ geniş bir tıbbi terim sözlüğü kullanır. Bu sayede pediatri vizitelerindeki
54
+ terminolojinin doğru transkribe edilmesini sağlar.
55
+ """
 
 
 
 
56
 
57
+ # CSS stilleri
58
+ css = """
59
+ .container {padding: 20px; border-radius: 10px; box-shadow: 0 4px 8px rgba(0,0,0,0.1);}
60
+ .result-text {margin-top: 10px; padding: 15px; background: #f8f9fa; border-radius: 5px; white-space: pre-wrap;}
61
+ .speaker {font-weight: bold; color: #1a5fb4;}
62
+ .timestamp {color: #666; font-size: 0.9em;}
63
+ .success {color: green; font-weight: bold;}
64
+ .error {color: red; font-weight: bold;}
65
+ .footer {margin-top: 50px; text-align: center; color: #666; font-size: 0.9em;}
66
+ .tips {background: #e7f5ff; padding: 15px; border-radius: 5px; margin-top: 20px;}
67
+ """
68
 
69
+ async def process_audio(audio_file, diarize=True, enhance=True, anonymize=True, progress=gr.Progress()):
 
 
 
 
 
 
 
 
70
  try:
71
+ if audio_file is None:
72
+ return {"error": "Lütfen bir ses dosyası yükleyin."}, None
73
+
74
+ progress(0, desc="Ses dosyası hazırlanıyor...")
75
 
76
+ # Ses dosyasını temizle
77
+ if enhance:
78
+ progress(0.1, desc="Ses iyileştiriliyor...")
79
+ audio_file = clean_audio(audio_file)
80
+
81
+ # Transkripsiyon yap
82
+ progress(0.3, desc="Ses metne dönüştürülüyor...")
83
+ result = transcribe_file(
84
+ audio_file,
85
+ language="tr",
86
+ model_name=settings.ASR_MODEL
87
  )
88
 
89
+ # Konuşmacı ayrımı
90
+ if diarize:
91
+ progress(0.6, desc="Konuşmacılar ayrıştırılıyor...")
92
+ diarization_result = diarize_segments(result["segments"])
93
+ result["diarization"] = diarization_result
94
+
95
+ # Kişisel verileri anonimleştir
96
+ if anonymize:
97
+ progress(0.8, desc="Kişisel veriler anonimleştiriliyor...")
98
+ privacy_processor = MedicalPrivacyProcessor()
99
+ result["text"] = privacy_processor.anonymize_text(result["text"])
100
+ result["anonymized"] = True
101
+
102
+ # Sonucu formatla
103
+ progress(0.9, desc="Sonuçlar hazırlanıyor...")
104
+ formatted_text = ""
105
+ if diarize and "diarization" in result:
106
+ for segment in result["diarization"]:
107
+ speaker = segment["speaker"]
108
+ text = segment["text"]
109
+ start = segment["start"]
110
+ end = segment["end"]
111
+ formatted_text += f"[{speaker}] ({start:.1f}s - {end:.1f}s): {text}\n\n"
112
+ else:
113
+ formatted_text = result["text"]
114
+
115
+ if result.get("anonymized"):
116
+ formatted_text += "\n🔒 Kişisel veriler anonimleştirildi."
117
+
118
+ progress(1.0, desc="Tamamlandı!")
119
+ return result, formatted_text
120
 
121
  except Exception as e:
122
+ print(f"Error in process_audio: {str(e)}")
123
+ return {"error": f"İşlem sırasında hata: {str(e)}"}, None
124
 
125
+ # Ana arayüz
126
+ with gr.Blocks(theme=gr.themes.Soft(primary_hue="indigo", secondary_hue="blue"), css=css) as demo:
127
+ gr.HTML(f"""
128
+ <div style="text-align: center; max-height: 150px; margin-bottom: 30px">
129
+ <h1>Türkçe Pediatrik Konuşma Tanıma Sistemi</h1>
130
+ <p>Çocuk doktorları için geliştirilmiş, pediatri alanına özel tıbbi terminoloji tanıma özellikli transkripsiyon sistemi</p>
131
+ </div>
132
+ """)
133
+
134
+ with gr.Row():
135
+ with gr.Column(scale=1):
136
+ audio_input = gr.Audio(
137
+ label="Ses Dosyası Yükleyin veya Kaydedin",
138
+ type="filepath",
139
+ elem_classes="container"
140
+ )
141
+
142
+ with gr.Group():
143
+ with gr.Row():
144
+ diarize = gr.Checkbox(value=True, label="Konuşmacı Ayrımı")
145
+ enhance = gr.Checkbox(value=True, label="Ses İyileştirme")
146
+
147
+ with gr.Row():
148
+ anonymize = gr.Checkbox(value=True, label="Kişisel Verileri Anonimleştir")
149
+ clear_btn = gr.Button("Temizle", variant="secondary")
150
+
151
+ process_btn = gr.Button("Transkribe Et", variant="primary")
152
+ gr.HTML('<div class="tips"><b>💡 İpucu:</b> En iyi sonuçlar için gürültüsüz ortamlarda kayıt yapın.</div>')
153
+
154
+ with gr.Column(scale=2, elem_classes="container"):
155
+ with gr.Tabs():
156
+ with gr.TabItem("Konuşma Metni"):
157
+ result_text = gr.Markdown(label="Transkripsiyon Sonucu", elem_classes="result-text")
158
+
159
+ with gr.TabItem("JSON Sonucu"):
160
+ json_output = gr.JSON(label="API Yanıtı")
161
+
162
+ with gr.TabItem("Kullanım Kılavuzu"):
163
+ gr.Markdown(usage_tips)
164
+
165
+ status = gr.Markdown("Sistem hazır.")
166
+
167
+ # Uyarı mesajı
168
+ gr.HTML("""
169
+ <div style="background-color: #fff3cd; color: #856404; padding: 15px; margin: 15px 0; border-radius: 5px; border: 1px solid #ffeeba;">
170
+ <h3>⚠️ Önemli Gizlilik Uyarısı</h3>
171
+ <p>
172
+ Bu demo uygulaması <strong>yalnızca eğitim amaçlıdır</strong> ve gerçek hasta verilerinin işlenmesi için tasarlanmamıştır.
173
+ Lütfen hasta bilgisi içeren ses kayıtlarını yüklemeyin. Sistemde paylaşılan ses kayıtları üçüncü şahıslar tarafından erişilebilir
174
+ ve gizlilik/güvenlik garantisi yoktur.
175
+ </p>
176
+ <p>
177
+ Bu aracı kullanarak, yüklediğiniz verilerin <a href="https://huggingface.co/terms-of-service" target="_blank">Hugging Face Kullanım Koşulları</a>'na
178
+ uygun olduğunu kabul etmiş olursunuz.
179
+ </p>
180
+ </div>
181
+ """)
182
+
183
+ # İzin onayı
184
+ with gr.Group():
185
+ privacy_agreement = gr.Checkbox(label="Gizlilik koşullarını okudum ve kabul ediyorum", value=False)
186
+
187
+ # Onay olmadan işlem yapılmasını engelle
188
+ def check_agreement(agreement, *args):
189
+ if not agreement:
190
+ return {"error": "Devam etmek için gizlilik koşullarını kabul etmelisiniz."}, "Lütfen gizlilik koşullarını kabul edin."
191
+ return process_audio(*args)
192
+
193
+ process_btn.click(
194
+ fn=check_agreement,
195
+ inputs=[privacy_agreement, audio_input, diarize, enhance, anonymize],
196
+ outputs=[json_output, result_text]
197
+ )
198
+
199
+ clear_btn.click(
200
+ lambda: (None, None, "Sistem hazır."),
201
+ outputs=[audio_input, result_text, status]
202
+ )
203
+
204
+ gr.HTML("""
205
+ <div class="footer">
206
+ <p>© 2023 Türkçe Pediatrik Konuşma Tanıma Sistemi | Çocuk doktorları için geliştirilmiştir.</p>
207
+ </div>
208
+ """)
209
 
210
+ # Hugging Face Spaces için gerekli
211
  if __name__ == "__main__":
212
+ demo.queue().launch(server_name="0.0.0.0", server_port=7860, share=False)