MIT License

技术解读

以下内容由 GitRead 中文社区 编辑团队基于项目 README 与官方资料整理, 结合中文开发者的常见使用场景补充技术选型建议。具体以项目官方文档为准。

VTuber_Unity:把“中之人”彻底交给算法的开源尝试

项目背景与痛点

虚拟主播行业走到今天,最大的隐性成本已经超出 3D 模型本身,主要来自中之人:直播时长受限于人的体力,人设维系依赖真人表演,一旦中之人离职,账号资产就会大幅缩水。商业方案如 VTube Studio、Live2D Cubism 解决的是“用摄像头驱动一张皮”的问题,但驱动源始终是人。

kwea123/VTuber_Unity 想撬动的正是这一环:让 Python 侧的深度学习算法扮演“中之人”,Unity 侧只负责把结果渲染成一张能推流的 3D 脸。它的价值不在模型本身有多先进,而在于把感知、决策、表达、渲染四条链路的连接打通了,给出了一个端到端可跑、每一段都能替换的开源骨架。对想自建 AI 主播的团队来说,这比任何一个单点 SOTA 模型都更有参考价值。

核心技术揭秘

这个项目最值得讨论的设计决策,是 Python 与 Unity 的职责切分。深度学习生态在 Python,实时渲染与骨骼/BlendShape 控制在 Unity,强行统一到一侧都会付出代价——在 Unity 里跑推理要走 Barracuda/ONNX,算子覆盖不全;在 Python 里做渲染则要面对 OpenGL 上下文与 VRM 加载的一堆坑。作者选择了双进程 + 轻量通信的路线,用 socket 传递状态帧,这在工程上是性价比最高的解。

数据流大致是这样的:

graph TD A[麦克风 / 文本输入] --> B[Python 端: ASR 与 LLM 对话] B --> C[Python 端: TTS 语音合成] C --> D[音频特征提取] D --> E{"是否需要音素级对口型"} E -->|"是"| F[生成 BlendShape 权重序列] E -->|"否"| G[退化为音量包络驱动] H[摄像头画面] --> I[人脸关键点检测] I --> J[表情与头部姿态解算] F --> K[Unity 端: VRM 骨骼与 Morph 驱动] G --> K J --> K K --> L[Unity 摄像机渲染] L --> M[虚拟摄像头推流至 OBS]

几个隐含的技术难点值得点出来:

其一是通信语义。 跨进程传动作数据,最容易犯的错是按“事件”发送(“现在张嘴”)。网络抖动一出现,Unity 侧就会卡在前一帧表情上。正确做法是周期性发送完整状态帧,接收端永远只渲染最新一帧,丢包退化为掉帧而非卡死。这类项目里如果看到心跳与序号机制,基本就是踩过坑之后的产物。

其二是时间对齐。 音频在 Python 侧生成、口型在 Unity 侧播放,两者时钟不同源。若不携带时间戳做缓冲重排,就会出现“声音到了嘴还没动”的经典错位。实践上需要在 Unity 侧维护一个 100–200ms 的抖动缓冲,用音频播放位置反查对应的 Morph 权重。

其三是 Unity 的线程模型。 socket 收包通常在后台线程,而 SkinnedMeshRenderer.SetBlendShapeWeight 必须在主线程调用。中间必须有一层线程安全的队列做交接,否则轻则画面撕裂,重则直接崩。

功能亮点与差异

相比同类的开源项目,它的差异点有三个:

  • 全链路而非片段。多数仓库只做“语音转口型”或“摄像头驱动表情”,使用者还得自己拼装对话、TTS、推流。这里把一条完整的直播链路串起来了,克隆下来配好环境就能开播。
  • 模型与表现解耦。算法侧输出的是标准化的表情/口型参数,Unity 侧消费的是 VRM 的 BlendShape,换模型、换 TTS、换 LLM 都只需替换单段,不必动整体管线。
  • 3D 优先于 2D。选择 VRM + Unity 而非 Live2D,意味着可以自由做头部六自由度转动、全身动作扩展、光照与镜头调度,天花板明显更高,代价是资源准备成本上升。

应用场景与落地建议

适合的场景很明确:无人值守的长时段直播、多语言/多时区的 24 小时频道、企业内部数字人播报、以及作为 AI Agent 的具身化前端。它不适合对表演精度要求极高的商业级虚拟偶像演出——那仍然需要真人动捕。

生产落地需要注意几点:

  1. 延迟预算要提前算清。ASR 端点检测 + LLM 首 token + TTS 首包 + 渲染一帧,累计很容易到 1.5 秒以上。必须实现“打断”机制,让用户在它说话时插话能立刻掐断当前 TTS,否则交互体验会崩。
  2. GPU 争抢。推理和渲染挤在同一张卡上,要限制 Python 侧的显存占用,或干脆拆到两台机器走局域网。
  3. 状态机比模型更重要。什么时候眨眼、什么时候做呼吸摆动、什么时候转向镜头,这些“微动作”决定了它像不像活人。建议在 Unity 侧独立维护一个 idle 动画层,与算法输出做叠加而非覆盖。
  4. 推流链路。Unity 直接输出到虚拟摄像头(或 Spout/NDI 送 OBS)比截屏方案稳定得多,务必在打包时固定渲染分辨率与帧率。

综合评价

