<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>数字人 on 方糖猫Blog</title>
    <link>https://ftmao.com/blog/tags/%E6%95%B0%E5%AD%97%E4%BA%BA/</link>
    <description>AI 视频、AI Agent 与工程实践笔记</description>
    <generator>Hugo</generator>
    <language>zh-CN</language>
    <lastBuildDate>Thu, 20 Aug 2026 17:30:00 +0800</lastBuildDate><atom:link href="https://ftmao.com/blog/tags/%E6%95%B0%E5%AD%97%E4%BA%BA/index.xml" rel="self" type="application/rss+xml" /><item>
      <title>LiveTalking 源码解剖：一个开源实时数字人是怎么跑起来的</title>
      <link>https://ftmao.com/blog/posts/livetalking-source-code-analysis/</link>
      <pubDate>Thu, 20 Aug 2026 17:30:00 +0800</pubDate>
      <guid>https://ftmao.com/blog/posts/livetalking-source-code-analysis/</guid>
      <description>&lt;h1 id=&#34;livetalking-源码解剖一个开源实时数字人是怎么跑起来的&#34;&gt;LiveTalking 源码解剖：一个开源实时数字人是怎么跑起来的&lt;/h1&gt;
&lt;p&gt;上一篇&lt;a href=&#34;https://ftmao.com/blog/blog/posts/digital-human-pipeline-beginner-to-mastery/&#34;&gt;《数字人链路从 0 到精通》&lt;/a&gt;画完了实时数字人的完整链路：耳朵（VAD+ASR）、眼睛（视觉感知）、大脑（LLM+RAG）、嘴巴（TTS）、脸（口型驱动）、神经（WebRTC）。概念图看完了，下一步自然的问题是：&lt;strong&gt;真实项目里这条链路长什么样？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;这篇解剖 &lt;a href=&#34;https://gitee.com/lipku/LiveTalking&#34;&gt;LiveTalking&lt;/a&gt;。选它的原因：它在实时数字人开源项目里 star 数排前列，架构足够典型——它把「输出侧」（TTS→口型驱动→WebRTC 推流）做到了工业级，而输入侧和智能侧保持着 demo 形态，正好当「链路完整但交互闭环不完整」的对照样本。读完你会知道一个能跑的数字人项目，哪些部分可以直接抄，哪些部分要自己做。&lt;/p&gt;
&lt;h2 id=&#34;1-项目定位与启动&#34;&gt;1. 项目定位与启动&lt;/h2&gt;
&lt;p&gt;一句话定位：&lt;strong&gt;纯 2D 真人克隆口型驱动 + 流式 TTS/LLM 的实时数字人服务端，前端是浏览器&lt;/strong&gt;。&lt;/p&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;python app.py --transport webrtc --model wav2lip --avatar_id wav2lip256_avatar1&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;ul&gt;
&lt;li&gt;入口 &lt;code&gt;app.py&lt;/code&gt;，HTTP 服务用 aiohttp，默认端口 8010。&lt;/li&gt;
&lt;li&gt;配置三级覆盖：命令行 &amp;gt; &lt;code&gt;config.yaml&lt;/code&gt; &amp;gt; 默认值（&lt;code&gt;config.py&lt;/code&gt;），加上 &lt;code&gt;.env&lt;/code&gt; 读密钥，配置管理做得比多数开源 demo 规范。&lt;/li&gt;
&lt;li&gt;插件注册表 &lt;code&gt;registry.py&lt;/code&gt; 是扩展点：stt / llm / tts / avatar / output 五类插件用装饰器注册，想换实现不用改主流程。&lt;/li&gt;
&lt;li&gt;输出模式五种：&lt;code&gt;--transport&lt;/code&gt; 可选 webrtc（浏览器 &lt;code&gt;/offer&lt;/code&gt; 信令）、whep、rtcpush（WHIP 主动推流到 SRS）、rtmp、virtualcam（虚拟摄像头）。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;顶层目录即架构：&lt;/p&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart TB
    WEB[web/ 浏览器前端] --&amp;gt;|HTTP /human /offer| SERVER[server/&amp;lt;br/&amp;gt;rtc_manager / session_manager / routes]
    SERVER --&amp;gt; AVATAR[avatars/&amp;lt;br/&amp;gt;base_avatar 渲染管线]
    SERVER --&amp;gt; LLM[llm.py&amp;lt;br/&amp;gt;qwen-plus 单轮对话]
    LLM --&amp;gt;|标点切句| TTS[tts/&amp;lt;br/&amp;gt;11 种 TTS 插件]
    TTS --&amp;gt;|20ms 音频帧| AVATAR
    AVATAR --&amp;gt; OUT[streamout/&amp;lt;br/&amp;gt;webrtc / rtcpush / rtmp / virtualcam]
    OUT --&amp;gt; USER([用户])&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;h2 id=&#34;2-输出侧精华一三种形象驱动方案&#34;&gt;2. 输出侧精华一：三种形象驱动方案&lt;/h2&gt;
&lt;p&gt;概念篇讲过口型驱动有三条路线（3D Blendshape / 真人克隆 / Live2D），LiveTalking 全部押在&lt;strong&gt;真人克隆&lt;/strong&gt;上，提供三个模型可切换，套路一致：&lt;strong&gt;离线预处理真人视频（抽帧 + s3fd 人脸检测 + 存坐标），运行时按音频特征只重绘嘴部区域，再贴回原始帧&lt;/strong&gt;。&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;方案&lt;/th&gt;
					&lt;th&gt;音频特征&lt;/th&gt;
					&lt;th&gt;模型&lt;/th&gt;
					&lt;th&gt;参考性能&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;wav2lip&lt;/td&gt;
					&lt;td&gt;Mel 频谱&lt;/td&gt;
					&lt;td&gt;256×256&lt;/td&gt;
					&lt;td&gt;RTX3060 约 60fps&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;musetalk&lt;/td&gt;
					&lt;td&gt;Whisper encoder 特征（只提特征，不做识别）&lt;/td&gt;
					&lt;td&gt;VAE + UNet（fp16）&lt;/td&gt;
					&lt;td&gt;RTX3080Ti 约 42fps&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;ultralight&lt;/td&gt;
					&lt;td&gt;HuBERT 特征&lt;/td&gt;
					&lt;td&gt;160×160 轻量 UNet&lt;/td&gt;
					&lt;td&gt;最轻量&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;三个读源码时要注意的点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;avatars/audio_features/&lt;/code&gt; 目录下的 mel/whisper/hubert 三个提取器名字叫 ASR，但&lt;strong&gt;不做语音识别&lt;/strong&gt;，只是把音频变成模型能吃的特征向量——新人最容易在这里迷路。&lt;/li&gt;
&lt;li&gt;帧率固定 25fps，音频 16kHz、每 20ms 一帧，这两个时钟是全管线的节拍器。&lt;/li&gt;
&lt;li&gt;README 里提到的 ernerf（NeRF 路线）在当前代码库已移除，别再找它。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;3-输出侧精华二渲染管线怎么省-gpu&#34;&gt;3. 输出侧精华二：渲染管线怎么省 GPU&lt;/h2&gt;
&lt;p&gt;核心在 &lt;code&gt;avatars/base_avatar.py&lt;/code&gt; 的 &lt;code&gt;render&lt;/code&gt; 循环：&lt;strong&gt;四条线程 + 三组队列&lt;/strong&gt;的流水线。&lt;/p&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart LR
    TTS[TTS 线程&amp;lt;br/&amp;gt;合成 20ms 音频帧] --&amp;gt; AQ[音频队列]
    AQ --&amp;gt; FEAT[主循环&amp;lt;br/&amp;gt;提取音频特征]
    FEAT --&amp;gt; FQ[feat_queue]
    FEAT --&amp;gt; OQ[output_queue&amp;lt;br/&amp;gt;音频透传]
    FQ --&amp;gt; INF[inference 线程&amp;lt;br/&amp;gt;批量 GPU 推理]
    INF --&amp;gt; RQ[res_frame_queue]
    RQ --&amp;gt; PROC[process_frames 线程&amp;lt;br/&amp;gt;嘴部贴回原帧]
    OQ --&amp;gt; PROC
    PROC --&amp;gt; OUT[输出层推流]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;p&gt;两个值得抄的设计：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;静音时不跑模型推理&lt;/strong&gt;：检测到静音段直接循环播放原始视频帧，只有说话时才走 GPU。这一个开关把 GPU 占用降了一个量级，是低成本并发的关键。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;背压降速&lt;/strong&gt;：渲染循环检查输出缓冲区积压，积压多了就主动 sleep 降速，防止队列无限膨胀。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;另外它还有 &lt;strong&gt;idle 待机动作编排&lt;/strong&gt;：自定义 audiotype 对应预切好的图片序列 + 音频循环播放，沉默时数字人不会「死机」。说话到静音的过渡混合代码存在但默认关闭（&lt;code&gt;enable_transition = False&lt;/code&gt;），追求自然度的可以自己打开调。&lt;/p&gt;
