[BugFix] Modify the splicing method of streaming audio output. (#3438)

Signed-off-by: amy-why-3459 <wuhaiyan17@huawei.com>
This commit is contained in:
amy-why-3459 authored and GitHub committed 2026-05-12 11:56:10 +08:00
1 parent dd5626e607
commit ce621be29b
1 file changed
+57 -6
+57 -6
View File
@@ -8,6 +8,7 @@ import ssl
import sys
import time
import traceback
import wave
from collections.abc import Iterable
from dataclasses import dataclass
from datetime import datetime
@@ -374,6 +375,14 @@ async def async_request_openai_chat_omni_completions(
# outputs or metrics from previous attempts.
generated_text = ""
generated_audio = None
# For wav responses, accumulate decoded PCM bytes per chunk
# to avoid repeated AudioSegment decode/concat.
wav_pcm_buffer = bytearray()
wav_audio_params: tuple[int, int, int] | None = None
wav_inconsistent_chunk_count = 0
first_inconsistent_wav_params: tuple[int, int, int] | None = None
# For non-wav responses, accumulate encoded bytes then decode once.
audio_bytes_buffer = bytearray()
ttft = 0.0
st = time.perf_counter()
output.start_time = st
@@ -440,12 +449,28 @@ async def async_request_openai_chat_omni_completions(
audio_generate_time = timestamp - st
if content:
audio_bytes = base64.b64decode(content)
seg = AudioSegment.from_file(io.BytesIO(audio_bytes))
if seg is not None:
if generated_audio is None:
generated_audio = seg
else:
generated_audio = generated_audio + seg
if response_format == "wav":
try:
with wave.open(io.BytesIO(audio_bytes), "rb") as wav_reader:
params = (
wav_reader.getnchannels(),
wav_reader.getsampwidth(),
wav_reader.getframerate(),
)
if wav_audio_params is None:
wav_audio_params = params
elif wav_audio_params != params:
wav_inconsistent_chunk_count += 1
if first_inconsistent_wav_params is None:
first_inconsistent_wav_params = params
continue
wav_pcm_buffer.extend(
wav_reader.readframes(wav_reader.getnframes())
)
except Exception as ex:
logger.warning("Failed to parse wav audio chunk: %s", ex)
else:
audio_bytes_buffer.extend(audio_bytes)
if metrics := data.get("metrics"):
output.output_tokens = metrics.get("num_tokens_out", 0)
@@ -454,8 +479,34 @@ async def async_request_openai_chat_omni_completions(
if (pt := usage.get("prompt_tokens")) is not None:
output.prompt_len = pt
if wav_inconsistent_chunk_count > 0:
logger.warning(
"Dropped %d wav chunks with inconsistent params during benchmark "
"(expected=%s, first_inconsistent=%s). "
"Audio frames/duration may be undercounted.",
wav_inconsistent_chunk_count,
wav_audio_params,
first_inconsistent_wav_params,
)
output.latency = timestamp - st
output.generated_text = generated_text
if response_format == "wav" and wav_pcm_buffer and wav_audio_params is not None:
channels, sample_width, frame_rate = wav_audio_params
generated_audio = AudioSegment(
data=bytes(wav_pcm_buffer),
sample_width=sample_width,
frame_rate=frame_rate,
channels=channels,
)
elif audio_bytes_buffer:
try:
generated_audio = AudioSegment.from_file(
io.BytesIO(bytes(audio_bytes_buffer)),
format=response_format,
)
except Exception as ex:
logger.warning("Failed to decode accumulated audio bytes: %s", ex)
if generated_audio is not None:
output.audio_duration = len(generated_audio) / 1000.0
frame_width = generated_audio.frame_width