继数字人项目介绍:LivePortrait,本文汇总介绍几款开源数字人项目,缺乏实战环节。
LiveTalking
官网,开源(GitHub,8K Star,1.3K Fork)。
支持:
- 多种数字人模型:ernerf、musetalk、wav2lip、Ultralight-Digital-Human
- 声音克隆
- 数字人说话被打断
- webrtc、虚拟摄像头输出
- 动作编排:不说话时播放自定义视频
- 多并发
架构
#mermaid-svg-Zk8ja0mvODySHejs{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-Zk8ja0mvODySHejs .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Zk8ja0mvODySHejs .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Zk8ja0mvODySHejs .error-icon{fill:#552222;}#mermaid-svg-Zk8ja0mvODySHejs .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Zk8ja0mvODySHejs .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Zk8ja0mvODySHejs .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Zk8ja0mvODySHejs .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Zk8ja0mvODySHejs .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Zk8ja0mvODySHejs .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Zk8ja0mvODySHejs .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Zk8ja0mvODySHejs .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Zk8ja0mvODySHejs .marker.cross{stroke:#333333;}#mermaid-svg-Zk8ja0mvODySHejs svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Zk8ja0mvODySHejs p{margin:0;}#mermaid-svg-Zk8ja0mvODySHejs .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-Zk8ja0mvODySHejs .cluster-label text{fill:#333;}#mermaid-svg-Zk8ja0mvODySHejs .cluster-label span{color:#333;}#mermaid-svg-Zk8ja0mvODySHejs .cluster-label span p{background-color:transparent;}#mermaid-svg-Zk8ja0mvODySHejs .label text,#mermaid-svg-Zk8ja0mvODySHejs span{fill:#333;color:#333;}#mermaid-svg-Zk8ja0mvODySHejs .node rect,#mermaid-svg-Zk8ja0mvODySHejs .node circle,#mermaid-svg-Zk8ja0mvODySHejs .node ellipse,#mermaid-svg-Zk8ja0mvODySHejs .node polygon,#mermaid-svg-Zk8ja0mvODySHejs .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Zk8ja0mvODySHejs .rough-node .label text,#mermaid-svg-Zk8ja0mvODySHejs .node .label text,#mermaid-svg-Zk8ja0mvODySHejs .image-shape .label,#mermaid-svg-Zk8ja0mvODySHejs .icon-shape .label{text-anchor:middle;}#mermaid-svg-Zk8ja0mvODySHejs .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-Zk8ja0mvODySHejs .rough-node .label,#mermaid-svg-Zk8ja0mvODySHejs .node .label,#mermaid-svg-Zk8ja0mvODySHejs .image-shape .label,#mermaid-svg-Zk8ja0mvODySHejs .icon-shape .label{text-align:center;}#mermaid-svg-Zk8ja0mvODySHejs .node.clickable{cursor:pointer;}#mermaid-svg-Zk8ja0mvODySHejs .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-Zk8ja0mvODySHejs .arrowheadPath{fill:#333333;}#mermaid-svg-Zk8ja0mvODySHejs .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-Zk8ja0mvODySHejs .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-Zk8ja0mvODySHejs .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Zk8ja0mvODySHejs .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-Zk8ja0mvODySHejs .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Zk8ja0mvODySHejs .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-Zk8ja0mvODySHejs .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-Zk8ja0mvODySHejs .cluster text{fill:#333;}#mermaid-svg-Zk8ja0mvODySHejs .cluster span{color:#333;}#mermaid-svg-Zk8ja0mvODySHejs div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-Zk8ja0mvODySHejs .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-Zk8ja0mvODySHejs rect.text{fill:none;stroke-width:0;}#mermaid-svg-Zk8ja0mvODySHejs .icon-shape,#mermaid-svg-Zk8ja0mvODySHejs .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Zk8ja0mvODySHejs .icon-shape p,#mermaid-svg-Zk8ja0mvODySHejs .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-Zk8ja0mvODySHejs .icon-shape .label rect,#mermaid-svg-Zk8ja0mvODySHejs .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Zk8ja0mvODySHejs .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-Zk8ja0mvODySHejs .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-Zk8ja0mvODySHejs :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-Zk8ja0mvODySHejs .blueBox>*{fill:#e3f2fd!important;stroke:#90caf9!important;stroke-width:1px!important;}#mermaid-svg-Zk8ja0mvODySHejs .blueBox span{fill:#e3f2fd!important;stroke:#90caf9!important;stroke-width:1px!important;}#mermaid-svg-Zk8ja0mvODySHejs .yellowGroup>*{fill:#fff8e1!important;stroke:#ffe082!important;stroke-width:2px!important;}#mermaid-svg-Zk8ja0mvODySHejs .yellowGroup span{fill:#fff8e1!important;stroke:#ffe082!important;stroke-width:2px!important;}#mermaid-svg-Zk8ja0mvODySHejs .labelText>*{fill:none!important;stroke:none!important;color:#bdbdbd!important;font-size:14px!important;}#mermaid-svg-Zk8ja0mvODySHejs .labelText span{fill:none!important;stroke:none!important;color:#bdbdbd!important;font-size:14px!important;}#mermaid-svg-Zk8ja0mvODySHejs .labelText tspan{fill:#bdbdbd!important;} AI_Modules
Web_Layer
接入与网络层 Web/RTC Layer
aiohttp
aiortc
会话控制层 Session Layer
数字人调度层 Avatar Engine
模型与算法层 AI Modules
LLM
TTS
数字人推理
四层模块化架构分层设计:
- 接入与网络层(Web/RTC Layer):基于
aiohttp和aiortc提供HTTP API和WebRTC协议接入,还支持RTMP和虚拟摄像头(VirtualCam)。 - 会话控制层(Session/Lifecycle Layer):提供基于Session ID的多线程、多路复用调度。保证不同接入用户的状态隔离。
- 数字人调度层(Avatar Engine Layer):流转核心,负责接收输入并协调TTS、音视频对齐以及最后的每一帧整合。
- 模型与算法层(AI Modules):最底层是可插拔式的AI模型,如Musetalk、Wav2Lip的端到端推理,CosyVoice、Edge-TTS等语音合成,以及基于LLM的思考层。
面向对象抽象和工厂模式(Registry)
#mermaid-svg-oIFr9r1ChRCpQ3cT{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-oIFr9r1ChRCpQ3cT .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-oIFr9r1ChRCpQ3cT .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-oIFr9r1ChRCpQ3cT .error-icon{fill:#552222;}#mermaid-svg-oIFr9r1ChRCpQ3cT .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-oIFr9r1ChRCpQ3cT .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-oIFr9r1ChRCpQ3cT .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-oIFr9r1ChRCpQ3cT .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-oIFr9r1ChRCpQ3cT .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-oIFr9r1ChRCpQ3cT .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-oIFr9r1ChRCpQ3cT .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-oIFr9r1ChRCpQ3cT .marker{fill:#333333;stroke:#333333;}#mermaid-svg-oIFr9r1ChRCpQ3cT .marker.cross{stroke:#333333;}#mermaid-svg-oIFr9r1ChRCpQ3cT svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-oIFr9r1ChRCpQ3cT p{margin:0;}#mermaid-svg-oIFr9r1ChRCpQ3cT g.classGroup text{fill:#9370DB;stroke:none;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:10px;}#mermaid-svg-oIFr9r1ChRCpQ3cT g.classGroup text .title{font-weight:bolder;}#mermaid-svg-oIFr9r1ChRCpQ3cT .cluster-label text{fill:#333;}#mermaid-svg-oIFr9r1ChRCpQ3cT .cluster-label span{color:#333;}#mermaid-svg-oIFr9r1ChRCpQ3cT .cluster-label span p{background-color:transparent;}#mermaid-svg-oIFr9r1ChRCpQ3cT .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-oIFr9r1ChRCpQ3cT .cluster text{fill:#333;}#mermaid-svg-oIFr9r1ChRCpQ3cT .cluster span{color:#333;}#mermaid-svg-oIFr9r1ChRCpQ3cT .nodeLabel,#mermaid-svg-oIFr9r1ChRCpQ3cT .edgeLabel{color:#131300;}#mermaid-svg-oIFr9r1ChRCpQ3cT .edgeLabel .label rect{fill:#ECECFF;}#mermaid-svg-oIFr9r1ChRCpQ3cT .label text{fill:#131300;}#mermaid-svg-oIFr9r1ChRCpQ3cT .labelBkg{background:#ECECFF;}#mermaid-svg-oIFr9r1ChRCpQ3cT .edgeLabel .label span{background:#ECECFF;}#mermaid-svg-oIFr9r1ChRCpQ3cT .classTitle{font-weight:bolder;}#mermaid-svg-oIFr9r1ChRCpQ3cT .node rect,#mermaid-svg-oIFr9r1ChRCpQ3cT .node circle,#mermaid-svg-oIFr9r1ChRCpQ3cT .node ellipse,#mermaid-svg-oIFr9r1ChRCpQ3cT .node polygon,#mermaid-svg-oIFr9r1ChRCpQ3cT .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-oIFr9r1ChRCpQ3cT .divider{stroke:#9370DB;stroke-width:1;}#mermaid-svg-oIFr9r1ChRCpQ3cT g.clickable{cursor:pointer;}#mermaid-svg-oIFr9r1ChRCpQ3cT g.classGroup rect{fill:#ECECFF;stroke:#9370DB;}#mermaid-svg-oIFr9r1ChRCpQ3cT g.classGroup line{stroke:#9370DB;stroke-width:1;}#mermaid-svg-oIFr9r1ChRCpQ3cT .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5;}#mermaid-svg-oIFr9r1ChRCpQ3cT .classLabel .label{fill:#9370DB;font-size:10px;}#mermaid-svg-oIFr9r1ChRCpQ3cT .relation{stroke:#333333;stroke-width:1;fill:none;}#mermaid-svg-oIFr9r1ChRCpQ3cT .dashed-line{stroke-dasharray:3;}#mermaid-svg-oIFr9r1ChRCpQ3cT .dotted-line{stroke-dasharray:1 2;}#mermaid-svg-oIFr9r1ChRCpQ3cT #compositionStart,#mermaid-svg-oIFr9r1ChRCpQ3cT .composition{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-oIFr9r1ChRCpQ3cT #compositionEnd,#mermaid-svg-oIFr9r1ChRCpQ3cT .composition{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-oIFr9r1ChRCpQ3cT #dependencyStart,#mermaid-svg-oIFr9r1ChRCpQ3cT .dependency{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-oIFr9r1ChRCpQ3cT #dependencyStart,#mermaid-svg-oIFr9r1ChRCpQ3cT .dependency{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-oIFr9r1ChRCpQ3cT #extensionStart,#mermaid-svg-oIFr9r1ChRCpQ3cT .extension{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-oIFr9r1ChRCpQ3cT #extensionEnd,#mermaid-svg-oIFr9r1ChRCpQ3cT .extension{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-oIFr9r1ChRCpQ3cT #aggregationStart,#mermaid-svg-oIFr9r1ChRCpQ3cT .aggregation{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-oIFr9r1ChRCpQ3cT #aggregationEnd,#mermaid-svg-oIFr9r1ChRCpQ3cT .aggregation{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-oIFr9r1ChRCpQ3cT #lollipopStart,#mermaid-svg-oIFr9r1ChRCpQ3cT .lollipop{fill:#ECECFF!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-oIFr9r1ChRCpQ3cT #lollipopEnd,#mermaid-svg-oIFr9r1ChRCpQ3cT .lollipop{fill:#ECECFF!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-oIFr9r1ChRCpQ3cT .edgeTerminals{font-size:11px;line-height:initial;}#mermaid-svg-oIFr9r1ChRCpQ3cT .classTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-oIFr9r1ChRCpQ3cT .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-oIFr9r1ChRCpQ3cT .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-oIFr9r1ChRCpQ3cT :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-oIFr9r1ChRCpQ3cT .SessionManage>*{fill:#e3f2fd!important;stroke:#90caf9!important;stroke-width:1px!important;}#mermaid-svg-oIFr9r1ChRCpQ3cT .SessionManage span{fill:#e3f2fd!important;stroke:#90caf9!important;stroke-width:1px!important;}#mermaid-svg-oIFr9r1ChRCpQ3cT .BaseAvatar>*{fill:#e3f2fd!important;stroke:#90caf9!important;stroke-width:1px!important;}#mermaid-svg-oIFr9r1ChRCpQ3cT .BaseAvatar span{fill:#e3f2fd!important;stroke:#90caf9!important;stroke-width:1px!important;}#mermaid-svg-oIFr9r1ChRCpQ3cT .MusetalkAvatar>*{fill:#e3f2fd!important;stroke:#90caf9!important;stroke-width:1px!important;}#mermaid-svg-oIFr9r1ChRCpQ3cT .MusetalkAvatar span{fill:#e3f2fd!important;stroke:#90caf9!important;stroke-width:1px!important;}#mermaid-svg-oIFr9r1ChRCpQ3cT .Wav2LipAvatar>*{fill:#e3f2fd!important;stroke:#90caf9!important;stroke-width:1px!important;}#mermaid-svg-oIFr9r1ChRCpQ3cT .Wav2LipAvatar span{fill:#e3f2fd!important;stroke:#90caf9!important;stroke-width:1px!important;}#mermaid-svg-oIFr9r1ChRCpQ3cT .BaseOutput>*{fill:#e3f2fd!important;stroke:#90caf9!important;stroke-width:1px!important;}#mermaid-svg-oIFr9r1ChRCpQ3cT .BaseOutput span{fill:#e3f2fd!important;stroke:#90caf9!important;stroke-width:1px!important;}#mermaid-svg-oIFr9r1ChRCpQ3cT .WebRTCOutput>*{fill:#e3f2fd!important;stroke:#90caf9!important;stroke-width:1px!important;}#mermaid-svg-oIFr9r1ChRCpQ3cT .WebRTCOutput span{fill:#e3f2fd!important;stroke:#90caf9!important;stroke-width:1px!important;}#mermaid-svg-oIFr9r1ChRCpQ3cT .RTMPOutput>*{fill:#e3f2fd!important;stroke:#90caf9!important;stroke-width:1px!important;}#mermaid-svg-oIFr9r1ChRCpQ3cT .RTMPOutput span{fill:#e3f2fd!important;stroke:#90caf9!important;stroke-width:1px!important;} manages
delegates stream
extends
extends
extends
extends
1..*
SessionManage
+dict sessions
+create_session()
+get_session()
BaseAvatar
+TTS tts
+ASR asr
+BaseOutput output
+inference()
+process_frames()
MusetalkAvatar
Wav2LipAvatar
<<Abstract>>
BaseOutput
+push_video_frame(frame)
+push_audio_frame(frame, eventpoint)
WebRTCOutput
RTMPOutput
解读:
SessionManager(全局会话管家):单例模式(Singleton)。在app.py启动后,所有WebRTC Offer经过处理会调用该管家生成或绑定一个上下文对话环境。BaseAvatar(数字人基类):每一个并行数字人连接对应一个Avatar实例,管理内部三大核心生命周期。不同驱动模型(如MusetalkAvatar,Wav2LipAvatar)继承自它,实现自定义的预加载、推理和贴图逻辑。- 在
BaseAvatar内部,有着高度解耦的三大核心组件,都通过registry.create()动态注入:self.tts:文字转语音模块(对接不同TTS引擎)。self.asr(Audio feat):特征提取及缓冲队列,实现音频对齐。self.output:流数据输出基类(继承链如WebRTCOutput,RTMPOutput)。
由于采用组件化+反射式加载(Import lib),开发者增加一个新的TTS或数字人推理算法,完全不需要修改主干代码流向,极大地增强二开友好性。
环环相扣的流式Pipeline:
- 请求入站与分流:前端用户发来音频流或长文本。若是音频,则不需要经过全链路的思考环节(无LLM和TTS参与),直接作为PCM数据送入下游进行数字人分发播报;若是文本,则触发LLM思考并交由TTS。
- 文本通道 (LLM->TTS):
- LLM开始思考,生成
Text chunk以保障低延迟。 - 文本进入
tts.put_msg_txt()。 TTS模块被唤醒,调用对应的API(如腾讯TTS或是本地模型),不断转换出np.float32的PCM采样矩阵(常规是16KHz),并按20ms一帧喂给系统的chunk_queue。
- LLM开始思考,生成
- 视觉推理准备(AudioFeature提取):音频序列被送给对应的处理模块提取视觉所需特征(如Wav2Lip的Mel频谱图,或Musetalk的whisper特征)。
- 核心AI推理循环 (Inference):获取到音频特征后,调用AI模型进行批量计算,将"静态图/视频帧+语音特征"推理生成对应Crop面部区域帧。
- 合帧处理(Process & Paste back):提取出的嘴唇视频帧需要回贴 (paste back) 到原来全尺寸的背景视频空间,进行Alpha融合或高斯模糊过渡操作。并进行说话/静音判断下的防抖和效果过渡。
- 音视频下发流推(StreamOut):
- 每一帧成型的图像以及对应40ms音频帧放进Output队列。
streamout/webrtc.py通过PlayerStreamTrack按时间戳定时消费,最终打成RTP包跨越公网到达浏览器!
StreamOut Frame Processing GPU Inference Audio Feature TTS LLM Client StreamOut Frame Processing GPU Inference Audio Feature TTS LLM Client #mermaid-svg-LmBtei9doHxem0Bj{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-LmBtei9doHxem0Bj .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-LmBtei9doHxem0Bj .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-LmBtei9doHxem0Bj .error-icon{fill:#552222;}#mermaid-svg-LmBtei9doHxem0Bj .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-LmBtei9doHxem0Bj .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-LmBtei9doHxem0Bj .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-LmBtei9doHxem0Bj .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-LmBtei9doHxem0Bj .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-LmBtei9doHxem0Bj .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-LmBtei9doHxem0Bj .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-LmBtei9doHxem0Bj .marker{fill:#333333;stroke:#333333;}#mermaid-svg-LmBtei9doHxem0Bj .marker.cross{stroke:#333333;}#mermaid-svg-LmBtei9doHxem0Bj svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-LmBtei9doHxem0Bj p{margin:0;}#mermaid-svg-LmBtei9doHxem0Bj .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-LmBtei9doHxem0Bj text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-LmBtei9doHxem0Bj .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-LmBtei9doHxem0Bj .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-LmBtei9doHxem0Bj .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-LmBtei9doHxem0Bj .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-LmBtei9doHxem0Bj #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-LmBtei9doHxem0Bj .sequenceNumber{fill:white;}#mermaid-svg-LmBtei9doHxem0Bj #sequencenumber{fill:#333;}#mermaid-svg-LmBtei9doHxem0Bj #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-LmBtei9doHxem0Bj .messageText{fill:#333;stroke:none;}#mermaid-svg-LmBtei9doHxem0Bj .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-LmBtei9doHxem0Bj .labelText,#mermaid-svg-LmBtei9doHxem0Bj .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-LmBtei9doHxem0Bj .loopText,#mermaid-svg-LmBtei9doHxem0Bj .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-LmBtei9doHxem0Bj .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-LmBtei9doHxem0Bj .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-LmBtei9doHxem0Bj .noteText,#mermaid-svg-LmBtei9doHxem0Bj .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-LmBtei9doHxem0Bj .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-LmBtei9doHxem0Bj .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-LmBtei9doHxem0Bj .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-LmBtei9doHxem0Bj .actorPopupMenu{position:absolute;}#mermaid-svg-LmBtei9doHxem0Bj .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-LmBtei9doHxem0Bj .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-LmBtei9doHxem0Bj .actor-man circle,#mermaid-svg-LmBtei9doHxem0Bj line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-LmBtei9doHxem0Bj :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 直接发送语音流 文本输入 思考后返回 Text chunks 语音 PCM 数据 音频特征 (Mel/Whisper) 推理出的人脸嘴形帧 合成融合图像及音频 通过 WebRTC/RTMP 发送
BaseAvatar设计经典三线程加一协程(3 Thread + 1 Async)的异步隔离并发架构:
- 线程 1:The Render Thread (主控调度)
大循环线程,只要系统在运行,它就在不停运转self.asr.run_step()并监控系统的缓冲区。当发现下游Buffer过载(来不及消费),会主动触发time.sleep等待,做简单的背压控制 (Backpressure) 来防止内存爆炸。
-
线程 2:The Inference Thread (重型计算)
- 目标:专职应对GPU加速操作。
- 机制:采用阻塞式队列等待
audiofeat_batch = self.asr.feat_queue.get()。平时休眠,一旦有积累特征,就开始走模型的前向传播 (inference_batch)。它保障了深度学习引擎发挥出最大算力(利用完整Batch推理),并且推理结束后将输出丢给下游队列。
-
线程 3: The Process_Frames Thread (轻型 CPU 处理)
- **目标:**主要负责 CPU 密集型的工作(如 OpenCV 的贴图拼合、视频画面的过渡效果切换)。
- **机制:**此类操作如果和 Inference 放在一起,CPU 的计算很容易拖慢 GPU 推理的节奏。独立出来后,只要队列里拿得到 推理后的 face 图片和音频阵列,就疯狂的
paste_back_frame,直接推向网络出口。
异步循环:The WebRTC IO(协程网络拉流)
WebRTC本身是由aiortc基于 Event Loop (Asyncio) 拉动的。通过PlayerStreamTrack的next_timestamp和recv()时钟触发器,按真实的walltime严格遵守20ms间隔取音频帧,40ms(25fps) 取视频帧。这一分离完全保证无论后端推理如何瞬时波动,前端观看依然尽可能保持平滑的时间戳消费。
#mermaid-svg-NEZXwf6TWcBe8Im9{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-NEZXwf6TWcBe8Im9 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-NEZXwf6TWcBe8Im9 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-NEZXwf6TWcBe8Im9 .error-icon{fill:#552222;}#mermaid-svg-NEZXwf6TWcBe8Im9 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-NEZXwf6TWcBe8Im9 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-NEZXwf6TWcBe8Im9 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-NEZXwf6TWcBe8Im9 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-NEZXwf6TWcBe8Im9 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-NEZXwf6TWcBe8Im9 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-NEZXwf6TWcBe8Im9 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-NEZXwf6TWcBe8Im9 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-NEZXwf6TWcBe8Im9 .marker.cross{stroke:#333333;}#mermaid-svg-NEZXwf6TWcBe8Im9 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-NEZXwf6TWcBe8Im9 p{margin:0;}#mermaid-svg-NEZXwf6TWcBe8Im9 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-NEZXwf6TWcBe8Im9 .cluster-label text{fill:#333;}#mermaid-svg-NEZXwf6TWcBe8Im9 .cluster-label span{color:#333;}#mermaid-svg-NEZXwf6TWcBe8Im9 .cluster-label span p{background-color:transparent;}#mermaid-svg-NEZXwf6TWcBe8Im9 .label text,#mermaid-svg-NEZXwf6TWcBe8Im9 span{fill:#333;color:#333;}#mermaid-svg-NEZXwf6TWcBe8Im9 .node rect,#mermaid-svg-NEZXwf6TWcBe8Im9 .node circle,#mermaid-svg-NEZXwf6TWcBe8Im9 .node ellipse,#mermaid-svg-NEZXwf6TWcBe8Im9 .node polygon,#mermaid-svg-NEZXwf6TWcBe8Im9 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-NEZXwf6TWcBe8Im9 .rough-node .label text,#mermaid-svg-NEZXwf6TWcBe8Im9 .node .label text,#mermaid-svg-NEZXwf6TWcBe8Im9 .image-shape .label,#mermaid-svg-NEZXwf6TWcBe8Im9 .icon-shape .label{text-anchor:middle;}#mermaid-svg-NEZXwf6TWcBe8Im9 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-NEZXwf6TWcBe8Im9 .rough-node .label,#mermaid-svg-NEZXwf6TWcBe8Im9 .node .label,#mermaid-svg-NEZXwf6TWcBe8Im9 .image-shape .label,#mermaid-svg-NEZXwf6TWcBe8Im9 .icon-shape .label{text-align:center;}#mermaid-svg-NEZXwf6TWcBe8Im9 .node.clickable{cursor:pointer;}#mermaid-svg-NEZXwf6TWcBe8Im9 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-NEZXwf6TWcBe8Im9 .arrowheadPath{fill:#333333;}#mermaid-svg-NEZXwf6TWcBe8Im9 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-NEZXwf6TWcBe8Im9 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-NEZXwf6TWcBe8Im9 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-NEZXwf6TWcBe8Im9 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-NEZXwf6TWcBe8Im9 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-NEZXwf6TWcBe8Im9 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-NEZXwf6TWcBe8Im9 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-NEZXwf6TWcBe8Im9 .cluster text{fill:#333;}#mermaid-svg-NEZXwf6TWcBe8Im9 .cluster span{color:#333;}#mermaid-svg-NEZXwf6TWcBe8Im9 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-NEZXwf6TWcBe8Im9 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-NEZXwf6TWcBe8Im9 rect.text{fill:none;stroke-width:0;}#mermaid-svg-NEZXwf6TWcBe8Im9 .icon-shape,#mermaid-svg-NEZXwf6TWcBe8Im9 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-NEZXwf6TWcBe8Im9 .icon-shape p,#mermaid-svg-NEZXwf6TWcBe8Im9 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-NEZXwf6TWcBe8Im9 .icon-shape .label rect,#mermaid-svg-NEZXwf6TWcBe8Im9 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-NEZXwf6TWcBe8Im9 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-NEZXwf6TWcBe8Im9 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-NEZXwf6TWcBe8Im9 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-NEZXwf6TWcBe8Im9 .threadBox>*{fill:#fff8e1!important;stroke:#ffe082!important;stroke-width:2px!important;}#mermaid-svg-NEZXwf6TWcBe8Im9 .threadBox span{fill:#fff8e1!important;stroke:#ffe082!important;stroke-width:2px!important;}#mermaid-svg-NEZXwf6TWcBe8Im9 .componentBox>*{fill:#e3f2fd!important;stroke:#90caf9!important;stroke-width:1px!important;}#mermaid-svg-NEZXwf6TWcBe8Im9 .componentBox span{fill:#e3f2fd!important;stroke:#90caf9!important;stroke-width:1px!important;} Main / Event Loop
Thread 3: Process
Thread 2: Inference
Thread 1: Render Loop
Trigger
Batch Queue
Res Frame Queue
Output Queue
Buffer Monitor & Step
Audio Feature Extractor
GPU Forward Pass
CPU Paste_back
RTC Manager
SoulX-LiveTalk
论文,项目主页,Soul AI Lab团队开源(GitHub,1.3K Star,127 Fork)数字人生成项目。核心突破:能够让虚拟形象根据音频输入实时生成逼真的面部表情和唇部动作,启动速度极快,仅需0.87秒就能开始工作。训练效率提升23倍,能够更快地学习并生成高质量的内容。
基于140亿参数的扩散Transformer模型,专门为解决实时流媒体应用中的延迟问题而设计。
功能特点
- 智能学习机制:采用独特的"双向蒸馏"技术,让模型能够同时考虑前后文信息,而不是像传统模型那样只能单向思考。使得生成的动作更加连贯自然,有效避免画面卡顿或失真。
- 实时性能表现:能够以32帧/秒的速度生成视频,完全满足实时对话的需求。无论是在短时间对话还是长达数小时的连续交流中,都能保持稳定的性能表现。
- 自我修正能力:具备智能的错误修正功能,能够在长时间运行中自动检测并纠正累积的误差,确保生成的画面始终清晰稳定。
SoulX-FlashHead
项目主页,开源(GitHub,855 Star,83 Fork)
MuseTalk
论文,腾讯团队基于潜在空间修复技术,实现实时高质量唇形同步的开源(GitHub,6.1K Star,871 Fork)项目。一个实时的音频驱动唇部同步模型,能够根据输入的音频信号,自动调整数字人物的面部图像,使其唇形与音频内容高度同步。特别适用于256 x 256像素的面部区域,且支持中英日等多种语言输入。在Tesla V100显卡上,能够实现超过每秒30帧的实时推理速度。还可通过调整面部区域的中心点,进一步优化生成效果。
主要包含三大块:
- 素材上传(上传驱动音频和参考视频素材)
- 参数调整(具体可根据实际情况调整)
- 生成预览(生成后的视频预览)
重要参数bbox_shift,用于调整面部区域的中心点,特别是用于控制生成视频中嘴巴的开合程度:
- 正值:使嘴巴向下半部分移动,增加嘴巴的张开度,使得生成的视频中角色看起来像是在更清晰地发音;
- 负值:使嘴巴向上半部分移动,减少嘴巴的张开度,使得角色看起来像是在轻微地发音或闭嘴。
输入视频的质量会影响输出的数字人效果:
- 注意视频最好不要有胡子,避免换嘴型后胡子变模糊
- 注意语速不用太快,要吐字清晰
- 灯光亮一点,脸白一点
- 避免侧脸
- 每句话之间保持嘴闭合的停顿
- 安静的环境中录制
使用ChatTTS制作输入音频,利用GFPGAN提高画质,使用FaceFusion融合原脸。
MuseV
项目主页,基于视觉条件并行去噪的无限长高保真开源(GitHub,2.8K Star,305 Fork)虚拟人视频生成模型,HF主页。
模型结构示意图

基于扩散模型,特点:
- 支持使用新颖的视觉条件并行去噪方案进行无限长度生成,不会再有误差累计的问题,尤其适用于固定相机位的场景
- 提供基于人物类型数据集训练的虚拟人视频生成预训练模型
- 支持图像到视频、文本到图像到视频、视频到视频的生成
- 兼容Stable Diffusion文图生成生态系统,包括
base_model、lora、controlnet等 - 支持多参考图像技术,包括IPAdapter、ReferenceOnly、ReferenceNet、IPAdapterFaceID
基于Docker部署:
bash
docker run --gpus all -it --entrypoint /bin/bash anchorxia/musev:latest
其他资源:
- ComfyUI整合包
- 参考视频:bilibili
- Windows整合包:https://www.123pan.com/s/Pf5Yjv-Bb9W3.html,密码:glut
MusePose
用于虚拟人物的开源(GitHub,2.7K Star,202 Fork)图像到视频生成框架,可根据控制信号(姿态)生成视频。结合MuseV和MuseTalk,旨在打造愿景:端到端生成具有全身运动和交互能力的虚拟人物。