Seicas commited on
Commit
432e60e
·
verified ·
1 Parent(s): bbd2003

Update diarization.py

Browse files
Files changed (1) hide show
  1. diarization.py +92 -85
diarization.py CHANGED
@@ -1,94 +1,101 @@
1
  from pyannote.audio import Pipeline
2
- from typing import List, Dict, Any
3
- import torch
4
- import os
5
- from config import settings # Düzeltildi
6
 
7
- # HuggingFace token'ı ayarla
8
- os.environ["HF_TOKEN"] = "hf_your_token_here" # Bu satırın yorumunu kaldırın ve kendi token'ınızı ekleyin
9
 
10
- _diarization_pipeline = None
11
-
12
- def get_diarization_pipeline():
13
- """Diarization pipeline singleton"""
14
- global _diarization_pipeline
15
- if _diarization_pipeline is None:
16
- # GPU varsa kullan
17
- device = "cuda" if torch.cuda.is_available() else "cpu"
18
- _diarization_pipeline = Pipeline.from_pretrained(
19
- "pyannote/speaker-diarization-3.0",
20
- use_auth_token=os.environ.get("HF_TOKEN"),
21
- device=device
22
- )
23
- return _diarization_pipeline
24
-
25
- def rename_speakers_for_pediatrics(segments: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
26
- """
27
- Konuşmacıları pediatri bağlamına göre yeniden isimlendirir
28
- """
29
- # Konuşmacıları basit bir şekilde yeniden isimlendiriyoruz
30
- # Gerçek bir uygulamada ses özellikleri analizi ile daha sofistike olabilir
31
- renamed_segments = []
32
-
33
- speaker_mapping = {}
34
- for segment in segments:
35
- speaker = segment["speaker"]
36
-
37
- if speaker not in speaker_mapping:
38
- # İlk konuşmacıyı bölüm başkanı olarak kabul ediyoruz
39
- if len(speaker_mapping) == 0:
40
- speaker_mapping[speaker] = "Bölüm_Başkanı"
41
- # İkinci konuşmacıyı hekim olarak kabul ediyoruz
42
- elif len(speaker_mapping) == 1:
43
- speaker_mapping[speaker] = "Hekim"
44
- # Üçüncü konuşmacıyı asistan olarak kabul ediyoruz
45
- elif len(speaker_mapping) == 2:
46
- speaker_mapping[speaker] = "Asistan"
47
- # Diğer konuşmacılar
48
- else:
49
- speaker_mapping[speaker] = f"Konuşmacı_{len(speaker_mapping) + 1}"
50
-
51
- # Segment kopyası oluştur ve konuşmacı ismini güncelle
52
- new_segment = segment.copy()
53
- new_segment["speaker"] = speaker_mapping[speaker]
54
- renamed_segments.append(new_segment)
55
-
56
- return renamed_segments
57
-
58
- def diarize_segments(audio_file: str, is_pediatrics: bool = True) -> List[Dict[str, Any]]:
59
  """
60
- Ses dosyasındaki konuşmacıları ayırt eder
61
 
62
- Args:
63
- audio_file: Ses dosyasının yolu
 
 
 
 
64
 
65
  Returns:
66
- Konuşmacı segmentleri listesi
67
- [
68
- {"speaker": "speaker_0", "start": 0.5, "end": 2.3, "text": "..."},
69
- {"speaker": "speaker_1", "start": 2.4, "end": 5.1, "text": "..."},
70
- ...
71
- ]
72
  """
73
- # Pipeline'ı al
74
- pipeline = get_diarization_pipeline()
75
-
76
- # Diyarizasyon gerçekleştir
77
- diarization = pipeline(audio_file)
78
-
79
- # Sonuçları formatlayalım
80
- results = []
81
- for turn, _, speaker in diarization.itertracks(yield_label=True):
82
- segment = {
83
- "speaker": speaker,
84
- "start": turn.start,
85
- "end": turn.end,
86
- "text": "" # Bu alanı transcribe işlemi sonrası dolduracağız
87
- }
88
- results.append(segment)
89
-
90
- # Pediatri bağlamı için konuşmacı isimlerini güncelle
91
- if is_pediatrics:
92
- results = rename_speakers_for_pediatrics(results)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
93
 
94
- return results
 
 
 
 
 
 
1
  from pyannote.audio import Pipeline
2
+ from config import settings
 
 
 
3
 
4
+ _diar_pipeline = Pipeline.from_pretrained(settings.DIAR_MODEL)
 
5
 
6
+ def diarize_segments(audio_path, segments):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7
  """
8
+ Konuşma segmentlerini konuşmacılara göre ayırır
9
 
10
+ Parameters:
11
+ -----------
12
+ audio_path : str
13
+ Ses dosyasının tam yolu
14
+ segments : list
15
+ ASR tarafından oluşturulan zaman damgalı segmentler
16
 
17
  Returns:
18
+ --------
19
+ list
20
+ Konuşmacı bilgisi eklenmiş segmentler
 
 
 
21
  """
22
+ try:
23
+ # Pyannote modelini yükle
24
+ import os
25
+ import torch
26
+ from pyannote.audio import Pipeline
27
+
28
+ # HuggingFace token kontrolü
29
+ token = os.environ.get("HF_TOKEN")
30
+ if not token:
31
+ print("UYARI: HF_TOKEN bulunamadı, diyarizasyon atlanıyor.")
32
+ # Tüm segmentleri Konuşmacı 1 olarak işaretle
33
+ for seg in segments:
34
+ seg["speaker"] = "Konuşmacı 1"
35
+ return segments
36
+
37
+ # Pyannote pipeline'ını oluştur
38
+ pipeline = Pipeline.from_pretrained(
39
+ settings.DIAR_MODEL,
40
+ use_auth_token=token
41
+ )
42
+
43
+ # GPU varsa kullan
44
+ if torch.cuda.is_available():
45
+ pipeline = pipeline.to(torch.device("cuda"))
46
+
47
+ # Diyarizasyon yap
48
+ diarization = pipeline(audio_path)
49
+
50
+ # Konuşmacı etiketlerini oluştur (Hekim, Asistan, vs.)
51
+ speaker_labels = {}
52
+
53
+ # Segmentlere konuşmacı bilgisi ekle
54
+ for seg in segments:
55
+ seg_start = seg["start"]
56
+ seg_end = seg["end"]
57
+
58
+ # Bu segment için en çok konuşan kişiyi bul
59
+ speaker_times = {}
60
+ for turn, _, speaker in diarization.itertracks(yield_label=True):
61
+ # Segment ve konuşma turu arasındaki çakışmayı hesapla
62
+ overlap_start = max(seg_start, turn.start)
63
+ overlap_end = min(seg_end, turn.end)
64
+
65
+ if overlap_end > overlap_start: # Çakışma varsa
66
+ duration = overlap_end - overlap_start
67
+ speaker_times[speaker] = speaker_times.get(speaker, 0) + duration
68
+
69
+ # En uzun konuşan kişiyi bul
70
+ if speaker_times:
71
+ max_speaker = max(speaker_times, key=speaker_times.get)
72
+
73
+ # Konuşmacıyı etiketle
74
+ if max_speaker not in speaker_labels:
75
+ # Yeni konuşmacı tespit edildi
76
+ # Pediatri bağlamında etiketler belirle (ilk konuşmacı genelde hekim)
77
+ idx = len(speaker_labels) + 1
78
+ if idx == 1:
79
+ label = "Hekim"
80
+ elif idx == 2:
81
+ label = "Asistan"
82
+ elif idx == 3:
83
+ label = "Ebeveyn"
84
+ else:
85
+ label = f"Konuşmacı {idx}"
86
+
87
+ speaker_labels[max_speaker] = label
88
+
89
+ seg["speaker"] = speaker_labels[max_speaker]
90
+ else:
91
+ # Diyarizasyon bilgisi yoksa
92
+ seg["speaker"] = "Bilinmeyen Konuşmacı"
93
+
94
+ return segments
95
 
96
+ except Exception as e:
97
+ # Hata durumunda basit etiketleme yap
98
+ print(f"Diyarizasyon hatası: {str(e)}")
99
+ for seg in segments:
100
+ seg["speaker"] = "Konuşmacı"
101
+ return segments