ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

SenseVoiceSmall 的 llama.cpp/GGUF 端侧运行时:CPU 与边缘设备上的离线 ASR 部署全指南

SenseVoiceSmall 的 llama.cpp/GGUF 端侧运行时:CPU 与边缘设备上的离线 ASR 部署全指南 人工智能大模型语音音频微调本地部署【免费下载链接】SenseVoiceOpen-source SenseVoiceSmall model for Mandarin, Cantonese, English, Japanese, and Korean ASR, language ID, emotion recognition, and audio event detection.项目地址https://gitcode.com/gh_mirrors/se/SenseVoice点击查看免费下载导读本文以 runtime/llama.cpp/README.md 为核心系统讲解如何在 llama.cpp/ggml 技术栈上运行SenseVoiceSmall——即把原本依赖 PyTorch/ONNX/libtorch 的 SAN-M 编码器 CTC 解码模型移植为单二进制、纯 C、CPU-only、离线可用、支持量化权重的 GGUF 运行时。读完本文你将掌握从权重导出、模型下载、编译构建到长音频 VAD 切分、精度验证与参数调优的完整部署链路并能直接复现该运行时给出的全部命令行与验证数据。一、为什么需要这个运行时SenseVoiceSmall 官方推理路径基于 PyTorch / ONNX / libtorch适合 GPU 服务器上的高并发批处理。但它在没有 GPU、没有 Python 环境的场景笔记本、手机、树莓派、嵌入式 C/C 应用、离线桌面程序并不适用。llama.cpp / ggml 恰好是这类场景的事实标准运行时Ollama、LM Studio、whisper.cpp 均构建于其上。本运行时把 SenseVoiceSmall 移植到ggml GGUF从而获得CPU-only、完全离线推理不依赖任何云服务与 Python 环境单文件自包含二进制静态链接可直接嵌入 C/C 应用量化权重通过 GGUF 格式支持 f16 / q8_0 等量化显著降低体积与内存占用与 llama.cpp 生态互通能跑在 llama.cpp 支持的任意平台上。如 DESIGN.md 中对比表所示PyTorch/vLLM 路径与本运行时是互补而非竞争的关系云端高 QPS 服务继续走 vLLM本运行时覆盖端侧、离线、嵌入式场景。二、架构总览SAN-M 编码器 CTC 头SenseVoiceSmall 的模型结构是SAN-M 编码器70 层 CTC 头不含 LLM、无自回归。整个推理管线全部在 C 中完成audio.wav (16k mono) │ kaldi 80-mel fbank LFR (C) ▼ features [T, 560] │ prepend 4 query tokens [lang, event, emotion, itn] ▼ [4 T, 560] │ SAN-M encoder (ggml) ── sensevoice-small.gguf ▼ encoder out [4T, 512] │ CTC head (Linear 512→25055) → greedy CTC (argmax, dedup, drop blank) ▼ token ids │ SentencePiece detok (detok.py) ▼ |zh||NEUTRAL||Speech||woitn| transcription...从 funasr-sensevoice/funasr-sensevoice.cpp 的源码可以看到70 层编码器由三部分构成encoder.encoders0.01 层无残差encoder.encoders.0..4849 层encoder.tp_encoders.0..1920 层中间穿插encoder.after_norm与encoder.tp_norm两个 LayerNorm。最终由ctc.ctc_lo线性层输出[25055, N]的 logits再执行贪心 CTC 解码逐帧 argmax → 相邻重复折叠 → 丢弃 blankid0。值得强调的是SAN-M 编码器与Fun-ASR-Nano使用完全相同的架构因此 ggml 前向计算在两者之间是共享的详见 DESIGN.md 的系统总览。2.1 音频前端kaldi 80-mel fbank LFR所有 FunASR 模型共用WavFrontend前端C 版compute_fbank见 funasr-sensevoice.cpp精确复刻其流程波形放大 32768 倍FunASR 以 int16 量程送入 kaldi逐帧处理去 DC 偏移 → 预加重系数 0.97→ 汉明窗25 ms / 10 ms即 400 点窗长 / 160 点步进→ 零填充到 512 点512 点基 2 FFT → 功率谱 → 80 个三角 mel 滤波器kaldi mel 刻度1127·ln(1f/700)低频 20 Hz高频 8000 Hz→ 取对数下限FLT_EPSILON低帧率LFR帧 0 左补 3 份副本按 7 帧堆叠、步进 6m7, n6输出560 维特征。关键常数在源码中直接可查FS16000, WINLEN400, SHIFT160, NFFT512, NMEL80, LFR_M7, LFR_N6, PREEMPH0.97。验证数据与 torchaudio 的kaldi.fbankdither0对比余弦相似度 1.000000最大绝对差 1.75e-3见 DESIGN.md。Gotcha —— dither 抖动FunASR 前端默认dither1.0即每个采样点叠加随机噪声因此参考实现的 fbank 及下游结果本质上是非确定性的。C 前端采用 dither0确定性模型对此足够鲁棒这也解释了与带抖动参考对比时出现的小于 1% 的余弦差距。2.2 SAN-M 编码器的 ggml 实现要点SAN-M 编码器每个 block 为 pre-norm 结构x → LN → SAN-M 自注意力 → residual → LN → FFN(relu) → residual。其中 SAN-M 自注意力 标准多头注意力 并行运行在 value 投影上的FSMN 记忆分支二者相加作为注意力输出。ggml 图中的实现sanm_attn一次融合投影linear_q_k_v得到 q/k/vFSMN 分支与 QK 注意力并行最后linear_out输出并叠加 FSMN 结果。三个必须精确匹配的编码器“怪癖”位置编码从 1 开始而非 0深度 输入特征维 560输入在编码前需乘以√(d_model) √512预缩放LayerNorm eps 1e-5全局统一。FSMN 的 f32 shift-accumulate 实现关键设计决策FSMN 本质是时间维上的逐通道depthwise一维卷积核大小 11。ggml 虽有ggml_conv_1d_dw但它a要求核为 F16b上游标记为“某些场景很可能有误”两者都不满足忠实移植的要求。因此本运行时将 FSMN 实现为精确 f32 shift-accumulate导出时把核转置为[K, D](D,1,K) → (K,D)见 export_sensevoice_gguf.pyvalue 张量在时间维两侧各零填充(K-1)/2输出为Σ_j kernel[:,j] ⊙ pad(v)[:, tj]加上残差——即 11 次逐元素乘加f32 下精确无误。这一决策把全编码器相对 PyTorch 的最大绝对差从 2.93 降到0.0052见 DESIGN.md §4.1。三、最快路径下载预构建 GGUF无需任何 Python ML 环境一条命令拉取预转换的 GGUF./download-funasr-model.sh sensevoice # pulls SenseVoice fsmn-vad GGUF from Hugging Face llama-funasr-sensevoice -m funasr-gguf/sensevoice-small-f16.gguf \ -a audio.wav --vad funasr-gguf/fsmn-vad.gguf脚本 download-funasr-model.sh 支持四种模型键sensevoice、paraformer、nano、fsmn-vad默认输出目录funasr-gguf/可用第二个参数指定。ASR 模型下载时会自动附带拉取fsmn-vad.gguf内置--vad长音频切分所需。脚本内部优先使用新的hfCLI缺失时回退到已弃用的huggingface-cli两者都没有则提示pip install -U huggingface_hub。预转换 GGUF 存放于 FunAudioLLM 的SenseVoiceSmall-GGUF与fsmn-vad-GGUF仓库。也可以自行转换python convert-funasr-to-gguf.py sensevoice --wtype f16convert-funasr-to-gguf.py 是一站式转换器自动从 Hugging Face 或 ModelScope 下载 checkpoint--src modelscope切换再调用对应的export_*.py完成导出无需手动两步操作对应 whisper.cpp 的convert流程。四、构建独立 CMakeCI 友好cmake -B build -DCMAKE_BUILD_TYPERelease # fetches pinned llama.cpp; static, self-contained cmake --build build -j # - build/bin/llama-funasr-*CMakeLists.txt 通过FetchContent拉取固定版本的 llama.cppGIT_TAG 锁定具体 commit关闭其 tests/examples/tools/server 构建静态链接出build/bin/下的三个二进制llama-funasr-sensevoice、llama-funasr-vad与sensevoice-server。Linux / macOS / Windows、x64 / arm64 均支持如需针对本地 llama.cpp 检出构建可传-DFETCHCONTENT_SOURCE_DIR_LLAMA/path/to/llama.cpp。4.1 手动嵌入 llama.cpp examplesQuickstart如果希望像 whisper.cpp 那样把示例源码直接并入 llama.cpp 仓库构建则按如下步骤对应 README.md 的 Quickstart 节git clone https://github.com/ggml-org/llama.cpp cd llama.cpp cp -r /path/to/runtime/llama.cpp/funasr-common examples/ # shared audio loader (miniaudio); each example CMake adds ../funasr-common cp -r /path/to/runtime/llama.cpp/funasr-sensevoice examples/ echo add_subdirectory(funasr-sensevoice) examples/CMakeLists.txt cmake -B build -DGGML_NATIVEON -DLLAMA_CURLOFF cmake --build build -j --target llama-funasr-sensevoice两种构建方式的产出等价llama-funasr-sensevoice可执行文件。五、权重转换export_sensevoice_gguf.py 详解如果不用预构建 GGUF可用导出脚本自行转换 checkpoint需要标准 FunASR checkpointmodel.ptam.mvn如FunAudioLLM/SenseVoiceSmallpython runtime/llama.cpp/export_sensevoice_gguf.py \ --model_pt model/model.pt --mvn model/am.mvn \ --out sensevoice-small.gguf # f32, ~936 MB python runtime/llama.cpp/export_sensevoice_gguf.py --wtype f16 \ --model_pt model/model.pt --mvn model/am.mvn \ --out sensevoice-small-f16.gguf # half size脚本 export_sensevoice_gguf.py 的命令行参数如下参数必填说明--model_pt是SenseVoice checkpoint 路径model.pt自动剥离state_dict包装--mvn是am.mvnkaldi nnet 格式含 shift/scale 两个 560 维块--out是输出 GGUF 路径--wtype否权重类型f32默认/f16/q8_0--spm否SentencePiece.bpe.model路径默认在model_pt同目录下自动查找--model-spec否可选 audio.cpp schema-v1 模型规格 JSON用于嵌入到 GGUF脚本写入的 GGUF 元数据源码 export_sensevoice_gguf.py 中可查包括sv.input_size560、sv.output_size512、sv.attention_heads4、sv.num_blocks50、sv.tp_blocks20、sv.kernel_size11、sv.vocab_size25055、sv.blank_id0以及sv.query_tokens[0,1,2,14]和可选的sv.vocab全部 25055 个 SentencePiece piece 直接嵌入 GGUF。几点实现细节张量名保持与 checkpoint 一致如encoder.encoders.3.norm1.weightC 端按名查表故无需重命名映射FSMN 核转置(D,1,K) → (K,D)使 C 的 shift-accumulate 能按 tap 取连续的[D]向量am.mvn解析为cmvn.shift/cmvn.scale两个 560 维张量SenseVoice 运行时实际不使用见下文 Gotcha量化策略--wtype f16只把 2-D matmul 权重存为 F16norm/bias/FSMN 核保持 f32GGUF 体积约减半935 → 469 MB余弦相似度仍达 0.999999--wtype q8_0对 2-D 权重排除 norm、fsmn_block、embed.weight且列数须为 32 的倍数执行 Q8_0 量化找不到*.bpe.model时打印警告GGUF 不带 vocab二进制自动回退为输出原始 id。5.1 面向 audio.cpp 的 spec 导出若要让导出的 GGUF 可被 audio.cpp 的 spec-backed 运行时直接加载导出时需嵌入sense_asrschema-v1 模型规格python runtime/llama.cpp/export_sensevoice_gguf.py --wtype q8_0 \ --model_pt model/model.pt --mvn model/am.mvn \ --model-spec model_specs/sense_asr.json \ --out sensevoice-small-q8-audiocpp-v1.gguf脚本会校验 spec 的schema_version 1与family sense_asr否则报错退出成功后以audiocpp.model_spec.version/family/json键嵌入 GGUF。六、转写CLI 使用与输出格式build/bin/llama-funasr-sensevoice -m sensevoice-small.gguf -a audio.wav # prints transcription text # --keep-tags keeps the |lang|/|emotion|/|event| tags; --ids prints raw CTC ids完整命令行见 funasr-sensevoice.cpp参数说明-m ggufSenseVoice GGUF必填-a wav或-f fbank.bin输入 WAV16k mono或预计算的 fbank 二进制T x 560f32--vad ggufFSMN-VAD GGUF开启内置长音频切分--vad-maxseg ms单个 VAD 段上限默认 30000--ids输出原始贪心 CTC token id空格分隔--keep-tags保留|lang|/|emotion|/|event|元标签预期输出示例我想问我在滨海新区有房我一直没有照顾孩子...你觉得这是正常的想法吗开头的|...|标签即模型预测的语言 / 情绪 / 音频事件 / ITN 归一化信息——SenseVoice 的独特能力单模型同时输出ASR 文本 语种识别language ID 情感识别 音频事件检测。解码流程源码 funasr-sensevoice.cppCTC logits 逐帧 argmax → 与前一帧相同则折叠 → 丢弃 blank(0) → 得到 id 序列。GGUF 内嵌 vocab 时走 C 端 detokdetok_sv跳过|...|元标签、▁(U2581) 转空格、收尾去空白否则回退输出原始 id可再用 Python 侧 detok.py 解码python detok.py bpe.model ids.txt七、长音频内置 FSMN-VAD无需 Python 前端SenseVoice 推理一个长片段属于分布外场景效果显著退化正确做法是 VAD 切段后逐段解码再拼接。本运行时把FSMN-VAD 原生跑在 ggml 内二进制自身即可完成切分python runtime/llama.cpp/export_vad_gguf.py \ --model_pt fsmn-vad/model.pt --mvn fsmn-vad/am.mvn --out fsmn-vad.gguf build/bin/llama-funasr-sensevoice -m sensevoice-small.gguf -a long.wav \ --vad fsmn-vad.gguf # segments internally, then concatenatesexport_vad_gguf.py 导出 FSMN-VAD 编码器 CMVN400 维到 GGUF写入vad.input_dim400、vad.proj_dim128、vad.fsmn_layers4、vad.lorder20、vad.output_dim248、vad.lfr_m5、vad.lfr_n1等元数据FSMNconv_left核同样从(C,1,lorder,1)转置为(lorder,C)tap-major 布局。单头文件 funasr-common/funasr_vad.h 实现了完整流程80-mel fbankLFR m5n1输出 400 维→ CMVN 归一化 → 4 层 FSMN 编码器softmax 输出 248 维概率→ 宿主机上的E2EVadModel 状态机窗口 20 帧、sil_to_speech 阈值 15、speech_to_sil 阈值 15、100 ms 前瞻、DEFAULT_SILENCE_SCHEDULE静音调度按 60 s chunk 边界步进。该状态机与 PyTorchfsmn-vad.generate在 184 条测试集上逐帧对齐误差 ≤ 1 帧即 10 ms。切分边界与 PyTorchfsmn-vad前端一致性误差在~10 ms 以内完整 184 条基准数据见 BENCHMARKS.md。此时整个运行时不再需要任何 Python 做切分——VAD 与 ASR 都在单二进制内完成。八、精度与验证本运行时的移植是逐阶段对照 PyTorch 参考验证的golden dump 对比余弦相似度 / 最大绝对差再端到端对比文本 / CER关键结论README.md 与 DESIGN.mdCTC token idC与 PyTorch 完全一致基准片段上 108/108去分词文本与 FunASRAutoModel输出逐字一致编码器对照 PyTorch与 Fun-ASR-Nano 运行时共享余弦相似度 1.0f32最大绝对差 5.2e-3fbank 对照 torchaudio余弦 1.000000最大绝对差 1.75e-344 秒片段编码耗时约 1.3 sCPU8 线程。BENCHMARKS.md 给出了在 184 条真实中文语音基准上的 CPU 对比micro-CERnormalize_zh8 线程SenseVoiceSmall 参考7.81fp32/8.17Q8 运行时速度约20× 实时f16 权重449 MB内置 FSMN-VAD 后裸二进制全 184 条达到8.01 %且整段无 VAD 时为 9.99 %印证了 VAD 对长音频的必要性。同表 whisper.cpp base / small / large-v3-turbo 分别为 31.33 / 22.12 / 23.15。为什么不做逐 token 位精确贪心解码是混沌的——约 5e-3 的数值差ggml-CPU 与 torch-GPU 的 matmul 求和顺序不同就可能在边界帧翻转 token长序列上路径随之发散这种情况在 PyTorch 自身 GPU 与 CPU 之间同样发生。忠实且可验证的是a逐张量数值余弦 1.0与b聚合 CER 在同条件下与参考一致。九、Tips Gotchas易踩的坑推理时不做 CMVN。SenseVoice 的inference()把原始log-mel fbank 直接送入编码器并不应用am.mvn一旦应用 CMVN模型会预测|nospeech|。导出脚本读取am.mvn只是完整性考虑运行时并不使用它源码 funasr-sensevoice.cpp 有明确注释。注意这与 Paraformer 相反——Paraformer必须应用 CMVN。4 个 query token取自embed.weight默认索引[languageauto(0), event1, emotion2, textnormwoitn(15)]。修改可固定语种或开启 ITN 数字归一化withitn14即use_itnTrue以对齐官方基准口径。它们在编码器√512缩放与位置编码之前拼接到输入头部。WAV 输入假定16 kHz 单声道 PCM16任意采样率 / 声道数需要先经 miniaudio 重采样到 16k mono。LayerNorm eps 1e-5全局统一FSMN 采用精确 f32 shift-accumulate见 §2.2fbank 与 torchaudio 数值一致。十、文件清单runtime/llama.cpp/ funasr-sensevoice/ ggml runtime: WAV → CTC token ids export_sensevoice_gguf.py export encoder CTC head query embeddings to GGUF detok.py SentencePiece id → text (bpe model ships with the checkpoint) funasr-vad/ built-in FSMN-VAD tool --vad library (funasr-common/funasr_vad.h) export_vad_gguf.py export FSMN-VAD encoder CMVN to GGUF download-funasr-model.sh one-command download of pre-converted GGUFs convert-funasr-to-gguf.py one-step checkpoint → GGUF (HF / ModelScope 双源) DESIGN.md 完整系统设计架构、GGUF 权重格式、数值保真与验证方法论、设计权衡与 gotchas BENCHMARKS.md CPU 基准与 whisper.cpp 的 CER/RTF/体积对比与复现方法 tests/ golden 回归测试见下十一、配套能力回归测试与 OpenAI 兼容 STT 服务11.1 回归测试tests/README.md 描述了 golden 回归机制对固定片段sample.wav约 6 秒运行各工具并与冻结的 golden 输出tests/golden/对比用于捕获 ggml 图、FSMN-VAD 状态机、CTC 解码的回归# from runtime/llama.cpp/, after building (cmake --build build): ./tests/run_regression.sh # VAD (tiny model auto-fetched) any tool whose GGUF is already local RUN_FULL1 ./tests/run_regression.sh # also download the ASR GGUFs and test every toolGolden 在 Linux x86-64参考平台上以公开发布的 f16 GGUF 采集任何更新都需经过评审。11.2 sensevoice-serverOpenAI 兼容 STT 服务同一构建体系还会产出 sensevoice-server——一个单二进制、CPU-only、无运行时 Python的 OpenAI 兼容 STT 服务提供两类接口RESTPOST /v1/audio/transcriptions任意 miniaudio 可解码的音频 → 16k mono支持json/text/verbose_json/srt/vtt/ SSE 流式Realtime WebSocket/v1/realtime?intenttranscriptionbase64 PCM16 分块流式输入返回增量 partial 与 VAD 断句后的 final 转录OpenAI realtime transcription 协议。启动示例sensevoice-server -m model/sensevoice-small-q8.gguf -vad model/fsmn-vad.gguf \ --web runtime/llama.cpp/sensevoice-server/webui # open http://127.0.0.1:8040/关键参数-ngl N可将整模型 offload 到 CUDA GPU需-DGGML_CUDAON构建无设备时回退 CPUfbank 与 VAD 恒在 CPU--partial-msWS partial 节奏默认 400--vad-slot-ms空闲槽位默认 2000防止静音会话空转 CPU--max-connections默认 4范围 1–128--max-audio-seconds默认 300范围 1–3600。测试端到端冒烟可用MODEL_GGUFmodel/sensevoice-small-q8.gguf VAD_GGUFmodel/fsmn-vad.gguf \ runtime/llama.cpp/tests/run_server_smoke.sh十二、Roadmap已知限制与规划README 明确列出的后续方向内置 SentencePiece detok去掉 Python 步骤任意 WAV 格式支持编码器 Q8 量化时间戳输出。DESIGN.md 进一步补充单文件打包 GGUF编码器 适配器 LLM 合一、一键转换器、流式、Paraformer CIF 峰值对齐的时间戳、以及将运行时以 whisper.cpp 风格工具上游到 ggml-org/llama.cpp 的独立路线。部署建议速查追求最快上手用./download-funasr-model.sh sensevoice拉取 f16 GGUF追求最小体积用--wtype q8_0导出处理长音频务必配--vad fsmn-vad.gguf需要服务化直接用sensevoice-server。更多架构细节与设计权衡请阅读 DESIGN.mdCPU 基准与复现方法见 BENCHMARKS.md。赞分享人工智能大模型语音音频微调本地部署【免费下载链接】SenseVoiceOpen-source SenseVoiceSmall model for Mandarin, Cantonese, English, Japanese, and Korean ASR, language ID, emotion recognition, and audio event detection.项目地址https://gitcode.com/gh_mirrors/se/SenseVoice点击查看免费下载相关推荐MiniCPM5 系列 llama.cpp GGUF 端侧部署实战指南CPU / 边缘设备 / 消费级 GPU 推理MiniCPM5 系列 llama.cpp GGUF 端侧部署实战指南CPU / 边缘设备 / 消费级 GPU 推理 MiniCPM5 1B 与 MiniCP大模型本地部署模型量化微调LoRA工具调用openBMBAscendMiniCPM5-1B 本地部署实战基于 llama.cpp 与 GGUF 在 CPU / 消费级 GPU / 边缘设备上运行MiniCPM5 1B 本地部署实战基于 llama.cpp 与 GGUF 在 CPU / 消费级 GPU / 边缘设备上运行 导读 本文以 MiniCPM人工智能大模型基础模型本地部署微调模型量化openBMBMiniCPM5-1B 部署实战使用 llama.cpp 与 GGUF 在 CPU / 边缘设备 / 消费级 GPU 上本地运行MiniCPM5 1B 部署实战使用 llama.cpp 与 GGUF 在 CPU / 边缘设备 / 消费级 GPU 上本地运行 本篇指南聚焦于在纯 CPU、人工智能大模型基础模型本地部署微调模型量化openBMB上一篇OpenDesign 设计系统 2.0 溯源证据体系以 Notion 包的 source 证据目录与 TOKEN_SCHEMA 契约为核心下一篇终极指南如何用RevokeMsgPatcher实现微信QQ防撤回与多开功能创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表