SenseVoice模型的时间戳解决办法

用SenseVoice进行语音转文字的时候,发现模型不会生成时间戳,只会输出文本的情况。所以对文本的输出进行了修改,仅作参考。

  最开始的时候,我想的是在模型里面进行修改,促使模型的输出自带一个时间戳,也尝试了他们给的方法:

alignment,  scores = torchaudio.functional.forced_align(ctc_probs, preds.unsqueeze(0), None, None, blank=0)

也加在模型里面试了试,发现可以输出单个字的的时间戳,后续我想转成句子的时候,发现模型输出的时间戳是正序的,但是句子的顺序不是正序的。然后每个句子的起始时间都是0,反正错的很离谱,大概如下:

  解决办法:

针对funasr推理(demo1.py)里面的内容进行修改,在进行模型推理前,先用模型fsmn-vad模型处理了音频,我们可以看一看fsmn-vad模型的介绍:models/speech_fsmn_vad_zh-cn-16k-common-pytorch/README.md · yuekai/paraformerX at main (huggingface.co)icon-default.png?t=N7T8https://huggingface.co/yuekai/paraformerX/blob/main/models/speech_fsmn_vad_zh-cn-16k-common-pytorch/README.md

它可以有效的对时间戳进行处理,在我们得到了开始时间和结束时间以后,再最终的输出上可以进行打印或者保存。整体代码如下:
 

from funasr import AutoModel
from funasr.utils.postprocess_utils import rich_transcription_postprocess
import soundfile as sf  # 用于读取和裁剪音频文件
import os
import pandas as pd

# 模型路径
model_dir = "iic/SenseVoiceSmall"
vad_model_dir = "fsmn-vad"  # VAD模型路径

# 音频文件路径
audio_file_path = '音频路径'

# 加载VAD模型
vad_model = AutoModel(
    model=vad_model_dir,
    trust_remote_code=True,
    remote_code="./model.py",
    device="cuda:0",
    disable_update=True
)

# 使用VAD模型处理音频文件
vad_res = vad_model.generate(
    input=audio_file_path,
    cache={},
    max_single_segment_time=30000,  # 最大单个片段时长
)

# 从VAD模型的输出中提取每个语音片段的开始和结束时间
segments = vad_res[0]['value']  # 假设只有一段音频,且其片段信息存储在第一个元素中

# 加载原始音频数据
audio_data, sample_rate = sf.read(audio_file_path)


# 定义一个函数来裁剪音频
def crop_audio(audio_data, start_time, end_time, sample_rate):
    start_sample = int(start_time * sample_rate / 1000)  # 转换为样本数
    end_sample = int(end_time * sample_rate / 1000)  # 转换为样本数
    return audio_data[start_sample:end_sample]


# 加载SenseVoice模型
model = AutoModel(
    model=model_dir,
    trust_remote_code=True,
    remote_code="./model.py",
    device="cuda:0",
    disable_update=True
)

# 对每个语音片段进行处理
results = []
for segment in segments:
    start_time, end_time = segment  # 获取开始和结束时间
    cropped_audio = crop_audio(audio_data, start_time, end_time, sample_rate)

    # 将裁剪后的音频保存为临时文件
    temp_audio_file = "temp_cropped.wav"
    sf.write(temp_audio_file, cropped_audio, sample_rate)

    # 语音转文字处理
    res = model.generate(
        input=temp_audio_file,
        cache={},
        language="auto",  # 自动检测语言
        use_itn=True,
        batch_size_s=60,
        merge_vad=True,  # 启用 VAD 断句
        merge_length_s=10000,  # 合并长度,单位为毫秒
    )
    # 处理输出结果
    text = rich_transcription_postprocess(res[0]["text"])
    # 添加时间戳
    results.append({"start": start_time // 1000, "end": end_time // 1000, "text": text})  # 转换为秒

# 输出结果
for result in results:
    print(f"Start: {result['start']} s, End: {result['end']} s, Text: {result['text']}")

另外附上阿里开源的SenseVoice模型的地址:

https://github.com/FunAudioLLM/SenseVoiceicon-default.png?t=N7T8https://github.com/FunAudioLLM/SenseVoice/blob/main/README_zh.md

说明:该方法可能不是最佳方法,如果有更棒的方法,欢迎交流!!!

评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值