&lt;h2 id=&#34;4-输出侧精华三tts-插件与-rtc-推流&#34;&gt;4. 输出侧精华三：TTS 插件与 RTC 推流&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;TTS 插件 11 种&lt;/strong&gt;：edgetts、gpt-sovits、xtts、cosyvoice、fishtts、tencent、doubao、indextts2、azuretts、qwentts、omnitts。统一基类 &lt;code&gt;tts/base_tts.py&lt;/code&gt;：队列收文本 → 合成 → 按 20ms chunk 推给渲染管线。注意两个坑：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;流式程度不一：gpt-sovits 是真 HTTP 流式，edge-tts 是「流式下载、整句合完再切片下发」的伪流式——首音延迟差很多，选型时实测。&lt;/li&gt;
&lt;li&gt;文本切分不在 TTS 层做，由上游 LLM 切好送进来。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;RTC 输出&lt;/strong&gt;用 aiortc 实现，自定义 &lt;code&gt;PlayerStreamTrack&lt;/code&gt; 时钟（视频 40ms/90kHz、音频 20ms/16kHz），编解码偏好 H264 优先于 VP8，支持 STUN。五种输出模式覆盖浏览器播放、推 SRS、RTMP 直播、虚拟摄像头进会议软件，输出侧的场景覆盖度是项目最成熟的部分。&lt;/p&gt;
&lt;h2 id=&#34;5-耗时分析从用户说完到数字人开口时间花在哪&#34;&gt;5. 耗时分析：从用户说完到数字人开口，时间花在哪&lt;/h2&gt;
&lt;p&gt;概念篇第 4 节说「每一环都要流式」。拿这个标准量 LiveTalking，结论先行：&lt;strong&gt;这是一条「半流式」管线——LLM、特征提取、推流是流式的，ASR 和口型推理是整段/攒批的&lt;/strong&gt;，两个非流式环节贡献了大部分延迟。&lt;/p&gt;
&lt;p&gt;逐环节拆解（耗时依据均来自代码常量与实现方式）：&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;环节&lt;/th&gt;
					&lt;th&gt;实现&lt;/th&gt;
					&lt;th&gt;流式？&lt;/th&gt;
					&lt;th&gt;耗时特征&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;ASR 语音识别&lt;/td&gt;
					&lt;td&gt;SenseVoice 整段识别（&lt;code&gt;asr_server.py:87-99&lt;/code&gt;）&lt;/td&gt;
					&lt;td&gt;❌ 非流式&lt;/td&gt;
					&lt;td&gt;等客户端发「说完了」才把整段 PCM 一次性识别，耗时与音频时长成正比（恒定 RTF）；全局推理锁串行，&lt;strong&gt;并发用户互相排队&lt;/strong&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;LLM 首 token&lt;/td&gt;
					&lt;td&gt;qwen-plus &lt;code&gt;stream=True&lt;/code&gt;（&lt;code&gt;llm.py&lt;/code&gt;）&lt;/td&gt;
					&lt;td&gt;✅ 流式&lt;/td&gt;
					&lt;td&gt;云 API 首 token 通常几百毫秒&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;LLM 切句&lt;/td&gt;
					&lt;td&gt;攒标点且超 10 字才送 TTS（&lt;code&gt;llm.py:44-49&lt;/code&gt;）&lt;/td&gt;
					&lt;td&gt;⚠️ 半流式&lt;/td&gt;
					&lt;td&gt;短回复、无标点回复会憋到最后才出声&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;TTS 首包&lt;/td&gt;
					&lt;td&gt;11 种插件差异大&lt;/td&gt;
					&lt;td&gt;⚠️ 看插件&lt;/td&gt;
					&lt;td&gt;edge-tts 伪流式：整句合成完才切片下发，首音 ≈ 整句耗时；gpt-sovits/cosyvoice/doubao 真流式：首音 ≈ 首 chunk 到达&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;音频特征&lt;/td&gt;
					&lt;td&gt;mel/whisper/hubert 滑窗（&lt;code&gt;config.py:52-54&lt;/code&gt;）&lt;/td&gt;
					&lt;td&gt;✅ 但有前瞻&lt;/td&gt;
					&lt;td&gt;右上下文 &lt;code&gt;r=10&lt;/code&gt; 意味着必须多等 &lt;strong&gt;200ms「未来」音频&lt;/strong&gt;；启动 warm_up 再加 200ms 相位偏移，合计约 400ms 结构性延迟&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;口型推理&lt;/td&gt;
					&lt;td&gt;GPU 批推理（&lt;code&gt;base_avatar.py:347&lt;/code&gt;）&lt;/td&gt;
					&lt;td&gt;❌ 攒批&lt;/td&gt;
					&lt;td&gt;攒满 32 个 20ms chunk（&lt;strong&gt;640ms&lt;/strong&gt;）才触发一次推理出 16 帧；一批推理约 267ms（wav2lip256 @ RTX3060 约 60fps 推算）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;画面合成&lt;/td&gt;
					&lt;td&gt;process_frames 逐帧贴回&lt;/td&gt;
					&lt;td&gt;✅ 流式&lt;/td&gt;
					&lt;td&gt;毫秒级，可忽略&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;WebRTC 发送&lt;/td&gt;
					&lt;td&gt;aiortc 软件时钟 40ms/帧（&lt;code&gt;webrtc.py:69-109&lt;/code&gt;）&lt;/td&gt;
					&lt;td&gt;✅ 流式&lt;/td&gt;
					&lt;td&gt;发送节奏与渲染解耦，无攒批；节拍 40ms + 网络传输&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart LR
    A[用户说完&amp;lt;br/&amp;gt;判停等待] --&amp;gt; B[ASR 整段识别&amp;lt;br/&amp;gt;非流式]
    B --&amp;gt; C[LLM 首 token&amp;lt;br/&amp;gt;流式]
    C --&amp;gt; D[攒句超 10 字&amp;lt;br/&amp;gt;半流式]
    D --&amp;gt; E[TTS 首包&amp;lt;br/&amp;gt;edge 最差]
    E --&amp;gt; F[特征右上下文&amp;lt;br/&amp;gt;+200ms 前瞻]
    F --&amp;gt; G[攒批 640ms&amp;lt;br/&amp;gt;非流式]
    G --&amp;gt; H[GPU 推理一批&amp;lt;br/&amp;gt;约 267ms]
    H --&amp;gt; I[RTC 节拍 40ms&amp;lt;br/&amp;gt;+ 网络传输]
    style B fill:#fee,stroke:#c00
    style G fill:#fee,stroke:#c00&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;p&gt;数量级估算（默认组合 wav2lip + edge-tts）：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;仅算「TTS 首段音频 → 口型首帧」：200ms 前瞻 + 最多 640ms 攒批 + 一批推理约 267ms + 40ms 发送节拍 ≈ &lt;strong&gt;1.1 秒量级&lt;/strong&gt;。这期间管线一直在播静音循环帧，用户看到的是「待机」而不是卡死。&lt;/li&gt;
&lt;li&gt;再加上 ASR 整段识别（几秒的整段音频、全局锁排队）和 edge-tts 整句合成，端到端「用户说完 → 数字人开口」会到&lt;strong&gt;数秒级&lt;/strong&gt;——这就是它演示效果还行、对话感弱的技术根源。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;三个值得记住的点：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;固定成本写死在常量里&lt;/strong&gt;：640ms 攒批来自 &lt;code&gt;batch_size=16&lt;/code&gt;（每批吃 32 个 chunk），200ms 前瞻来自 &lt;code&gt;-r 10&lt;/code&gt;。做延迟优化最先动这两个数——但 &lt;code&gt;batch_size&lt;/code&gt; 调小会降 GPU 吞吐，这是延迟与并发的权衡，不是免费午餐。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;假流式要会分辨&lt;/strong&gt;：edge-tts 的 &lt;code&gt;stream()&lt;/code&gt; 是「流式下载、整句合成完才切片」；判断一个 TTS 插件是不是真流式，看首个音频 chunk 是否即时进队列——代码里 sovits/cosyvoice/doubao 都有 &lt;code&gt;Time to first chunk&lt;/code&gt; 打点，edge 没有。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;打点有但不成链&lt;/strong&gt;：LLM 首 chunk、TTS 首包、推理 fps（每 100 帧打 &lt;code&gt;actual avg infer fps&lt;/code&gt;）、推流 fps、ASR RTF 各有分散日志，但&lt;strong&gt;没有端到端统一 trace&lt;/strong&gt;（无 request-id 串联）。想定位延迟瓶颈得自己加链路追踪，这也是第 8 节工程化缺口里的一项。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;6-输入侧与智能侧demo-级别照抄&#34;&gt;6. 输入侧与智能侧：demo 级，别照抄&lt;/h2&gt;
&lt;p&gt;对照概念篇的链路图，短板集中在上半场：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ASR（耳朵）&lt;/strong&gt;：&lt;code&gt;server/asr_server.py&lt;/code&gt; 用 FunASR 的 SenseVoiceSmall + fsmn-vad，但&lt;strong&gt;不是真流式&lt;/strong&gt;——客户端按 60ms chunk 上行，服务端攒缓冲，收到停止信号才整段识别一次，没有增量 partial 输出。还有一条更糙的路：直接用浏览器 Web Speech API 按住说话。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;LLM（大脑）&lt;/strong&gt;：&lt;code&gt;llm.py&lt;/code&gt; 单文件几十行，qwen-plus 流式调用，&lt;strong&gt;无多轮历史、无 RAG、无记忆、无工具调用&lt;/strong&gt;——每次只发一条 user message。文本切句是最简版：扫标点攒够 10 字就 flush，没有概念篇 3.3.1 讲的首句激进策略、超时兜底、标点陷阱清洗。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;打断（barge-in）&lt;/strong&gt;：有 &lt;code&gt;/interrupt_talk&lt;/code&gt; 接口，清空 TTS 队列 + 置暂停，但这是&lt;strong&gt;前端主动 HTTP 打断&lt;/strong&gt;，不是 VAD 检测到用户插话自动触发——算半个 barge-in。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;视觉感知（眼睛）&lt;/strong&gt;：完全没有运行时摄像头输入。人脸检测只用于离线建 avatar 素材。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;架构上的本质差异&lt;/strong&gt;：它的 RTC &lt;strong&gt;只发不收&lt;/strong&gt;——用户音频根本不上行到服务端，ASR 走浏览器侧。这个设计 demo 友好，但意味着服务端做不了 AEC、做不了语义 VAD、打断链路不闭环，是「demo 架构」和「产品架构」的分水岭。&lt;/p&gt;
&lt;h2 id=&#34;7-跑通它的坑安装模型与素材&#34;&gt;7. 跑通它的坑：安装、模型与素材&lt;/h2&gt;
&lt;p&gt;源码读得再明白，跑不起来都白搭。下面是从这个项目代码里逐条核实的坑，按严重程度分三级。&lt;/p&gt;
&lt;h3 id=&#34;71-跑不起来级&#34;&gt;7.1 跑不起来级&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;依赖管理是半成品&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;requirements.txt&lt;/code&gt; 里&lt;strong&gt;没有 torch&lt;/strong&gt;——必须按 README 手动装指定版本（&lt;code&gt;torch==2.9.1+cu128&lt;/code&gt;），直接 &lt;code&gt;pip install -r requirements.txt&lt;/code&gt; 后启动必报 &lt;code&gt;No module named &#39;torch&#39;&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;关键依赖（aiortc、librosa、transformers、edge_tts）&lt;strong&gt;全不锁版本&lt;/strong&gt;。aiortc 历年 API 变动大，新环境装到不兼容版本是常见翻车点。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;librosa 定时炸弹&lt;/strong&gt;：&lt;code&gt;avatars/wav2lip/audio.py:18&lt;/code&gt; 用了 &lt;code&gt;librosa.output.write_wav&lt;/code&gt;，这个 API 在 librosa 0.10 已删除，新版环境下走到该路径直接 AttributeError。&lt;/li&gt;
&lt;li&gt;Python 版本三个口径互不一致：README badge 写 3.10+，实测环境是 3.12 + CUDA 12.8，Dockerfile 里还是 3.10 + CUDA 11.3。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;funasr&lt;/code&gt;/&lt;code&gt;modelscope&lt;/code&gt; 在 requirements.txt 里被注释掉了，不手动装的话 &lt;code&gt;/api/asr&lt;/code&gt; &lt;strong&gt;静默不注册&lt;/strong&gt;（只打一行 info 日志），新人会以为 ASR 功能坏了。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;模型权重全靠网盘手动摆位，路径还硬编码&lt;/strong&gt;：&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;模型&lt;/th&gt;
					&lt;th&gt;坑&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;wav2lip&lt;/td&gt;
					&lt;td&gt;路径硬编码 &lt;code&gt;./models/wav2lip.pth&lt;/code&gt;（&lt;code&gt;app.py:148&lt;/code&gt;），README 要求把下载的 &lt;code&gt;wav2lip256.pth&lt;/code&gt; &lt;strong&gt;手动改名&lt;/strong&gt;，忘改直接报文件不存在&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;musetalk&lt;/td&gt;
					&lt;td&gt;四件套要全部就位：unet + sd-vae + &lt;strong&gt;HF transformers 格式的 whisper&lt;/strong&gt;（不是 OpenAI 权重格式，放错 load 失败）+ face-parse 模型&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;ultralight&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;最深的坑&lt;/strong&gt;：&lt;code&gt;from_pretrained&lt;/code&gt; 传的是本地路径不会自动拉取；且每个 avatar 需要自己训练的 &lt;code&gt;ultralight.pth&lt;/code&gt;——&lt;code&gt;genavatar.py&lt;/code&gt; 末尾只是 &lt;code&gt;cp&lt;/code&gt; 你在项目外训练好的 checkpoint，&lt;strong&gt;训练过程根本不在本仓库&lt;/strong&gt;。新人选 ultralight 基本必卡&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;s3fd 人脸检测&lt;/td&gt;
					&lt;td&gt;首次使用从外网（adrianbulat.com）下载权重，国内/离线环境 genavatar 直接挂&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;另外默认 TTS 是 edge-tts，&lt;strong&gt;依赖微软在线服务&lt;/strong&gt;，离线或被墙环境无声且无重试（只打日志）。&lt;/p&gt;