优点:架构切分干净,Python/Unity 各司其职;每一层都可单独替换,是很好的二次开发底座;以极低门槛验证了“AI 驱动 3D 虚拟主播”的完整可行性,代码可读性对一个研究型仓库来说已经不错。

缺点:工程化程度仍停留在 demo 级——配置硬编码、缺少异常恢复、没有连接断开后的重连与降级策略;口型多为音量包络驱动,音素级对齐缺失,遇到爆破音会明显“糊”;单机部署为主,横向扩展与多实例调度完全没有考虑。

一句话总结:它不是可以直接上生产的成品,而是一张画得很清楚的架构草图。想认真做 AI 虚拟主播的团队,值得把它的数据流设计吃透,然后按自己的延迟预算和可靠性要求重写一遍通信层与状态机。

关于

GitHub 原始描述(英文)

Use Unity 3D character and Python deep learning algorithms to stream as a VTuber!

描述取自 GitHub 官方 API,保持仓库作者书写的原文。

简要分析

热度分
1021
价值分
516
活跃状态
归档

语言占比

Python

Release

贡献者

README

VTuber_Unity

2021/9/1: Due to massive bugs and the fast-moving virtual character technology, I decide to archive this repository (no updates anymore). Nowadays you can basically find many public tools on the internet, even for mobile platforms. This repository doesn’t work as well as those tools, but can still serve as a tool if you want to integrate your character in Unity and custom it (e.g. play around with Unity objects).

Use Unity 3D character and Python deep learning algorithms to stream as a VTuber!

This is part of the OpenVTuberProject, which provides many toolkits for becoming a VTuber.

Youtube Playlist (Chinese) (Covers videos 1-4): teaser


Credits

First of all, I’d like to give credits to the following projects that I borrow code from:

Project LICENSE
head-pose-estimation LICENSE
face-alignment LICENSE
GazeTracking LICENSE

And the virtual character unity-chan © UTJ/UCL.

Installation

Hardware

  • OS: Ubuntu 16.04 (18.04 may also work) or Windows 10 64bits or MacOS
  • (Optional but recommended) An NVIDIA GPU (tested with CUDA 9.0, 10.0 and 10.1, but may also work with other versions)

Software

  • Python3.x (installation via Anaconda is recommended; mandatory for Windows users)

    • (Optional) It is recommended to use conda environments. Run conda create -n vtuber python=3.6. Activate it by conda activate vtuber.
  • Python libraries

    • Ubuntu:
      • Install the requirements by pip install -r requirements_(cpu or gpu).txt
      • If you have CUDA 10.1, pip install onnxruntime-gpu to get faster inference speed using onnx model.
    • Windows:
      • CPU:
        • pip install -r requirements_cpu.txt
        • if dlib cannot be properly installed, follow here.
      • GPU:
        • Install pytorch using conda. Example: conda install pytorch==1.2.0 torchvision==0.4.0 cudatoolkit=10.0 -c pytorch
        • Install other dependencies by pip install -r requirements_gpu.txt.
        • If you have CUDA 10, pip install onnxruntime-gpu to get faster inference speed using onnx model.
  • Optional

Example usage

Here we assume that you have installed the requirements and activated the virtual environment you are using.

0. Model download

You need to download the models here, extract and put into face_alignment/ckpts.

If you don’t use onnxruntime, you can omit this step as the script will automatically download them for you.

1. Face detection test

Run python demo.py --debug. (add --cpu if you have CPU only)

You should see the following:


Left: CPU model. Right: GPU model run on a GTX1080Ti.

2. Synchronize with the virtual character

  1. Download and launch the binaries here depending on your OS to launch the unity window featuring the virtual character (unity-chan here). Important: Ensure that only one window is opened at a time!
  2. After the vitual character shows up, run python demo.py --connect to synchronize your face features with the virtual character. (add --debug to see your face and --cpu if you have CPU only as step 1.)

You should see the following:


Left: CPU model. Right: GPU model run on a GTX1080Ti.

Enjoy your VTuber life!

Functionalities details

In this section, I will describe the functionalities implemented and a little about the technology behind.

Head pose estimation

Using head-pose-estimation and face-alignment, deep learning methods are applied to do the following: face detection and facial landmark detection. A face bounding box and the 68-point facial landmark is detected, then a PnP algorithm is used to obtain the head pose (the rotation of the face). Finally, kalman filters are applied to the pose to make it smoother.

The character’s head pose is synchronized.

As for the visualization, the white bounding box is the detected face, on top of which 68 green face landmarks are plotted. The head pose is represented by the green frustum and the axes in front of the nose.

Gaze estimation

Using GazeTracking, The eyes are first extracted using the landmarks enclosing the eyes. Then the eye images are converted to grayscale, and a pixel intensity threshold is applied to detect the iris (the black part of the eye). Finally, the center of the iris is computed as the center of the black area.

The character’s gaze is not synchronized. (Since I didn’t find a way to move unity-chan’s eyes)

As for the visualization, the red crosses indicate the iris.

Miscellaneous

  1. Estimate eye aspect ratio: The eye aspect ratio can be used to detect blinking, but currently I just use auto blinking since this estimation is not so accurate.

  2. Estimate mouth aspect ratio: I use this number to synchronize with the character’s mouth.

  3. The mouth distance is used to detect smile and synchronize with the character.

Unity Project

If you want to customize the virtual character, you can find the unity project in release.

License

MIT License

评论

暂无评论