feat: chunked upload + direct downloads instead of base64 JSON - #6
Open
devin-ai-integration[bot] wants to merge 1 commit into
Open
feat: chunked upload + direct downloads instead of base64 JSON#6devin-ai-integration[bot] wants to merge 1 commit into
devin-ai-integration[bot] wants to merge 1 commit into
Conversation
Split the Modal service into a CPU FastAPI app (upload/separate/download) and the GPU AudioSeparator, sharing an 'audio-separator-jobs' Volume. The browser uploads the MP3 in 8 MB chunks, starts separation by job id, receives only metadata over SSE and downloads each track directly.
Author
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
Contributor
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Replaces the base64-in-JSON transport (one 35 MB request in, one ~37 MB SSE event out) with a job-based flow over a shared Modal Volume. On the 40-min sermon this cuts end-to-end time from 208 s → 135 s (warm GPU; server work unchanged at ~123 s, so transport overhead went from ~85 s to ~12 s) and the
completeevent from ~37 MB to 13 KB. The browser never holds the audio in JS memory.New topology (
run-service/modal_app.py):AudioSeparator.separate_job(job_id, languages)is now a Modal generator (remote_gen.aiofrom the web app). The pipeline runs in a worker thread and progress is relayed through aqueue.Queue, so the SSE stream stays alive during the ~2 min of GPU work; the oldseparate_bytes/_write_uploaded_audio/ base64 code is gone.job_path()only accepts 32-hex ids, so every filesystem path derived from a request stays under/jobs(traversal returns 404/400). Jobs are purged after 24 h bypurge_old_jobs()on eachPOST /upload;input.mp3is deleted as soon as the tracks are published.check_languages_shape()on the CPU, fullvalidate_languages()on the GPU..aio();ensure_visible()only reloads when a path written by another container isn't visible yet.completepayload gainsjob_idanddownloads: {lang1, lang2}(paths relative to the API base) and dropslanguage1/language2.Frontend (
app/page.tsx,lib/types.ts):uploadFile()slices theFileintochunk_bytespieces, PUTs 3 in flight with 3 retries each (upload = first 20 % of the progress bar), then calls/separate; downloads are a plain<a href=".../download/{job}/{track}" download>.Deployment note (breaking)
The web endpoint URL changes: the app now exposes
.../audio-separator-api.modal.runinstead of.../audioseparator-separate.modal.run. After this merges (and CI/modal deployruns), updateNEXT_PUBLIC_MODAL_ENDPOINTaccordingly. The Volumeaudio-separator-jobsis created on first deploy.Verification
python -m py_compile, helper tests (incl. newjob_path/assemble_chunks/purge_old_jobscases),tsc --noEmit, scoped eslint,npm run buildall pass.audio-separator-devand ran the real 40-min sermon through all five routes twice (cold + warm). Output identical to feat: route tracks by language (pyannote 3.1 FP32 + Whisper language ID) #5 (English 919 s / Chinese 829 s, 44.1 kHz). Warm run:../traversal → 404, bad job id on/separate→ SSEerrorevent.Link to Devin session: https://app.devin.ai/sessions/d3ad67079eea4dabbaedb4334dbe7c2f
Open in Devin Desktop: https://app.devin.ai/desktop/session/d3ad67079eea4dabbaedb4334dbe7c2f?variant=devin
Requested by: @balebbae