
FunASR 自定义任务与模型扩展指南从旧 Task 架构迁移到注册表与 AutoModel 扩展点【免费下载链接】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 仓库中扩展功能的开发者系统讲解如何选择正确的扩展点、如何将基于旧版AbsTask/ASRTask的扩展迁移到当前架构以及如何利用注册表registry与AutoModel编排机制接入新的模型实现。读完本文你将掌握当前代码库中注册模型 ≠ 接入服务的核心边界、两种模型加载路径直接注册与模型目录解析的差异以及如何安全地完成扩展验证。背景build_task.md的定位与旧 Task 架构的终结build_task.md 在仓库中承担迁移入口migration entry的角色它取代了早期的 Task-based 教程。早期的教程描述的是 FunASR 旧版架构其中AbsTask/ASRTask类在当前代码检查版本中已不再是真实接口因此官方明确警告不要在新集成中复制这些旧示例。这意味着如果你在网络上或旧文档中找到类似实现一个 Task 子类完成自定义任务的代码片段需要先确认其针对的 FunASR 版本。当前版本以 funasr/register.py 与 funasr/auto/auto_model.py 为实现的版本通过注册表 AutoModel机制组织模型、前端、分词器、数据集等组件旧 Task 类没有对等的替代实现。第一步选择正确的扩展点build_task.md给出的核心建议是先明确你要做的事再选择对应的维护中指南。下表完整来自原文档是扩展决策的总纲你需要做的事维护中的指南需要验证的内容运行已有 checkpointPython SDK 指南模型、输入与输出契约微调已有架构训练指南Recipe、数据格式、checkpoint 与评估新增模型架构模型注册指南注册名、配置、inference()与结果字段接入第三方模型MOSS 集成指南上游归属、依赖与适配器边界暴露转写服务部署矩阵运行时、协议与支持的模型组合原文特别强调了一个容易被忽视的事实当前模型注册机制实现在 funasr/register.py推理编排在 funasr/auto/auto_model.py但注册一个模型不等于为每个 HTTP、WebSocket 或 C 运行时添加支持。如果你要暴露服务必须遵循对应服务契约并单独测试目标路由——例如 部署矩阵 中列出的 OpenAI 兼容 API、运行时 WebSocket 服务、ONNX/C 运行时、vLLM 加速等各有各的协议与模型组合约束注册表只负责 Python 层对象查找。注册表机制源码剖析funasr/register.pyfunasr/register.py 是整个扩展机制的基石。它定义了一个RegisterTables数据类内部维护多张进程级全局字典每张字典对应一类组件model_classes {} frontend_classes {} specaug_classes {} normalize_classes {} encoder_classes {} decoder_classes {} joint_network_classes {} predictor_classes {} stride_conv_classes {} tokenizer_classes {} dataloader_classes {} batch_sampler_classes {} dataset_classes {} index_ds_classes {}从源码可以看到注册的核心逻辑register(register_tables_key, key)是一个装饰器工厂返回的decorator将目标类写入对应字典若key未指定默认使用target_class.__name__作为注册名若key已存在代码仅输出 debug 日志Key ... already exists ... re-register并覆盖旧条目不会报错——这正是model_registration.md中import 顺序因此重要的根源装饰器还通过inspect.getfile/inspect.getsourcelines记录类文件与行号形成*_meta元数据表供tables.print()展示注册名 / 类名 / 类位置三列信息。一个值得注意的细节注册表允许新增表名——如果register_tables_key不存在hasattr检查不通过时会自动setattr创建新表。这意味着拼写错误不会立刻失败而是悄悄创建一个无人消费的空表调试时容易踩坑务必检查tables.print()输出确认注册目标。AutoModel 编排链路注册名如何变成可推理模型funasr/auto/auto_model.py约 1366 行是推理编排的核心。它通过tables.model_classes[name]查找已注册实现然后完成配置解析、权重加载、组件VAD/标点/说话人构建与generate()调度。关键调用链从源码与文档共同确认构造AutoModel(model..., model_conf...)若传入model_confbuild_model会跳过 hub/配置解析直接把model当作已注册类 key 使用详见下文玩具契约示例否则走 hub 加载器funasr/download/download_model_from_hub.py读取configuration.json或config.yaml解析模型 key 与资源路径generate()在无 VAD 时将输入批处理为data_in与key两个列表在torch.no_grad()下调用model.inference(**batch, **kwargs)模型返回二元组(results, meta_data)AutoModel处理后以扁平结果列表返回给调用方。因此注册表中的条目必须满足 model_registration.md 定义的契约模型对象通常是torch.nn.Module需支持.to(...)、.eval()、.parameters()inference的返回必须是(results, meta_data)二元组其中results是list[dict]ASR 场景至少包含字符串key与text字段meta_data是字典。返回裸的字典列表是错误的AutoModel 会把第一项当成整个批次的唯一结果。第二步迁移旧扩展的标准流程build_task.md给出了三条迁移步骤这里结合当前仓库补充细节1. 记录原始环境在改动环境之前记录原 FunASR 提交版本、配置、checkpoint 与依赖版本。这一步是后续可复现对比的前提。2. 选择匹配的 recipe 或已注册模型选择输入输出匹配的当前 recipe 或已注册模型把旧预处理preprocessing、数据整理collation与模型构建model construction职责映射过去。不要假设旧 Task 类有即插即用的替代品。可参考的当前注册实现SenseVoice 实现 —— 同时具备训练、推理与导出一体化集成的完整范例FunASRNano 实现第 32 行tables.register(model_classes, FunASRNano)—— LLM 类 ASR 模型范例MOSS 适配器 —— 第三方 OpenMOSS 模型接入范例其forward明确拒绝训练raise RuntimeError证明已注册模型不代表支持微调或导出。3. 小规模验证在训练或服务前先验证配置加载、checkpoint 兼容性与小样本推理与旧固定环境对比输出再运行相关评估。历史实验应保留其匹配的源码修订版本于隔离环境。模型注册的完整契约以官方玩具示例为骨架model_registration.md 提供了一个无需权重、音频、hub 下载或 GPU的最小本地契约示例是理解注册机制的最佳入口。把它放在可导入的custom_model_demo.py中运行需安装当前 checkoutimport torch from funasr import AutoModel from funasr.register import tables MODEL_NAME DocsEchoModelV1 if MODEL_NAME in tables.model_classes: raise RuntimeError(fRegistry collision: {MODEL_NAME}) tables.register(model_classes, MODEL_NAME) class DocsEchoModel(torch.nn.Module): def __init__(self, **kwargs): super().__init__() self.anchor torch.nn.Parameter(torch.zeros(1), requires_gradFalse) def inference( self, data_in, data_lengthsNone, keyNone, tokenizerNone, frontendNone, **kwargs, ): results [ {key: sample_key, text: str(value)} for sample_key, value in zip(key, data_in) ] return results, {} if __name__ __main__: model AutoModel( modelMODEL_NAME, model_conf{}, devicecpu, disable_updateTrue, disable_pbarTrue, ) result model.generate(input[hello, world], data_typetext) assert [row[text] for row in result] [hello, world] assert all(isinstance(row[key], str) for row in result) print([row[text] for row in result])这个示例刻意不做语音识别只是回显输入文本但它完整演示了三个关键点冲突守卫注册前检查MODEL_NAME in tables.model_classes避免与内置模型名如SenseVoiceSmall、Paraformer、FunASRNano冲突model_conf{}的语义只要提供model_confAutoModel.build_model就跳过 hub/配置解析model直接作为已注册类 key 使用而非模型目录或 hub ID必须有参数因为AutoModel.inference会检查next(model.parameters()).device无参数玩具会在此路径失败——这也是为什么示例里放了一个anchor参数。最终打印结果为[hello, world]。注意注册名大小写敏感省略注册名时默认用类名装饰器返回原类并用inspect记录源码位置所以自定义模型应写在可导入的.py文件中而不是只在 REPL 或动态生成的类里定义。推理、训练与导出契约速查接口当前 checkout 的契约模型对象通常为torch.nn.Module支持.to(...)、.eval()、.parameters()构造配置因模型而异inference输入无 VAD 时 AutoModel 将输入批处理为data_in与key列表在torch.no_grad()下调用data_typefbank且单条输入时直接传特征对象并附带data_lengthsinput_lentokenizer/frontend 为已解析对象或None模型级返回二元组(results, meta_data)results为list[dict]meta_data为字典ASR 使用字符串key与text字段并保持输入顺序元数据可选load_data、extract_feat、batch_data_time音频场景下batch_data_time单位是秒正值设为 0 会导致计时代码除零省略则使用内部-1哨兵值公开返回AutoModel.generate(...)返回扁平化结果列表时间戳等额外字段是模型相关的注册本身不承诺它们训练实现与数据集 collator 命名字段匹配的可微forwardTrainer 解包(loss, stats, weight)SenseVoice 与 Nano 使用force_gatherable导出导出工具 调用模型的export及export_dummy_inputs等方法仅注册不提供这些能力自定义模型必须自行实现音频加载、特征准备、分词/解码与批处理。参考一个相近真实模型的契约而非其能力——照抄接口、不实现逻辑是常见错误。两种加载路径直接注册与模型目录解析路径一直接注册Direct registration导入你的模块传入注册 key 与model_conf如上例。此路径不执行任何 hub 代码导入如需要权重自行提供兼容的 tokenizer/frontend/配置与既有init_param。路径二模型目录解析Model-directory resolution传入已审核的本地目录或 hub ID不提供model_conf。加载器读取configuration.json元数据或config.yaml解析模型 key 与资源并加载权重。一个简单的本地config.yaml目录通常还需要model.pt以及所有引用的 tokenizer/frontend 资源。任意 HF 权重文件夹不会自动成为 FunASR 模型目录。ModelScope 路径的接口示例要求models/custom-asr已包含兼容的已审核配置与权重且custom_asr_model.py注册了精确的配置 keyfrom funasr import AutoModel model AutoModel( model./models/custom-asr, hubms, trust_remote_codeTrue, remote_code./custom_asr_model.py, devicecpu, disable_updateTrue, ) print(model.generate(inputdata/audio/heldout.wav))hub 差异ms与hf行为不同这是最容易踩坑的地方来自 model_registration.md 与源码 dynamic_import.pyModelScope 路径download_from_ms在trust_remote_codeTrue时导入remote_code默认模块名model导入器支持模块/文件路径及 URL 下载将目录追加到sys.path后按 basename 导入相对路径是相对于工作目录不是自动相对于权重目录basename 冲突与 Python 导入缓存可能选中已加载模块请使用不重复的模块名并验证活跃类该 helper 对导入异常只打印而不重抛需自行检查错误与注册表状态Hugging Face 路径download_from_hf在信任标志下可以安装模型 requirements但不会调用import_module_from_path——不要假设remote_code在hubhf下被执行。使用hubhf时请先显式导入你的已审核自定义模块或走带完整配置的直接注册路径本地config.yaml回退路径对init_param的处理也不同ModelScope 保留显式路径Hugging Face 则赋值为目录下的model.pt。请检查解析后的实际路径不要假设所选 checkpoint 覆盖生效。参考实现Nano 的 demo1.py 展示了trust_remote_codeTrue、remote_code./model.py、hubms的用法它假定在 recipe 目录下运行其 本地实现 注册FunASRNano并导入兄弟模块ctc、tools——这可能覆盖内置实现funasr/models/fun_asr_nano/model.py两者并非所有特性都可互换包括内置 LoRA务必审计活跃类与 checkpoint key。安全与验证扩展的自检清单trust_remote_codeTrue意味着允许 Python 执行hub 加载器还可能安装模型目录的requirements.txt本地目录并非天然可信。原文档的安全要点完整如下审核源码、依赖与权重序列化使用隔离环境不要加载不受信任的 pickle checkpoint不要将不受信任的 URL、模块名或配置拼接进加载流程无法依赖远端修订处理时保留带哈希的本地已审核快照model_revision在全部加载器路径上都不是通用 pin加载前确认活跃注册 key/类/源码ignore_init_mismatch在 AutoModel 中默认为 true不存在的直接init_param只打印错误而不保证构造失败请自行验证 checkpoint 存在性在训练/导出/部署前分别测试单条输入、多条输入、错误处理与目标流水线FunASR 软件采用 MIT 许可见 LICENSE但模型权重、数据集与上游组件许可各不相同分发前需单独核对。对自定义模型契约的聚焦式检查可运行python -m pytest -q tests/test_training_docs_contract.py该测试只做语法、仓库链接与无下载玩具契约检查不认证任意自定义代码、实际 ASR 质量、GPU 训练、真实 checkpoint 恢复或导出兼容性。结语扩展的正确姿势回到build_task.md的核心结论当前版本没有Task 子类魔法扩展的正确路径是先选扩展点再对齐契约最后分路径验证。运行已有模型看 Python SDK 指南微调看 训练指南新增架构看 模型注册指南 与 历史注册教程作为历史参考与当前源码不一致处以当前行为为准接入第三方模型看 MOSS 集成指南暴露服务看 部署矩阵。记住注册表连接的是Python 实现与配置名它不会下载权重、不会让任意 Transformers 模型自动兼容、不提供训练/导出支持也不认证模型质量——这些边界都在你的验证清单里。【免费下载链接】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),仅供参考