OpenAvatarChat LiteAvatar 数字人 Handler 完全指南:配置、模型下载与多会话部署

原创2026-10-03 17:06:42689 阅读
文章标签:数字人AI 应用语音多模态音视频后端

OpenAvatarChat LiteAvatar 数字人 Handler 完全指南:配置、模型下载与多会话部署

LiteAvatar 是 OpenAvatarChat 内置的 2D 数字人渲染 Handler,它接收上游 TTS 产出的语音流,通过 LiteAvatar 算法将语音实时转换为口型与面部表情驱动信号,最终输出"带数字人形象 + 同步语音"的视频流,可让聊天机器人以拟人形象实时开口说话。本文围绕该 Handler 的模型依赖、配置参数、多会话并发与底层实现展开,读完即可在 OpenAvatarChat 中完整接入并调优一个 LiteAvatar 数字人链路。

一、LiteAvatar Handler 是什么

LiteAvatar 是一种 2D 数字人方案:利用一张人物形象素材,结合音频驱动模型(audio2param / param2img)生成贴合语音内容的口型与表情变化,再与背景图合成完整视频帧。OpenAvatarChat 在 src/handlers/avatar/liteavatar/avatar_handler_liteavatar.py 中将其封装为标准 Handler(类名 HandlerTts2Face),对外表现:

  • 输入:AVATAR_AUDIO 类型的语音数据(一次消费),来源于 TTS Handler 生成的合成语音;
  • 输出:AVATAR_AUDIO(24kHz 单声道音频流)与 AVATAR_VIDEO(BGR24 视频帧流,最高 30fps,见 avatar_handler_liteavatar.py 的输出定义);
  • 形象来源:OpenAvatarChat 在 ModelScope 的 HumanAIGC-Engineering/LiteAvatarGallery 模型仓库中提供了约 100 个数字人形象资产可供选用,通过配置 avatar_name 即可切换。

该 Handler 定位为"语音到数字人"的最后一环,与 ASR、LLM、TTS 等 Handler 通过 ChatEngine 的流水线串联:用户语音 → VAD 检测 → ASR 转写 → LLM 生成回复 → TTS 合成语音 → LiteAvatar 渲染数字人视频 → RTC/WS 推流给前端。

二、模型依赖:下载 LiteAvatar 权重与形象数据

LiteAvatar Handler 需要两类资源:算法网络权重(音频转口型参数的模型)与具体形象数据(含参考图、人物素材等)。二者都可以通过仓库提供的脚本一键获取。

1. 统一下载脚本(推荐)

在项目根目录执行:

uv run scripts/download_models.py --handler liteavatar

该命令同时完成网络权重与形象数据的下载。从 scripts/download_models.py 的实现可以看到:

  • liteavatar 处理器下载的权重文件为 lm.pb、model_1.onnx、model.pb,目标目录为 src/handlers/avatar/liteavatar/algo/liteavatar;
  • 下载通道偏好 ModelScope(scripts/download_models.py 中 prefer_modelscope = {"liteavatar", "lam"}),调用 modelscope download --model HumanAIGC-Engineering/LiteAvatarGallery;
  • 若目标权重已存在,脚本会跳过下载并打印 "LiteAvatar weights already exist, skipping.",可重复执行。

2. 独立脚本

若只想单独准备 LiteAvatar 资源,也可使用独立脚本:

bash scripts/download_liteavatar_weights.sh

它对应 download_models.py 中 download_liteavatar 分支的等价操作。

3. 形象数据按需自动拉取

除权重外,具体的数字人形象数据由 Handler 在运行时按 avatar_name 自动从 ModelScope 拉取:Tts2faceCpuAdapter._download_from_modelscope(见 tts2face_cpu_adapter.py)会把 avatar_name 补齐 .zip 后缀后下载到 resource/avatar/liteavatar 目录,若本地不存在则自动解压,随后加载到模型。因此你只需在配置中指定 avatar_name,形象数据即可按需就绪。

三、配置参数详解

在总配置文件的 chat_engine.handler_configs 下注册 LiteAvatar Handler。最小配置如下:

LiteAvatar:
  module: avatar/liteavatar/avatar_handler_liteavatar
  avatar_name: 20250408/sample_data
  fps: 25
  use_gpu: true

参数一览

参数 默认值 说明
LiteAvatar.avatar_name 20250408/sample_data 数字人形象数据名(取自 LiteAvatarGallery,对应一个可用形象)
LiteAvatar.fps 25 数字人视频输出帧率
LiteAvatar.enable_fast_mode False 低延迟模式开关
LiteAvatar.use_gpu True 是否使用 GPU 推理
LiteAvatar.debug False 调试模式:在视频帧上叠加状态与帧号文本(源码级附加参数)
LiteAvatar.stop_ack_timeout 5.0 会话结束确认超时(秒),超时后自动重启数字人子进程(源码级附加参数)

参数源码级说明

以上参数由 liteavatar_worker.py 中的 Tts2FaceConfigModel 定义(Pydantic 模型),Handler 加载时将其作为 config_model 解析。各参数的实际作用:

  • avatar_name:直接决定使用哪一个数字人形象。它既会被用于按需下载解压形象 zip(存放到 resource/avatar/liteavatar/<avatar_name>),也会在 Tts2faceCpuAdapter.init 中作为 data_dir 传给 liteAvatar 模型;
  • fps:传给 AvatarInitOption.video_frame_rate,用于设定数字人视频帧率、控制管线各线程的帧节奏与音画对齐(signal2img 线程按 1/fps 间隔逐帧输出);
  • enable_fast_mode:透传给 SpeechAudioProcessor(见 avatar_processor.py 中 _reset_processor_status),开启后采用低延迟的音频切片处理策略,以更激进的节奏消费语音数据换取更低的端到端延迟;
  • use_gpu:在 liteAvatar(data_dir=..., fps=..., use_gpu=...) 构造时传入,控制音频驱动模型是否跑在 GPU 上(仓库源码通过 InspectUtils.has_init_param 检测模型构造签名后决定是否传递该参数);
  • debug:为 True 时,AvatarProcessor._mouth2full_loop 会在每一帧视频左上角用红色文本绘制当前 AvatarStatus 与全局帧号(global_frame_id),便于排查口型状态切换与帧率问题;
  • stop_ack_timeout:数字人子进程停止后需在超时内回执 _stop_ack_event,否则 LiteAvatarWorker.release 判定子进程异常并执行 _restart_avatar_process 重启,防止僵尸会话占用资源。

完整示例:云端 LLM/TTS + LiteAvatar 的轻量配置

OpenAvatarChat 提供了一份可直接运行的完整示例配置 config/chat_with_openai_compatible_bailian_cosyvoice.yaml,其中 LLM 与 TTS 均使用云端 API,本地只跑 VAD/ASR/数字人,是最轻量的 LiteAvatar 链路。其 Handler 注册部分如下:

default:
  chat_engine:
    concurrent_limit: 2
    handler_search_path:
      - "src/handlers"
    handler_configs:
      RtcClient:
        module: client/rtc_client/client_handler_rtc
        connection_ttl: 900
      InterruptHandler:
        module: logic/interrupt/interrupt_handler
      SileroVad:
        module: vad/silerovad/vad_handler_silero
      SenseVoice:
        module: asr/sensevoice/asr_handler_sensevoice
      CosyVoice:
        module: tts/bailian_tts/tts_handler_cosyvoice_bailian
        voice: "longxiaochun"
      LLMOpenAICompatible:
        module: llm/openai_compatible/llm_handler_openai_compatible
      LiteAvatar:
        module: avatar/liteavatar/avatar_handler_liteavatar
        avatar_name: 20250408/sample_data
        fps: 25
        debug: false
        enable_fast_mode: false
        use_gpu: true

对应快速启动步骤(详见 docs/en/getting-started/liteavatar.md):

uv run install.py --config config/chat_with_openai_compatible_bailian_cosyvoice.yaml
uv run scripts/download_models.py --handler liteavatar
uv run src/demo.py --config config/chat_with_openai_compatible_bailian_cosyvoice.yaml

提示:云端 LLM/TTS 需要设置 DASHSCOPE_API_KEY 环境变量,或在项目根目录创建 .env 文件。

