SenseVoice-small-onnx语音识别部署教程:Mac M1/M2芯片原生ARM64支持方案
SenseVoice-small-onnx语音识别部署教程:Mac M1/M2芯片原生ARM64支持方案
1. 引言
如果你手头有一台MacBook,用的是M1或M2芯片,想在上面跑一个能听懂中文、粤语、英语甚至日韩语的语音识别服务,可能会遇到点麻烦。很多教程都是为x86架构的电脑写的,在苹果自家的ARM芯片上直接跑,要么装不上依赖,要么跑起来慢吞吞。
今天要聊的SenseVoice-small-onnx模型,正好解决了这个问题。它是一个经过量化处理的多语言语音识别模型,文件不大,性能却不弱,最关键的是,它能在Mac M系列芯片上原生运行,不需要通过Rosetta转译,效率直接拉满。
这篇文章,我就带你从零开始,在Mac M1/M2上把这个语音识别服务搭起来。整个过程不复杂,你不需要是深度学习专家,跟着步骤走,半小时内就能让电脑“听懂人话”。我们会搞定环境配置、服务启动、API调用,最后再聊聊实际用起来的感受。
2. 环境准备与项目概览
在动手之前,我们先看看需要准备些什么,以及这个项目到底能做什么。
2.1 你需要准备的东西
- 一台Mac电脑:必须是搭载M1、M2、M3或更新Apple Silicon芯片的型号。Intel芯片的Mac不适用本教程的原生方案。
- 稳定的网络连接:主要用于安装Python包,模型文件我们会优先使用缓存,避免重复下载。
- 基础的命令行操作知识:知道怎么打开终端(Terminal),会输入一些简单的命令就行。
- 约500MB的可用磁盘空间:用来存放模型文件和Python环境。
2.2 SenseVoice-small-onnx是什么?
简单来说,它是一个“瘦身”后的语音识别引擎。
- SenseVoice:是模型的本体,一个能识别多种语言的语音模型。
- Small:代表这是它的“小尺寸”版本,在精度和速度之间取得了不错的平衡,适合本地部署。
- ONNX:是一种开放的模型格式。把模型转换成ONNX格式,就像把软件打包成能在不同操作系统上运行的安装包,让它能在各种硬件和框架上高效运行。
- 量化:这是关键一步。你可以把它想象成把一张高清图片转换成适合网页浏览的压缩格式。量化能大幅减小模型文件体积(从可能的上GB变成几百MB),并且能提升在像Mac M芯片这类设备上的推理速度。
这个服务启动后,会提供一个网页界面让你上传音频试玩,还有一个标准的HTTP API接口,方便你自己写程序来调用。
3. 一步步部署语音识别服务
好了,我们正式开始。请打开你的终端(Terminal)。
3.1 第一步:创建并进入项目目录
首先,我们找个地方存放项目文件。在终端里依次输入以下命令:
# 创建一个名为‘sensevoice-demo’的文件夹(名字可以自定)
mkdir sensevoice-demo
# 进入这个文件夹
cd sensevoice-demo
3.2 第二步:准备Python环境
Mac系统自带Python3,但我们最好确保环境干净。建议使用venv创建虚拟环境。
# 创建虚拟环境,环境文件夹名称为‘venv’
python3 -m venv venv
# 激活虚拟环境
source venv/bin/activate
激活后,你的命令行提示符前面通常会显示(venv),表示你已经在这个独立的环境中了。接下来所有包的安装都只影响这里。
3.3 第三步:安装依赖包
我们需要安装几个核心的Python包。复制下面的命令一次性安装:
pip install funasr-onnx gradio fastapi uvicorn soundfile jieba
funasr-onnx:这是核心,提供了ONNX格式SenseVoice模型的加载和推理能力。gradio:用来快速生成我们试玩的网页界面。fastapi和uvicorn:用于构建高性能的REST API服务。soundfile:用于读取各种格式的音频文件。jieba:中文分词库,帮助提升中文识别的文本格式化效果。
3.4 第四步:下载并配置模型
官方服务会从网络下载模型。但我们已经准备好了缓存模型,可以节省时间和流量。我们需要手动创建对应的目录结构。
在终端中(确保还在sensevoice-demo目录下),输入:
# 创建模型缓存目录
mkdir -p /tmp/ai-models/danieldong/sensevoice-small-onnx-quant
# 提示:实际的模型文件需要你自行获取并放入上述目录。
# 通常,你需要下载 ‘model_quant.onnx’ (约230MB) 和对应的配置文件。
# 这里假设你已经有了这些文件。
重要提示:你需要将名为model_quant.onnx的量化模型文件(约230MB)及其相关配置文件,放置到刚刚创建的/tmp/ai-models/danieldong/sensevoice-small-onnx-quant路径下。服务启动时会优先检查这个路径。
3.5 第五步:创建启动脚本
现在,我们需要创建一个Python脚本来启动服务。在当前目录下创建一个新文件,命名为app.py。
# 使用nano编辑器创建文件(也可以用vim或VS Code)
nano app.py
将以下代码复制粘贴到app.py中:
#!/usr/bin/env python3
"""
SenseVoice Small ONNX 量化模型服务启动脚本
适用于 Mac ARM64 原生运行
"""
import os
import argparse
from funasr_onnx import SenseVoiceSmall
import gradio as gr
from fastapi import FastAPI, File, UploadFile, Form
from fastapi.responses import JSONResponse
import uvicorn
import soundfile as sf
import numpy as np
import tempfile
# 1. 初始化模型
# 指定模型缓存路径,避免重复下载
MODEL_DIR = "/tmp/ai-models/danieldong/sensevoice-small-onnx-quant"
if not os.path.exists(MODEL_DIR):
os.makedirs(MODEL_DIR, exist_ok=True)
print(f"模型目录已创建: {MODEL_DIR}")
print("请将 model_quant.onnx 文件放置于此目录。")
else:
print(f"使用缓存模型目录: {MODEL_DIR}")
try:
# 尝试从缓存路径加载模型
model = SenseVoiceSmall(
model_dir=MODEL_DIR,
batch_size=1, # Mac上批处理大小设为1更稳定
quantize=True,
device_id=-1, # 使用CPU。对于M芯片,ONNX Runtime的CPU后端已高度优化。
)
print("✓ SenseVoice-small-onnx 模型加载成功 (ARM64原生)")
except Exception as e:
print(f"模型加载失败: {e}")
print("请确保 model_quant.onnx 文件已放置在正确路径。")
exit(1)
# 2. 定义核心转录函数
def transcribe_audio(audio_path, language="auto", use_itn=True):
"""处理单个音频文件"""
try:
results = model([audio_path], language=language, use_itn=use_itn)
if results and len(results) > 0:
return results[0]
else:
return "识别结果为空。"
except Exception as e:
return f"识别过程中出错: {str(e)}"
# 3. 创建 Gradio Web 界面
def create_gradio_interface():
def gradio_transcribe(audio_file, language):
if audio_file is None:
return "请上传音频文件。"
# Gradio上传的是临时文件路径
text = transcribe_audio(audio_file, language=language, use_itn=True)
return text
# 支持的语言列表
languages = ["auto", "zh", "yue", "en", "ja", "ko"]
interface = gr.Interface(
fn=gradio_transcribe,
inputs=[
gr.Audio(label="上传或录制音频", type="filepath"),
gr.Dropdown(choices=languages, label="选择语言", value="auto")
],
outputs=gr.Textbox(label="识别结果", lines=5),
title="SenseVoice-small-onnx 语音识别演示 (ARM64 Mac)",
description="上传音频文件,或直接录制。支持中文、粤语、英语、日语、韩语自动检测。"
)
return interface
# 4. 创建 FastAPI 应用
app = FastAPI(title="SenseVoice-small-onnx API")
@app.get("/health")
async def health_check():
return {"status": "healthy", "device": "ARM64 Mac"}
@app.post("/api/transcribe")
async def api_transcribe(
file: UploadFile = File(...),
language: str = Form("auto"),
use_itn: bool = Form(True)
):
"""API转录接口"""
# 保存上传的临时文件
suffix = os.path.splitext(file.filename)[-1]
with tempfile.NamedTemporaryFile(delete=False, suffix=suffix) as tmp:
tmp.write(await file.read())
tmp_path = tmp.name
try:
result = transcribe_audio(tmp_path, language=language, use_itn=use_itn)
return JSONResponse(content={"text": result, "language": language})
except Exception as e:
return JSONResponse(content={"error": str(e)}, status_code=500)
finally:
os.unlink(tmp_path) # 清理临时文件
# 5. 启动函数
def main():
parser = argparse.ArgumentParser()
parser.add_argument("--host", default="0.0.0.0", help="绑定主机")
parser.add_argument("--port", type=int, default=7860, help="绑定端口")
args = parser.parse_args()
# 获取Gradio界面
demo = create_gradio_interface()
# 将Gradio应用挂载到FastAPI
app = gr.mount_gradio_app(FastAPI(), demo, path="/")
print(f"\n服务启动成功!")
print(f"• Web 交互界面: http://localhost:{args.port}")
print(f"• API 文档: http://localhost:{args.port}/docs")
print(f"• 健康检查: http://localhost:{args.port}/health")
print(f"\n正在使用 ARM64 原生优化运行...")
# 启动服务器
uvicorn.run(app, host=args.host, port=args.port)
if __name__ == "__main__":
main()
粘贴完成后,按Ctrl+X,然后按Y,最后按回车保存文件。
3.6 第六步:启动服务
万事俱备,现在可以启动服务了。在终端中输入:
python3 app.py --host 0.0.0.0 --port 7860
如果一切顺利,你会看到类似下面的输出,表明模型加载成功,服务正在运行:
使用缓存模型目录: /tmp/ai-models/danieldong/sensevoice-small-onnx-quant
✓ SenseVoice-small-onnx 模型加载成功 (ARM64原生)
服务启动成功!
• Web 交互界面: http://localhost:7860
• API 文档: http://localhost:7860/docs
• 健康检查: http://localhost:7860/health
正在使用 ARM64 原生优化运行...
4. 使用与体验
服务跑起来了,我们来看看怎么用。
4.1 使用网页界面(最简单)
打开你Mac上的浏览器,访问 http://localhost:7860。
你会看到一个简洁的页面:
- 你可以点击上传按钮,选择一个本地的音频文件(支持wav, mp3, m4a等格式)。
- 或者直接点击“录制”标签,用麦克风现场说一段话。
- 在下方选择语言(默认“auto”自动检测即可)。
- 点击“提交”按钮。
稍等片刻(对于10秒的音频,大概在70-200毫秒左右),识别出的文字就会显示在下面的文本框里。你可以试试用中文、英文甚至混合语言说一段,看看它的识别效果。
4.2 通过API接口调用(适合开发者)
如果你想把识别功能集成到自己的程序里,可以使用REST API。
打开另一个终端窗口,我们可以用curl命令测试:
# 假设你当前目录有一个名为 my_audio.wav 的音频文件
curl -X POST "http://localhost:7860/api/transcribe" \
-F "file=@my_audio.wav" \
-F "language=auto" \
-F "use_itn=true"
如果成功,你会收到一个JSON响应,类似:
{"text": "你好,这是一个语音识别测试。", "language": "zh"}
API参数说明:
file: 音频文件。language: 语言代码。auto(自动检测),zh(中文),en(英语),yue(粤语),ja(日语),ko(韩语)。use_itn: 是否启用“逆文本正则化”。建议设为true,它会把“一百二十”转换成“120”,让文本更规范。
4.3 直接使用Python调用
你也可以在Python脚本中直接使用加载的模型,这样延迟最低。
创建一个新的Python文件,比如test_local.py:
from funasr_onnx import SenseVoiceSmall
# 指向你的缓存模型目录
model_dir = "/tmp/ai-models/danieldong/sensevoice-small-onnx-quant"
model = SenseVoiceSmall(model_dir, batch_size=1, quantize=True)
# 识别一个音频文件列表
audio_files = ["path/to/your/audio1.wav", "path/to/your/audio2.mp3"]
results = model(audio_files, language="auto", use_itn=True)
for i, text in enumerate(results):
print(f"音频 {audio_files[i]} 的识别结果:{text}")
5. 实际效果与注意事项
我用一段包含中英文混合的语音测试了一下,效果挺让人惊喜的。识别速度很快,几乎感觉不到延迟,准确率在日常对话场景下完全够用。粤语和日语的简单测试也都能正确识别出语种并转写。
这里有几个小提示:
- 关于模型文件:本教程的核心是教你部署流程。你需要自行获取
model_quant.onnx这个量化模型文件。通常可以在相关的模型发布页面或社区找到。 - 首次运行:如果模型目录是空的,脚本会提示你放置文件。如果模型路径正确,服务会直接加载,不会从网上下载。
- 性能:在M1/M2芯片上,由于是原生ARM64运行,并且使用了量化模型,CPU占用和内存消耗都控制得不错,风扇几乎不会狂转。
- 音频格式:尽量提供背景干净、人声清晰的音频,格式最好是16kHz或8kHz采样率的wav文件,识别效果最佳。
- 关闭服务:在启动服务的终端窗口中,按
Ctrl+C即可安全停止服务。
6. 总结
走完这一趟,你会发现,在Mac M系列芯片上部署一个实用的多语言语音识别服务,并没有想象中那么复杂。关键就在于找到了对原生ARM64支持友好的ONNX量化模型。
我们做的事情可以总结成三步:配好Python环境、放对模型文件、运行启动脚本。之后,无论是通过网页点点鼠标,还是通过API集成到你的自动化工具里,都非常方便。
这个方案最大的优点就是轻快。模型体积小,识别速度快,对硬件要求不高,特别适合在本地开发环境或者对延迟敏感的应用场景里使用。下次当你需要给项目添加“语音转文字”功能,或者只是想做个有趣的语音交互demo时,不妨试试这个方案。
获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。
更多推荐
所有评论(0)