Seicas commited on
Commit
1f694e8
·
verified ·
1 Parent(s): ce7ec9b

Update diarization.py

Browse files
Files changed (1) hide show
  1. diarization.py +85 -92
diarization.py CHANGED
@@ -1,101 +1,94 @@
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
  "pyannote/speaker-diarization-3.0",
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
 
1
  from pyannote.audio import Pipeline
2
+ from typing import List, Dict, Any
3
+ import torch
4
+ import os
5
+ from config import settings # Eğer göreceli import varsa düzelt
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