Spaces:
Sleeping
Sleeping
Commit
·
ece1c42
1
Parent(s):
943f366
Video dosyalarının paralel işlenmesi için yeni bir işlev eklendi. Thread havuzu kullanılarak video transkripsiyonu optimize edildi ve hata yönetimi geliştirildi. Ayrıca, işlem süresi ve sonuç sayısı hakkında bilgilendirici çıktılar eklendi.
Browse files- main-videopluskazanim.py +77 -35
main-videopluskazanim.py
CHANGED
@@ -35,6 +35,8 @@ from typing import List, Dict, Optional
|
|
35 |
from transformers import AutoTokenizer, AutoModelForSequenceClassification, pipeline
|
36 |
import torch
|
37 |
import functools
|
|
|
|
|
38 |
import kazanim_id_konu_isim_dict_list as kazanimlar
|
39 |
import logging
|
40 |
import whisper
|
@@ -137,6 +139,50 @@ logging.basicConfig(stream=sys.stdout,
|
|
137 |
level=logging.INFO,
|
138 |
format="%(asctime)s %(levelname)s %(message)s")
|
139 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
140 |
@app.post("/predict", response_model=PredictResponse)
|
141 |
async def predict(req: PredictRequest):
|
142 |
t0 = time.time()
|
@@ -177,9 +223,9 @@ async def predict(req: PredictRequest):
|
|
177 |
async def transcribe_videos(files: List[UploadFile] = File(...),
|
178 |
model_name: str = "small",
|
179 |
language: str = "Turkish"):
|
180 |
-
"""Video dosyalarını metne çevir"""
|
181 |
t0 = time.time()
|
182 |
-
print(f"new whisper request /model = {model_name} / n = {len(files)}")
|
183 |
|
184 |
try:
|
185 |
if not files:
|
@@ -188,44 +234,40 @@ async def transcribe_videos(files: List[UploadFile] = File(...),
|
|
188 |
# Whisper modelini yükle
|
189 |
model = load_whisper_model(model_name)
|
190 |
|
191 |
-
|
|
|
|
|
|
|
|
|
192 |
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
# Geçici dosya oluştur
|
198 |
-
with tempfile.NamedTemporaryFile(delete=False, suffix=os.path.splitext(file.filename)[1]) as temp_file:
|
199 |
-
content = await file.read()
|
200 |
-
temp_file.write(content)
|
201 |
-
temp_file_path = temp_file.name
|
202 |
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
# Geçici dosyayı temizle
|
221 |
-
if os.path.exists(temp_file_path):
|
222 |
-
os.unlink(temp_file_path)
|
223 |
|
224 |
dt = time.time() - t0
|
225 |
-
print(f"✅ Whisper done | took {dt:.2f}s")
|
226 |
-
print(f"Tamamlandı: {len(
|
227 |
|
228 |
-
return WhisperResponse(model=model_name, results=
|
229 |
|
230 |
except Exception as e:
|
231 |
print(f"Whisper Hatası: {e}")
|
|
|
35 |
from transformers import AutoTokenizer, AutoModelForSequenceClassification, pipeline
|
36 |
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
|
|
|
139 |
level=logging.INFO,
|
140 |
format="%(asctime)s %(levelname)s %(message)s")
|
141 |
|
142 |
+
# Thread pool for parallel processing - HF Space friendly
|
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 |
+
|
151 |
+
# Geçici dosya oluştur
|
152 |
+
with tempfile.NamedTemporaryFile(delete=False, suffix=os.path.splitext(file.filename)[1]) as temp_file:
|
153 |
+
content = await file.read()
|
154 |
+
temp_file.write(content)
|
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):
|
175 |
+
try:
|
176 |
+
os.unlink(temp_file_path)
|
177 |
+
except:
|
178 |
+
pass # HF Space'te silme hatası olabilir
|
179 |
+
|
180 |
+
# Thread pool'da transcription çalıştır
|
181 |
+
loop = asyncio.get_event_loop()
|
182 |
+
text = await loop.run_in_executor(executor, transcribe_sync)
|
183 |
+
|
184 |
+
return VideoResult(id=file.filename, text=text)
|
185 |
+
|
186 |
@app.post("/predict", response_model=PredictResponse)
|
187 |
async def predict(req: PredictRequest):
|
188 |
t0 = time.time()
|
|
|
223 |
async def transcribe_videos(files: List[UploadFile] = File(...),
|
224 |
model_name: str = "small",
|
225 |
language: str = "Turkish"):
|
226 |
+
"""Video dosyalarını metne çevir - PARALEL İŞLEME"""
|
227 |
t0 = time.time()
|
228 |
+
print(f"🚀 new whisper request /model = {model_name} / n = {len(files)} - PARALEL İŞLEME BAŞLIYOR")
|
229 |
|
230 |
try:
|
231 |
if not files:
|
|
|
234 |
# Whisper modelini yükle
|
235 |
model = load_whisper_model(model_name)
|
236 |
|
237 |
+
# HF SPACE İÇİN CHUNK'LI PARALEL İŞLEME
|
238 |
+
chunk_size = 16 # HF Space için güvenli chunk boyutu
|
239 |
+
final_results = []
|
240 |
+
|
241 |
+
print(f"📡 {len(files)} dosya {chunk_size}'lı chunk'larda paralel işlenecek...")
|
242 |
|
243 |
+
# Dosyaları chunk'lara böl ve her chunk'ı paralel işle
|
244 |
+
for i in range(0, len(files), chunk_size):
|
245 |
+
chunk = files[i:i + chunk_size]
|
246 |
+
print(f"🔄 Chunk {i//chunk_size + 1}: {len(chunk)} dosya işleniyor...")
|
|
|
|
|
|
|
|
|
|
|
247 |
|
248 |
+
# Bu chunk'ı paralel işle
|
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 |
|
272 |
except Exception as e:
|
273 |
print(f"Whisper Hatası: {e}")
|