The Problem
PersonaLive addresses the gap between offline portrait animation (which produces high-quality but slow, finite clips) and the demands of live streaming, which requires real-time, infinite-length generation. The system is a diffusion-based framework that animates a single reference portrait image using a driving video's pose and expression, optimized for continuous streaming rather than one-shot generation.
What This Does
The repo contains a full training and inference pipeline for expressive portrait animation. The core model architecture lives in src/models/, including unet_3d.py, unet_3d_explicit_reference.py, and mutual_self_attention.py. The src/pipelines/ directory holds the pose-to-image (pipeline_pose2img.py) and pose-to-video (pipeline_pose2vid.py) generation pipelines, while src/liveportrait/ handles motion extraction from the driving video.
The project ships three execution modes: inference_offline.py for clip generation, inference_online.py (a WebSocket server for streaming), and a full webcam application under webcam/ with a Svelte/TypeScript frontend. Training scripts are split into three stages (train_stage1.py, train_stage2.py, train_stage3.py), each with corresponding YAML configs in configs/train/.
How It Is Wired
Execution starts at main in inference_offline.py:46, which reaches 55 functions. The critical hub is the to function (PyTorch's device-transfer method), called from 42 distinct places — changing tensor placement logic will break nearly everything downstream. mean (called from 9 places) and _parse_padding (6 places) are the next most-coupled utilities.
The three training scripts (train_stage1/2/3.py) are the most unstable modules in the import graph, each importing 12-13 modules with zero inbound dependencies — they are the leaves of the dependency tree. src/wrapper.py and src/wrapper_trt.py (TensorRT variant) are the bridge between inference code and model internals, with instability scores of 0.89-0.9.
The system touches the outside world through src/utils/util.py, which handles filesystem operations (save_checkpoint, delete_additional_ckpt) and runs external commands. inference_online.py reads/writes files and manages the WebSocket endpoint. src/stylegan2/dnnlib/util.py performs network calls and secret-generation operations. The shortest path from entry point to external effect is main -> save_checkpoint (filesystem via os.remove).
How To Use It
Setup: Clone and install dependencies:
git clone https://github.com/GVCLab/PersonaLive
cd PersonaLive
conda create -n personalive python=3.10
conda activate personalive
pip install -r requirements_base.txt
Configuration: Download pretrained weights via python tools/download_weights.py, or manually into ./pretrained_weights. Inference configs live in configs/inference/ and configs/prompts/.
Running it: For offline generation, python inference_offline.py with the YAML prompt configs. For the webcam UI, the webcam/ directory contains a Svelte frontend (webcam/frontend/) with a Vite build, and backend Python scripts (vid2vid.py, vid2vid_trt.py). The web_start.sh script appears to orchestrate the webcam startup.
Real-World Use
A streamer uploads a reference portrait once, then drives animation through a webcam feed. The webcam/ frontend captures video frames, sends them over WebSocket to inference_online.py, which runs the pose-to-video pipeline and streams generated frames back. The system supports real-time replacement of the reference image during streaming, per the README's feature list.
Code Health & Issues
Static analysis (from the pipeline's measured analysis, not opinion) found 62 issues: 12 high, 49 medium, 1 low.
- High - duplicated code blocks: 1,876 repeated 6-line blocks across 48 files, including
inference_offline.pyandsrc/pipelines/pipeline_pose2img.py. This makes fixes fragile — patching one copy misses others. - High - deep nesting: Max indentation depth of 9 in
src/models/mutual_self_attention.py,src/utils/util.py, andsrc/models/motion_module.py. Control flow is hard to follow. - Medium - unmanaged file handles: 9 instances of
open(...)without context managers insrc/utils/util.pyandwebcam/util.py. - Medium - broad exception handling: 8 bare or
Exception-wide catches insrc/utils/util.pyandsrc/modeling/engine_model.py. - Medium - oversized files:
unet_2d_condition.pyat 1,063 code lines; changes ripple widely. - Medium - high branching density: 28 branch points over 65 lines in
src/stylegan2/torch_utils/ops/bias_act.cpp.
SDLC gaps: no test suite, no CI pipeline, no Dockerfile. Three GIF files over 10MB each (assets/demo_1.gif through demo_3.gif) bloat every clone. License is present.
The Bottom Line
This is a research-grade CVPR 2026 codebase with a working three-stage training pipeline and a functional webcam streaming UI. The lack of tests and CI makes it risky to modify, and the duplicated code blocks will make maintenance painful. It's suitable for researchers reproducing the paper or building on the architecture, not for production deployment without significant hardening.