四、多会话并发与显存规划

LiteAvatar 支持单机多会话并发。通过在总配置中设置 default.chan_engine.concurrent_limit 即可声明最大并发路数(如上示例中的 2)。

从源码看,并发能力由 liteavatar_worker_manager.py 中的 LiteAvatarWorkerManager 实现:

  • 管理器在初始化时按 concurrent_limit 数量预创建 LiteAvatarWorker 实例,每个 Worker 是一个独立的多进程单元(启动间以 time.sleep(5) 错峰加载,避免同时初始化模型引发资源竞争);
  • 每个新会话到来时,start_worker 会轮询选取状态为 IDLE 的 Worker,置为 BUSY 并通过 event_in_queue 发送 START 事件占用;会话结束释放后回到 IDLE 供复用;
  • 每个 Worker 内部包含独立的模型进程、输入/输出队列与共享内存缓冲池(音频池 10 个缓冲、视频池 10 个缓冲),会话间的模型状态互不干扰。

显存规划:每一路并发大约占用 3GB 显存。concurrent_limit 设置过大可能直接导致显存溢出(OOM),配置时务必结合 GPU 实际显存容量:例如 24GB 显存建议并发上限不超过 6~7 路,并为系统留出余量。

五、源码层面的工作原理

1. 多进程 + 共享内存架构

LiteAvatar 的数字人推理被隔离在独立子进程中(mp.Process,见 liteavatar_worker.py),主进程与子进程之间通过 5 条 multiprocessing 队列通信(事件输入/输出、音频输入/输出、视频输出),音视频帧数据则通过 SharedMemoryBufferPool 共享内存缓冲池零拷贝传递,避免大帧数据反复序列化带来的开销。主进程侧由 HandlerTts2FaceContext 启动两个常驻线程(_media_out_loop、_event_out_loop)不断从共享内存取帧并转交引擎,最终输出 AVATAR_AUDIO 与 AVATAR_VIDEO 数据流。

2. 三阶段渲染管线

子进程内的 AvatarProcessor(avatar_processor.py)以三个线程构成串行流水线:

  1. audio2signal:把语音切片送入算法适配器(Tts2faceCpuAdapter.audio2signal),由 LiteAvatar 模型 audio2param 生成口型参数序列,并按目标帧率限速消费;
  2. signal2img:将口型参数经 param2img 渲染成嘴部图像,并选择背景帧(BgFrameCounter 按 30 / fps 步进轮换参考背景图);队列空闲时自动生成 idle 静默帧,使数字人在无语音时保持自然待机表情(AvatarStatus.LISTENING);
  3. mouth2full:将嘴部图像通过 merge_mouth_to_bg 合成到背景得到完整画面,同时按 PTS 对齐音频帧与视频帧,输出音画同步的 AudioResult / VideoResult。

算法适配器在初始化时会执行 5 次 warm_up(audio2param(bytes(16000*2))),预热模型后再对外提供服务。

3. 打断(Interrupt)机制

Handler 通过信号过滤器监听 STREAM_CANCEL 信号(关联 CLIENT_PLAYBACK 数据流),一旦上游 TTS/LLM 被打断,立即执行 context.interrupt()(见 avatar_handler_liteavatar.py):清空主进程音频/视频输出队列并释放共享内存缓冲,同时向子进程发送 INTERRUPT 事件,由 AvatarProcessor.interrupt 清空 audio_slice → signal → mouth_img 三段中间队列并把状态重置为"可接收新语音",从而保证数字人快速闭嘴、停止渲染,切换到聆听状态。

六、小结

LiteAvatar Handler 为 OpenAvatarChat 提供了一条开箱即用的 2D 数字人渲染链路:一条命令下载模型,一组参数切换形象与帧率,一个 concurrent_limit 开启多会话。结合本文的源码解析,你可以进一步通过 fps 平衡流畅度与算力、用 enable_fast_mode 压缩端到端延迟、按显存预算精确规划并发路数,并利用 debug 模式直观观察口型状态机切换是否符合预期。

相关参考:

登录后查看全文
OpenAvatarChat