Repository navigation
Replies: 2 comments 1 reply
|
The measurements in PR #545 match what I saw here. In the next release, the Inquire chunks of a completed recording are built by an index job on its own worker ( |
1 reply
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Description
Transcription jobs currently generate transcript chunk embeddings synchronously at the end of every transcription, inside the worker thread that just ran the ASR call.
On the instance measured for this request, a 30-second clip takes about 16.4 seconds of processing time, of which roughly 2.4 seconds is the ASR call and the remaining ~14 seconds is embedding generation. This makes the transcription queue drain roughly five times slower than the ASR alone would allow, and it blocks completion status until embeddings finish.
The recording is already marked COMPLETED before chunks are built, and an embedding failure does not fail the recording, so deferring this work is safe and would not change the user-visible success path.
Affected Version
v0.10.18-alpha
Requested Feature
Move
process_recording_chunks(src/services/embeddings.py:547) off the transcription critical path so that a transcription job finishes as soon as the ASR result is stored, and embeddings are generated afterward without blocking the worker that is serving the queue.The recording's COMPLETED status and transcript must be available to the user before embeddings finish.
Proposed Implementation
process_recording_chunksasynchronously afterfinish_processingmarks the recording COMPLETED (src/tasks/processing.py:346), instead of synchronously inside it. Options: enqueue it as a low-priority job in the existingFairJobQueue(src/services/job_queue.py:42), run it in a separate thread pool or process pool, or generate embeddings lazily on first search or detail access.src/services/embeddings.py:547-560). The recording stays COMPLETED regardless of embedding outcome.generate_embeddingsbills the recording owner for API-mode usage, so the deferred path must still passrecording.user_id.embed_chunks) to the transcription category so it reuses the existing worker pool and fair scheduling, or to a separate low-priority pool so it cannot starve transcription.ENABLE_INQUIRE_MODEgating: when it is false, skip chunk processing entirely, as today.Expected Behavior
Root Cause Analysis
finish_processinginsrc/tasks/processing.py:346callsprocess_recording_chunks(recording_id)synchronously after settingrecording.status = 'COMPLETED'.process_recording_chunks(src/services/embeddings.py:547) callschunk_transcript_segmentsand thengenerate_embeddings, which runs a localall-MiniLM-L6-v2model and takes ~14 seconds for a 30-second clip. This runs inside the transcription worker thread (src/services/job_queue.py:485_run_transcription->transcribe_audio_task->finish_processing), so the worker cannot claim the next job until embeddings finish. With 2 workers and 10 jobs, the queue drains in over 5 minutes even though the ASR itself processes a clip in ~2.3 seconds.The work is CPU-bound and blocks the GIL (
src/services/job_queue.py:108-118usesthreading.Thread), so the second worker does not provide real parallelism for embeddings. The ASR service itself serializes requests, so it is not the bottleneck; embedding generation is.Relevant files:
src/tasks/processing.py:346(finish_processing),src/services/embeddings.py:547(process_recording_chunks),src/services/job_queue.py:24(TRANSCRIPTION_WORKERS),src/services/job_queue.py:108-118(worker threads),src/services/job_queue.py:485(_run_transcription).All reactions