ARTICLE DETAIL

资讯详情

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

FunASR llama.cpp/GGUF 运行时:在纯 C++ 环境中运行 Fun-ASR-Nano、SenseVoice 与 Paraformer 的完整实践

FunASR llama.cpp/GGUF 运行时:在纯 C++ 环境中运行 Fun-ASR-Nano、SenseVoice 与 Paraformer 的完整实践 FunASR llama.cpp/GGUF 运行时在纯 C 环境中运行 Fun-ASR-Nano、SenseVoice 与 Paraformer 的完整实践【免费下载链接】FunASROpen-source speech recognition toolkit for training, inference, streaming ASR, VAD, punctuation, speaker diarization pipelines, and OpenAI-compatible/MCP serving.项目地址: https://gitcode.com/GitHub_Trending/fun/FunASRruntime/llama.cpp/是 FunASR 仓库中一套面向 CPU 与边缘设备的 C 推理运行时它把 Fun-ASR-Nano、SenseVoiceSmall 和 Paraformer 三个模型移植到 llama.cpp / ggml 栈上以量化的 GGUF 权重、单个自包含二进制、无 Python 依赖的方式完成语音识别。读完本文你将掌握三种 GGUF 模型的下载与转换方式、独立与共享两种构建流程、FSMN-VAD 长音频切分与 SRT 字幕输出、CUDA/Vulkan GPU 后端的启用与排障方法以及 OpenAI 兼容的轻量 HTTP 包装服务并能理解各阶段与 PyTorch 参考实现的数值一致性验证方法。定位它与 PyTorch / ONNX / vLLM 路线的关系FunASR 的参考推理跑在 PyTorchLLM 类模型另有 vLLM 路线之上服务于 GPU 高并发场景而runtime/llama.cpp/解决的是“没有 GPU、也没有 Python”的场景笔记本、手机、树莓派、边缘盒子、嵌入式 C/C 应用。两者互补而非竞争——云端批量服务继续走 vLLM设备端/离线场景使用本运行时。DESIGN.md 中给出了两条路线的对照引自 fun-asr-nano/README.mdPyTorch / vLLM既有路线本运行时llama.cpp目标GPU 服务器、高 QPSCPU / 边缘 / 嵌入式依赖Python CUDA PyTorch无C/C 单二进制权重HF fp16/bf16 safetensorsGGUF2–8 bit 量化关键技术PagedAttention、连续批处理量化、mmap、CPU SIMD适用在线服务、批量评测离线、端侧、嵌入式支持的模型与共享架构README.md 列出了当前支持的三个模型模型架构运行时二进制验证状态Fun-ASR-NanoSenseVoice SAN-M 编码器 适配层 Qwen3-0.6B LLMllama-funasr-cli与 PyTorch 验证一致SenseVoiceSmallSAN-M 编码器 CTCllama-funasr-sensevoiceCTC token id 与 PyTorch 完全一致ParaformerSAN-M 编码器 CIF 预测器 SAN-M 解码器非自回归llama-funasr-paraformer文本与 PyTorch 完全一致三个模型共享同一套 ggml SAN-M 编码器 / FSMN / attention 原语以及同一套 kaldi 兼容的 fbank 前端80-mel、LFR 7/6因此 C 实现在模型之间是一致的。总体数据流如下引自 DESIGN.md┌─────────────────────── 共享 C / ggml ───────────────────────┐ audio.wav (16k mono) ──► kaldi 80-mel fbank LFR(7/6) ──► SAN-M 编码器 (50 层, ggml) └───────────────────────────────────────────────────────────────┘ │ encoder_out [T, 512] ┌───────────────────────────────────┼───────────────────────────────────┐ Fun-ASR-Nano SenseVoiceSmall Paraformer adaptor → 音频嵌入 4 个 query token CIF 预测器 (host C) → 注入 Qwen3-0.6B CTC 头 → 贪心 CTC → SAN-M 解码器 (cross-attn) (llama_decode embd 路径) → SentencePiece → argmax → tokens.json → 文本 → 文本 → 文本各模型的头部/解码器形态模型头 / 解码器是否自回归输出单位Fun-ASR-Nanoadaptor Qwen3-0.6B LLM是LLMQwen3 BPESenseVoiceSmallCTC否spectok BPE25055ParaformerCIF SAN-M 解码器否并行字符/BPE8404从源码结构看这一共享性对应目录布局fun-asr-nano/funasr-cli、funasr-encoder、funasr-embd与 export_encoder_gguf.py、sensevoice/、paraformer/ 三个模型目录加上 funasr-common/ 中的共享头文件funasr_audio.h音频加载、funasr_vad.h内置 VAD、funasr_srt.hSRT 输出、miniaudio.h解码器和 funasr-vad/ 独立的 FSMN-VAD 工具。工作原理ggml 图 C 前端 GGUF 权重每个模型的神经网络路径都实现为一张 ggml 图音频前端kaldi fbank是纯 C。权重通过各模型的export_*_gguf.py脚本转换为 GGUFf32 或 f16。Fun-ASR-Nano 的 LLM 一半是标准的 Qwen3 GGUF音频嵌入通过llama_decode的 embedding 输入通道注入即 llava/mtmd 机制CLI 把提示构造成[前缀 token | 音频嵌入 | 后缀 token]的混合序列前缀/后缀以 token id 喂入音频槽位以嵌入喂入。几个值得注意的实现决策详见 DESIGN.md音频前端C 的compute_fbank精确复现 FunASRWavFrontend——25 ms/10 ms hamming 窗、0.97 预加重、DC 去除、512 点 FFT、80 三角 mel 滤波器再经 LFR7 帧、步长 6堆叠为 560 维特征。与 torchaudio kaldi.fbankdither0对比 cosine 为 1.000000max_abs_diff 1.75e-3。注意 FunASR 参考前端默认dither1.0会引入随机噪声C 前端使用 dither0这是与带 dither 参考对比时出现微小 cosine 差异的来源。FSMN 用精确 f32 移位累加ggml 的ggml_conv_1d_dw要求 F16 核且上游标注“某些情况下可能出错”因此 FSMN 被实现为精确的 f32 移位累加值张量沿时间两侧零填充 (K-1)/2输出为逐 tap 的乘累加加残差。这一决策把整个编码器相对 PyTorch 的 max_abs_diff 从 2.93 降到 0.0052。SenseVoice 推理期不做 CMVNinference()直接把原始 log-mel fbank 喂给编码器应用 CMVN 反而会让模型输出|nospeech|而 Paraformer 恰恰相反必须做 CMVN(fbank shift)·scale逐维 560且am.mvn含三个方括号块[Splice idx]、[AddShiftshift]、[Rescalescale]必须按长度解析否则 CIF 会少发约 4 倍 token。CIF 预测器在 host C 中运行它是串行 integrate-and-fire 循环约 0.5 G MACs代价很低编码器与解码器则跑在 ggml 上。GGUF 布局张量名从 checkpoint 原样保留C 按名查找FSMN 核在导出时从 (D,1,K) 转置为 [K,D]--wtype f16把 2-D matmul 权重存为 F16norm/bias/FSMN 核保持 f32编码器 GGUF 约减半935 → 469 MB。各模型典型权重与体积文件模型dtype体积funasr-encoder.ggufFun-ASR-Nano 编码器adaptorf32 / f16935 / 469 MBqwen3-0.6b-q8_0.ggufFun-ASR-Nano LLMQ8_0805 MBsensevoice-small.ggufSenseVoiceSmallf32936 MBparaformer.ggufParaformerf32863 MB下载预构建 GGUF最快路径无需 Python ML 环境download-funasr-model.sh 负责从 Hugging Face 拉取已转换好的 GGUF要求安装 Hugging Face CLIpip install -U huggingface_hub脚本会自动探测hf或旧版huggingface-cli。默认只下载一个实用量化变体加 FSMN-VAD而不是仓库里的全部 GGUF./download-funasr-model.sh sensevoice # q8默认 FSMN-VAD ./download-funasr-model.sh paraformer # q8默认 FSMN-VAD ./download-funasr-model.sh nano # encoder-f16 q8_0默认 FSMN-VAD ./download-funasr-model.sh fsmn-vad # 仅 FSMN-VAD从脚本源码可见其参数规则第二个可选参数是输出目录默认funasr-gguf第三个可选参数选择变体——SenseVoice 和 Paraformer 支持q8、f16、f32、allNano 支持q8_0、q4km、q5km、all。下载 ASR 模型时会自动附带fsmn-vad.gguf内置--vad长音频切分需要它./download-funasr-model.sh sensevoice funasr-gguf f16 ./download-funasr-model.sh nano funasr-gguf q4km ./download-funasr-model.sh paraformer funasr-gguf all # 显式下载该仓库全部 GGUF如果希望自行转换权重例如从本地 checkpoint可以使用 convert-funasr-to-gguf.py 或各模型目录下的export_*_gguf.py例如 SenseVoicepython runtime/llama.cpp/sensevoice/export_sensevoice_gguf.py \ --model_pt model/model.pt --mvn model/am.mvn \ --out sensevoice-small.gguf # f32, 约 936 MB python runtime/llama.cpp/sensevoice/export_sensevoice_gguf.py --wtype f16 \ --model_pt model/model.pt --mvn model/am.mvn \ --out sensevoice-small-f16.gguf # 体积减半构建独立构建CI 友好与共享构建独立构建根 CMakeLists.txt 通过 CMake FetchContent 拉取固定版本pinned的 llama.cppcommit803b7fcae893e9caaee3921779628fef83ac0965该版本包含 Vulkan 提交批处理与 DeviceLost 诊断修复适配较新的 AMD 驱动静态链接生成自包含二进制也支持-DFETCHCONTENT_SOURCE_DIR_LLAMA/path/to/llama.cpp改用本地 llama.cpp 检出。构建产物统一落在build/bin/cmake -B build -DCMAKE_BUILD_TYPERelease # 拉取 pinned llama.cpp静态、自包含 cmake --build build -j # - build/bin/llama-funasr-*全部工具CMake 注册的 6 个目标一目了然llama-funasr-cliNano 集成 CLI、llama-funasr-encoder与llama-funasr-embdNano 编码器/嵌入路径用于验证与调试、llama-funasr-sensevoice、llama-funasr-paraformer、llama-funasr-vad。共享构建在 llama.cpp 检出中git clone https://github.com/ggml-org/llama.cpp cd llama.cpp cp -r /path/to/runtime/llama.cpp/funasr-common examples/ # 共享音频加载 (miniaudio)各 example CMake 添加 ../funasr-common cp -r /path/to/runtime/llama.cpp/model/example-dir examples/ echo add_subdirectory(example-dir) examples/CMakeLists.txt cmake -B build -DGGML_NATIVEON -DLLAMA_CURLOFF cmake --build build -j --target target共享的FSMN-VAD前端以同样方式构建funasr-vad/funasr-common/targetllama-funasr-vad权重用 export_vad_gguf.py 导出。之后给三个 ASR 工具任意一个传--vad fsmn-vad.gguf即可获得内置的长音频切分。转录示例# SenseVoiceSmall打印转录文本 build/bin/llama-funasr-sensevoice -m sensevoice-small.gguf -a audio.wav # --keep-tags 保留 |lang|/|emotion|/|event| 标签--ids 打印原始 CTC id # Paraformer非自回归单遍出全部 token build/bin/llama-funasr-paraformer -m paraformer.gguf -a audio.wav # 期望输出 # 我想问我在滨海新区有房我一直没有照顾孩子...你觉得这是正常的想法吗 # [paraformer] T742 N_tok105 enc 1.24s dec 0.48s # Fun-ASR-Nano长音频务必加 --chunk 15 build/bin/llama-funasr-cli --enc funasr-encoder.gguf -m qwen3-0.6b-q8_0.gguf -a audio.wav --chunk 15长音频注意Fun-ASR-Nano 把整段如 60 s当单窗口解码是分布外输入会导致贪心解码重复循环--chunk 15用 15 s 窗口每窗口新建 KV把 micro-CER 从约 29% 降到约 9.5%同时 CLI 自动执行“低帧率截断”只取 adaptor 输出的前fake_token_len帧作为音频 token喂全部帧会使 LLM 陷入重复。SRT 字幕输出Fun-ASR-Nano、SenseVoiceSmall 和 Paraformer 都支持--srt向 stdout 写出标准 SRT 条目。使用 FSMN-VAD 切分可获得与语音对齐的时间戳Fun-ASR-Nano 也可以对--chunk选定的固定窗口打时间戳不用切分时SenseVoiceSmall 与 Paraformer 只输出覆盖整段输入的单条目。./build/bin/llama-funasr-cli --enc encoder.gguf -m llm.gguf \ --vad fsmn-vad.gguf -a audio.wav --srt audio.srt ./build/bin/llama-funasr-sensevoice -m sensevoice-small.gguf \ --vad fsmn-vad.gguf -a audio.wav --srt audio.srt ./build/bin/llama-funasr-paraformer -m paraformer.gguf \ --vad fsmn-vad.gguf -a audio.wav --srt audio.srt进度与计时诊断保留在 stderr因此重定向 stdout 即可得到干净的字幕文件省略--srt时普通文本输出不变。内置 FSMN-VAD 与长音频--vad fsmn-vad.gguf是原生 ggml 实现的 FSMN-VAD在二进制内部完成长音频切分无需 Python 前端三个 ASR 工具均支持。音频输入经内置 miniaudio 加载器支持 wav/mp3/flac、任意采样率/通道。在 184 条标准基准集上的“裸二进制 内置 VAD” micro-CER 为SenseVoiceSmall8.01/ Paraformer9.85/ Fun-ASR-Nano8.30详见 BENCHMARKS.md--chunk固定窗口仍是更简单的兜底方案。说话人分离的能力边界需要明确独立 llama.cpp / GGUF 二进制目前不实现CAM 说话人嵌入与说话人聚类--vad只做长音频切分、不分配说话人标签。若需要带说话人的转录应使用 PythonAutoModel管线spk_modelcam参见 FunASR 快速开始或 Fun-ASR-Nano vLLM 服务serve_vllm.py接受spktrue并运行独立的说话人模型。当需求只是“自包含 ASR 可选 FSMN-VAD、不依赖 Python”时继续使用 llama.cpp 二进制。GPU 后端Windows CUDA 与 VulkanSenseVoiceSmallWindows CUDA 包CPU 版发布 ZIP 是跨平台可移植包tag 版本另发布 SenseVoiceSmall 的 CUDA 包funasr-llamacpp-windows-x64-cuda.zip面向 CUDA 架构 86funasr-llamacpp-windows-x64-cuda-blackwell.zip面向架构 120sm_120RTX 50 / Blackwell。选择匹配 GPU 的归档运行时启用后端# 从解压后的 windows-x64-cuda 包目录执行 ./llama-funasr-sensevoice \ -m sensevoice-small-q8.gguf --vad fsmn-vad.gguf -a sample.wav --backend cuda自源码构建可针对其他架构或本地复现架构 120 构建cmake -B build-cuda -DCMAKE_BUILD_TYPERelease -DGGML_CUDAON \ -DCMAKE_CUDA_ARCHITECTURES120 cmake --build build-cuda -j --target llama-funasr-sensevoice ./build-cuda/bin/llama-funasr-sensevoice \ -m sensevoice-small-f16.gguf -a sample.wav --backend cuda发布工作流的成功构建只验证了架构 120 的代码生成与 ZIP 完整性并不等同于在真实 Blackwell 硬件上验证过执行。CUDA ZIP 捆绑cublas64_13.dll与cublasLt64_13.dll附带 NVIDIA 许可证并静态链接 MSVC 运行时——运行无需单独安装 CUDA Toolkit 或 Visual C 可再发行包但仍需要与发布工作流所配置 CUDA Toolkit 版本兼容的 NVIDIA 驱动。未用-DGGML_CUDAON构建的二进制在请求--backend cuda时会给出明确报错。--backend cpu始终默认。Linux / Windows Vulkan 包tag 版本同时发布funasr-llamacpp-linux-x64-vulkan.tar.gz与funasr-llamacpp-windows-x64-vulkan.zip让 SenseVoiceSmall 走 ggml 的 Vulkan 后端适用于暴露可用 Vulkan 驱动/ICD 的 AMD、Intel、NVIDIA 或核显系统。Linux 侧# 从解压后的 linux-x64-vulkan 包目录执行 ./llama-funasr-sensevoice \ -m sensevoice-small-q8.gguf --vad fsmn-vad.gguf -a sample.wav --backend vulkan需要本地 Vulkan SDK、发行版特定驱动栈或先在发布打包前验证设备时自源码构建sudo apt-get install libvulkan-dev glslc spirv-headers vulkan-tools vulkaninfo --summary cmake -B build-vulkan -DCMAKE_BUILD_TYPERelease -DGGML_VULKANON cmake --build build-vulkan -j --target llama-funasr-sensevoice ./build-vulkan/bin/llama-funasr-sensevoice \ -m sensevoice-small-f16.gguf -a sample.wav --backend vulkanWindows 侧预构建包不要求 Vulkan SDK但需要提供可用 Vulkan loader 与设备的最新显卡驱动# 从解压后的 windows-x64-vulkan 包目录执行 vulkaninfo --summary # 可选安装了 vulkaninfo 时的驱动检查 .\llama-funasr-sensevoice.exe -m sensevoice-small-q8.gguf --vad fsmn-vad.gguf -a sample.wav --backend vulkan若提示无可用 Vulkan 设备先更新厂商 GPU 驱动该包刻意依赖驱动安装的vulkan-1.dll而非自带 SDK 副本。未用-DGGML_VULKANON构建的二进制在请求--backend vulkan时同样会明确报错。Vulkan 性能与设备可用性取决于已安装驱动/ICD而非 CUDA 计算能力。两个 Vulkan 包目前都仅加速 SenseVoiceSmall。故障诊断Vulkan 边界日志与 AMD 排障遇到 Windows 访问违例退出码-1073741819/0xC0000005时捕获 stderr 并记录最后完成的边界行——运行时 v0.2.3 会立即冲刷每条边界缺失的下一行即指明失败阶段最后完成的边界下一步排查方向无initializing vulkan backend ...设备枚举或选择initializing ...ggml_backend_dev_init()或其下驱动initialized ...; resolving buffer type默认 buffer 类型解析vulkan backend ready ...模型元数据加载[sensevoice] model ready ...音频加载或特征提取[sensevoice] audio ready ...启用--vad时为 VAD[sensevoice] VAD ready ...图构建[sensevoice] graph built图分配[sensevoice] graph allocated后端计算提交[sensevoice] compute startingVulkan 计算或 GPU 驱动[sensevoice] compute complete: status0输出搬运或 CTC 解码提 issue 时附上 GPU 型号、驱动版本、完整命令与全部 stderr。这些边界用于定位失败位置并不声称已修复某个驱动/硬件特定的访问违例。AMD Windows 排障较新的 AMD 驱动在图提交超过驱动超时时可能报VK_ERROR_DEVICE_LOST或终止进程pinned ggml 版本已减小小容量 AMD GPU 上的提交尺寸并修正批处理阈值。强制更小提交或收集最后提交的张量用于 bug 报告$env:GGML_VK_MAX_NODES_PER_SUBMIT 16 $env:GGML_VK_SERIALIZE_SUBMISSIONS 1 .\llama-funasr-sensevoice.exe -m sensevoice-small-f16.gguf --vad fsmn-vad.gguf -a sample.wav --backend vulkan若16仍触发驱动超时试8或1诊断完成后移除这些变量因为串行提交会牺牲吞吐。受影响驱动/设备组合上可靠的兜底是--backend cpu。当前 SenseVoiceSmall 图不产生 flash-attention 操作因此--no-flash-attn开关不会改变该执行路径。Windows 上从源码构建 Vulkan 需要 LunarG Vulkan SDK含glslc、Developer PowerShellVULKAN_SDK已设置以及固定 llama.cpp 版本所期望的SPIRV-HeadersCMake 包README 给出了完整 clone/checkout/构建/安装步骤后执行cmake -B build-vulkan -A x64 -DCMAKE_BUILD_TYPERelease -DGGML_VULKANON。轻量 HTTP 服务OpenAI 兼容的包装GGUF 二进制首先是命令行工具。对期望 HTTP 转录端点的本地应用server/funasr_gguf_server.py 包装一个现成二进制暴露 OpenAI 兼容的POST /v1/audio/transcriptions路由它只用 Python 标准库推理仍在 C 二进制中完成从源码看服务解析 multipart 上传后通过subprocess拼出[binary, -m, model, -a, audio]加可选--vad/--backend/ 额外参数的命令执行并返回 stdout 文本python server/funasr_gguf_server.py \ --host 127.0.0.1 --port 8000 \ --binary ./build/bin/llama-funasr-sensevoice \ --model ./gguf/sensevoice-small-q8.gguf \ --vad ./gguf/fsmn-vad.gguf调用方用与 OpenAI 兼容客户端相同的形状发送音频curl http://127.0.0.1:8000/v1/audio/transcriptions \ -F filesample.wav \ -F modelfunasr-gguf响应{text: transcribed text}启用 CUDA/Vulkan 的 SenseVoice 构建可用--backend cuda或--backend vulkan选择额外二进制参数可用重复的--extra-arg转发例如--extra-arg --keep-tags。该包装每请求启动一个子进程最适合本地工具、演示与集成测试持续生产流量应使用 Pythonfunasr-serverOpenAI 兼容服务或基于 C 运行时构建专用原生服务。数值一致性验证每个模型都对照 FunASR PyTorch 参考做了分阶段验证先用 golden dumpfbank、编码器输出、adaptor/CIF 输出、logits/ids做 cosine 与 max-abs-diff 比较再端到端比较文本 / CER方法论详见 DESIGN.md 第 7 节阶段指标kaldi fbank vs torchaudiocosine 1.000000SAN-M 编码器整体vs PyTorchcosine 1.000000max_abs_diff 5e-3f32SenseVoice CTC token id完全一致108/108Paraformer 文本 / token 数完全一致 / 105 105Fun-ASR-Nano 端到端 CER相同条件C 11.68% vs PyTorch 11.70%Δ0.02%为什么不做逐 token 位级一致贪心解码具有混沌性——约 5e-3 的差异来自 ggml-CPU 与 torch 的 matmul 求和顺序不同即可在临界帧翻转 token长序列上路径随之发散这在 PyTorch 自己的 GPU 与 CPU 之间同样会发生。真正被验证的是 (a) 逐张量数值cosine 1.0与 (b) 相同条件下的聚合 CER。另注意 fp16 风险Fun-ASR-Nano adaptor 输出幅值大std ≈ 28|max| ≈ 1187音频路径保持 f32 激活权重可用 f16。仓库内还有回归测试兜底tests/ 用固定音频sample.wav约 6 s跑每个工具并与golden/下冻结输出做 diff覆盖 ggml 图、FSMN-VAD 状态机、CIF 预测器与 CTC 解码的回归./tests/run_regression.sh # VAD小模型自动获取 本地已有 GGUF 的工具 RUN_FULL1 ./tests/run_regression.sh # 另从 Hugging Face 下载 ASR GGUF测试全部工具目录导航与延伸阅读runtime/llama.cpp/README.md本运行时的总览本文主体来源runtime/llama.cpp/DESIGN.md完整系统设计——架构、共享 SAN-M 编码器、GGUF 权重格式、数值保真与验证方法、设计权衡与坑runtime/llama.cpp/sensevoice/README.md、runtime/llama.cpp/paraformer/README.md、runtime/llama.cpp/fun-asr-nano/README.md各模型的架构图、构建/转换/运行快速上手、验证数据与注意事项runtime/llama.cpp/BENCHMARKS.md与 whisper.cpp 的中文 CPU 基准对比及方法论runtime/llama.cpp/tests/README.mdgolden 回归测试runtime/llama.cpp/server/funasr_gguf_server.pyOpenAI 兼容 HTTP 包装当前发布记录见 current-release.txt适用前提小结本运行时面向 16 kHz 单声道音频miniaudio 加载器已支持 wav/mp3/flac 与任意采样率/通道--backend cpu为默认且是可移植预构建二进制的形态GPU 加速CUDA/Vulkan目前仅覆盖 SenseVoiceSmall说话人分离需回到 Python 管线。整套runtime/llama.cpp/为新增目录不修改 FunASR 既有代码。【免费下载链接】FunASROpen-source speech recognition toolkit for training, inference, streaming ASR, VAD, punctuation, speaker diarization pipelines, and OpenAI-compatible/MCP serving.项目地址: https://gitcode.com/GitHub_Trending/fun/FunASR创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表