[Bugfix] Fix Qwen3-Omni streaming crops in mixed-length batches (#7340)

Signed-off-by: Deep Shah <deep@socratic.co>
This commit is contained in:
Deep Shah authored and GitHub committed 2026-09-15 18:26:43 -07:00
1 parent a1a234a0b4
commit c197cd2422
2 files changed
+52 -33

No files matched your search

@@ -316,21 +316,16 @@ class Qwen3OmniMoeCode2Wav(nn.Module, Qwen3OmniNestedSupportsQuant):
else:
# Fallback: assume all batch elements share the same sequence length.
code_seq_lens = [codes.shape[-1]] * codes.shape[0]
# The decoder trims the same right-edge tail from every batch row.
# Infer it from the decoded window, not a shorter request's length:
# padding that request with codec zeros does not provide valid context.
tail = max(0, int(codes.shape[-1] * self.total_upsample) - batch_wav.shape[-1])
for idx, code_seq_len in enumerate(code_seq_lens):
# The eager decoder (self(codes)) emits a fixed `tail` fewer samples than
# code_seq_len*total_upsample: the causal conv stack trims the sequence end
# because it lacks right context. The original slice assumed full length, so
# under async_chunk every streaming chunk silently dropped its last `tail`
# samples -> a ~23ms gap at every chunk boundary + cumulative ~1.2% time
# compression. Shift the start back by `tail` so this chunk refills the gap the
# previous chunk left (those frames are re-decoded here with proper context).
# `tail` is measured per call, so this is a no-op only when the decoder returns
# the nominal full length (tail==0, e.g. a C==0 decoder like Qwen3-TTS); for
# Qwen3-Omni Code2Wav both the eager forward AND the CUDA-graph wrapper
# (_trim_replay_output -> actual*upsample - 555) are short, so it applies to both.
tail = max(0, int(code_seq_len * self.total_upsample) - batch_wav.shape[-1])
# Refill the previous chunk's tail using the re-decoded left context,
# and exclude the current row's padded tail just as singleton decode does.
start = max(0, left_context_size[idx] * self.total_upsample - tail)
wav_chunk = batch_wav[idx, :, start : code_seq_len * self.total_upsample]
end = max(0, code_seq_len * self.total_upsample - tail)
wav_chunk = batch_wav[idx, :, start:end]
wavs.append(wav_chunk)
return wavs