语音转文字ASR-FunASR SenseVoiceSmall介绍和使用

介绍

SenseVoiceSmall 是阿里巴巴 FunAudioLLM 团队于2024年7月开源的轻量级多任务语音理解模型,主打“ASR+语种+情感+事件”四维一体能力,专为边缘设备与实时场景设计。

基本信息

  • 开发者:阿里 FunASR / FunAudioLLM 团队
  • 发布时间:2024年7月
  • 模型架构:Encoder-only 非自回归(CTC),无 Decoder,并行推理
  • 参数量:约 14M(与 Whisper-Small 相当)
  • 支持语种:中文(普通/粤语)、英、日、韩(Small 版限定)
  • 训练数据:约 40万小时 多语言音频

功能

1. 语音识别 ASR

  • 中文/粤语识别准确率优于 Whisper-Small
  • 支持逆文本归一化(ITN),自动格式化数字、时间、符号

2. 语种识别 LID

  • 自动区分:zh(普通话)、yue(粤语)、en、ja、ko

3. 情感识别 SER(开源最优)

  • 7类基础情感:
    • 开心 (Happy)
    • 生气 (Angry)
    • 伤心 (Sad)
    • 恐惧 (Fear)
    • 厌恶 (Disgust)
    • 惊讶 (Surprise)
    • 中性 (Neutral)
  • 直接从声学特征建模,不依赖文本语义

4. 声学事件检测 AED

  • 支持:音乐、掌声、笑声、哭声、咳嗽、喷嚏、静音 等
  • 端到端定位事件,非后处理分类

技术亮点

1. 极致推理速度

  • 10秒音频仅需 ~70ms(CPU)
  • 比 Whisper-Small 快约5倍,比 Whisper-Large 快约15倍
  • 支持 INT8/FP16 量化,可在手机、树莓派、车载/家居 NPU 运行

2. 原生多任务共享表征

  • 情感/事件/语种共享同一 Encoder,非多模型拼接
  • 输入音频 → 输出带标签的富文本,例如:
    [SOUND:掌声] 你好![EMO:开心]
    

3. 轻量高效设计

  • 编码器:SAN-M(Conformer 改进版),CNN+Self-Attention 平衡效率与效果
  • 损失函数:CTC Loss + 多分类任务 Loss 加权和

性能对比

  • 中文 ASR:CER(字符错误率)低于 Whisper-Small
  • 情感识别:WAA(加权平均准确率)达SOTA 水平
  • 推理延迟:10s 音频 ~70ms(CPU),远低于 Whisper 同规模

适用场景

  • 实时语音交互:智能助手、车载语音、直播字幕
  • 情感化客服:呼叫中心情绪分析、满意度预判
  • 边缘端设备:智能家居、可穿戴设备、离线录音笔
  • 语音内容审核:音频情感/暴力事件快速筛查

局限性

  • 语种限制:Small 版仅支持 5种(中/粤/英/日/韩),Large 版支持 50+
  • 事件粒度:基础事件检测,非专业事件检测模型深度
  • 长音频:建议分片处理(≤30秒),长时依赖建模弱于自回归模型

总结

SenseVoiceSmall 是轻量、高速、多能力合一的语音模型,在中文场景+边缘实时性上优势显著,适合快速构建能听内容、懂情绪、识场景的语音应用。

使用教程

三种运行方式,如下:

1. ModelScope 路线(官方“全家桶”)

这是阿里官方最推荐的入门路线,属于“开箱即用”型。

  • 核心逻辑:直接依赖阿里的 modelscope 库。你只需要指定模型 ID(如 iic/SenseVoiceSmall),它会自动帮你下载模型、配置环境。
  • 底层技术:通常基于 PyTorch。
  • 优点:
    • 最简单:代码量最少,几行 Python 代码就能跑通。
    • 功能全:自动包含 VAD(语音活动检测)、标点模型等后处理功能。
  • 缺点:
    • 依赖重:需要安装 PyTorch,体积较大。
    • 联网依赖:首次运行必须联网下载模型,且启动时可能会检查更新(内网环境需特殊配置)。
  • 适用人群:初学者、快速验证功能的开发者。

2. FunASR 路线(框架集成)

这是目前最通用的开发路线,适合将 SenseVoice 作为一个组件集成到项目中。

  • 核心逻辑:使用 funasr 这个统一的语音识别框架。SenseVoice 只是 FunASR 支持的一个模型而已(FunASR 还支持 Paraformer 等其他模型)。
  • 底层技术:虽然底层也是 PyTorch,但它提供了更高级的封装(如 AutoModel),并且支持 ONNX 加速(即 funasr-onnx)。
  • 优点:
    • 标准化:调用接口统一,方便切换不同模型。
    • 灵活:可以方便地开启/关闭 VAD、标点、情感识别等模块。
    • WebUI 支持好:目前的 Gradio/Streamlit 教程大多基于此路线。
  • 缺点:依然依赖 Python 环境和一定的库体积。
  • 适用人群:Python 开发者、需要构建 Web 服务(如 Gradio)的用户。

