eraydikyologlu commited on
Commit
39c78ba
·
1 Parent(s): ece1c42

Video işleme fonksiyonuna thread güvenliği eklendi. Model kullanımını senkronize etmek için lock mekanizması kullanıldı. Hata yönetimi ve işlem sonuçları için detaylı istatistikler eklendi.

Browse files
Files changed (1) hide show
  1. main-videopluskazanim.py +42 -15
main-videopluskazanim.py CHANGED
@@ -37,6 +37,7 @@ import torch
37
  import functools
38
  import asyncio
39
  import concurrent.futures
 
40
  import kazanim_id_konu_isim_dict_list as kazanimlar
41
  import logging
42
  import whisper
@@ -143,8 +144,11 @@ logging.basicConfig(stream=sys.stdout,
143
  # HF Space'lerde çok aggressive olmamak için worker sayısını azalttık
144
  executor = concurrent.futures.ThreadPoolExecutor(max_workers=4)
145
 
 
 
 
146
  async def process_single_video(file: UploadFile, model, language: str) -> VideoResult:
147
- """Tek bir video dosyasını işle - paralel kullanım için"""
148
  if not file.filename.lower().endswith(('.mp4', '.wav', '.mp3', '.m4a', '.flac')):
149
  return VideoResult(id=file.filename, text="")
150
 
@@ -155,20 +159,28 @@ async def process_single_video(file: UploadFile, model, language: str) -> VideoR
155
  temp_file_path = temp_file.name
156
 
157
  def transcribe_sync():
158
- """Senkron transcription - thread pool'da çalışacak - HF Space optimized"""
159
  try:
160
- # HF Space için daha conservative ayarlar
161
- result = model.transcribe(
162
- temp_file_path,
163
- language=language.lower(),
164
- verbose=False,
165
- fp16=False, # HF Space'te daha stabil
166
- temperature=0.0 # Deterministic output
167
- )
168
- return result['text'].strip()
 
 
 
 
 
 
 
169
  except Exception as e:
170
- print(f"Video işleme hatası ({file.filename}): {e}")
171
  return ""
 
172
  finally:
173
  # Geçici dosyayı temizle
174
  if os.path.exists(temp_file_path):
@@ -249,23 +261,38 @@ async def transcribe_videos(files: List[UploadFile] = File(...),
249
  tasks = [process_single_video(file, model, language) for file in chunk]
250
  chunk_results = await asyncio.gather(*tasks, return_exceptions=True)
251
 
252
- # Exception'ları handle et
 
 
253
  for j, result in enumerate(chunk_results):
254
  if isinstance(result, Exception):
255
  print(f"❌ Dosya {chunk[j].filename} işlenirken hata: {result}")
256
  final_results.append(VideoResult(id=chunk[j].filename, text=""))
 
257
  else:
258
  final_results.append(result)
 
 
 
 
 
259
 
260
- print(f"✅ Chunk {i//chunk_size + 1} tamamlandı!")
261
 
262
  # Memory'yi rahatlatmak için küçük bir bekleme (HF Space için)
263
  if i + chunk_size < len(files):
264
  await asyncio.sleep(0.1)
265
 
266
  dt = time.time() - t0
 
 
 
 
 
 
267
  print(f"✅ Whisper PARALEL done | took {dt:.2f}s")
268
- print(f"🎯 Tamamlandı: {len(final_results)} video PARALEL olarak transkript edildi")
 
269
 
270
  return WhisperResponse(model=model_name, results=final_results)
271
 
 
37
  import functools
38
  import asyncio
39
  import concurrent.futures
40
+ import threading
41
  import kazanim_id_konu_isim_dict_list as kazanimlar
42
  import logging
43
  import whisper
 
144
  # HF Space'lerde çok aggressive olmamak için worker sayısını azalttık
145
  executor = concurrent.futures.ThreadPoolExecutor(max_workers=4)
146
 
147
+ # Thread-safe model kullanımı için lock
148
+ whisper_lock = threading.Lock()
149
+
150
  async def process_single_video(file: UploadFile, model, language: str) -> VideoResult:
151
+ """Tek bir video dosyasını işle - THREAD SAFE paralel kullanım için"""
152
  if not file.filename.lower().endswith(('.mp4', '.wav', '.mp3', '.m4a', '.flac')):
153
  return VideoResult(id=file.filename, text="")
154
 
 
159
  temp_file_path = temp_file.name
160
 
161
  def transcribe_sync():
162
+ """Senkron transcription - thread pool'da çalışacak - THREAD SAFE"""
163
  try:
164
+ # 🔒 THREAD SAFETY: Model kullanımını serialize et
165
+ with whisper_lock:
166
+ print(f"🔄 {file.filename}: Model kullanımı başlıyor...")
167
+ result = model.transcribe(
168
+ temp_file_path,
169
+ language=language.lower(),
170
+ verbose=False
171
+ )
172
+ text = result['text'].strip()
173
+
174
+ # Model çıktısının bir kısmını logla (debug için)
175
+ preview = text[:150] + "..." if len(text) > 150 else text
176
+ print(f"📝 {file.filename}: {preview}")
177
+
178
+ return text
179
+
180
  except Exception as e:
181
+ print(f"Video işleme hatası ({file.filename}): {e}")
182
  return ""
183
+
184
  finally:
185
  # Geçici dosyayı temizle
186
  if os.path.exists(temp_file_path):
 
261
  tasks = [process_single_video(file, model, language) for file in chunk]
262
  chunk_results = await asyncio.gather(*tasks, return_exceptions=True)
263
 
264
+ # Exception'ları handle et + SUCCESS/ERROR COUNT
265
+ success_count = 0
266
+ error_count = 0
267
  for j, result in enumerate(chunk_results):
268
  if isinstance(result, Exception):
269
  print(f"❌ Dosya {chunk[j].filename} işlenirken hata: {result}")
270
  final_results.append(VideoResult(id=chunk[j].filename, text=""))
271
+ error_count += 1
272
  else:
273
  final_results.append(result)
274
+ # Başarılı sayısı = boş olmayan text'ler
275
+ if result.text.strip():
276
+ success_count += 1
277
+ else:
278
+ error_count += 1
279
 
280
+ print(f"✅ Chunk {i//chunk_size + 1} tamamlandı! ✅{success_count} ❌{error_count}")
281
 
282
  # Memory'yi rahatlatmak için küçük bir bekleme (HF Space için)
283
  if i + chunk_size < len(files):
284
  await asyncio.sleep(0.1)
285
 
286
  dt = time.time() - t0
287
+
288
+ # Final istatistikler
289
+ total_success = len([r for r in final_results if r.text.strip()])
290
+ total_failed = len(final_results) - total_success
291
+ success_rate = (total_success / len(final_results) * 100) if final_results else 0
292
+
293
  print(f"✅ Whisper PARALEL done | took {dt:.2f}s")
294
+ print(f"🎯 SONUÇ: {len(final_results)} video | ✅{total_success} başarılı | ❌{total_failed} hatalı | 📊{success_rate:.1f}% başarı oranı")
295
+ print(f"⚡ Hız: {len(final_results)/dt:.1f} video/saniye (chunk_size={chunk_size})")
296
 
297
  return WhisperResponse(model=model_name, results=final_results)
298