Spaces:
Sleeping
Sleeping
fix: run partial inference in background to stop blocking WebSocket receive loop
Browse files
main.py
CHANGED
|
@@ -38,7 +38,7 @@ CHUNK_LENGTH_S = 30
|
|
| 38 |
OVERLAP_S = 1
|
| 39 |
|
| 40 |
# Minimum seconds of audio before running partial inference (reduces hallucinations)
|
| 41 |
-
MIN_AUDIO_FOR_INFERENCE_S = 1.
|
| 42 |
MIN_SAMPLES_FOR_INFERENCE = int(MIN_AUDIO_FOR_INFERENCE_S * SAMPLE_RATE)
|
| 43 |
|
| 44 |
ALLOWED_EXTS = {".wav", ".m4a", ".mp3", ".flac", ".ogg"}
|
|
@@ -141,6 +141,16 @@ async def stream_transcribe(ws: WebSocket):
|
|
| 141 |
audio_buffer = bytearray()
|
| 142 |
last_inference_len = 0 # track buffer size at last inference to avoid redundant runs
|
| 143 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 144 |
try:
|
| 145 |
while True:
|
| 146 |
message = await ws.receive()
|
|
@@ -157,12 +167,9 @@ async def stream_transcribe(ws: WebSocket):
|
|
| 157 |
# Run partial inference ONLY if the CPU is free.
|
| 158 |
# This prevents thousands of requests from queuing and timing out the final run.
|
| 159 |
if not _inference_lock.locked():
|
| 160 |
-
async with _inference_lock:
|
| 161 |
-
text = await asyncio.get_event_loop().run_in_executor(
|
| 162 |
-
None, _transcribe_pcm_buffer, bytes(audio_buffer)
|
| 163 |
-
)
|
| 164 |
last_inference_len = len(audio_buffer)
|
| 165 |
-
|
|
|
|
| 166 |
|
| 167 |
# --- Text frame: control message ------------------------------
|
| 168 |
elif "text" in message and message["text"] is not None:
|
|
|
|
| 38 |
OVERLAP_S = 1
|
| 39 |
|
| 40 |
# Minimum seconds of audio before running partial inference (reduces hallucinations)
|
| 41 |
+
MIN_AUDIO_FOR_INFERENCE_S = 1.0
|
| 42 |
MIN_SAMPLES_FOR_INFERENCE = int(MIN_AUDIO_FOR_INFERENCE_S * SAMPLE_RATE)
|
| 43 |
|
| 44 |
ALLOWED_EXTS = {".wav", ".m4a", ".mp3", ".flac", ".ogg"}
|
|
|
|
| 141 |
audio_buffer = bytearray()
|
| 142 |
last_inference_len = 0 # track buffer size at last inference to avoid redundant runs
|
| 143 |
|
| 144 |
+
async def _run_partial(pcm_data: bytes):
|
| 145 |
+
try:
|
| 146 |
+
async with _inference_lock:
|
| 147 |
+
text = await asyncio.get_event_loop().run_in_executor(
|
| 148 |
+
None, _transcribe_pcm_buffer, pcm_data
|
| 149 |
+
)
|
| 150 |
+
await ws.send_json({"type": "partial", "text": text})
|
| 151 |
+
except Exception as e:
|
| 152 |
+
print(f"[ws] partial inference error: {e}", flush=True)
|
| 153 |
+
|
| 154 |
try:
|
| 155 |
while True:
|
| 156 |
message = await ws.receive()
|
|
|
|
| 167 |
# Run partial inference ONLY if the CPU is free.
|
| 168 |
# This prevents thousands of requests from queuing and timing out the final run.
|
| 169 |
if not _inference_lock.locked():
|
|
|
|
|
|
|
|
|
|
|
|
|
| 170 |
last_inference_len = len(audio_buffer)
|
| 171 |
+
# We must run this in the background, otherwise we block ws.receive()
|
| 172 |
+
asyncio.create_task(_run_partial(bytes(audio_buffer)))
|
| 173 |
|
| 174 |
# --- Text frame: control message ------------------------------
|
| 175 |
elif "text" in message and message["text"] is not None:
|