3. 纯 ONNX 路线(复杂,不推荐)

这是追求高性能、跨平台或完全离线的“硬核”路线。

  • 核心逻辑:完全抛弃 PyTorch 和 ModelScope 的依赖,直接使用 ONNX Runtime 推理引擎加载转换好的 .onnx 模型文件。
  • 代表工具:sherpa-onnx(目前最流行的方案)、funasr-onnx(仅推理)。
  • 优点:
    • 完全离线:不需要联网,没有“检查更新”的卡顿。
    • 极速轻量:依赖极小,推理速度极快(特别是 INT8 量化版本),内存占用低。
    • 跨平台:可以在 C++、Android、iOS、树莓派甚至浏览器(WASM)中运行。
  • 缺点:
    • 配置稍繁琐:需要手动下载 ONNX 模型文件并指定路径。
    • 功能剥离:通常只负责核心的“语音转文字”,VAD 和标点可能需要自己额外处理或使用集成好的工具(如 sherpa-onnx 已集成了这些)。
  • 适用人群:C++ 开发者、移动端部署、内网服务器、追求极致速度的用户。

总结对比表

路线 核心依赖 优势 劣势 推荐指数
ModelScope PyTorch + ModelScope SDK 傻瓜式启动,自动下载 包体积大,强依赖网络 ⭐⭐⭐ (入门首选)
FunASR FunASR 框架 (PyTorch/ONNX) 接口统一,功能模块化 仍需 Python 环境 ⭐⭐⭐⭐ (开发首选)
纯 ONNX ONNX Runtime (sherpa-onnx) 最快、最小、完全离线 需手动管理模型文件 ⭐⭐⭐⭐⭐ (部署首选)

建议

  • 如果只是想跑通代码看看效果,选 ModelScope。

  • 功能强大、且占用资源比 ModelScope 少,用 FunASR。

  • 如果要做成产品发布给别人用,或者在没有网的服务器上跑,请务必选择 纯 ONNX (sherpa-onnx) 方案。

  • 功能强大、且占用资源少、速度快,用 FunASR + ONNX(很难调通)

下载模型

官方文档:
https://modelscope.cn/models/iic/SenseVoiceSmall-onnx/summary

提示:下载时,不指定路径,模型下载到默认路径 C:\Users\你的用户名\.cache\modelscope\hub

modelscope 下载

在下载前,请先通过如下命令安装 ModelScope

pip install modelscope

启动cmd 或 PowerShell,执行下面命令行,下载完整模型库:

modelscope download --model iic/SenseVoiceSmall

下载单个文件到指定本地文件夹(以下载README.md到当前路径下“dir”目录为例)

modelscope download --model iic/SenseVoiceSmall README.md --local_dir ./dir

SDK下载模型下载

from modelscope import snapshot_download
model_dir = snapshot_download('iic/SenseVoiceSmall')

Git下载

请确保 lfs 已经被正确安装

git lfs install
git clone https://www.modelscope.cn/iic/SenseVoiceSmall.git

如果您希望跳过 lfs 大文件下载,可以使用如下命令

GIT_LFS_SKIP_SMUDGE=1 git clone https://www.modelscope.cn/iic/S

安装依赖

# 基础安装 (CPU 推理,最通用)
pip install modelscope funasr torch torchaudio

Python 代码示例

注意 model 参数指定为 ONNX 版本的模型(通常带 -onnx 后缀),或者 FunASR 会自动下载 ONNX 版本。

from funasr import AutoModel

# SenseVoiceSmall模型路径
model_path = r"D:\ai_model\SenseVoiceSmall"
# 加载 VAD 模型,实现长音频自动切片
vad_model_path = r"D:\ai_model\speech_fsmn_vad_zh-cn-16k-common-pytorch"
# 输出结果路径
output_dir = "./result"

# 音频文件
audio_path = r"H:\Users\mym\Documents\录音\录音.m4a"


# 1. 初始化模型
model = AutoModel(
    # 不要指定模型名,会自动联网检测
    # model="iic/SenseVoiceSmall",
    # vad_model="fsmn-vad",
    model=model_path,
    vad_model=vad_model_path,      # 【关键】加载 VAD 模型,实现长音频自动切片
    vad_kwargs={"max_single_segment_time": 30000}, # 设置切片阈值
    device="cpu",              # 在 CPU 上执行
    ncpu=4,                    # 如果使用 CPU,指定核心数
    disable_log=True,           # 关键:关闭日志
    disable_bar=True,           # 关键:关闭进度条
    disable_update=True,        # 禁止检查更新
    output_dir=output_dir       # 如果设置,输出结果的输出路径
)
# 2. 识别长音频
# 直接丢入 1 小时的录音,FunASR 会利用 VAD 切片,然后 SenseVoiceSmall 负责快速推理
res = model.generate(
    input=audio_path,
    language="auto",           # 自动识别语种
    use_itn=True,              # 开启数字正则化 (如 "一百" -> "100")
    merge_vad=True,            # 开启结果合并,让句子更通顺
)
# 3. 输出结果
# print(res)
raw_text = res[0]["text"]
print(raw_text)

