flow match cache版本推理出现爆音,同时prompt文本过长,推理时稳定出现合成音频前面带有prompt中的音频
代码版本采用最新的版本,做流式推理。
load_jit=False, load_trt=False, fp16=False, use_flow_cache=True
使用inference_zero_shot推理
出现两个问题: 1、音频出现爆音
2、合成音频前面带有prompt音频的内容
推理代码提供一下
推理代码提供一下
推理代码采用的官方的inference的代码,流式输入的方式推理会稳定复现,非流式输入不会出现。
同样,我也遇到了此问题,inference_zero_shot流式推理遇到爆音,想问下解决了吗
如果指的是流式音频开头的爆音,是因为模型返回数据包含了wav的文件头,我尝试将第一个chunk丢弃后便不再出现爆音
第二个问题解决了吗?我这边也出现同样的问题
推理时稳定出现合成音频前面带有prompt中的音频 我正在遭遇通用的问题,至于流式推理块前的爆音如楼上所说是wav头文件引起的
推理代码提供一下
def tts_stream_speech_synthesis_sync(self, text_generator):
'''TTS
Args:
text_generator: yield生成器
Returns:
bool: 是否成功
'''
try:
if self.callback and self.callback.on_open:
self.callback.on_open()
# 流式推理,每一段文本生成一个音频块 _用于忽略块数
for _, result in enumerate(self.cosyvoice.inference_zero_shot(
text_generator,
self.prompt_txt,
self.prompt_speech_16k,
stream=True #流式推理
)):
# 获取原始音频数据
audio_tensor = result['tts_speech']
original_sample_rate = 24000 # CosyVoice2 默认输出采样率
# 如果采样率不是16kHz,进行重采样
if original_sample_rate != 16000:
resampler = torchaudio.transforms.Resample(
orig_freq=original_sample_rate,
new_freq=16000
)
audio_tensor = resampler(audio_tensor)
# 确保音频数据是单声道
if audio_tensor.shape[0] > 1:
audio_tensor = audio_tensor.mean(dim=0, keepdim=True)
# 音量归一化处理
audio_numpy = audio_tensor.numpy()
max_abs = np.max(np.abs(audio_numpy))
if max_abs > 0:
# 将音量归一化到0.8,留出一些余量防止爆音
audio_numpy = audio_numpy * (0.8 / max_abs)
# 将音频数据转换为16位PCM格式的字节
pcm_data = (audio_numpy * 32767).astype(np.int16).tobytes()
if self.callback and self.callback.on_data:
self.callback.on_data(pcm_data)
# 完成回调
if self.callback and self.callback.on_complete:
self.callback.on_complete()
return True
except Exception as e:
logger.error(f"TTS过程中发生错误: {str(e)}")
if self.callback and self.callback.on_error:
self.callback.on_error(str(e))
return False
async def ws_msg_send_task_run(self): audio_processor = AudioProcessor() remain_data = b'' while True: await asyncio.sleep(0.1) while not self.ws_send_msg.empty(): # 从消息队列中获取消息 message = self.ws_send_msg.get() # 二进制数据: PCM-16bit 音频数据 if isinstance(message, bytes): samples_per_frame = int(audio_processor.frame_duration_ms * audio_processor.sample_rate / 1000)*2 message = remain_data + message # 切片, 编码, 打包, 发送 for i in range(0, len(message), samples_per_frame): frame_slice = message[i:i + samples_per_frame] if len(frame_slice) == samples_per_frame: # 编码当前帧并发送 opus_data = audio_processor.encode_audio(frame_slice) bin_data = audio_processor.pack_bin_frame(type=0, version=self.protocol_version, payload=opus_data) await self.ws_send_binary(bin_data) else: # 最后一帧不足时, 保留 remain_data = frame_slice pass # JSON数据 else: await self.ws_send_json(message)