数字人AI 应用语音多模态音视频后端【免费下载链接】OpenAvatarChat项目地址https://gitcode.com/gh_mirrors/op/OpenAvatarChat点击查看免费下载导读本文围绕 docs/reference/handlers/llm/qwen-omni.md 展开完整讲解 OpenAvatarChat 中 Qwen-Omni Handler 的设计思路、配置方式与源码级运行机制。Qwen-Omni Handler 通过阿里云百炼DashScope的实时 API 接入通义千问多模态模型在手动manual模式下与本地 SileroVAD、SenseVoice 及 LiteAvatar/MuseTalk 数字人模块协同工作构成一套「语音入 → 多模态大模型推理 → 语音与文本出 → 数字人驱动」的实时对话链路。读完本文你将掌握chat_with_qwen_omni.yaml中每个配置项的取值含义与边界条件理解该 Handler 的音频/视频/文本三条处理管线、心跳保活与自动重连机制并能够按步骤完成环境准备、模型下载与实际部署运行。一、Handler 定位与适用场景在 OpenAvatarChat 的模块化 Handler 架构中LLM Handler 负责语言模型推理、生成对话回复而 Qwen-Omni Handler 是一个特殊角色它不像传统 LLM TTS 组合那样「先出文本再合成语音」而是直接通过百炼实时 API 与 Qwen-Omni 多模态模型建立全双工会话原生返回音频流Avatar Audio与实时文本流Avatar Text同时还能接收摄像头视频帧CAMERA_VIDEO作为多模态输入。需要特别注意原文档声明的三点约束它们直接决定了整套方案的架构形态当前仅支持 manual 模式语音断句端点检测由本地 SileroVAD 完成模型侧的服务端 VADenable_turn_detection暂未启用manual 模式下模型内置 ASR 效果差因此额外引入本地 SenseVoice 模块专门用于把用户说的话转写成文字、回显到前端对话记录Avatar 模块二选一在 MuseTalk 与 LiteAvatar 之间自由切换默认使用 LiteAvatar。从源码角度看Handler 实现位于 src/handlers/llm/qwen_omni/llm_handler_qwen_omni.py核心类是HandlerSeq2SeqQwenOmni其输入输出契约get_handler_detail清晰地体现了职责边界输入HUMAN_AUDIO用户 16kHz 单声道音频、CAMERA_VIDEO摄像头视频帧输出AVATAR_AUDIO24kHz 单声道浮点音频、AVATAR_TEXT数字人实时文本、HUMAN_TEXT仅在开启输入转写时用于回显。二、整体工作流与数据流结合 config/chat_with_qwen_omni.yaml 的 Handler 编排Qwen-Omni 方案的完整数据流如下接入RtcClient通过 WebRTC 接收浏览器端的音视频流打断InterruptHandler监听 INTERRUPT 信号并执行流取消VAD 断句本地SileroVad判定用户说话的起止输出语音片段manual 模式的核心多模态推理QwenOmni把语音片段可选叠加视频帧通过append_audio/append_video送入百炼实时会话收到response.audio.delta音频流与response.text.delta文本流回显SenseVoice把同一段用户语音本地转写成文本输出HUMAN_TEXT用于对话记录回显数字人驱动LiteAvatar默认或MuseTalk根据音频驱动面部动画回传合成的音视频流经 WebRTC 返回给浏览器。这套流程的独特之处在于Qwen-Omni 同时承担了 LLM 与 TTS 的职责而 ASR 职责被拆成「模型侧效果差默认关闭转写」与「本地 SenseVoice专用于回显」两部分。三、配置文件详解chat_with_qwen_omni.yaml原文档明确指出「完整配置文件可以参考chat_with_qwen_omni.yaml」以下对该文件进行逐段拆解并补充配置模型中的默认值与约束。3.1 全局与 RTC 客户端default: logger: log_level: INFO service: host: 0.0.0.0 port: 8282 cert_file: ssl_certs/localhost.crt cert_key: ssl_certs/localhost.key chat_engine: model_root: models concurrent_limit: 1 handler_search_path: - src/handlers handler_configs: RtcClient: module: client/rtc_client/client_handler_rtc connection_ttl: 36000 # max time a session will last for connection_ttl: 900要点说明concurrent_limit: 1表示同时只处理一个会话这是针对 Qwen-Omni 实时会话资源的保守设置handler_search_path: [src/handlers]定义了按模块名解析 Handler 的搜索根目录connection_ttl表示单个会话的最大存活时长单位为秒。注意原配置中该键出现了两次按 YAML 解析规则后者生效即实际会话生命周期上限为900 秒15 分钟WebRTC 服务需要 TLS默认使用仓库 ssl_certs/ 目录下的自签证书。3.2 打断与本地 VAD# 打断处理器 - 接收 INTERRUPT 信号并执行流取消 InterruptHandler: module: logic/interrupt/interrupt_handler SileroVad: module: vad/silerovad/vad_handler_silero speaking_threshold: 0.5 start_delay: 2048 end_delay: 5000 buffer_look_back: 5000 speech_padding: 512SileroVad是 manual 模式的断句引擎各参数含义与默认值可参考 docs/reference/handlers/vad/silero-vad.md参数配置值默认值说明speaking_threshold0.50.5判定输入音频为语音的置信度阈值start_delay20482048持续大于阈值超过此采样数后判定说话开始end_delay50002048持续小于阈值超过此采样数后判定说话结束本配置调大减少尾音截断buffer_look_back50001024语音起始点往前回溯的采样数本配置调大避免吞字头speech_padding512512起始与结束两端补上的静音采样数3.3 SenseVoice对话记录回显模块SenseVoice: enabled: True module: asr/sensevoice/asr_handler_sensevoice model_name: iic/SenseVoiceSmall正如原文档所述manual 模式下 Qwen-Omni 自带的输入语音识别效果较差因此引入 SenseVoice ASR Handler 仅用于把用户语音转写为文本回显。它基于 FunASR 框架model_name默认iic/SenseVoiceSmall加载时会自动从 ModelScope 下载asr_handler_sensevoice.py 中会优先检查models/目录下是否已有本地模型若存在则直接使用本地路径也可将model_name改为本地模型绝对路径。3.4 QwenOmni 核心配置块QwenOmni: enabled: true module: llm/qwen_omni/llm_handler_qwen_omni model_name: qwen-omni-turbo-realtime # api_key: # defaultos.getenv(DASHSCOPE_API_KEY) api_key可以通过此处设置或者通过环境变量没设必挂 voice: Serena #Chelsie, Serena, Ethan, Cherry enable_video_input: true video_frame_interval_ms: 1000 # 每1000ms发送一帧图片防止拥塞可按需调整根据omni的文档不要低于500ms enable_text_output: true input_audio_format: PCM_16000HZ_MONO_16BIT output_audio_format: PCM_24000HZ_MONO_16BIT enable_turn_detection: false # 目前暂未支持服务端vad模式此处默认为false不要修改 enable_input_transcription: false # 手动模式下omni的输入的语音识别效果非常差几乎不可用默认关闭直接使用正常asr的结果 transcription_model: gummy-realtime-v1对照 llm_handler_qwen_omni.py 中的QwenOmniConfigpydantic 模型可得到完整的参数表参数默认值说明model_nameqwen-omni-turbo-realtime百炼实时多模态模型名api_keyos.getenv(DASHSCOPE_API_KEY)鉴权密钥不设环境变量则必须在此显式配置否则加载阶段直接抛ValueErrorvoiceChelsie源码默认/ Serena配置示例语音音色可选 Chelsie、Serena、Ethan、Cherryenable_video_inputFalse是否把摄像头视频帧送入模型多模态视觉输入enable_text_outputFalse是否流式输出实时文本response.text.deltainput_audio_formatPCM_16000HZ_MONO_16BIT上送音频格式与 SileroVAD 输出的采样率对齐output_audio_formatPCM_24000HZ_MONO_16BIT模型返回音频格式即 Avatar 驱动与 WebRTC 回传的采样率enable_turn_detectionFalse服务端 VAD当前未支持保持 False 不要修改enable_input_transcriptionFalse模型侧输入转写manual 模式下效果差默认关闭transcription_modelgummy-realtime-v1若开启转写时使用的转写模型video_frame_interval_ms1000ge500视频帧发送间隔毫秒下限 500ms防止上送拥塞关键约束提醒video_frame_interval_ms在源码中被定义为Field(default1000, ge500)即低于 500ms 的取值会被配置校验拒绝enable_turn_detection当前必须保持false因为 manual 模式的断句完全由本地 SileroVAD 负责。3.5 Avatar 模块MuseTalk 与 LiteAvatar 二选一原文档特别说明 Avatar 可在 MuseTalk 与 LiteAvatar 之间选择配置中默认启用了 LiteAvatar# Musetalk和LiteAvatar可以通过配置自由选默认使用LiteAvatar了 # AvatarMusetalk: # module: avatar/musetalk/avatar_handler_musetalk # fps: 20 # Video frame rate # batch_size: 2 # Batch processing frame count, must be greater than 2 # avatar_video_path: src/handlers/avatar/musetalk/MuseTalk/data/video/yongen.mp4 # Initialization video path # avatar_model_dir: models/musetalk/avatar_model # Default avatar model directory # force_create_avatar: false # Whether to force regenerate digital human data # debug: false # Whether to enable debug mode LiteAvatar: module: avatar/liteavatar/avatar_handler_liteavatar avatar_name: 20250408/sample_data fps: 25 debug: false enable_fast_mode: false use_gpu: true切换方式很简单取消注释AvatarMusetalk块并注释掉LiteAvatar块即可。二者的区别在于MuseTalk 是基于潜在扩散模型latent diffusion的 2D 说话人头生成配置中需要指定初始化视频avatar_video_path与模型目录avatar_model_dir且batch_size必须大于 2LiteAvatar 是轻量级 2D 数字人方案按avatar_name加载预训练样例数据20250408/sample_data支持enable_fast_mode快速模式与 GPU 加速。四、源码级运行机制剖析4.1 会话建立与参数下发Handler 在start_context阶段llm_handler_qwen_omni.py完成以下步骤校验dashscope.api_key未设置则抛ValueError启动音频处理线程与文本处理线程均为 daemon 线程创建OmniRealtimeConversation(modelmodel_name, callbackcallback)来自dashscope.audio.qwen_omni并connect()最多等待 15 秒建立 WebSocket 连接通过update_session(...)下发会话参数输出模态固定为[AUDIO, TEXT]、voice、输入/输出音频格式、enable_input_audio_transcription、转写模型与enable_turn_detection启动心跳线程。其中音频格式通过getattr(AudioFormat, config.input_audio_format)动态解析若配置了非法格式名代码会回退到PCM_16000HZ_MONO_16BIT/PCM_24000HZ_MONO_16BIT默认组合。4.2 心跳保活Heartbeat实时会话需要保持活跃_heartbeat_loopllm_handler_qwen_omni.py以25 秒下限 20 秒为周期仅在「连接存活且当前未在生成回复is_processing为 False」时重新发送session.update作为心跳防止长空闲连接被服务端回收。4.3 自动重连机制针对网络抖动导致的 WebSocket 断连QwenOmniContext内置了一套自动重连逻辑断连回调on_close记录断连时间并触发trigger_reconnection()重连条件启用了重连、未关闭、未在重连中、且尝试次数 3 次重连策略首次立即重试之后每次间隔5 秒连接建立超时15 秒等待过程每 0.5 秒检查一次关闭事件以保证可被中断重连成功后会自动用缓存的历史session_update_params重新下发会话参数并复位尝试计数。4.4 音频收发链路上行_handle_audio_inputllm_handler_qwen_omni.py把 VAD 送来的HUMAN_AUDIO统一转为 int16float32 会先 clip 到 [-1,1] 再乘 32767base64 编码后append_audio上送当数据携带human_speech_end标记时调用commit()create_response()触发模型回复并将is_processing置 True。下行_audio_processing_workerllm_handler_qwen_omni.pyresponse.audio.delta回调把 base64 音频放入接收队列工作线程解码为 int16、归一化为 float32/32767.0、reshape 为(1, N)后以AVATAR_AUDIO类型提交给下游收到response.done时向队列写入结束标记工作线程随即补发一段(1, 240)的零音频作为流结束信号。4.5 视频输入链路enable_video_input: true时摄像头帧会以CAMERA_VIDEO类型进入_handle_video_inputllm_handler_qwen_omni.py处理规则如下audio-first 约束只有当前轮语音已经开始上送current_turn_audio_started为 True才允许发视频避免纯视频帧触发多余推理频率节流距上次发送不足video_frame_interval_ms默认 1000ms则丢弃本帧图像处理_process_video_frame对帧做 squeeze、BGR→RGB 通道反转OpenCV 默认 BGRPIL 需要 RGB、缩放并 JPEG 编码quality75, optimizeTrue最后 base64 后append_video上送。4.6 文本输出链路enable_text_output: true时response.text.delta回调将增量文本放入接收队列_text_processing_workerllm_handler_qwen_omni.py逐段以AVATAR_TEXT类型提交并携带avatar_text_end元数据标记流结束供前端/数字人模块做打字机式渲染。若开启enable_input_transcriptionconversation.item.input_audio_transcription.completed事件会把转写文本以HUMAN_TEXT输出用于回显——但正如原文档强调manual 模式下该结果「非常差且不可靠」因此默认关闭改由本地 SenseVoice 承担回显。五、部署运行指南5.1 前置准备Qwen-Omni 方案依赖百炼 API 密钥。配置方式二选一# 方式一环境变量推荐 export DASHSCOPE_API_KEYsk-xxxxxx # 方式二直接写入 chat_with_qwen_omni.yaml 的 QwenOmni.api_key 字段若二者都未提供Handler 在load阶段会直接抛错DASHSCOPE_API_KEY is required for Qwen-Omni handler。其余环境准备git-lfs、CUDA ≥ 12.8、uv 安装等参见 docs/getting-started/index.md。5.2 依赖安装与模型下载# 按配置安装依赖会自动解析并安装所有 handler 依赖 uv run install.py --config config/chat_with_qwen_omni.yaml # 下载配置所需的模型SenseVoice、LiteAvatar/MuseTalk 等国内推荐 modelscope 源 uv run scripts/download_models.py --config config/chat_with_qwen_omni.yaml --source modelscope5.3 启动服务uv run src/demo.py --config config/chat_with_qwen_omni.yaml启动后访问 WebRTC 前端页面默认0.0.0.0:8282使用 ssl_certs/ 自签证书即可体验「摄像头 语音」多模态对话与数字人驱动效果。六、注意事项与已知限制服务端 VAD 未启用enable_turn_detection必须保持false断句完全依赖本地 SileroVAD 的参数调优模型侧转写不可用manual 模式下enable_input_transcription默认关闭对话回显由 SenseVoice 承担若强行开启会获得质量很差的转写文本视频帧频率下限video_frame_interval_ms不得低于 500ms源码级ge500约束并发限制配置中concurrent_limit: 1实时多模态会话资源开销较大不建议盲目调高会话时长RtcClient.connection_ttl生效值为 900 秒长对话需关注会话重建密钥安全建议优先使用环境变量而非明文写入配置文件。七、延伸阅读Handler 概览与分类SenseVoice ASR HandlerSileroVAD HandlerLiteAvatar Handler / MuseTalk HandlerRTC Client Handler工作原理与整体数据流快速开始依赖安装与模型下载赞分享数字人AI 应用语音多模态音视频后端【免费下载链接】OpenAvatarChat项目地址https://gitcode.com/gh_mirrors/op/OpenAvatarChat点击查看免费下载相关推荐Flutter url_launcher 插件实战指南跨平台 URL 启动、平台配置与源码级解析Flutter url_launcher 插件实战指南跨平台 URL 启动、平台配置与源码级解析 本指南以 Flutter 官方维护的 url_launche数字人AI 应用语音多模态音视频后端AIRI 接入阿里云百炼 CosyVoice 语音合成从 API Key 到全链路配置实战AIRI 接入阿里云百炼 CosyVoice 语音合成从 API Key 到全链路配置实战 本文是 AIRI 语音合成Text to Speech提供者配AI 应用人工智能大模型数字人AI Agent语音前端后端桌面应用移动开发即时通讯3D渲染microUI1100 行 ANSI C 到底能画出多少界面microUI1100 行 ANSI C 到底能画出多少界面 microUI 是一个用 ANSI C 编写的即时模式immediate modeUI 库数字人AI 应用语音多模态音视频后端上一篇终极解决方案5个快速排查步骤解决MoviePilot番剧推荐空白问题下一篇5步彻底解决AEUX插件连接障碍从设计到动画的无缝转换指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考