如何高效识别语音并提取情感?用SenseVoice Small镜像快速上手
1. 引言:语音理解的新范式
在智能交互、客服质检、情绪分析等场景中,传统的语音识别(ASR)已无法满足对语义+情感+事件的多维理解需求。如何实现高精度、低延迟的富文本语音理解,成为当前AI应用的关键挑战。
SenseVoice Small 是由阿里开源的音频基础模型,具备语音识别(ASR)、语种识别(LID)、语音情感识别(SER)和声学事件检测(AED)能力。经过超过40万小时数据训练,支持50+语言,在中文场景下表现尤为突出,且推理速度远超Whisper系列模型。
本文将基于“SenseVoice Small根据语音识别文字和情感事件标签 二次开发构建by科哥”这一CSDN星图镜像,带你从零开始掌握其WebUI使用方法与Python API调用技巧,快速实现语音转文字 + 情感分析 + 事件标注一体化处理。
2. 镜像环境准备与启动
2.1 环境说明
该镜像已预装以下核心组件:
- SenseVoice Small模型:轻量级非自回归端到端模型
- FunASR框架:阿里巴巴达摩院推出的语音处理工具包
- Gradio WebUI:可视化交互界面,支持上传/录音/实时识别
- JupyterLab:可进行代码调试与二次开发
2.2 启动服务
若未自动启动WebUI,请进入JupyterLab后执行以下命令重启应用:
/bin/bash /root/run.sh2.3 访问地址
浏览器打开:
http://localhost:7860即可进入SenseVoice WebUI操作界面。
3. WebUI操作全流程详解
3.1 界面布局解析
┌─────────────────────────────────────────────────────────┐ │ [紫蓝渐变标题] SenseVoice WebUI │ │ webUI二次开发 by 科哥 | 微信:312088415 │ ├─────────────────────────────────────────────────────────┤ │ 📖 使用说明 │ ├──────────────────────┬──────────────────────────────────┤ │ 🎤 上传音频 │ 💡 示例音频 │ │ 🌐 语言选择 │ - zh.mp3 (中文) │ │ ⚙️ 配置选项 │ - en.mp3 (英文) │ │ 🚀 开始识别 │ - ja.mp3 (日语) │ │ 📝 识别结果 │ - ko.mp3 (韩语) │ └──────────────────────┴──────────────────────────────────┘左侧为功能区,右侧提供示例音频快速体验。
3.2 使用步骤详解
3.2.1 上传或录制音频
方式一:上传本地文件
点击“🎤 上传音频或使用麦克风”,选择支持格式的音频文件: - 支持格式:MP3、WAV、M4A - 推荐采样率:16kHz 或更高 - 建议时长:30秒以内以获得更快响应
方式二:麦克风实时录音
点击右侧麦克风图标,授权浏览器访问麦克风权限: 1. 点击红色按钮开始录音 2. 再次点击停止录音 3. 系统自动保存并加载音频
提示:安静环境下录制效果更佳,避免回声干扰。
3.2.2 选择识别语言
通过“🌐 语言选择”下拉菜单指定目标语言:
| 选项 | 说明 |
|---|---|
| auto | 自动检测(推荐) |
| zh | 中文 |
| en | 英文 |
| yue | 粤语 |
| ja | 日语 |
| ko | 韩语 |
| nospeech | 无语音 |
对于混合语言或不确定语种的情况,建议选择auto模式。
3.2.3 开始识别
点击“🚀 开始识别”按钮,系统将在数秒内完成处理:
| 音频时长 | 平均识别耗时 |
|---|---|
| 10秒 | 0.5~1秒 |
| 1分钟 | 3~5秒 |
性能受CPU/GPU资源影响,建议在GPU环境中部署以提升并发能力。
3.2.4 查看识别结果
识别结果展示于“📝 识别结果”文本框中,包含三大信息层:
(1)文本内容
原始语音转写的文字内容。
(2)情感标签(结尾处)
| 表情 | 标签 | 含义 |
|---|---|---|
| 😊 | HAPPY | 开心 |
| 😡 | ANGRY | 生气/激动 |
| 😔 | SAD | 伤心 |
| 😰 | FEARFUL | 恐惧 |
| 🤢 | DISGUSTED | 厌恶 |
| 😮 | SURPRISED | 惊讶 |
| 无表情 | NEUTRAL | 中性 |
(3)事件标签(开头处)
| 图标 | 事件类型 | 对应标签 |
|---|---|---|
| 🎼 | 背景音乐 | BGM |
| 👏 | 掌声 | Applause |
| 😀 | 笑声 | Laughter |
| 😭 | 哭声 | Cry |
| 🤧 | 咳嗽/喷嚏 | Cough/Sneeze |
| 📞 | 电话铃声 | Ringtone |
| 🚗 | 引擎声 | Engine |
| 🚶 | 脚步声 | Footsteps |
| 🚪 | 开门声 | Door Open |
| 🚨 | 警报声 | Alarm |
| ⌨️ | 键盘声 | Keyboard |
| 🖱️ | 鼠标声 | Mouse Click |
3.3 识别结果示例
示例1:中文情感识别
开放时间早上9点至下午5点。😊- 文本:开放时间早上9点至下午5点。
- 情感:😊 开心
示例2:英文朗读
The tribal chieftain called for the boy and presented him with 50 pieces of gold.- 文本:部落首领叫来了男孩,并给了他50块金币。
示例3:带事件标签
🎼😀欢迎收听本期节目,我是主持人小明。😊- 事件:🎼 背景音乐 + 😀 笑声
- 文本:欢迎收听本期节目,我是主持人小明。
- 情感:😊 开心
4. Python API调用实战
除了WebUI外,SenseVoice Small也支持程序化调用,适用于自动化流水线、嵌入式系统等场景。
4.1 安装依赖
确保安装最新版funasr:
pip install funasr -U4.2 基础调用代码
from funasr import AutoModel from funasr.utils.postprocess_utils import rich_transcription_postprocess # 加载模型 model = AutoModel( model=r"/path/to/SenseVoiceSmall", trust_remote_code=True, remote_code="./model.py", vad_model="fsmn-vad", vad_kwargs={"max_single_segment_time": 30000}, device="cpu", # 可改为 "cuda:0" use_itn=True, disable_update=True, disable_pbar=True, disable_log=True ) def sound2text(audio_file): res = model.generate( input=audio_file, cache={}, language="zh", # 支持: zh, en, yue, ja, ko use_itn=True, batch_size_s=60, merge_vad=True, merge_length_s=15, ) text = rich_transcription_postprocess(res[0]["text"]) return text # 调用示例 audio_path = "example.wav" result = sound2text(audio_path) print("识别结果:", result)4.3 使用ModelScope Pipeline方式
from modelscope.pipelines import pipeline from modelscope.utils.constant import Tasks inference_pipeline = pipeline( task=Tasks.auto_speech_recognition, model='iic/SenseVoiceSmall', model_revision="master", device="cuda:0", use_itn=True, disable_update=True ) rec_result = inference_pipeline("output.wav") print(rec_result)注意:需提前下载模型权重并配置路径。
4.4 提取纯中文文本(正则清洗)
若需去除表情符号和其他非中文字符,可用如下函数提取干净中文:
import re def extract_chinese(input_string): """ 提取字符串中的汉字 """ chinese_characters = re.findall(r'[\u4e00-\u9fa5]', input_string) chinese_text = ''.join(chinese_characters) return chinese_text # 示例 raw_text = "🎼😀欢迎收听本期节目,我是主持人小明。😊" clean_text = extract_chinese(raw_text) print(clean_text) # 输出:欢迎收听本期节目我是主持人小明5. 高级实践:实时语音流处理修复方案
原始代码存在音频帧丢失、播放速度异常等问题。以下是优化后的完整解决方案。
5.1 关键问题修复点
| 问题 | 修复措施 |
|---|---|
| 音频帧丢失 | 使用collections.deque构建循环缓冲区 |
| 录音过快 | 统一使用标准采样率常量AUDIO_RATE |
| VAD漏检 | 改为“VAD OR 频谱分析”双通道判断机制 |
| 起始部分截断 | 添加语音前300ms历史数据 |
5.2 完整修复代码
import pyaudio import numpy as np import wave import collections import os import datetime from funasr import AutoModel from funasr.utils.postprocess_utils import rich_transcription_postprocess import webrtcvad # 参数配置 AUDIO_RATE = 16000 # 统一采样率 CHUNK_SIZE = 480 # 30ms @ 16kHz VAD_MODE = 1 vad = webrtcvad.Vad(VAD_MODE) # 创建临时目录 os.makedirs("temp_wave", exist_ok=True) # 加载模型 sound_recongnition_model = AutoModel( model="/root/models/SenseVoiceSmall", trust_remote_code=False, device="cpu", use_itn=True, disable_update=True, disable_pbar=True, disable_log=True ) class SpeechDetector: def __init__(self): self.audio_buffer = collections.deque(maxlen=500) # 存储最近15秒 self.speech_buffer = bytearray() self.speech_state = False self.consecutive_speech = 0 self.consecutive_silence = 0 self.required_speech_frames = 2 self.required_silence_frames = 15 def analyze_spectrum(self, audio_chunk): audio_data = np.frombuffer(audio_chunk, dtype=np.int16) if len(audio_data) == 0: return False window = np.hanning(len(audio_data)) windowed_data = audio_data * window spectrum = np.abs(np.fft.rfft(windowed_data)) spectral_mean = np.mean(spectrum) peak_count = sum( spectrum[i] > spectrum[i-1] and spectrum[i] > spectrum[i+1] and spectrum[i] > spectral_mean * 1.5 for i in range(1, len(spectrum)-1) ) return peak_count >= 3 def is_speech(self, audio_chunk): amplitude = np.abs(np.frombuffer(audio_chunk, dtype=np.int16)).mean() if amplitude < 1000: return False vad_result = vad.is_speech(audio_chunk, AUDIO_RATE) spectral_result = self.analyze_spectrum(audio_chunk) return vad_result or spectral_result # 使用OR逻辑降低误判 def process_chunk(self, audio_chunk): recognized_text = None temp_audio = None self.audio_buffer.append(audio_chunk) is_speech_chunk = self.is_speech(audio_chunk) if is_speech_chunk: self.consecutive_speech += 1 self.consecutive_silence = 0 if not self.speech_state and self.consecutive_speech >= self.required_speech_frames: self.speech_state = True self.speech_buffer = bytearray() for chunk in list(self.audio_buffer)[-10:]: self.speech_buffer.extend(chunk) if self.speech_state: self.speech_buffer.extend(audio_chunk) else: self.consecutive_silence += 1 self.consecutive_speech = 0 if self.speech_state: self.speech_buffer.extend(audio_chunk) if self.speech_state and self.consecutive_silence >= self.required_silence_frames: if len(self.speech_buffer) > CHUNK_SIZE * 5: temp_audio = bytes(self.speech_buffer) timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S") wav_filename = f"temp_wave/rec_{timestamp}.wav" save_audio_to_wav(temp_audio, AUDIO_RATE, 1, wav_filename) try: res = sound_recongnition_model.generate(input=wav_filename, language="zh", use_itn=True) recognized_text = rich_transcription_postprocess(res[0]["text"]) os.remove(wav_filename) except Exception as e: print(f"处理失败: {e}") self.speech_state = False self.speech_buffer = bytearray() return recognized_text, temp_audio def save_audio_to_wav(audio_data, sample_rate, channels, filename): with wave.open(filename, 'wb') as wf: wf.setnchannels(channels) wf.setsampwidth(2) wf.setframerate(sample_rate) wf.writeframes(audio_data) print(f"已保存: {filename}") if __name__ == "__main__": p = pyaudio.PyAudio() stream = p.open( format=pyaudio.paInt16, channels=1, rate=AUDIO_RATE, input=True, frames_per_buffer=CHUNK_SIZE ) detector = SpeechDetector() print("开始监听... (Ctrl+C退出)") try: while True: chunk = stream.read(CHUNK_SIZE, exception_on_overflow=False) text, _ = detector.process_chunk(chunk) if text: print("【识别】", text) except KeyboardInterrupt: print("\n停止监听") finally: stream.stop_stream() stream.close() p.terminate()6. 性能优化与最佳实践
6.1 提升识别准确率
| 方法 | 说明 |
|---|---|
| 使用高质量音频 | WAV > MP3 > M4A,推荐16kHz以上 |
| 控制背景噪音 | 在安静环境中采集 |
| 明确语言选择 | 若知悉语种,避免使用auto |
| 保持语速适中 | 避免过快或吞音 |
6.2 推理加速建议
- 启用GPU:设置
device="cuda:0"可显著提升速度 - 批处理优化:合理设置
batch_size_s=60 - 关闭日志输出:生产环境添加
disable_log=True
6.3 微调定制支持
SenseVoice 提供便捷微调脚本,可用于: - 修复特定口音识别问题 - 增强行业术语识别能力 - 适配特殊场景下的情感分类
详见官方GitHub仓库文档。
7. 常见问题解答
Q1: 上传音频无反应?
检查文件是否损坏,尝试重新编码为WAV格式。
Q2: 识别结果不准确?
请确认语言选择正确,优先使用auto检测;同时检查音频清晰度。
Q3: 识别速度慢?
- 检查服务器资源占用情况
- 尽量使用短音频片段(<1分钟)
- 推荐使用GPU运行
Q4: 如何复制识别结果?
点击结果框右侧的“复制”按钮即可。
8. 总结
本文系统介绍了基于“SenseVoice Small”镜像的语音识别与情感提取全流程:
- WebUI快速体验:无需编程即可完成语音上传、识别、查看结果;
- API深度集成:通过Python脚本实现自动化语音处理;
- 实时流修复方案:解决原始代码中存在的音频丢失与节奏异常问题;
- 工程化建议:涵盖性能优化、文本清洗、部署策略等实用技巧。
SenseVoice Small凭借其高精度、多语言、低延迟、富语义输出等优势,已成为语音理解领域的优选方案。结合CSDN星图镜像的一键部署能力,开发者可迅速构建具备情感感知能力的智能语音系统。
获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。