解释

  1. 解决了“显存焦虑”:
    如果你没有独立显卡,或者显存很小(<4GB),纯 PyTorch 模式可能会跑不动或者很慢。而 FunASR + ONNX (Int8 量化版) 可以在普通 CPU 上流畅运行,内存占用仅几百兆。

  2. 解决了“长音频切片”烦恼:
    如果你直接用纯 ONNX (如 onnxruntime 原生接口),你需要自己写代码去切割音频(比如每 30 秒切一刀)。
    但在 FunASR 框架下,你只需要传入 vad_model,它会自动帮你把长音频切成小段,喂给 ONNX 模型,最后再把文字拼好。

输出示例

<|zh|><|NEUTRAL|><|Speech|><|withitn|>你好你好,123456。

SenseVoiceSmall 轻量化版不单独输出 json 字段,
而是把 语种、情绪、语音类型、文本规整 全部用特殊标签前缀塞在 text 里。

翻译成人话: 这段是中文普通话、情绪中性、纯人声说话、已做数字文本规整,识别内容为:你好你好,123456。

下面拆分各个部分解释:

1. <|zh|>

含义:语种标签
zh = 中文普通话
作用:模型标记这段语音是中文。

2. <|NEUTRAL|>

含义:情绪标签
NEUTRAL = 情绪中性
就是语气平淡、正常说话,不开心、不生气、不难过。
其他情绪详见上面的 3. 情感识别 SER(开源最优)

3. <|Speech|>

含义:音频类型标签
代表这段是人声说话片段,不是静音、不是噪音、不是音乐。

4. <|withitn|>

含义:带逆文本归一化标记
通俗解释:

  • itn = Inverse Text Normalization 逆文本归一化
  • 作用:把口语里的数字、时间、金额,转换成标准书面文字
    比如说话“一二三四五六” → 规整成 123456
    比如“下午三点” → 规整成 下午3点

清洗结果

开发时,可以直接正则把这些 <|xxx|> 全部过滤掉,只保留后面正常文字就行。

def parse_result(text:str):
    """
    解析结果
    :param text:
    :return:
    """
    arr = text.split("|>")
    # 拆分成变量
    lang = arr[0][2:]  # 语种
    emotion = arr[1][2:]  # 情绪
    speech_type = arr[2][2:]  # 语音类型
    itn_type = arr[3][2:]  # 文本格式化

    return {
        "lang": lang,
        "emotion": emotion,
        "type": speech_type,
        "itn": itn_type,
        "text": arr[-1]
    }

输出结果: {'lang': 'zh', 'emotion': 'NEUTRAL', 'type': 'Speech', 'itn': 'withitn', 'text': '你好你好,123456。'}

完整代码

from funasr import AutoModel

# SenseVoiceSmall模型路径
model_path = r"D:\ai_model\SenseVoiceSmall"
# 加载 VAD 模型,实现长音频自动切片
vad_model_path = r"D:\ai_model\speech_fsmn_vad_zh-cn-16k-common-pytorch"
# 输出结果路径
output_dir = "./result"

# 音频文件
audio_path = r"H:\Users\mym\Documents\录音\录音.m4a"


def parse_result(text:str):
    """
    解析结果
    :param text:
    :return:
    """
    arr = text.split("|>")
    # 拆分成变量
    lang = arr[0][2:]  # 语种
    emotion = arr[1][2:]  # 情绪
    speech_type = arr[2][2:]  # 语音类型
    itn_type = arr[3][2:]  # 文本格式化

    return {
        "lang": lang,
        "emotion": emotion,
        "type": speech_type,
        "itn": itn_type,
        "text": arr[-1]
    }

# 1. 初始化模型
model = AutoModel(
    # 不要指定模型名,会自动联网检测
    # model="iic/SenseVoiceSmall",
    # vad_model="fsmn-vad",
    model=model_path,
    vad_model=vad_model_path,      # 【关键】加载 VAD 模型,实现长音频自动切片
    vad_kwargs={"max_single_segment_time": 30000}, # 设置切片阈值
    device="cpu",              # 在 CPU 上执行
    ncpu=4,                    # 如果使用 CPU,指定核心数
    disable_log=True,           # 关键:关闭日志
    disable_bar=True,           # 关键:关闭进度条
    disable_update=True,        # 禁止检查更新
    output_dir=output_dir       # 如果设置,输出结果的输出路径
)
# 2. 识别长音频
# 直接丢入 1 小时的录音,FunASR 会利用 VAD 切片,然后 SenseVoiceSmall 负责快速推理
res = model.generate(
    input=audio_path,
    language="auto",           # 自动识别语种
    use_itn=True,              # 开启数字正则化 (如 "一百" -> "100")
    merge_vad=True,            # 开启结果合并,让句子更通顺
)
# 3. 输出结果
# print(res)
raw_text = res[0]["text"]
# print(raw_text)
print(parse_result(raw_text))

原文出处:/show_1GW3G2d8krUE.html