ComfyUI可视化流程集成:SenseVoice-Small语音识别节点开发教程
ComfyUI可视化流程集成:SenseVoice-Small语音识别节点开发教程
你是不是已经用ComfyUI玩转各种文生图、图生图,甚至搭建了复杂的AI绘画工作流?有没有想过,如果能让你的工作流“听懂”语音指令,或者自动把一段播客、会议录音转成文字,再交给AI去生成对应的画面,那该多酷?
今天,我们就来点不一样的。不聊怎么用现成的节点,而是教你如何自己动手,在ComfyUI里“造”一个节点。我们要造的,是一个能集成SenseVoice-Small语音识别模型的节点。SenseVoice-Small是一个轻量但效果不错的语音转文字模型,把它塞进ComfyUI,你的工作流就能直接从音频里提取文本,开启“声控作画”或者“音频驱动内容生成”的新玩法。
听起来有点技术含量?别担心,这篇教程就是给ComfyUI的“高级玩家”准备的。我们会从零开始,一步步带你走通自定义节点开发的全过程。你不需要是Python大神,但需要对ComfyUI的节点系统有基本了解,并且愿意动手敲点代码。学完这篇,你不仅能拥有一个语音识别节点,更重要的是,你会掌握在ComfyUI里创造任何你想要的功能节点的能力。
1. 开发前的准备:理清思路与环境搭建
在开始写代码之前,我们得先想明白这个节点要干什么,以及需要准备哪些东西。
简单来说,我们的目标是:创建一个ComfyUI节点,它接收一个音频文件的路径作为输入,调用SenseVoice-Small模型进行识别,最后输出识别出的文本字符串。
为了实现这个目标,我们需要搞定三件事:
- 模型本身:如何让Python代码调用SenseVoice-Small。
- 节点框架:如何遵循ComfyUI的规则,创建一个能被识别和使用的节点。
- 流程集成:如何设计输入输出,让这个节点能无缝嵌入到其他工作流中。
1.1 环境与依赖安装
首先,确保你的ComfyUI运行环境是正常的。然后,我们需要安装SenseVoice-Small模型所依赖的Python包。打开你的终端(或ComfyUI启动命令所在的环境),执行以下命令:
pip install torch torchaudio --index-url https://download.pytorch.org/whl/cu118 # 如果你用CUDA 11.8
pip install modelscope funasr
这里解释一下:
torch和torchaudio:PyTorch深度学习框架及其音频处理库,是模型运行的基础。modelscope和funasr:ModelScope是阿里开源的模型社区,FunASR是专注于语音识别的工具包。SenseVoice-Small模型可以通过它们方便地加载和使用。
安装完成后,建议你单独写一个小的Python脚本测试一下模型是否能正常加载和推理,确保基础环境没问题。
1.2 理解ComfyUI节点的基础结构
ComfyUI的节点本质上是一个Python类。这个类必须定义一些特定的方法和属性,ComfyUI的图形化界面才能识别它、渲染它。最核心的几个部分包括:
FUNCTION:一个字符串属性,指定节点执行的主函数名。CATEGORY:一个字符串属性,决定这个节点在节点菜单中被归类到哪个目录下,比如”audio”或”custom_nodes”。RETURN_TYPES和RETURN_NAMES:这两个属性定义了节点的输出。RETURN_TYPES是一个元组,指定每个输出的数据类型(如”STRING”);RETURN_NAMES也是一个元组,给每个输出起一个显示名称。INPUT_TYPES静态方法:这个方法返回一个字典,用来定义节点的所有输入参数(也就是那些可以连接线的小插座)。字典的键是参数名,值是这个参数的配置(比如类型、默认值等)。- 一个主执行方法:方法名由
FUNCTION属性指定。这个方法接收INPUT_TYPES中定义的参数,执行核心逻辑,并返回一个元组,其元素顺序和类型要与RETURN_TYPES严格对应。
理清了这些,我们就可以开始动手创建了。
2. 核心代码编写:从模型调用到节点封装
接下来,我们进入核心环节,一步步构建我们的SenseVoiceSmall节点。
2.1 创建节点文件与目录结构
在ComfyUI的安装目录下,有一个custom_nodes文件夹。所有第三方节点都放在这里。我们在其中创建一个属于自己的目录,比如comfyui-sensevoice-node。
ComfyUI/
├── custom_nodes/
│ └── comfyui-sensevoice-node/
│ ├── __init__.py
│ └── nodes.py
├── ...
__init__.py:可以是一个空文件,它告诉Python这个目录是一个包。nodes.py:我们将在这里编写节点的所有代码。
2.2 编写节点类代码
打开nodes.py,开始编写代码。我会分段解释,你可以跟着一起写。
第一部分:导入依赖和定义节点类
import torch
import torchaudio
from modelscope.pipelines import pipeline
from modelscope.utils.constant import Tasks
import os
import numpy as np
import folder_paths
import comfy.utils
class SenseVoiceSmall:
"""
ComfyUI自定义节点:使用SenseVoice-Small模型进行语音识别。
输入音频文件路径,输出识别文本。
"""
# 定义节点在ComfyUI中的行为标识
FUNCTION = “process_audio”
# 定义节点在菜单中的分类,可以自定义,这里放在“audio”类别
CATEGORY = “audio”
# 定义输出类型,这里只有一个字符串输出
RETURN_TYPES = (“STRING”,)
# 定义输出名称,方便在界面上识别
RETURN_NAMES = (“text”,)
# 模型管道对象,作为类变量,实现懒加载(第一次使用时加载)
_pipe = None
这里我们导入了必要的库,并定义了节点类SenseVoiceSmall。注意FUNCTION和CATEGORY的设置。_pipe是一个类变量,用于缓存加载的模型管道,避免每次执行节点都重新加载模型,这很耗时。
第二部分:定义输入参数 (INPUT_TYPES)
@staticmethod
def INPUT_TYPES():
# 获取ComfyUI中预设的输入目录(如`input`文件夹)
input_dir = folder_paths.get_input_directory()
# 扫描该目录下的音频文件
audio_files = [f for f in os.listdir(input_dir) if f.lower().endswith((‘.wav’, ‘.mp3’, ‘.flac’, ‘.m4a’))]
return {
“required”: {
“audio_file”: (audio_files, {“default”: audio_files[0] if audio_files else “”}), # 下拉选择框
},
“optional”: {
“language”: ([“auto”, “zh”, “en”], {“default”: “auto”}), # 可选语言参数
}
}
INPUT_TYPES方法返回一个字典,定义了节点的输入插座。
”required”字典里是必须连接的参数。这里我们定义了一个audio_file参数,类型是列表audio_files,这会让ComfyUI将它渲染成一个下拉选择框,列出input文件夹下的所有音频文件。”optional”字典里是可选的参数。这里我们添加了一个language参数,让用户可以选择识别语言(自动、中文、英文)。
第三部分:实现模型加载与推理 (process_audio)
def process_audio(self, audio_file, language=“auto”):
"""
核心处理函数:加载音频并调用模型进行识别。
"""
# 1. 构建完整的音频文件路径
input_dir = folder_paths.get_input_directory()
audio_path = os.path.join(input_dir, audio_file)
# 2. 检查文件是否存在
if not os.path.exists(audio_path):
raise FileNotFoundError(f“音频文件未找到: {audio_path}”)
# 3. 懒加载模型管道
if SenseVoiceSmall._pipe is None:
print(“[SenseVoiceSmall] 正在加载模型,首次使用可能需要一些时间...”)
try:
# 使用ModelScope的pipeline加载SenseVoice-Small模型
SenseVoiceSmall._pipe = pipeline(
task=Tasks.auto_speech_recognition,
model=“iic/SenseVoiceSmall”,
device=“cuda:0” if torch.cuda.is_available() else “cpu”,
)
print(“[SenseVoiceSmall] 模型加载完毕。”)
except Exception as e:
print(f“[SenseVoiceSmall] 模型加载失败: {e}”)
return (“模型加载失败,请检查依赖和环境。”,)
# 4. 执行语音识别
print(f“[SenseVoiceSmall] 正在识别: {audio_file}, 语言: {language}”)
try:
# 调用管道进行识别,传入语言参数
rec_result = SenseVoiceSmall._pipe(
audio_in=audio_path,
batch_size_s=300, # 批处理大小,影响内存和速度
language=language if language != “auto” else None, # 模型内部处理auto
)
# 提取识别文本
recognized_text = rec_result.get(“text”, “”)
print(f“[SenseVoiceSmall] 识别完成: {recognized_text[:50]}...” if len(recognized_text) > 50 else f”...“)
except Exception as e:
print(f“[SenseVoiceSmall] 识别过程出错: {e}”)
recognized_text = f“识别出错: {e}”
# 5. 返回结果,必须是一个元组,且与RETURN_TYPES对应
return (recognized_text,)
这是节点的核心逻辑:
- 拼接出音频文件的绝对路径。
- 进行基本的文件检查。
- 懒加载模型:只有第一次运行节点时才会加载模型,后续调用会复用,极大提升工作流执行效率。
- 调用
pipeline进行语音识别。batch_size_s参数可以根据你的硬件调整,值越大处理越快,但占用内存越多。 - 从结果中提取文本并返回。返回的必须是一个元组
(recognized_text,)。
第四部分:节点注册与额外功能
为了让ComfyUI发现我们的节点,需要在文件末尾添加一个节点列表。
# 所有自定义节点都必须在这个列表中声明
NODE_CLASS_MAPPINGS = {
“SenseVoiceSmall”: SenseVoiceSmall
}
# 节点显示名称的映射(可选)
NODE_DISPLAY_NAME_MAPPINGS = {
“SenseVoiceSmall”: “SenseVoice Small 语音识别”
}
至此,一个功能完整的自定义节点就编写完成了。将nodes.py文件保存。
3. 测试与集成:让节点跑起来
代码写好了,但它真的能在ComfyUI里用吗?我们来测试一下。
3.1 启动ComfyUI并查找节点
- 重启你的ComfyUI服务。如果之前是启动状态,需要关闭后重新运行
python main.py。 - 打开ComfyUI的Web界面。
- 在节点菜单中,找到我们定义的
CATEGORY,也就是”audio”分类。你应该能看到一个名为”SenseVoice Small 语音识别”的节点(如果你设置了NODE_DISPLAY_NAME_MAPPINGS),或者直接叫”SenseVoiceSmall”。 - 把它拖到画布上。
3.2 配置节点并运行
- 准备音频:将你想要识别的音频文件(如
my_audio.wav)放入ComfyUI根目录下的input文件夹。 - 配置节点:点击画布上的
SenseVoiceSmall节点,在右侧的属性面板中,audio_file下拉框里应该会出现你刚放入的my_audio.wav文件,选择它。你还可以选择识别语言。 - 连接输出:从节点的输出插座
text拉出一根线,可以连接到一个Show Text节点(用于在界面上显示文本),或者连接到任何其他接受字符串输入的节点,比如一个CLIP Text Encode节点,为文生图提供提示词! - 执行:点击
Queue Prompt按钮。在后台终端里,你应该能看到模型加载和识别的打印信息。稍等片刻,识别出的文本就会传递到下游节点。
3.3 集成到复杂工作流
这才是自定义节点的魅力所在。现在,你可以发挥创意,构建自动化流程了:
- 声控AI绘画:
麦克风录音->保存音频到input文件夹->SenseVoiceSmall节点->CLIP文本编码器->K采样器。对着麦克风说“一只在星空下奔跑的狐狸”,工作流就能自动生成这幅画。 - 播客内容可视化:将一段播客音频切片,批量通过
SenseVoiceSmall节点转成文字,再将每一段文字描述生成对应的概念图,快速制作播客的图文摘要。 - 视频配音字幕提取与重绘:从视频中提取音频,识别成字幕文本,再用文本分析节点提取关键词,生成新的配图或视频风格化素材。
4. 进阶优化与问题排查
一个能跑的节点是基础,一个健壮、好用的节点才是目标。这里有一些进阶建议。
4.1 提升节点健壮性
我们的基础代码已经包含了错误处理,但还可以加强:
- 音频格式兼容:可以集成
pydub或ffmpeg库,在节点内部自动转换不支持的音频格式为WAV格式,再交给模型处理。 - 进度提示:对于长音频,模型处理需要时间。可以尝试利用ComfyUI的进度条功能,给用户更友好的反馈。
- 模型配置化:将
model=“iic/SenseVoiceSmall”这类参数也放到INPUT_TYPES中作为可选参数,让高级用户可以切换不同的模型版本。
4.2 常见问题与解决
- 节点不显示:检查
custom_nodes目录结构是否正确,nodes.py文件名是否拼写准确,NODE_CLASS_MAPPINGS字典是否正确。重启ComfyUI。 - 模型加载失败:
- 检查网络,首次加载需要从ModelScope下载模型。
- 检查
modelscope和funasr版本兼容性。 - 查看终端完整的错误信息。
- 识别结果为空或乱码:
- 检查音频文件是否损坏,或是否为静音文件。
- 尝试调整
language参数,明确指定”zh”或”en”。 - 对于嘈杂环境下的音频,识别效果会下降,这是模型本身的限制。
获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。
更多推荐
所有评论(0)