feat(audio): batch Qwen3-ASR transcriptions#5172
Conversation
|
Warning You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again! |
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request implements batching support for the Qwen3 ASR model by integrating BatchMixin and refactoring transcription methods, accompanied by new unit tests. The reviewer feedback suggests popping max_inference_batch_size from kwargs to avoid TypeErrors, handling None values in the language list to prevent transcription errors, and adding a close method to BatchMixin to clean up the background task and prevent memory leaks.
OliverBryant
left a comment
There was a problem hiding this comment.
Nice work. The batching integration follows the existing create_embedding @extensible/.batch convention, and the BatchMixin._process_batch hardening (moving the count check inside try, dropping cancelled futures, restartable processor task) is a solid robustness improvement. Tests cover ordering, batch-size, kwargs grouping, and cancellation survival. LGTM.
Left two minor, non-blocking notes below. The only one I'd genuinely suggest acting on is a mention in the PR description of the shared batch.py boundary change, since it affects every batch-capable model, not just Qwen3-ASR.
Summary
batch_intervalconfigurableBatchMixinsize limit while preserving FIFO order for requests deferred to the next batchWhy
Qwen3-ASR supports batched transcription, but Xinference currently invokes each concurrent audio request separately. This change lets compatible requests share one model call while preserving the existing API response behavior.
The shared 3 ms batching interval is too short for differently sized audio uploads to reach the model actor together. Qwen3-ASR therefore uses a 100 ms default without changing the global
BatchMixindefault.BatchMixinis shared by embedding, rerank, and Qwen3-ASR models. Because one queued request can contain multiple inputs, checking only the current accumulated size is insufficient: the next request can push a batch past its configured limit. The worker now retains such a request as a FIFO-preserving pending item for the next batch. A single request that already exceeds the limit still runs alone because the mixin cannot split one request.Validation
pytest -q xinference/model/tests/test_batch.py xinference/model/audio/tests/test_qwen3_asr.py— 8 passedpre-commit run --files xinference/model/batch.py xinference/model/tests/test_batch.py xinference/model/audio/qwen3_asr.py— passedgit diff --check— passedThe shared batch tests cover a request that would overflow the remaining capacity, exact-capacity batches, FIFO preservation across deferred requests, and a single oversized request.
GPU end-to-end results
Tested through a real Xinference service on an NVIDIA GeForce RTX 3090 Ti with
Qwen3-ASR-1.7B,batch_size=2, and the defaultbatch_interval=0.1.Method:
蝶恋花·春景.mp3×2 (180.024 s each)synthesized_speech_92345053.mp3×2 (106.606 s each)Debug logs confirmed that sequential runs invoked native batch sizes
[1, 1], while concurrent runs invoked[2].Sequential and batched outputs matched exactly for both files in every measured round. This validates output parity, not transcript ground-truth accuracy.
The mixed-duration pair is slower because native batching pads work toward the longest item: the two inputs contain 286.630 seconds of audio in total, while a two-item batch can process approximately 360.048 seconds of padded frames. The throughput gain is therefore strongest when requests have similar lengths.