
FunASR Python SDK 实战AutoModel 构建、推理、VAD 流水线与流式 Cache 生命周期全解析【免费下载链接】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本文以 FunASR 开源语音识别工具包当前仓库的funasr.AutoModel为绝对主线系统讲解进程内模型构建与推理的完整契约构建参数与单次推理参数的语义边界、本地文件批处理、VAD标点说话人流水线、模型特有的语言/热词/时间戳控制、流式 Cache 生命周期以及版本复现与离线使用的注意事项。读完本文你将能独立基于AutoModel编写可复用的推理脚本并准确判断哪些能力属于 SDK、哪些属于服务端避免把两者混用。from funasr import AutoModel在当前 Python 进程内直接运行模型它不是 HTTP 客户端也不实现完整的 OpenAI API。本文描述的是当前代码版本以仓库内 auto_model.py 等源码为准的实现不代表所有历史 FunASR 版本或上游 checkpoint 的行为。若你只需要 Fun-ASR-Nano 的原生推理可改用 Transformers 5.17.0 快速开始它加载独立的-hf权重、不依赖 FunASR 工具库本页的依赖、参数与输出契约与其不可混用。模型构建与推理调用两个阶段两套参数构建阶段与推理阶段的分工AutoModel(**kwargs)负责解析模型配置 → 通过注册表register.py查找已注册的实现 → 加载权重 → 按需构建 VAD、标点、说话人三个子模型。而model.generate(input, input_lenNone, progress_callbackNone, **cfg)只负责用已经加载好的组件执行推理。因此有一条重要边界在generate()中传入新的model、vad_model或device不是重新构建或迁移流水线的受支持方式——需要另建一个实例。包装层接收**kwargs但并不存在覆盖所有模型的统一参数校验参数能传进去不等于所选模型会使用它同时模型仓库中的config.yaml配置可能覆盖下表中的代码回退默认值。建议结合以下源码阅读本节AutoModel 源码、注册表、模型下载与解析、别名映射。构建参数一览参数代码回退默认值含义model必填模型平台别名、完整模型 ID 或完整本地模型目录。别名依赖平台不是版本锁定。hubmsms/modelscope或hf/huggingface。特殊的openai分支用于 Whisper 加载不代表 HTTP API 兼容性。model_revision平台加载器中为masterModelScope 会向下载器转发此版本。通用 Hugging Face 下载助手当前会忽略它详见版本复现与离线使用。devicecuda例如cuda:0或cpu。经检查不可用的加速后端会回退到 CPU显式ngpu0也会如此并设置batch_size1。ngpu1设为零选择 CPU。它不是多 GPU 服务或模型分片配置。ncpu4正整数 CPU 线程数非法值使用回退值小于 1 的值限制为 1。修改进程级 PyTorch 线程数。vad_model,punc_model,spk_modelNone可选组件在构建时加载。正确名称是vad_model拼错为vda_model会被拒绝。vad_kwargs,punc_kwargs,spk_kwargs{}子组件配置字典。设备继承主模型平台和 CPU 线程数在子字典未指定时继承。vad_model_revision,punc_model_revision,spk_model_revision各自为master分别指定子组件版本不继承 ASR 版本。这些顶层参数会覆盖子字典中的model_revision。spk_modepunc_segment使用punc_segment或vad_segment。校验还接受历史值default但后续句子构造分支未实现它请勿选择。disable_updateFalse仅禁用 FunASR 包版本检查不会禁用模型下载。disable_pbarFalse隐藏包装层进度条。trust_remote_code平台加载器中为False允许模型附带的依赖安装及代码路径启用前检查实际文件和依赖。源码佐证AutoModel.__init__中会显式拒绝vda_model拼写错误TypeError并在构建 VAD/标点/说话人子模型时把顶层device、ncpu默认 4、hub继承进子字典同时用顶层的xxx_model_revision默认master覆盖子字典中的model_revisionauto_model.py。设备回退逻辑位于build_model当cuda/xpu/mps/npu后端不可用或ngpu0时强制回退 CPU 并设置batch_size1随后_resolve_ncpu保证线程数为不小于 1 的整数并通过torch.set_num_threads生效auto_model.py。build_model还完成了从 hub 下载/解析配置、构建 tokenizer 与 frontend、通过tables.model_classes查表实例化模型、加载init_param、按fp16/bf16切换精度并model.eval()的完整链路auto_model.py。单次推理参数一览参数代码回退默认值作用范围与限制input必填音频路径、URL、波形、受支持的音频 bytes或输入列表。标点等文本模型接收文本。input_lenNone直接推理包装层仅对单条data_typefbank输入将它转发为data_lengths不是统一的波形长度控制参数。progress_callbackNone直接推理每批结束后调用callback(current, total)。VAD 流程可能向子组件调用转发它因此不能当作整个流水线单调递增的全局进度。batch_size1直接推理每批输入数量。是否支持批量取决于模型。batch_size_s300VAD 路径的秒级批处理预算按最长补齐片段长度乘以片段数量估算不是文件时长硬上限。CPU 的 VAD 路径按单片段处理。batch_size_threshold_s60VAD 片段参与组批的时长阈值不是 VAD 切分参数。merge_vadFalse为本次调用启用 VAD 区域合并。merge_length_s15VAD 合并目标在本次参数合并进 ASR 配置之前读取。当前代码版本应在构建时设置它。cache包装层不维护会话每次流式调用都传入调用方持有的字典。它不是模型下载缓存。sentence_timestampFalse请求 VAD 流程输出句子记录依赖实际时间戳与标点部分情形可回退到 VAD 区域。return_spk_resTrue配置 VAD 与说话人模型时输出聚类结果。设为False并不能省去模型构建或片段说话人特征计算。preset_spk_numNone向聚类后端提供可选的说话人数提示。return_spk_centerFalse聚类运行时增加spk_embedding_center。数组类型输出在 JSON 序列化前可能需要转换。return_raw_textFalse在实际应用标点的路径上保留标点前文本不保证所有路径都返回该字段。源码佐证generate()入口会先调用_reset_runtime_configs()恢复构建时保存的基线配置再根据是否配置vad_model分别路由到inference()单条直接推理或inference_with_vad()长音频分段流水线最后统一经过apply_postprocess_hotwords_to_results做文本级热词后处理auto_model.py。_reset_runtime_configs通过_base_kwargs_map快照把每个*_kwargs字典恢复为构建时的深拷贝auto_model.py。务必记住两条使用纪律generate()在合并本次选项前会恢复构建时保存的配置。每次调用都应明确传入本次需要的语言、批处理、热词等选项不要依赖上一次调用遗留的值。配置重置不代表线程安全也不重置每个模型属性——例如说话人模式回退会修改self.spk_mode。除非自行验证过并发行为否则应串行访问共享实例。在inference_with_vad中配置了spk_model且本次调用未显式给出时间戳开关时包装层会自动打开output_timestamp与return_time_stampsauto_model.py因为说话人聚类依赖时间戳。本地文件与批处理从单条到清单先按安装指南 安装 SDK。下面三个示例都是带命令行参数的独立脚本需要提前准备完整本地模型快照和真实音频仓库测试仅在不下载权重的条件下检查语法与包装层契约不宣称完成了真实模型推理测试你自己运行时请同样意识到这一点。示例一本地 ASR 目录 批量音频第一个示例依次接收本地 ASR 模型目录和一个或多个音频路径例如python transcribe.py /models/paraformer recording.wav recording2.wav。路径不存在时会在模型构建前失败resolve(strictTrue)is_dir()校验。import argparse from pathlib import Path from funasr import AutoModel parser argparse.ArgumentParser() parser.add_argument(model_dir) parser.add_argument(audio, nargs) args parser.parse_args() model_dir Path(args.model_dir).expanduser().resolve(strictTrue) if not model_dir.is_dir(): raise ValueError(model_dir must be a complete local model directory) audio [str(Path(path).expanduser().resolve(strictTrue)) for path in args.audio] model AutoModel(modelstr(model_dir), devicecpu, disable_updateTrue) results model.generate(inputaudio, batch_size1) for result in results: print(result.get(key), result.get(text, ))几个容易被误用的点batch_size1在直接推理路径中逐条处理列表只有确认模型支持批量并测量过内存占用后再增大它。batch_size_s含义不同只控制包装层的 VAD 路径。VAD 切分不是麦克风增量流式识别也不保证无限录音长度或固定的总内存占用。波形应为采样率已知的一维单声道 float32 数组。使用通用音频加载器的模型在generate()中通过fs指定数组的原始采样率回退值为 16000目标采样率由模型前端决定。不要把立体声矩阵或数字列表默认当作单条波形——Python 列表通常被解释为多条输入。文件解码能力取决于已安装的音频后端。顶层 bytes 由load_bytes处理识别出的容器格式会被解码并重采样为 16 kHz否则按没有采样率元数据的 int16 PCM 解释。输入格式有歧义时优先使用解码后的数组并明确采样率。参见音频加载代码 和 bytes 输入测试。不要向不可信调用方直接开放任意路径或 URL 输入。清单文件与输入迭代器prepare_data_iteratorauto_model.py还接受清单文件.scp的一行可以是utterance_id /path/to/audio.wav以空白切分首列为 key其余为数据只有单列时自动生成rand_key_随机 key.jsonl使用{source: /path/to/audio.wav, key: utterance_id}.txt/.text按文本行处理字符串 URL 会被download_from_url拉取后再走本地逻辑。注意该迭代器不会把.json文件当作任意 JSON 数组解析.json不在filelist [.scp, .txt, .json, .jsonl, .text]之外的特殊分支中。key字段通常取文件名主干extract_filename_without_extension否则生成 13 位随机字符串 key不保证全局唯一。VAD、时间戳与说话人四模型组合流水线下面示例依次接收ASR、VAD、标点、说话人模型目录最后是音频路径。它面向兼容的本地 Paraformer/SeACo-Paraformer、FSMN-VAD、CT-Transformer 标点与 CAM 组合不适用于任意模型组合。import argparse from pathlib import Path from funasr import AutoModel parser argparse.ArgumentParser() for name in (asr_dir, vad_dir, punc_dir, spk_dir, audio): parser.add_argument(name) args parser.parse_args() paths {name: Path(value).expanduser().resolve(strictTrue) for name, value in vars(args).items()} if not all(paths[name].is_dir() for name in (asr_dir, vad_dir, punc_dir, spk_dir)): raise ValueError(All model arguments must be complete local directories) model AutoModel( modelstr(paths[asr_dir]), vad_modelstr(paths[vad_dir]), punc_modelstr(paths[punc_dir]), spk_modelstr(paths[spk_dir]), spk_modepunc_segment, devicecpu, disable_updateTrue, ) for result in model.generate(inputstr(paths[audio]), return_spk_resTrue): print(result.get(text, )) for sentence in result.get(sentence_info, []): print(sentence.get(start), sentence.get(end), sentence.get(spk), sentence.get(text, ))包装层到底做了什么配置vad_model后inference_with_vad按以下步骤工作auto_model.pyVAD 检测语音区域先对整条输入跑 VAD 模型得到value中的语音区间毫秒级[start, end]。若本次调用merge_vadTrue会按merge_length_s默认 15 秒构建时设置把相邻区域合并merge_vadauto_model.py。按时长排序组批识别片段按时长升序排序sorted_data sorted(..., keylambda x: x[0][1] - x[0][0])以batch_size_s默认 300 秒预算 max(int(kwargs.get(batch_size_s, 300)) * 1000, 1)毫秒与batch_size_threshold_s默认 60 秒决定哪些短片段合批CPU 设备强制单片段处理if kwargs[device] cpu: batch_size 0。恢复原始顺序restored_data[index] results_sorted[j]按 VAD 区间的原始下标还原。时间戳偏移每个片段的 token/词时间戳统一加上该片段在原始录音中的起始毫秒偏移t[0] int(t[0]) int(vadsegments[j][0])Nano 的字典式timestamps同样做秒→毫秒换算并加偏移。标点若配置punc_model且结果中无timestamps字段对拼接文本跑标点模型并尝试把标点 ID 对齐回原始 surface 文本_punctuate_surface_text、_merge_timestamp_units、_timestamp_sentences_from_surfaceauto_model.py。说话人聚类对每个 VAD 片段切块提取说话人嵌入sv_chunk拼接后交给ClusterBackendCAM 聚类后端得到匿名spk标签再按spk_mode把标签分布到sentence_infodistribute_spk。要点提醒只设置spk_model不会给直接推理增加说话人分离——通用说话人聚类只在这条 VAD 路径运行。punc_segment依赖可用的标点和时间戳缺少标点或时间戳字段可能使模式变为vad_segment源码中会在raw_text is None或结果无timestamp/timestamps时打印 warning 并把self.spk_mode改成vad_segment见 auto_model.py。VAD 边界是语音区域边界不一定是说话人切换点。spk0等标签是本次结果内的匿名标签不是已验证的身份也不是跨录音稳定的 ID。没有说话人模型而设置sentence_timestampTrue时当前包装层可在标点与 token 时间戳均缺失、或标点与时间戳长度无法对齐时返回按 VAD 区域对齐的句子记录_vad_segment_sentences。其他组合可能返回空的sentence_info包括已有时间戳但没有标点结果的情形。该开关不会创建强制对齐模型。返回字段解读generate()返回 Pythonlist其中是模型结果字典而不是 OpenAI 响应对象。不要假设所有模型都有全部字段也不要未经检查直接使用results[0]VAD 路径中的部分空文本分支会跳过一条结果。没有检测到语音时VAD 流程通常返回{key: ..., text: , timestamp: []}。字段含义key输入标识通常是文件名主干或清单中的 key。其他情况下会生成随机 key不保证全局唯一。text解码文本可能包含模型特有的富文本标签不一定可直接作为纯文本展示。timestamp本文 ASR 路径产生该字段时通常为 token/词/字的区间对[[start_ms, end_ms], ...]单位为毫秒。粒度与可用性取决于模型和 checkpoint。timestampsNano 的 CTC 对齐可返回包含token、start_time、end_time的字典单位是秒。VAD 合并会偏移这些时间并可额外生成毫秒单位的timestamp。sentence_info流水线句子字典start/end单位为毫秒包含text、可选timestamp完成说话人分配时包含spk。部分路径也有sentence。raw_text可选的标点前文本不保证它是所有可能处理前完全未改动的副本。value独立 VAD 模型的语音区间而非 ASR 文本。在线 VAD 可能输出尚未闭合的边界应遵循对应模型的流式协议。words、ctc_timestamps、说话人特征等额外字段属于模型特有输出。不能不经换算就把 SDK 毫秒值当作服务端秒值。参见时间戳回归测试覆盖pred_timestamp优先于output_timestamp回退的参数约定及下列模型源码。语言、热词和对齐全部取决于模型language、hotword/hotwords、时间戳这类控制没有跨模型的统一语义必须按具体实现传参实现当前代码版本的运行参数SeACo-Paraformerhotword为单数回退值None空白分隔的字符串、本地.txt路径或受支持的 URL。此解析器要求字符串不是 Nano 的列表形式。ModelScope 的paraformer-zh别名映射到该实现的 checkpoint。Paraformer指定pred_timestamp时优先使用它否则读取默认False的output_timestamp。checkpoint 保存的配置可能启用时间戳。不能把某一 Paraformer 变体的热词或时间戳行为推广到所有变体。SenseVoicelanguageauto语言 token 包含zh、en、yue、ja、ko。未知提示回退到 auto token。use_itnFalse显式text_norm优先output_timestampFalse启用后使用该实现的 CTC 对齐路径。此处不读取通用解码热词参数。Fun-ASR-Nanohotwords[]为复数接收字符串列表languageNone、itnTrue。语言直接插入文本提示不经过 SenseVoice 的语言 token 表归一化。CTC 时间戳取决于已加载的组件和完整权重而不只是一个输出开关。Qwen3-ASR 适配器languageNoneauto转为None实现中已有的zh/en等 ISO 别名转为完整语言名。上下文提示为context不是hotword。return_time_stampsFalse或output_timestampFalse任一启用都会请求时间戳但必须在构建时配置forced_aligner。未配置时适配器会警告并跳过时间戳。这些是参数约定不是语言覆盖、准确率或不同平台 checkpoint 内容相同的承诺。Nano 缺少所需张量时会禁用 CTC 输出见 checkpoint 校验。MOSS-Transcribe-Diarize 是第三方OpenMOSS模型原生联合完成转写与说话人分离拥有独立的输出结构和依赖路径请使用 MOSS 指南而不是照搬上面的外部 VAD/CAM 组合。文本级热词纠正postprocess_hotwords包装层还支持在generate()中传入postprocess_hotwords字符串、列表或字典和postprocess_hotword_file用于解码之后的文本级纠正与模型级的hotword/hotwords提示是完全不同的机制模块文档明确说明见 postprocess_hotwords.py显式映射可写成{wrong: right}或文件中一行wrongright分隔符还支持-、→文件行以#开头视为注释。回退默认值postprocess_hotword_threshold0.85、postprocess_hotword_fuzzyTrue、return_postprocess_hotword_matchesFalse。模糊匹配需要pypinyin和rapidfuzz懒加载缺失时抛ImportError并提示安装设为postprocess_hotword_fuzzyFalse时只做显式替换。postprocess_hotword_threshold必须落在[0.0, 1.0]越界抛ValueErrorpostprocess_hotwords.py。输入形式三态字符串按行解析每行可为显式映射或纯目标词字典的键值即错误词→目标词键空或键值相同时退化为模糊目标序列逐项按行规则解析postprocess_hotwords.py。关键语义此处理发生在解码之后会更新顶层text和句子级text/sentence字段并有意保留与原始识别对齐的时间戳源码# Timestamps intentionally remain aligned to the original recognition见 postprocess_hotwords.py。它既不影响声学解码也不对替换后的内容重新对齐。将纠正结果用于逐词字幕前应检查替换明细开启return_postprocess_hotword_matchesTrue时结果带postprocess_hotword_matches列表。这些参数必须按调用传入generate()向后处理器传递的是本次cfg不是构建默认配置。参见实现 和测试。流式 Cache 生命周期字典就是会话状态下面示例只面向本地 Paraformer 流式 checkpoint如iic/speech_paraformer_asr_nat-zh-cn-16k-common-vocab8404-online不代表给离线模型传入cache{}就能变成流式。运行时依次传入模型目录和非空的单声道 16 kHz 音频文件。示例依据仓库原有示例 和流式实现。import argparse from pathlib import Path import soundfile as sf from funasr import AutoModel parser argparse.ArgumentParser() parser.add_argument(model_dir) parser.add_argument(audio) args parser.parse_args() model_dir Path(args.model_dir).expanduser().resolve(strictTrue) if not model_dir.is_dir(): raise ValueError(model_dir must be a complete local streaming model directory) speech, sample_rate sf.read(args.audio, dtypefloat32) if sample_rate ! 16000 or speech.ndim ! 1 or len(speech) 0: raise ValueError(Expected nonempty mono 16 kHz audio) model AutoModel(modelstr(model_dir), devicecpu, disable_updateTrue) chunk_size [0, 10, 5] stride chunk_size[1] * 960 cache {} for start in range(0, len(speech), stride): end min(start stride, len(speech)) result model.generate( inputspeech[start:end], cachecache, is_finalend len(speech), chunk_sizechunk_size, encoder_chunk_look_back4, decoder_chunk_look_back1, batch_size1, ) print(result)数值与默认值解读该实现的chunk_size回退值为[0, 10, 5]is_final回退值为Falseparaformer_streaming/model.py。中间值乘以 960 得到输入步长16 kHz 下 9600 个采样点为600 ms[0, 8, 4]则为 480 ms见 demo 注释。源码中encoder_chunk_look_back和decoder_chunk_look_back的默认值都是0paraformer_streaming/model.py示例中的4和1是显式示例设置不是包装层默认值。生命周期纪律每条流创建一个新的cache{}按顺序处理各块时始终传入同一个字典。保持 chunk/look-back 设置固定并在最后一块传入is_finalTrue冲刷缓冲状态。当前 Paraformer 流式实现在结束时会重新初始化 cache但结束、取消或开始其他流时仍应丢弃旧字典。不要在不同录音或并发用户之间共享 cache。保持batch_size1该实现断言每次只有一条波形。返回文本对应本次调用解码的块不保证是累计全文应用侧需要自行保留各次输出。WebSocket 会话协议及服务端缓冲机制与这里的字典生命周期是不同层次不要混为一谈。版本复现与离线使用SDK 版本/commit、依赖版本与模型文件必须分别锁定。记录 ASR 及每个辅助模型的平台、完整模型 ID、解析后的上游版本、配置和权重哈希。别名或持续变化的master不是可复现的版本锁定。通用 ModelScope 加载器会向快照下载器转发model_revisiondownload_from_ms中model_revision kwargs.get(model_revision, master)并传给get_or_download_model_dir见 download_model_from_hub.py。通用 Hugging Face 助手虽然接收该参数当前实际调用却是snapshot_download(model)没有传入revision、local_files_only或check_latest。不能宣称hubhf, model_revision...能锁定这条路径。有些适配器使用自己的加载逻辑如 Whisper 的openai分支也要检查实际选用的适配器。离线运行前应在联网环境准备并验证完整本地快照包括 tokenizer/前端文件、配置、权重、嵌套编码器/LLM 以及可选对齐器。为所有组件传入已存在的本地目录。本地路径绕过通用平台下载解析但嵌套模型代码仍可能联网或缺少依赖必须在实际网络限制下验证。disable_updateTrue只跳过包更新检查。check_latestFalse不保证离线这些通用下载助手也没有统一的local_files_only开关。URL 音频和 URL 热词仍需联网已有缓存的模型别名也可能触发平台请求。除非审查过的模型代码确实需要否则保持trust_remote_codeFalse。ModelScope 通用加载器在信任开启时可以导入remote_code默认值为model两个通用平台加载器都可能在信任开启时安装模型的requirements.txt但代码导入行为并不相同。本地快照不等于安全代码。FunASR 软件采用 MIT 许可证模型权重、数据集、第三方适配器和依赖可能采用不同许可证。再分发或部署前请检查具体模型自身的许可证和使用条件。SDK 与服务接口边界别把进程内 API 当 HTTP API接口应遵循的契约PythonAutoModel本文描述的进程内模型配置、波形输入、流式字典及模型特有的 Python 结果。没有base_url、API key 或 HTTPresponse_format契约。funasr-server打包的 CLI 创建服务应用。/v1/audio/transcriptions是 OpenAI 风格的语音接口子集/asr是另一个服务特有接口。表单参数、默认值、单位及说话人行为属于该服务不属于generate()。OpenAI 兼容示例服务示例服务 与打包服务不是同一实现。可查阅它的 OpenAPI 说明、客户端示例 和安全/网关指南再核对实际部署服务的/openapi.json。不要假设二者默认值或响应字段相同。vLLMAutoModelVLLM、FunASR 模型专用服务与原生vllm serve是不同入口。SDK 的cache或一个 HTTP 转写端点都不能证明兼容实时会话协议。按所选路线与 checkpoint 格式阅读 vLLM 指南。llama.cpp / GGUF独立的 C 可执行程序与 GGUF 文件不使用PythonAutoModel的 kwargs 或结果结构。请参考运行时指南。仅有 VAD 不等于说话人分离。Hydra 推理入口 从配置构建AutoModel后调用generate()不会把所有 CLI/配置项变成 HTTP 表单字段。开放服务前应在相应边界落实鉴权、TLS、上传限制、超时及访问限制——OpenAI 客户端的占位 API key 不是访问控制。延伸阅读English 版本文档 | 安装指南 | 模型选择 | vLLM 指南 | MOSS 转写说话人分离指南【免费下载链接】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),仅供参考