&lt;h3 id=&#34;72-avatar-素材制作的坑genavatar&#34;&gt;7.2 avatar 素材制作的坑（genavatar）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;输入视频必须 25fps，但代码不校验&lt;/strong&gt;（&lt;code&gt;config.py:51&lt;/code&gt; 注释写着 &amp;ldquo;must be 25&amp;rdquo;）。喂 30fps 视频会口型节奏错位，且无任何报错。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;人脸检测失败静默兜底&lt;/strong&gt;：检测不到人脸时直接用整帧坐标（&lt;code&gt;avatars/wav2lip/genavatar.py:107&lt;/code&gt;），产出垃圾素材也不报警，要等跑起来看到崩坏画面才知道。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;全量帧读进内存&lt;/strong&gt;：所有 PNG 帧一次性 load 进 RAM 且常驻（&lt;code&gt;wav2lip_avatar.py:81-86&lt;/code&gt;），长视频直接撑爆内存，也没有时长上限引导。&lt;/li&gt;
&lt;li&gt;抽帧逐帧写 PNG，几分钟 1080p 视频就是几千个文件，磁盘消耗无提示。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;73-体验受损级能跑但别扭&#34;&gt;7.3 体验受损级（能跑但别扭）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;DASHSCOPE_API_KEY&lt;/code&gt; 没配置时静默失败&lt;/strong&gt;（&lt;code&gt;llm.py&lt;/code&gt; 只 catch 打日志），前端表现是「数字人就是不说话」，没有任何错误提示。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;getUserMedia 需要安全上下文&lt;/strong&gt;：用 &lt;code&gt;http://&amp;lt;局域网IP&amp;gt;:8010&lt;/code&gt; 访问时浏览器禁麦克风，语音功能无声失效，README 没提。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;WebRTC 端口要求夸张&lt;/strong&gt;：README 要求开放 UDP 全端口，且只配 STUN 不配 TURN，严格 NAT 下连接失败无引导。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LLM 切句粗糙&lt;/strong&gt;：攒够标点且超 10 字才送 TTS，短回复、无标点回复会憋到最后才出声——概念篇 3.3.1 讲的超时兜底这里没有。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;wav2lip 嘴部硬贴回&lt;/strong&gt;：直接 &lt;code&gt;cv2.resize&lt;/code&gt; 覆盖矩形区域，无边缘融合（musetalk 才有 mask blending）；说话/静音过渡混合代码存在但默认关闭，帧切换有跳变。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;一句话避坑总结：&lt;strong&gt;按 README 跑 &lt;code&gt;wav2lip + webrtc + edgetts&lt;/code&gt; 默认组合成功率最高&lt;/strong&gt;；深坑集中在模型权重手动摆位、ultralight 需项目外自训、25fps 与人脸检测失败均无校验这三处。&lt;/p&gt;
&lt;h2 id=&#34;8-从-demo-到商业级产品还差什么&#34;&gt;8. 从 demo 到商业级产品，还差什么&lt;/h2&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart LR
    subgraph 已有[&amp;#34;LiveTalking 已覆盖（工业级）&amp;#34;]
        A1[形象驱动三方案]
        A2[渲染管线 + 省 GPU]
        A3[TTS 插件 + 克隆]
        A4[RTC 五种输出]
        A5[idle 待机]
    end

    subgraph 缺失[&amp;#34;到产品还差（要自己造）&amp;#34;]
        B1[RTC 音频上行 + AEC]
        B2[真流式 ASR + 语义 VAD]
        B3[自动 barge-in]
        B4[RAG + 多轮 + 记忆]
        B5[视觉感知]
        B6[测试/CI/鉴权/部署]
    end

    已有 --&amp;gt;|补全后| P[商业级&amp;lt;br/&amp;gt;数字人]
    缺失 --&amp;gt; P&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;p&gt;具体缺口清单，按补齐优先级排序：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;交互闭环&lt;/strong&gt;：用户语音走 RTC 上行 → 服务端 AEC + 流式 ASR + 语义 VAD → 自动 barge-in。这是从「能演示」到「能用」的第一刀。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;智能&lt;/strong&gt;：LLM 层接多轮历史 + RAG（概念篇 3.2 节的完整方案），&lt;code&gt;llm.py&lt;/code&gt; 只有几十行，改造量小、收益最大。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;视觉感知&lt;/strong&gt;：按概念篇 3.1.3 的方案，端侧轻量模型起步。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;工程化与安全&lt;/strong&gt;：测试、CI、鉴权、部署——当前几乎是空白，见下面的上线隐患清单。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;81-上线隐患级想部署公网必须先补的课&#34;&gt;8.1 上线隐患级（想部署公网必须先补的课）&lt;/h3&gt;
&lt;p&gt;这些问题不影响跑 demo，但每一个都是生产事故的种子：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;全无鉴权&lt;/strong&gt;：&lt;code&gt;/human&lt;/code&gt;、&lt;code&gt;/interrupt_talk&lt;/code&gt;、&lt;code&gt;/record&lt;/code&gt;、&lt;code&gt;/api/admin/*&lt;/code&gt;、&lt;code&gt;/sse&lt;/code&gt; 全部裸奔；admin 接口直接 &lt;code&gt;vars(opt)&lt;/code&gt; 输出全量配置；CORS 是 &lt;code&gt;*&lt;/code&gt; 全开。公网部署等于敞开大门。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;录制功能用 &lt;code&gt;os.system&lt;/code&gt; 拼 ffmpeg 命令&lt;/strong&gt;（&lt;code&gt;base_avatar.py:285&lt;/code&gt;），sessionid 来自外部传入，存在路径注入风险；临时文件落在工作目录，同名会话重录互相覆盖。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GPU 资源不释放&lt;/strong&gt;：&lt;code&gt;session_manager.remove_session&lt;/code&gt; 只 pop 字典，注释里自己留了一句「todo: 还可以主动调 avatar_session 释放」——avatar 素材常驻显存不回收，&lt;code&gt;global_avatars&lt;/code&gt; 缓存永不淘汰，频繁换 avatar 会显存泄漏。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GPU 模型全局共享且无锁&lt;/strong&gt;：每个 session 起独立 inference 线程并发调同一个模型，高并发同时说话时显存峰值不可控，没有任何排队或互斥防护。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;线程泄漏风险&lt;/strong&gt;：inference 线程里 &lt;code&gt;output_queue.get()&lt;/code&gt; 无超时阻塞（&lt;code&gt;base_avatar.py:348&lt;/code&gt;），TTS 断供时线程永远卡住，shutdown 的 &lt;code&gt;join()&lt;/code&gt; 会挂起；LLM 调用走默认 executor 无线程池上限，刷接口可起大量线程。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;队列清空不持锁&lt;/strong&gt;：打断时直接 &lt;code&gt;queue.queue.clear()&lt;/code&gt; 操作内部 deque（&lt;code&gt;tts/base_tts.py:31&lt;/code&gt;），打断瞬间恰逢 put 有小概率竞态。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Dockerfile 是坏的&lt;/strong&gt;：CUDA 11.6/torch 1.12 与 README 要求的 torch 2.9.1/cu128 矛盾，且 &lt;code&gt;COPY&lt;/code&gt; 路径还是上个项目的名字 &lt;code&gt;nerfstream&lt;/code&gt;——这个 Dockerfile 根本 build 不出当前项目。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;82-文档与代码不一致宣称-vs-实际&#34;&gt;8.2 文档与代码不一致（宣称 vs 实际）&lt;/h3&gt;
&lt;p&gt;读这个项目要建立「README 说的是理想、代码才是现实」的警觉：&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;README 宣称&lt;/th&gt;
					&lt;th&gt;代码实际&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;支持 ernerf（附演示视频链接）&lt;/td&gt;
					&lt;td&gt;ernerf 已移除，&lt;code&gt;app.py&lt;/code&gt; 只注册 musetalk/wav2lip/ultralight&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;支持说话被打断&lt;/td&gt;
					&lt;td&gt;仅 HTTP 主动打断，无语音 barge-in（服务端不收上行音轨）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;支持多并发&lt;/td&gt;
					&lt;td&gt;有限流，但模型共享无锁 + 资源不释放&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;requirements.txt 列了 Flask&lt;/td&gt;
					&lt;td&gt;实际用 aiohttp，&lt;code&gt;app.py&lt;/code&gt; 里的 Flask 代码是死代码&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;admin API 文档暗示 fps 可配&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;config.py&lt;/code&gt; 写死 25，改了整条音视频时钟链都会错位&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;已在业内广泛商用&lt;/td&gt;
					&lt;td&gt;无鉴权/无测试/资源不释放，开源代码距离可商用部署有明显差距&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;9-源码怎么读推荐顺序&#34;&gt;9. 源码怎么读：推荐顺序&lt;/h2&gt;
&lt;p&gt;项目文件不少，按这个顺序读最省力：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;app.py&lt;/code&gt; + &lt;code&gt;config.py&lt;/code&gt;：看启动流程和配置体系，建立全局。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;registry.py&lt;/code&gt;：十几行的装饰器注册表，理解插件机制后所有模块的可替换性就清楚了。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;avatars/base_avatar.py&lt;/code&gt;：全文核心，渲染管线的四条线程、静音跳推理、idle 编排都在这。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;tts/base_tts.py&lt;/code&gt; + 一个具体实现（如 &lt;code&gt;tts/sovits.py&lt;/code&gt;）：理解真假流式的差别。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;server/webrtc.py&lt;/code&gt;：看自定义时钟轨道怎么把音视频帧喂给 WebRTC。&lt;/li&gt;
&lt;li&gt;最后回头看 &lt;code&gt;llm.py&lt;/code&gt; 和 &lt;code&gt;server/asr_server.py&lt;/code&gt;——看清 demo 级实现的边界在哪，正好是练手改造的切入点。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;10-总结&#34;&gt;10. 总结&lt;/h2&gt;
&lt;p&gt;LiveTalking 的价值在于&lt;strong&gt;输出侧的真实工程参考&lt;/strong&gt;：三种驱动方案的取舍、四线程渲染管线、静音跳推理省 GPU、插件化 TTS、五种 RTC 输出——这些在概念文章里只是一句话，在源码里是踩过坑的实现。它的边界也清晰：输入侧和智能侧保持 demo 形态，不是缺陷，是定位。&lt;/p&gt;
&lt;p&gt;对学习者，正确的用法是&lt;strong&gt;概念篇当地图、这个项目当实地&lt;/strong&gt;：先知道链路全貌，再在源码里逐个模块对号入座，最后从「补齐缺口清单」里挑一个动手改——比如给 &lt;code&gt;llm.py&lt;/code&gt; 接上 RAG 和多轮历史，就是性价比最高的第一个实战任务。&lt;/p&gt;
</description>
    </item>
    <item>
      <title>数字人链路从 0 到精通：新人也能看懂的学习总结</title>
      <link>https://ftmao.com/blog/posts/digital-human-pipeline-beginner-to-mastery/</link>
      <pubDate>Thu, 20 Aug 2026 16:30:00 +0800</pubDate>
      <guid>https://ftmao.com/blog/posts/digital-human-pipeline-beginner-to-mastery/</guid>
      <description>&lt;h1 id=&#34;数字人链路从-0-到精通新人也能看懂的学习总结&#34;&gt;数字人链路从 0 到精通：新人也能看懂的学习总结&lt;/h1&gt;
&lt;p&gt;写这篇文章的动机很实际：数字人（Digital Human）这个方向资料多但碎，新人很容易被各种名词（ASR、TTS、Viseme、Blendshape、WebRTC、中之人、MetaHuman）淹没，看了很多文章还是拼不出一张完整的图。&lt;/p&gt;
&lt;p&gt;本文的目标：&lt;strong&gt;一篇文章讲清楚数字人是什么、整条技术链路怎么跑、每环有哪些坑、新人按什么顺序学&lt;/strong&gt;。假设读者有基本编程能力，但不要求任何音视频或图形学背景。&lt;/p&gt;
&lt;h2 id=&#34;1-先搞清楚数字人到底是什么&#34;&gt;1. 先搞清楚：数字人到底是什么&lt;/h2&gt;
&lt;h3 id=&#34;11-从元宇宙说起&#34;&gt;1.1 从元宇宙说起&lt;/h3&gt;
&lt;p&gt;2021 年「元宇宙（Metaverse）」概念爆火时，有一个被广泛引用的定义：元宇宙是一个&lt;strong&gt;持久在线的、可沉浸交互的虚拟世界&lt;/strong&gt;。热闹过后概念降温，但它留下了几样真正落地的资产：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;虚拟形象（Avatar）&lt;/strong&gt;：人在虚拟世界里的「身体」，从游戏捏脸到 Meta 的虚拟人，再到苹果的 Persona。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;数字身份（Digital Identity）&lt;/strong&gt;：虚拟世界里的「你是谁」，关联账号、资产、社交关系。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;实时渲染与交互引擎&lt;/strong&gt;：Unity、Unreal（含 MetaHuman）、WebGL 这些让虚拟世界「看得见」的技术。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;XR 入口&lt;/strong&gt;：VR/AR 设备作为进入虚拟世界的「门」。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;数字人就是元宇宙沉淀下来最值钱的那部分&lt;/strong&gt;：一个「有形象、能说话、能交流」的虚拟实体。元宇宙讲的是一个世界，数字人是这个世界里最先实现商业闭环的单元——你不需要一整个虚拟世界，只需要一个能 7x24 小时直播带货、能接客服电话、能当虚拟偶像的数字人，就有客户愿意付钱。&lt;/p&gt;
&lt;h3 id=&#34;12-数字人的三个分类维度&#34;&gt;1.2 数字人的三个分类维度&lt;/h3&gt;
&lt;p&gt;新人最容易混淆的是「数字人」一词涵盖了很多完全不同的技术路线。按三个维度拆开看：&lt;/p&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart TB
    DH[数字人] --&amp;gt; A[按形象分]
    DH --&amp;gt; B[按驱动方式分]
    DH --&amp;gt; C[按交互方式分]

    A --&amp;gt; A1[2D 卡通 / Live2D]
    A --&amp;gt; A2[3D 写实&amp;lt;br/&amp;gt;MetaHuman / 捏脸]
    A --&amp;gt; A3[真人形象克隆&amp;lt;br/&amp;gt;照片/视频驱动]

    B --&amp;gt; B1[真人驱动&amp;lt;br/&amp;gt;中之人 + 动捕]
    B --&amp;gt; B2[AI 驱动&amp;lt;br/&amp;gt;文本/语音全自动]
    B --&amp;gt; B3[混合驱动&amp;lt;br/&amp;gt;AI 为主 真人兜底]

    C --&amp;gt; C1[离线内容型&amp;lt;br/&amp;gt;录播视频/短视频]
    C --&amp;gt; C2[实时交互型&amp;lt;br/&amp;gt;对话/直播/客服]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;形象维度&lt;/strong&gt;：Live2D 成本最低（一张立绘就能动），3D 写实最重（建模 + 绑定 + 渲染），真人克隆最像真人（用真人的照片或视频训练）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;驱动维度&lt;/strong&gt;：虚拟主播圈常说的「中之人」就是真人在幕后戴动捕设备驱动皮套；AI 驱动则是全自动化，这也是本文的重点。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;交互维度&lt;/strong&gt;：离线内容型（批量生成口播视频）对实时性没要求，工程难度低一个量级；实时交互型（你说一句它答一句）才是技术深水区。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;典型应用场景对号入座&lt;/strong&gt;：虚拟主播直播（实时 + 真人/AI 驱动）、AI 客服数字人（实时 + AI 驱动）、短视频口播矩阵（离线 + AI 驱动）、数字分身/数字永生（真人克隆 + 实时）、企业数字员工大屏（实时 + 3D）。&lt;/p&gt;
&lt;h2 id=&#34;2-一张图看懂整体链路&#34;&gt;2. 一张图看懂整体链路&lt;/h2&gt;
&lt;p&gt;数字人系统本质上是把一个真人的沟通能力拆成流水线，每个环节用一个技术组件替代：&lt;/p&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart LR
    subgraph 感知[&amp;#34;感知（耳朵 + 眼睛）&amp;#34;]
        MIC[麦克风] --&amp;gt; VAD[VAD 语音检测] --&amp;gt; ASR[ASR 语音识别]
        CAM[摄像头] --&amp;gt; VIS[视觉感知&amp;lt;br/&amp;gt;人脸/唇动/表情/手势]
    end

    subgraph 认知[&amp;#34;认知（大脑）&amp;#34;]
        ASR --&amp;gt; LLM[LLM 对话引擎&amp;lt;br/&amp;gt;+ RAG + 记忆 + 工具]
        VIS -.情绪/注意力标签.-&amp;gt; LLM
    end

    subgraph 表达[&amp;#34;表达（嘴巴 + 脸 + 身体）&amp;#34;]
        LLM --&amp;gt; TTS[TTS 语音合成]
        TTS --&amp;gt; DRIVE[驱动引擎&amp;lt;br/&amp;gt;口型/表情/动作]
        DRIVE --&amp;gt; RENDER[渲染引擎&amp;lt;br/&amp;gt;2D/3D 形象]
    end

    subgraph 传输[&amp;#34;传输（神经）&amp;#34;]
        RENDER --&amp;gt; RTC[WebRTC 低延迟推流]
        RTC --&amp;gt; USER([用户屏幕/音箱])
    end

    USER -.用户说话.-&amp;gt; MIC
    USER -.用户在镜头前.-&amp;gt; CAM&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;p&gt;记住这个拟人化口诀：&lt;strong&gt;耳朵（ASR）听清、眼睛（视觉感知）看懂 → 大脑（LLM）想好 → 嘴巴（TTS）说出 → 脸（口型驱动）对上 → 神经（WebRTC）送达&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;整条链路分两大形态：&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;形态&lt;/th&gt;
					&lt;th&gt;特点&lt;/th&gt;
					&lt;th&gt;延迟要求&lt;/th&gt;
					&lt;th&gt;典型延迟预算&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;离线内容生产&lt;/td&gt;
					&lt;td&gt;批量生成视频，可反复重试&lt;/td&gt;
					&lt;td&gt;无&lt;/td&gt;
					&lt;td&gt;分钟级也无所谓&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;实时交互&lt;/td&gt;
					&lt;td&gt;一问一答，像打电话&lt;/td&gt;
					&lt;td&gt;端到端小于 1.5 秒才自然&lt;/td&gt;
					&lt;td&gt;每一环都要抠毫秒&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;离线形态是实时形态的子集（少了 ASR 和 RTC，渲染换成离线出片），所以下面重点拆实时链路。&lt;/p&gt;
&lt;h2 id=&#34;3-实时交互链路逐环拆解&#34;&gt;3. 实时交互链路逐环拆解&lt;/h2&gt;
&lt;p&gt;先看一次完整对话的时序，建立整体感觉：&lt;/p&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;sequenceDiagram
    participant U as 用户
    participant E as 边缘采集端
    participant A as ASR 服务
    participant L as LLM 服务
    participant T as TTS 服务
    participant D as 驱动+渲染
    participant R as RTC 网络

    U-&amp;gt;&amp;gt;E: 说话（语音流）
    E-&amp;gt;&amp;gt;E: VAD 检测说话起止
    E-&amp;gt;&amp;gt;A: 流式发送音频
    A--&amp;gt;&amp;gt;L: 边说边出识别文本
    L--&amp;gt;&amp;gt;T: 流式输出回答（按句切分）
    T--&amp;gt;&amp;gt;D: 流式合成音频（边收边播）
    D-&amp;gt;&amp;gt;D: 音频驱动口型/表情
    D-&amp;gt;&amp;gt;R: 音视频帧推流
    R--&amp;gt;&amp;gt;U: 看到听到数字人回答
    Note over U,R: 用户感知延迟 = 最后一个字说完到数字人开口的时间&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;p&gt;关键设计原则：&lt;strong&gt;每一环都是流式（streaming）的&lt;/strong&gt;。如果等 LLM 把整段话说完再送 TTS、等 TTS 合成完整段再播放，延迟会叠加到无法接受。流式的含义是「边产生边消费」，像水管一样一环接一环地流。&lt;/p&gt;
&lt;h3 id=&#34;31-耳朵与眼睛vad--asr--视觉感知&#34;&gt;3.1 耳朵与眼睛：VAD + ASR + 视觉感知&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;VAD（Voice Activity Detection，语音活动检测）&lt;/strong&gt;：判断用户什么时候开始说、什么时候说完了。它是交互节奏的总开关——判早了会把用户一句话切成两半，判晚了用户会觉得数字人反应迟钝。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ASR（Automatic Speech Recognition，语音识别）&lt;/strong&gt;：把语音流实时转成文字。&lt;/p&gt;
&lt;h4 id=&#34;311-vad-到底怎么判断开始说和说完了&#34;&gt;3.1.1 VAD 到底怎么判断「开始说」和「说完了」&lt;/h4&gt;
&lt;p&gt;VAD 把音频切成 10-30ms 的小帧，对每一帧打一个「是语音的概率」，然后用状态机做判定：&lt;/p&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;stateDiagram-v2
    [*] --&amp;gt; 静音
    静音 --&amp;gt; 可能说话: 连续 N 帧概率超阈值
    可能说话 --&amp;gt; 说话中: 确认（防突发噪音）
    可能说话 --&amp;gt; 静音: 概率回落（是咳嗽/关门声）
    说话中 --&amp;gt; 可能结束: 出现连续静音帧
    可能结束 --&amp;gt; 说话中: 重新检测到语音（句中停顿）
    可能结束 --&amp;gt; 静音: 静音持续超 hangover 阈值&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;p&gt;算法分三代，了解演进就知道怎么选：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;能量 + 过零率&lt;/strong&gt;：最原始的做法，能量突增判说话。安静机房能用，真实环境（空调声、键盘声）全是误判。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;统计模型&lt;/strong&gt;：代表作是 Google 的 WebRTC VAD（GMM 高斯混合模型），内置 0-3 四档灵敏度，免费、极快，至今仍是很多项目内置的默认项。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;神经网络模型&lt;/strong&gt;：工业主流。开源首选 &lt;strong&gt;Silero VAD&lt;/strong&gt;（几 MB 的 ONNX 模型，CPU 上实时跑，自带 30ms 帧判定）；国内还有阿里的 FSMN-VAD（FunASR 自带）、TEN-VAD。抗噪能力比前代强一个量级。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;三个必须知道的工程细节：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;判起要有「提前量」&lt;/strong&gt;：VAD 确认「开始说话」需要连续若干帧，如果确认后才把音频送 ASR，句首会被吃掉（「你好，数字人」变成「数字人」）。解法是&lt;strong&gt;预滚动缓冲（pre-roll buffer）&lt;/strong&gt;：始终缓存最近 200-300ms 音频，VAD 触发时把缓冲一并送出。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;判停（端点检测）是延迟与完整的权衡&lt;/strong&gt;：静音持续多久算「说完了」，默认 500-800ms。设太短切断用户的长句停顿（「那个……我想问一下」被切成两段），设太长每轮对话白等几百毫秒。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;语义 VAD 是高阶玩法&lt;/strong&gt;：不只看静音时长，还结合 ASR 的中间识别结果判断语义是否完整——识别文本还没形成完整句子就延长等待。大模型语音产品（GPT-4o 类）和商用方案普遍在用，纯声学 VAD 容易被「思考停顿」骗过。&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;312-流式-asr现成-api-还是自己改-whisper&#34;&gt;3.1.2 流式 ASR：现成 API 还是自己改 Whisper&lt;/h4&gt;
&lt;p&gt;先说结论：&lt;strong&gt;商用快速上线选云 API；数据敏感或量大图便宜选自部署开源方案；改造 Whisper 只适合练手和理解原理，别上生产。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;现成 API（WebSocket 流式，接入即用）：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;国内：阿里云实时语音识别、腾讯云 ASR、讯飞、火山引擎——中文效果好、热词支持完善、按量付费，首字延迟可做到 200-300ms。&lt;/li&gt;
&lt;li&gt;海外：Deepgram、AssemblyAI、Azure Speech、OpenAI Realtime API。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;自部署开源方案：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;FunASR&lt;/strong&gt;（阿里开源）：Paraformer 流式版，自带 VAD + 标点恢复，中文场景首选，社区活跃。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;sherpa-onnx&lt;/strong&gt;（k2 团队）：流式 Zipformer/Transducer 模型，跨平台，端侧（手机/嵌入式）都能跑。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SenseVoice&lt;/strong&gt;（阿里）：多语言、低延迟，还带情感与事件检测。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Whisper 为什么难办：它原生是&lt;strong&gt;离线架构&lt;/strong&gt;——encoder 要吃 30 秒的音频窗口，天然不是流式模型。三种常见改造路线：&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;路线&lt;/th&gt;
					&lt;th&gt;做法&lt;/th&gt;
					&lt;th&gt;问题&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;VAD 切段 + faster-whisper&lt;/td&gt;
					&lt;td&gt;VAD 检出完整一段话后送 faster-whisper（CTranslate2 加速版）&lt;/td&gt;
					&lt;td&gt;是「段级准实时」，不是真流式；每段延迟 1-3 秒，数字人场景偏慢&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;LocalAgreement 策略&lt;/td&gt;
					&lt;td&gt;whisper_streaming 项目的做法：滑动小窗反复识别，连续两次结果一致的前缀才确认输出&lt;/td&gt;
					&lt;td&gt;体验接近真流式，但同一段音频重复计算，GPU 成本高&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;换流式架构模型&lt;/td&gt;
					&lt;td&gt;承认 Whisper 不适合流式，直接用 Paraformer-streaming / Zipformer / SenseVoice&lt;/td&gt;
					&lt;td&gt;正解，但等于放弃了 Whisper&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;选型对照：&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;路线&lt;/th&gt;
					&lt;th&gt;首字延迟&lt;/th&gt;
					&lt;th&gt;中文效果&lt;/th&gt;
					&lt;th&gt;成本&lt;/th&gt;
					&lt;th&gt;适合谁&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;云 API&lt;/td&gt;
					&lt;td&gt;200-300ms&lt;/td&gt;
					&lt;td&gt;好（热词完善）&lt;/td&gt;
					&lt;td&gt;按量付费，量大贵&lt;/td&gt;
					&lt;td&gt;快速上线、没运维团队&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;FunASR / sherpa 自部署&lt;/td&gt;
					&lt;td&gt;200-500ms&lt;/td&gt;
					&lt;td&gt;好&lt;/td&gt;
					&lt;td&gt;自己的 GPU，量大便宜&lt;/td&gt;
					&lt;td&gt;数据敏感、有推理运维能力&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Whisper 改造&lt;/td&gt;
					&lt;td&gt;1s 以上&lt;/td&gt;
					&lt;td&gt;好&lt;/td&gt;
					&lt;td&gt;重复计算，贵&lt;/td&gt;
					&lt;td&gt;学习、离线转写场景&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;新人要点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;选&lt;strong&gt;流式 ASR&lt;/strong&gt;（边说边出字），不要选录音文件识别接口。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;热词（hotword）功能必须用起来&lt;/strong&gt;：业务专有名词（产品名、品牌名）通过热词表喂给 ASR，否则识别错误会一直污染下游 LLM。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AEC（回声消除）&lt;/strong&gt;：如果数字人的声音从音箱播出来又进麦克风，ASR 会把数字人自己的话识别成用户输入，造成「自己跟自己对话」。用扬声器场景必须开 AEC（WebRTC 自带，自研采集端要接 Speex/WebRTC APM 这类模块）。&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;313-眼睛视觉感知数字人能不能看到用户&#34;&gt;3.1.3 眼睛：视觉感知，数字人能不能「看到」用户&lt;/h4&gt;
&lt;p&gt;只有耳朵的数字人，相当于一个闭着眼打电话的人——能用，但离「像人」差一层。加上摄像头这条通道，感知层才完整。视觉信号在数字人里有六个典型用途：&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;视觉能力&lt;/th&gt;
					&lt;th&gt;干什么用&lt;/th&gt;
					&lt;th&gt;典型场景&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;存在检测&lt;/td&gt;
					&lt;td&gt;判断镜头前有没有人、有几个人，有人靠近才激活交互&lt;/td&gt;
					&lt;td&gt;大屏数字员工、门店导购，免唤醒词&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;视觉 VAD（唇动检测）&lt;/td&gt;
					&lt;td&gt;看着用户的嘴判断是否真在说话&lt;/td&gt;
					&lt;td&gt;嘈杂环境辅助音频 VAD，大幅降低误触发&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;表情/情绪识别&lt;/td&gt;
					&lt;td&gt;识别皱眉、笑、困惑，作为上下文注入 LLM&lt;/td&gt;
					&lt;td&gt;客服场景感知用户不满，共情回应&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;视线/注意力检测&lt;/td&gt;
					&lt;td&gt;用户是否在看屏幕&lt;/td&gt;
					&lt;td&gt;用户转头就走时数字人停止讲解，不自言自语&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;手势识别&lt;/td&gt;
					&lt;td&gt;挥手打招呼、举手打断、比划指令&lt;/td&gt;
					&lt;td&gt;展厅、车载等不方便说话的场景&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;人脸识别身份&lt;/td&gt;
					&lt;td&gt;认出是谁，关联记忆系统调出画像&lt;/td&gt;
					&lt;td&gt;VIP 客户识别、数字分身授权核验&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;工程实现分三层，按需取用：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;端侧轻量模型&lt;/strong&gt;：人脸检测、唇动、手势这类高频低算力任务放端侧跑（MediaPipe、YOLO 系列、厂商人脸 SDK），只把结论标签上传，不上传原始视频流——省带宽、降延迟、利隐私。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;云端识别&lt;/strong&gt;：情绪识别等重模型走云端，按帧抽样的低频调用即可，不要全帧率送云。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;端到端多模态大模型&lt;/strong&gt;：GPT-4o、Gemini Live 这类音视频直接进模型的路线，跳过「ASR 转文字」环节，能直接听懂语气、看到画面。这是趋势，但目前成本高、可控性弱（不好接 RAG 和业务约束），商用数字人中台主流仍是「ASR + LLM」模块化架构加视觉辅助信号。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;视觉信号进大脑的正确姿势&lt;/strong&gt;：视觉结果不作为对话内容，而是作为&lt;strong&gt;低优先级异步上下文标签&lt;/strong&gt;注入 LLM——比如 &lt;code&gt;[用户皱眉]&lt;/code&gt; &lt;code&gt;[用户看向别处]&lt;/code&gt; &lt;code&gt;[检测到 3 位观众]&lt;/code&gt;，让人格层决定如何反应（加快语速、主动询问、暂停讲解）。直接把视觉识别文本拼进用户输入会污染对话流，是新人常犯的错误。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;合规红线&lt;/strong&gt;：人脸信息在《个人信息保护法》里属于&lt;strong&gt;敏感个人信息&lt;/strong&gt;，采集需单独同意、明示用途。门店大屏这类被动采集场景尤其要小心，能端侧处理就不要上传原图，能用人形检测就不要做人脸识别。&lt;/p&gt;
&lt;p&gt;回答「数字人要不要眼睛」这道题的思路：&lt;strong&gt;不是必须，但它是从「语音机器人」到「数字人」的分水岭&lt;/strong&gt;——语音通道解决「听懂」，视觉通道解决「看懂场合」，两者融合（多模态感知）才有真正的临场感。在技术评审或方案讨论中，能讲清视觉信号作为异步标签注入、端侧优先、隐私合规这三点，就说明理解到位了。&lt;/p&gt;
&lt;h3 id=&#34;32-大脑llm-对话引擎&#34;&gt;3.2 大脑：LLM 对话引擎&lt;/h3&gt;
&lt;p&gt;这一环是大家最熟悉的：把识别文本丢给大模型，拿回答。但在数字人场景有几个特殊要求：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;System Prompt 分层&lt;/strong&gt;：人格设定（你是谁、什么性格）、业务知识（RAG 注入）、表达约束（口语化、每句别太长）分三层管理，不要揉成一大段。人格一致性是「数字人」区别于「聊天框」的核心。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;输出要为「说」优化&lt;/strong&gt;：prompt 里明确要求口语化短句、不要 markdown、不要列表符号——TTS 会把「1.」「**」念出来。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;长时记忆&lt;/strong&gt;：多轮对话靠上下文窗口，跨会话的「记住用户」要靠记忆系统（如 Mem0 这类长时记忆中间件：向量检索 + 用户画像 + 摘要）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Function Calling&lt;/strong&gt;：查天气、下单、转人工这类动作走工具调用，返回结果再让 LLM 组织成口语。&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;321-rag给大脑喂业务知识的标准流程&#34;&gt;3.2.1 RAG：给大脑喂业务知识的标准流程&lt;/h4&gt;
&lt;p&gt;数字人要回答企业业务问题，靠模型自身的知识不够，必须外挂知识库。RAG（Retrieval-Augmented Generation，检索增强生成）的标准流程新人必须掌握：&lt;/p&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart LR
    subgraph 离线建库[&amp;#34;离线：建知识库&amp;#34;]
        DOC[业务文档] --&amp;gt; CHUNK[切分 Chunking] --&amp;gt; EMB[Embedding 向量化] --&amp;gt; VDB[(向量数据库&amp;lt;br/&amp;gt;Qdrant/Milvus/Chroma)]
    end

    subgraph 在线检索[&amp;#34;在线：问答时&amp;#34;]
        Q[用户问题] --&amp;gt; REWRITE[Query 改写/补全] --&amp;gt; SEARCH[混合检索&amp;lt;br/&amp;gt;向量 + BM25 关键词]
        VDB -.相似度召回.-&amp;gt; SEARCH
        SEARCH --&amp;gt; RERANK[Rerank 重排序]
        RERANK --&amp;gt; PACK[拼装 Prompt&amp;lt;br/&amp;gt;system + 知识 + 历史 + 问题]
        PACK --&amp;gt; GEN[LLM 流式生成]
    end&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;p&gt;核心要点（方案讨论和实战都绕不开）：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;切分（Chunking）&lt;/strong&gt;：按语义/段落切，块太大噪音多、块太小上下文断裂，常用 200-500 字加 10% 重叠。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Embedding 选型&lt;/strong&gt;：中文场景主流 BGE 系列（BGE-M3 支持多语言与稠密稀疏混合），决定了召回质量的上限。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;混合检索&lt;/strong&gt;：纯向量检索对「型号、编号、专有名词」这类精确匹配很差，向量召回 + BM25 关键词召回合并是工业标配。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rerank&lt;/strong&gt;：召回 topK 比如 20 条，用 Rerank 模型（如 bge-reranker）精排取前 3-5 条进 prompt，显著降噪。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;评估闭环&lt;/strong&gt;：召回命中率、答案忠实度（有没有幻觉）要有评估集回归，改任何一环都跑一遍。&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;322-核心问题首-tokenttft怎么做到最快&#34;&gt;3.2.2 核心问题：首 token（TTFT）怎么做到最快&lt;/h4&gt;
&lt;p&gt;数字人场景里，LLM 是整个链路的延迟黑洞，而用户感知的快慢主要看 &lt;strong&gt;TTFT（Time To First Token，首 token 延迟）&lt;/strong&gt;——因为输出是流式的，第一个 token 出来，后面的 TTS 就能开工。先把公式摆出来：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TTFT = 检索耗时 + 网络与排队耗时 + Prefill（预填充）耗时&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;理解三个组成部分，优化手段就是对号入座：&lt;/p&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart LR
    A[用户说完话] --&amp;gt; B[RAG 检索&amp;lt;br/&amp;gt;50-300ms]
    B --&amp;gt; C[网络 RTT + 排队&amp;lt;br/&amp;gt;50-500ms]
    C --&amp;gt; D[Prefill 预填充&amp;lt;br/&amp;gt;随 prompt 长度线性增长]
    D --&amp;gt; E[首 token 吐出]
    style D fill:#fee,stroke:#c00&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;p&gt;&lt;strong&gt;第一路：让检索更快&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;向量库用 HNSW 这类内存索引，召回压到几十毫秒；向量检索和 BM25 关键词检索&lt;strong&gt;并行发&lt;/strong&gt;，取并集。&lt;/li&gt;
&lt;li&gt;Embedding 模型本地/就近部署，别为一次向量化跨地域调 API。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;高频问题语义缓存&lt;/strong&gt;：命中缓存直接跳过检索和生成（客服场景命中率可以做到很高），甚至直接返回预生成的音视频片段，TTFT 趋近于零。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;第二路：让 prompt 更短（砍 Prefill）&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Prefill 耗时随输入 token 数近似线性增长，prompt 每砍一半，这部分就快一半：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;system prompt 精简，人格层/业务层/约束层按需加载，不要每次都全量带上。&lt;/li&gt;
&lt;li&gt;RAG 注入的 chunk 控制在 3-5 条，靠 Rerank 保证质量而不是靠堆数量。&lt;/li&gt;
&lt;li&gt;历史对话做摘要压缩，多轮后只带摘要 + 最近几轮原文。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;第三路：让前缀可缓存（KV Cache / Prompt Caching）&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;把&lt;strong&gt;不变的内容放 prompt 最前面&lt;/strong&gt;（人格设定、业务规则），变化的内容（检索结果、用户问题）放最后。主流推理框架（vLLM 的 Automatic Prefix Caching）和商用 API（Claude/DeepSeek 的 prompt cache）都能复用前缀的 KV Cache，命中后 Prefill 几乎免费。&lt;/li&gt;
&lt;li&gt;反面教材：在 system prompt 里塞时间戳、随机 ID——前缀每次都变，缓存永远miss。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;第四路：让引擎和部署更快&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;推理框架选 vLLM/SGLang 这类支持 continuous batching 的，吞吐和排队时间都受益。&lt;/li&gt;
&lt;li&gt;模型分级：简单问答走小模型（几百毫秒出首 token），复杂问题再路由大模型；或对延迟敏感的数字人场景直接上中小尺寸模型。&lt;/li&gt;
&lt;li&gt;就近部署 + 长连接连接池 + 定期预热，避免冷启动和跨地域 RTT。&lt;/li&gt;
&lt;li&gt;进阶要点：&lt;strong&gt;投机采样（speculative decoding）加速的是解码阶段，对 TTFT 帮助不大&lt;/strong&gt;——能分清「首 token 快」和「整体生成快」是两套优化，说明真懂推理过程。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;第五路：感知层兜底&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;优化到头也压不进目标时，用填充音（「嗯，我想想」）先开口争取 500-800ms，用户感知立刻好转。&lt;/li&gt;
&lt;li&gt;记住目标：&lt;strong&gt;流式架构下 TTFT 就是用户感知的全部&lt;/strong&gt;，后续 token 只要比语速快（TTS 会按说话节奏消费），生成总时长不影响体验。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;一句话总结：「TTFT 等于检索加排队加 Prefill。我的优化顺序是：语义缓存先拦截高频问题，RAG 检索并行化并本地部署 Embedding，prompt 精简加 Rerank 控量，稳定前缀前置吃满 KV Cache，小模型分级响应，最后填充音兜底感知。」&lt;/p&gt;
&lt;h3 id=&#34;33-嘴巴tts-语音合成&#34;&gt;3.3 嘴巴：TTS 语音合成&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;TTS（Text To Speech）&lt;/strong&gt; 决定数字人「听起来像不像人」。新人要点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;同样必须选&lt;strong&gt;流式 TTS&lt;/strong&gt;，而且关注一个核心指标：&lt;strong&gt;首包延迟（TTFB，Time To First Byte）&lt;/strong&gt;——从给文本到第一帧音频出来的时间，主流云服务在 200-400ms。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;分句策略&lt;/strong&gt;：LLM 流式输出的文本按标点切成短句送 TTS，句与句之间流水线并行。怎么切是个真问题，展开见 3.3.1。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;音色克隆&lt;/strong&gt;：商用数字人大多需要定制音色（克隆老板、克隆主播）。主流方案（火山、阿里 CosyVoice、GPT-SoVITS 开源）只需几分钟到几小时的样本。&lt;strong&gt;注意合规红线：音色克隆必须取得本人授权&lt;/strong&gt;，国内已有相关判例和《生成式人工智能服务管理暂行办法》的约束。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;韵律和情感&lt;/strong&gt;：检查 TTS 是否支持 SSML 或情感标签，数字人「说话像念经」多半是没做韵律控制。&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;331-从首-token-到首包llm-和-tts-怎么衔接&#34;&gt;3.3.1 从首 token 到首包：LLM 和 TTS 怎么衔接&lt;/h4&gt;
&lt;p&gt;工程上绕不开的一道题：LLM 通过 SSE（Server-Sent Events）逐 token 往外吐，TTS 在另一头等着合成——&lt;strong&gt;中间这段，是攒够 N 个 token 就送一次 TTS，还是有更好的方案？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;先纠正一个概念：&lt;strong&gt;SSE 只是传输管道&lt;/strong&gt;，它决定的是「token 一个一个到达」这个事实，不包含任何切分策略。真正要做决策的是服务端的&lt;strong&gt;聚合层（aggregator）&lt;/strong&gt;——它消费 SSE 流，决定什么时候把一段文本交给 TTS。&lt;/p&gt;
&lt;p&gt;三种方案的对比：&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;方案&lt;/th&gt;
					&lt;th&gt;做法&lt;/th&gt;
					&lt;th&gt;评价&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;按 token 攒批&lt;/td&gt;
					&lt;td&gt;攒够 N 个 token 就送 TTS&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;差方案&lt;/strong&gt;。token 边界和语言边界无关，会切在半个词、半个标点上；每次 TTS 请求有固定开销，请求过碎成本高；韵律上下文残缺，合成质量差&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;按句/子句切分&lt;/td&gt;
					&lt;td&gt;缓冲 token，命中边界标点且长度达标才 flush&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;工业标配&lt;/strong&gt;。切点干净、韵律完整，首句策略可调&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;流式文本输入 TTS&lt;/td&gt;
					&lt;td&gt;TTS 本身支持边收文本边合成（WebSocket 双向流），把 SSE token 直接转发进去&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;更好但依赖厂商能力&lt;/strong&gt;。切句职责交给最懂韵律的 TTS 引擎，首包最快。ElevenLabs、火山、CosyVoice 流式版都支持；自部署 GPT-SoVITS 需要自己做这层&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;按句切分（方案二）的工程细节&lt;/strong&gt;，这是自建聚合层必须写对的：&lt;/p&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart TD
    T[SSE 收到一个 token] --&amp;gt; BUF[写入缓冲区]
    BUF --&amp;gt; C1{命中句末标点&amp;lt;br/&amp;gt;。！？ 且长度达标?}
    C1 -- 是 --&amp;gt; FLUSH[flush：送 TTS 队列]
    C1 -- 否 --&amp;gt; C2{缓冲长度超上限?}
    C2 -- 是 --&amp;gt; C3{回找最近的&amp;lt;br/&amp;gt;逗号/顿号}
    C3 -- 找到 --&amp;gt; FLUSH
    C3 -- 没有 --&amp;gt; WAIT[继续等&amp;lt;br/&amp;gt;到硬上限强切]
    C2 -- 否 --&amp;gt; C4{缓冲超时&amp;lt;br/&amp;gt;300-500ms?}
    C4 -- 是 --&amp;gt; FLUSH
    C4 -- 否 --&amp;gt; T
    WAIT --&amp;gt; T
    FLUSH --&amp;gt; NEXT[句子带序号进 TTS 队列&amp;lt;br/&amp;gt;并发合成 按序播放]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;p&gt;四条规则记牢：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;首句激进，后续放宽&lt;/strong&gt;：第一句是首音延迟的关键，切得短（命中第一个逗号、8-15 字就 flush，甚至 LLM prompt 里直接要求「第一句简短应答」）；后续句子放宽到 20-80 字保证韵律。首音快 200ms，用户感知就高一档。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;切点优先级&lt;/strong&gt;：句号/问号/叹号最优先，分号/冒号次之，逗号只在超长兜底时用。顿号不切。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;标点陷阱&lt;/strong&gt;：小数点（「3.5 秒」）、省略号、引号内标点、英文缩写（「e.g.」）都会造成误判，正则切分前先做这些特例清洗；markdown 符号（&lt;code&gt;**&lt;/code&gt;、&lt;code&gt;#&lt;/code&gt;、&lt;code&gt;1.&lt;/code&gt;）在进缓冲前就要剥掉，否则 TTS 会念出来。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;并发合成、按序播放&lt;/strong&gt;：切出来的句子打上序号进队列，多个 TTS 请求可以并发，但播放端必须按序号拼接，乱序就出「先说第二句」的事故。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;超时兜底&lt;/strong&gt;为什么必须有：LLM 有时会输出不带句末标点的长句，如果没有 300-500ms 的缓冲超时强刷，用户会眼睁睁看着数字人「憋着不说话」。&lt;/p&gt;
&lt;p&gt;一句话总结：「SSE 只负责把 token 送过来，切分在服务端聚合层做。不按 token 数攒批——按标点加长度双阈值切句，首句切得激进来压低首音时间，后续句放宽保韵律，再加超时兜底；如果 TTS 厂商支持流式文本输入，就直接把 token 流转发进去让引擎自己切，首包还能再快一截。」&lt;/p&gt;
&lt;h3 id=&#34;34-脸口型与表情驱动&#34;&gt;3.4 脸：口型与表情驱动&lt;/h3&gt;
&lt;p&gt;这是数字人区别于「语音助手」的关键一环，也是新人知识盲区最大的一环。&lt;/p&gt;
&lt;p&gt;核心技术概念：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Viseme（视素）&lt;/strong&gt;：音素（phoneme）对应的口型。比如 /b/ /p/ /m/ 都对应「双唇闭合」这个口型。英文一般归并为十几个 viseme，中文可按韵母口型归类。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Blendshape（混合形状）&lt;/strong&gt;：3D 模型的表情通过一组预定义变形（如 &lt;code&gt;jawOpen&lt;/code&gt;、&lt;code&gt;mouthSmile&lt;/code&gt;）按权重混合出来。音频 → 音素 → viseme → blendshape 权重，就是经典的口型驱动路径。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;2D 真人形象驱动&lt;/strong&gt;：wav2lip、SadTalker、MuseTalk 这类模型，输入音频 + 人脸视频/照片，直接生成口型对齐的人脸帧。&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart TB
    AUDIO[TTS 音频流] --&amp;gt; PATH{形象路线}
    PATH --&amp;gt;|3D 写实路线| P1[音频提取音素/声学特征]
    P1 --&amp;gt; P2[映射 Viseme / Blendshape 权重]
    P2 --&amp;gt; P3[Unity/UE 实时渲染]
    PATH --&amp;gt;|2D 真人克隆路线| Q1[wav2lip / MuseTalk 等&amp;lt;br/&amp;gt;音频到人脸帧模型]
    Q1 --&amp;gt; Q2[逐帧生成口型对齐画面]
    PATH --&amp;gt;|Live2D 路线| R1[音量/音素驱动&amp;lt;br/&amp;gt;参数开合]
    R1 --&amp;gt; R2[Live2D SDK 渲染]

    P3 --&amp;gt; OUT[合成视频帧推流]
    Q2 --&amp;gt; OUT
    R2 --&amp;gt; OUT&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;p&gt;选型经验：&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;路线&lt;/th&gt;
					&lt;th&gt;效果&lt;/th&gt;
					&lt;th&gt;成本&lt;/th&gt;
					&lt;th&gt;适用&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Live2D&lt;/td&gt;
					&lt;td&gt;二次元，口型精度要求低&lt;/td&gt;
					&lt;td&gt;极低（CPU 可跑）&lt;/td&gt;
					&lt;td&gt;虚拟主播、轻量客服&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;3D Blendshape&lt;/td&gt;
					&lt;td&gt;可控、风格化或写实&lt;/td&gt;
					&lt;td&gt;中（需要建模绑定 + GPU 渲染）&lt;/td&gt;
					&lt;td&gt;品牌 IP、大屏数字员工&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;真人克隆（wav2lip 类）&lt;/td&gt;
					&lt;td&gt;最像真人&lt;/td&gt;
					&lt;td&gt;高（每帧都要过模型，吃 GPU）&lt;/td&gt;
					&lt;td&gt;数字分身、口播视频&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&#34;35-身体动作与姿态&#34;&gt;3.5 身体：动作与姿态&lt;/h3&gt;
&lt;p&gt;只有脸会动的数字人被称为「花瓶数字人」。完整的身体驱动包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;待机动作（idle）&lt;/strong&gt;：不说话时的呼吸、眨眼、微动作。没有 idle 的数字人在沉默时会「死机感」十足。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;动作库触发&lt;/strong&gt;：LLM 输出时打标签（如 &lt;code&gt;[挥手]&lt;/code&gt;），引擎播放对应动画片段。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;动作生成/动捕&lt;/strong&gt;：高端场景用动作生成模型或真人动捕（光学动捕、惯性动捕、视觉动捕）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;视线与点头&lt;/strong&gt;：根据对话状态做倾听点头、眼神接触，对「像人」的提升性价比极高。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;36-渲染与呈现&#34;&gt;3.6 渲染与呈现&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;客户端渲染&lt;/strong&gt;：形象资源下发到 App/Web/小程序，本地用 Unity、WebGL（three.js）、Live2D SDK 渲染。好处是不耗服务端 GPU、画面清晰；代价是包体积和端上性能适配。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;服务端渲染 + 推流&lt;/strong&gt;：服务端用 UE/Unity 无头渲染成视频流推给端上。好处是端上零成本、形象保密；代价是每路并发一块 GPU，成本高。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;像素流送（Pixel Streaming）&lt;/strong&gt;：UE 官方的「服务端渲染 + WebRTC 推流」方案，超写实数字人大屏常用。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;37-神经webrtc-低延迟传输&#34;&gt;3.7 神经：WebRTC 低延迟传输&lt;/h3&gt;
&lt;p&gt;实时交互必须走 &lt;strong&gt;WebRTC&lt;/strong&gt;（或声网 Agora、腾讯 TRTC、即构 ZEGO 这类商用 RTC SDK，底层同源）。不要用 HLS/RTMP 做交互——它们的延迟是秒级到十秒级，只能用于纯观看的直播场景。&lt;/p&gt;
&lt;p&gt;WebRTC 给数字人的价值：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;端到端延迟可压到 200-400ms；&lt;/li&gt;
&lt;li&gt;自带弱网对抗（ jitter buffer、NACK、FEC）、AEC、降噪；&lt;/li&gt;
&lt;li&gt;天然支持双向音视频（用户上行说话 + 数字人下行画面）。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;工程上通常自建或租用 SFU（Selective Forwarding Unit）做转发，数字人服务端作为一个「虚拟参会者」接入 RTC 房间。&lt;/p&gt;
&lt;h2 id=&#34;4-延迟预算实时数字人的生死线&#34;&gt;4. 延迟预算：实时数字人的生死线&lt;/h2&gt;
&lt;p&gt;交互自然度的经验值：&lt;strong&gt;用户说完话到数字人开口，超过 1.5 秒就会觉得「卡」，控制在 1 秒内算流畅，500ms 内接近真人&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;逐环预算参考（单位毫秒）：&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;环节&lt;/th&gt;
					&lt;th&gt;典型耗时&lt;/th&gt;
					&lt;th&gt;优化手段&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;VAD 判停（说完话确认）&lt;/td&gt;
					&lt;td&gt;300-600&lt;/td&gt;
					&lt;td&gt;语义 VAD、动态超时&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;ASR 末字出结果&lt;/td&gt;
					&lt;td&gt;100-300&lt;/td&gt;
					&lt;td&gt;流式 + 就近节点&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;LLM 首 token&lt;/td&gt;
					&lt;td&gt;300-800&lt;/td&gt;
					&lt;td&gt;小模型前置、就近部署、prompt 精简&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;TTS 首包&lt;/td&gt;
					&lt;td&gt;200-400&lt;/td&gt;
					&lt;td&gt;流式、句级流水线&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;口型驱动 + 渲染首帧&lt;/td&gt;
					&lt;td&gt;50-200&lt;/td&gt;
					&lt;td&gt;预加载、模型量化&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;RTC 传输&lt;/td&gt;
					&lt;td&gt;100-300&lt;/td&gt;
					&lt;td&gt;就近接入、专线&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart LR
    A[VAD 判停&amp;lt;br/&amp;gt;300-600ms] --&amp;gt; B[ASR 出字&amp;lt;br/&amp;gt;100-300ms]
    B --&amp;gt; C[LLM 首 token&amp;lt;br/&amp;gt;300-800ms]
    C --&amp;gt; D[TTS 首包&amp;lt;br/&amp;gt;200-400ms]
    D --&amp;gt; E[驱动渲染&amp;lt;br/&amp;gt;50-200ms]
    E --&amp;gt; F[RTC 送达&amp;lt;br/&amp;gt;100-300ms]
    style C fill:#fee,stroke:#c00&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;p&gt;注意 &lt;strong&gt;LLM 是最大的延迟黑洞&lt;/strong&gt;，这也是为什么很多产品用「嗯、我想想」这类填充音（filler）先开口争取时间，以及用小参数模型做第一轮快速响应。&lt;/p&gt;
&lt;h2 id=&#34;5-离线内容生产链路&#34;&gt;5. 离线内容生产链路&lt;/h2&gt;
&lt;p&gt;做口播短视频、课程录播的场景不需要实时，链路简化为：&lt;/p&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart LR
    S[文案脚本] --&amp;gt; T[TTS 合成配音]
    T --&amp;gt; D[wav2lip / 形象克隆&amp;lt;br/&amp;gt;生成画面]
    D --&amp;gt; E[FFmpeg 合成&amp;lt;br/&amp;gt;字幕/背景/BGM]
    E --&amp;gt; V[成品视频]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;p&gt;这条链路的工程重点是&lt;strong&gt;批量化和质量控制&lt;/strong&gt;：文案队列、素材版本管理、抽帧质检（口型错位检测）、FFmpeg 自动化后期。它也是新人练手的最佳起点——没有实时性压力，每一步都可以慢慢调试。&lt;/p&gt;
&lt;h2 id=&#34;6-元宇宙视角下的数字人&#34;&gt;6. 元宇宙视角下的数字人&lt;/h2&gt;
&lt;p&gt;虽然元宇宙概念已过炒作高峰，但它的知识框架对理解数字人很有帮助：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;数字人是元宇宙的「界面」&lt;/strong&gt;：元宇宙的愿景里，人通过 Avatar 进入虚拟世界，而 AI 数字人是这个世界里的 NPC、导游、店员。今天落地的数字人客服、数字人员工，可以看作「没有整个元宇宙、先把 NPC 做出来」的务实路线。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;数字身份与数字资产&lt;/strong&gt;：虚拟形象的版权归属、音色的人格权、数字分身的行为授权，都是元宇宙法律框架讨论的核心，做商用数字人绕不开。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;XR 是下一级放大器&lt;/strong&gt;：目前的数字人主要在手机屏和大屏上，VR/AR 设备普及后，「面对面」的沉浸交互会把实时渲染和低延迟的要求再推高一个量级。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;技术栈高度重合&lt;/strong&gt;：游戏引擎、实时渲染、Avatar 系统、RTC——元宇宙基建没浪费，全都迁移到了数字人赛道。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;一句话总结两者的关系：&lt;strong&gt;元宇宙是「世界」，数字人是「人」；世界还在建，人已经开始打工了。&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&#34;7-避坑清单新人最常踩的十个坑&#34;&gt;7. 避坑清单（新人最常踩的十个坑）&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;用 HTTP 轮询或 WebSocket 传实时音视频&lt;/strong&gt;：WebSocket 传音频可以，但视频和双向通话必须 WebRTC。架构选错后面全是补丁。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;等 LLM 全句生成完再送 TTS&lt;/strong&gt;：首音延迟直接多出 1-3 秒。必须按句流式切分。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;TTS 分句切在奇怪的位置&lt;/strong&gt;：按标点切，且避免切出「的」「了」这种单字句，否则韵律全毁。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;忽略 VAD 判停时间&lt;/strong&gt;：默认 500-800ms 的静音判停在口语场景经常切断用户长句，要按场景调。反过来判起也有坑——不做 200-300ms 预滚动缓冲（pre-roll）会吃掉句首，「你好」变成「好」。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;没做 AEC 就上扬声器场景&lt;/strong&gt;：数字人听见自己说话，无限自答。音箱/大屏场景必查。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;口型和音频各走各的时钟&lt;/strong&gt;：音频流和视频帧必须共用时间戳对齐，否则网络抖动后口型越偏越远。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;忽视打断（barge-in）&lt;/strong&gt;：用户插话时数字人必须能立刻闭嘴并清空播放队列，这是「像人」的及格线，很多 Demo 死在这。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;没有 idle 状态&lt;/strong&gt;：沉默时形象完全静止，恐怖谷效应拉满。眨眼和呼吸是性价比最高的两个动作。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;音色克隆不管授权&lt;/strong&gt;：合规风险，商用前必须签授权。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;并发成本没算清就接客&lt;/strong&gt;：真人克隆路线每路并发都吃 GPU，一路成本可能是纯语音机器人的几十倍，报价前先压测。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;8-典型问题与解决方案&#34;&gt;8. 典型问题与解决方案&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Q1：口型和声音对不上，越聊偏得越远。&lt;/strong&gt;
音频帧和驱动帧的时间戳没有同源。方案：以音频流为主时钟，口型权重按音频时间戳生成，渲染帧消费时做对齐；网络侧开启 NACK 减少重传造成的画面跳变。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Q2：数字人响应慢，用户说完要等两三秒。&lt;/strong&gt;
按第 4 节的预算表逐环打点定位。八成问题在 LLM 首 token 和 TTS 首包：LLM 换更快的模型或精简 prompt，TTS 确认开了流式，两句之间流水线并行。还不行就加填充音。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Q3：用户插话，数字人不理继续说完。&lt;/strong&gt;
没有 barge-in 机制。方案：ASR 检测到新的用户语音起始 → 立即向 TTS/播放器发中断信号 → 清空待发队列 → LLM 侧中断当前生成（保留已说内容到上下文）。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Q4：声音机械、像念稿。&lt;/strong&gt;
检查：文本是否带了 markdown 符号（TTS 会念出来）；是否用了支持韵律/情感的模型；分句是否过碎。可以在送 TTS 前加一道「口语化改写」。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Q5：回声、啸叫、把自己当用户。&lt;/strong&gt;
AEC 没生效。WebRTC 场景确认 &lt;code&gt;echoCancellation: true&lt;/code&gt;；自研管线接入 WebRTC APM；硬件上麦克风和扬声器做物理隔离。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Q6：大促/高峰期并发上不去，GPU 烧钱。&lt;/strong&gt;
真人克隆路线把渲染挪到闲时（离线预生成常见回答视频片段，实时只做拼接）；或降级到 3D/Live2D 路线；LLM 层加意图缓存，高频问题直接命中预置音视频。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Q7：数字人前后人设不一致，聊着聊着「换人」了。&lt;/strong&gt;
人格 prompt 没有和记忆系统打通。方案：人格定义放 system 层固定不动；用户画像和会话摘要由记忆系统（如 Mem0）注入；定期用人格一致性评估集回归测试。&lt;/p&gt;
&lt;h2 id=&#34;9-学习路径从-0-到精通&#34;&gt;9. 学习路径：从 0 到精通&lt;/h2&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart TB
    subgraph S1[&amp;#34;第一阶段：跑通（1-2 周）&amp;#34;]
        A1[调通云 ASR + LLM + TTS&amp;lt;br/&amp;gt;做一个语音对话命令行 Demo]
        A2[用 wav2lip 开源模型&amp;lt;br/&amp;gt;离线生成一个口播视频]
    end

    subgraph S2[&amp;#34;第二阶段：像人（3-4 周）&amp;#34;]
        B1[全链路流式化改造&amp;lt;br/&amp;gt;打点测延迟]
        B2[实现 barge-in 打断]
        B3[接入一个 2D/3D 形象&amp;lt;br/&amp;gt;完成口型驱动]
    end

    subgraph S3[&amp;#34;第三阶段：上线（4-8 周）&amp;#34;]
        C1[WebRTC 推拉流&amp;lt;br/&amp;gt;端到端联调]
        C2[记忆系统 + 人格 prompt 工程]
        C3[压测与成本核算&amp;lt;br/&amp;gt;弱网对抗]
    end

    subgraph S4[&amp;#34;第四阶段：精通（持续）&amp;#34;]
        D1[自研/微调 TTS 与驱动模型]
        D2[情感计算与多模态交互]
        D3[中台化：多形象/多租户/编排]
    end

    S1 --&amp;gt; S2 --&amp;gt; S3 --&amp;gt; S4&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;p&gt;练手项目建议（按递进排序）：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;命令行语音助手：打通 ASR → LLM → TTS，全程流式。&lt;/li&gt;
&lt;li&gt;离线口播视频生成器：文案进、成片出，加 FFmpeg 字幕。&lt;/li&gt;
&lt;li&gt;网页实时数字人：Live2D 或 wav2lip 形象 + WebRTC，实现打断。&lt;/li&gt;
&lt;li&gt;有记忆的数字人：接入长时记忆，连续聊三天还记得用户说过什么。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;10-总结&#34;&gt;10. 总结&lt;/h2&gt;
&lt;p&gt;数字人链路说复杂也复杂，说简单就是一句话：&lt;strong&gt;把人的「听、想、说、动」拆成 ASR、LLM、TTS、驱动渲染、RTC 五个流式环节，再把总延迟压进 1 秒&lt;/strong&gt;。新人入门的正确姿势不是啃论文，而是先跑通最小闭环，再逐环升级——每一环的坑本文都列了，剩下的就是动手。&lt;/p&gt;
&lt;p&gt;概念地图有了，想看这条链路在真实开源项目里长什么样，接着读&lt;a href=&#34;https://ftmao.com/blog/blog/posts/livetalking-source-code-analysis/&#34;&gt;《LiveTalking 源码解剖：一个开源实时数字人是怎么跑起来的》&lt;/a&gt;——它把本文的输出侧（TTS、口型驱动、RTC 推流）做成了工业级实现，输入侧和智能侧留着 demo 形态，正好当对照样本。&lt;/p&gt;
</description>
    </item>
    
  </channel>
</rss>
