File size: 4,052 Bytes
2b524bd 0117db0 56a884d 0117db0 56a884d 27eb3e4 922901f 7323fd3 0117db0 7323fd3 56a884d 7323fd3 b00efa4 7323fd3 0117db0 922901f 27eb3e4 922901f 7323fd3 27eb3e4 922901f 7323fd3 27eb3e4 922901f 27eb3e4 922901f 27eb3e4 0117db0 27eb3e4 922901f b00efa4 922901f b00efa4 7323fd3 27eb3e4 b00efa4 27eb3e4 7323fd3 27eb3e4 0117db0 7323fd3 b00efa4 7b109f5 4601ab2 b00efa4 7323fd3 27eb3e4 7323fd3 922901f b00efa4 0117db0 7323fd3 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
from flask import Flask, request, jsonify, Response # Add Response here
from faster_whisper import WhisperModel
import torch
import io
import time
import datetime
from threading import Semaphore
import os
from werkzeug.utils import secure_filename
import tempfile
app = Flask(__name__)
# Configuration
MAX_CONCURRENT_REQUESTS = 2 # Adjust based on your server capacity
MAX_AUDIO_DURATION = 60 * 30 # 30 minutes maximum audio duration (adjust as needed)
TEMPORARY_FOLDER = tempfile.gettempdir()
ALLOWED_EXTENSIONS = {'mp3', 'wav', 'ogg', 'm4a', 'flac'}
# Device check for faster-whisper
device = "cuda" if torch.cuda.is_available() else "cpu"
compute_type = "float16" if device == "cuda" else "int8"
print(f"Using device: {device} with compute_type: {compute_type}")
# Faster Whisper setup with optimized parameters for long audio
beamsize = 2 # Slightly larger beam size can help with long-form accuracy
wmodel = WhisperModel(
"guillaumekln/faster-whisper-small",
device=device,
compute_type=compute_type,
download_root="./model_cache" # Cache model to avoid re-downloading
)
# Concurrency control
request_semaphore = Semaphore(MAX_CONCURRENT_REQUESTS)
active_requests = 0
def allowed_file(filename):
return '.' in filename and \
filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
def cleanup_temp_files(file_path):
"""Ensure temporary files are deleted after processing"""
try:
if os.path.exists(file_path):
os.remove(file_path)
except Exception as e:
print(f"Error cleaning up temp file {file_path}: {str(e)}")
@app.route("/health", methods=["GET"])
def health_check():
"""Endpoint to check if API is running"""
return jsonify({
'status': 'API is running',
'timestamp': datetime.datetime.now().isoformat(),
'device': device,
'compute_type': compute_type,
'active_requests': active_requests,
'max_duration_supported': MAX_AUDIO_DURATION
})
@app.route("/status/busy", methods=["GET"])
def server_busy():
"""Endpoint to check if server is busy"""
is_busy = active_requests >= MAX_CONCURRENT_REQUESTS
return jsonify({
'is_busy': is_busy,
'active_requests': active_requests,
'max_capacity': MAX_CONCURRENT_REQUESTS
})
@app.route("/whisper_transcribe", methods=["POST"])
def whisper_transcribe():
global active_requests
if not request_semaphore.acquire(blocking=False):
return jsonify({'error': 'Server busy'}), 503
active_requests += 1
start_time = time.time()
temp_file_path = None
try:
if 'audio' not in request.files:
return jsonify({'error': 'No file provided'}), 400
audio_file = request.files['audio']
if not (audio_file and allowed_file(audio_file.filename)):
return jsonify({'error': 'Invalid file format'}), 400
temp_file_path = os.path.join(TEMPORARY_FOLDER, secure_filename(audio_file.filename))
audio_file.save(temp_file_path)
segments, _ = wmodel.transcribe(
temp_file_path,
beam_size=beamsize,
vad_filter=True,
without_timestamps=True, # Ensure timestamps are not included
compression_ratio_threshold=2.4,
word_timestamps=False
)
full_text = " ".join(segment.text for segment in segments)
return jsonify({'transcription': full_text}), 200
except Exception as e:
return jsonify({'error': str(e)}), 500
finally:
if temp_file_path:
cleanup_temp_files(temp_file_path)
active_requests -= 1
request_semaphore.release()
print(f"Processed in {time.time()-start_time:.2f}s (Active: {active_requests})")
if __name__ == "__main__":
# Create temporary folder if it doesn't exist
if not os.path.exists(TEMPORARY_FOLDER):
os.makedirs(TEMPORARY_FOLDER)
app.run(host="0.0.0.0", port=7860, threaded=True) |