周记(2025春第14周)
使用 INSTA-pytorch 处理人头模型
INSTA-pytorch 简介
Instant Volumetric Head Avatars(INSTA)
- 项目网站:https://zielon.github.io/insta/
- 代码:https://github.com/Zielon/INSTA-pytorch
- 论文:https://arxiv.org/pdf/2211.12499v2
- 数据集示例:https://keeper.mpdl.mpg.de/d/5ea4d2c300e9444a8b0b/
该项目原有一个 C++ 版本(https://github.com/Zielon/INSTA),其论文也是基于 C++ 撰写的。本实验采用它的 Python 适配版本。
有关 INSTA 的学习笔记:
- Instant Volumetric Head Avatars,10分钟训练一个! - 知乎:https://zhuanlan.zhihu.com/p/590379734
- 论文简析 INSTA - 知乎:https://zhuanlan.zhihu.com/p/660660840
- INSTA笔记 - 知乎:https://zhuanlan.zhihu.com/p/636256298
- [CVPR-23] Instant Volumetric Head Avatars-CSDN博客:https://blog.csdn.net/qq_40731332/article/details/135117745
INSTA-pytorch 的 GPU 依赖性
【注意】不要试图在没有 NVIDIA 显卡的计算机上使用 INSTA-pytorch!很遗憾,INSTA 目前不支持纯 CPU 模式运行——它在底层大量依赖 NVIDIA 的 CUDA 扩展来做高速的体积光线行进、最近邻查询和哈希编码等工作,这些模块都需要 nvcc 编译的 GPU 代码。
进一步解释:首先,该项目的许多子模块都是通过 torch.utils.cpp_extension.CUDAExtension 编译的,只能生成 .cu(CUDA)版本的动态库。如果没有 CUDA 编译器和 GPU,这些扩展根本就编译不过;再者,本项目对应的论文也有写,该项目就是对传统 CPU 方式的 GPU 优化,即使你强行把所有 CUDA 调用改成纯 CPU,那么每一条光线都要在 CPU 上做数千次体积采样、MLP 前向、哈希查询……在纯 CPU 上训练和渲染流程的时间会从几分钟/秒级直接飙升到几天/小时级,基本不可用。
我选择了阿里云按小时计费的某个云服务器,搭载 NVIDIA A10 显卡。原价 10 块多一小时,新客可以每小时减免 8 块使用 100 小时。
INSTA-pytorch 安装出现的问题
-
requirements.txt 中 pysdf 安装的相关问题,网上已有现成资料或询问 ChatGPT。
-
高版本的 CUDA 可能不适用 C++14。尝试将所有 setup.py 文件中的 C++14 替换为 C++17。
-
CUDA版本太高。先前独立安装了最新版本 12.9 的 CUDA,但编译时要求适用 pytorch 的版本为 12.6 的 CUDA。被迫卸载后降级,且更换环境变量指向。降级后依然报错,故强制使其指向 pytorch 适配的 CUDA 以确保正常编译。
-
tinycudann 安装时不反馈任何错误或警告,只是卡在那里?这只是正常的安装过程,多等等!一开始发现安装过程中长时间无反应,以为可能是哪里的死循环错误,后发现这仅仅是因为其安装耗时比较长。
-
执行 ./scripts/install_ext.sh 的过程中一直报 C++17 不兼容错,查阅资料后发现因为高版本的 CUDA 可能不适用 C++14。尝试将所有 setup.py 文件中的与 C++14 相关的语句替换为 C++17 相关,具体方法见下面的代码块。
-
最后安装时报错宏 NUM_THREADS 冲突。这种情况在 CUDA 11.x 版本一般不出现,但 CUDA 12.x 使用了这一宏名。将此项目 /insta-pytorch/bvh/setup.py 中定义的 NUM_THREADS 宏修改名字即可。
INSTA-pytorch 的安装示例
# 克隆项目
sudo su # root 权限
git clone https://github.com/Zielon/insta-pytorch # 主程序下载
# 安装 Anaconda
curl -O https://repo.anaconda.com/archive/Anaconda3-2024.10-1-Linux-x86_64.sh # Anaconda 下载,文件较大,约 1 GB,阿里云 10 Mbps 带宽约需 4 min
bash ~/Anaconda3-2024.10-1-Linux-x86_64.sh # Anaconda 安装
# Anaconda 的下载与安装参见 https://www.anaconda.com/docs/getting-started/anaconda/install#macos-linux-installation:how-do-i-verify-my-installers-integrity
conda init --all # 初始化
conda create -n insta-pytorch python=3.9
conda activate insta-pytorch
cd insta-pytorch
# 安装依赖库
pip install pybind11>=2.5.0 # 提前解决依赖文件中 pysdf 的安装问题
pip install pysdf # 安装 pysdf
pip install -r requirements.txt # 安装依赖
# deb 安装 CUDA(不成功,仅作记录!)
# wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/x86_64/cuda-ubuntu2204.pin # 下载与安装 CUDA
# sudo mv cuda-ubuntu2204.pin /etc/apt/preferences.d/cuda-repository-pin-600
# wget https://developer.download.nvidia.com/compute/cuda/12.6.0/local_installers/cuda-repo-ubuntu2204-12-6-local_12.6.0-560.28.03-1_amd64.deb # 文件较大,约 4 GB
# sudo rm /var/lib/dpkg/lock-frontend # 提前解决前端锁问题
# sudo dpkg -i cuda-repo-ubuntu2204-12-6-local_12.6.0-560.28.03-1_amd64.deb
# sudo cp /var/cuda-repo-ubuntu2204-12-6-local/cuda-*-keyring.gpg /usr/share/keyrings/
# sudo apt-get update
# sudo apt-get -y install cuda-toolkit-12-6
# # 此时发生磁盘 I/O 错误
# 删除 torch
pip uninstall torch torchvision torchaudio # 删除原有 torch
# 安装 NVIDIA 驱动程序
hostnamectl # 查看发行版本和版本号
uname -r # 查看正在运行的内核包
# 搜索驱动程序:https://www.nvidia.cn/geforce/drivers/
# [download] https://cn.download.nvidia.com/tesla/550.127.08/nvidia-driver-local-repo-ubuntu2204-550.127.08_1.0-1_amd64.deb # 下载驱动
# [SFTP_update] # 上传
dpkg -i nvidia-driver-local-repo-ubuntu2204-550.127.08_1.0-1_amd64.deb # 解压并安装
apt update
cp /var/nvidia-driver-local-repo-ubuntu2204-550.127.08/nvidia-driver-local-42AEA102-keyring.gpg /usr/share/keyrings/ # 注册临时密钥
apt install cuda-drivers #安装驱动
# Ubuntu 安装 NVIDIA 驱动详见:https://docs.nvidia.com/datacenter/tesla/driver-installation-guide/index.html#ubuntu
# 安装 CUDA
nvidia-smi # 输出中 CUDA 最高版本为 12.4
# run 安装 CUDA
wget https://developer.download.nvidia.com/compute/cuda/12.4.0/local_installers/cuda_12.4.0_550.54.14_linux.run
sudo sh cuda_12.4.0_550.54.14_linux.run # 文件较大,约 4 GB,大约需要 6 min,注意不要在图形化界面安装,选择 continue -> 输入 accept -> 注意取消勾选 driver(你已经有了!不然会 failed!)和 nvidia-fs(否则你还要提前额外安装 mofed,不然也会报 failed),注意 "x" 是勾选," "是不选 -> install
# CUDA 的安装日志一般在 /var/log/cuda-installer.log 。
# CUDA 12.4.0 页面:https://developer.nvidia.com/cuda-12-4-0-download-archive
export PATH=/usr/local/cuda-12.4/bin:$PATH # 配置环境变量
export LD_LIBRARY_PATH=/usr/local/cuda-12.4/lib64:$LD_LIBRARY_PATH
# 安装 pytorch
conda install pytorch==2.5.1 torchvision==0.20.1 torchaudio==2.5.1 pytorch-cuda=12.4 -c pytorch -c nvidia # pytorch 安装,文件较大,约 2.8 GB
# pytorch 安装页面:https://pytorch.org/get-started/previous-versions/
# 安装 tiny-cuda-nn
sudo apt update
sudo apt install -y cmake ninja-build
sudo apt install -y python3-dev python3-pip build-essential
python3 -m pip install --upgrade pip setuptools wheel
pip install git+https://github.com/NVlabs/tiny-cuda-nn/#subdirectory=bindings/torch # 这是 install.sh 中的一行,安装可能需要半个小时左右
# 修改 setup.py
# 将 insta-pytorch 文件夹及其所有子文件夹中的 setup.py 中的 '-O3', '-std=c++14' 和 '/O3', '/std:c++17' 全部改为 '-O2', '-std=c++17' 。注意要把所有的斜杠全部改成横杠!把英文冒号改成等于号!把 c++14 改成 c++17!
# 将 /insta-pytorch/bvh 中的 setup.py 的第 66 行中的 -DNUM_THREADS=256 改为 -DBVH_NUM_THREADS=256 。解决此问题参考了文章 https://blog.csdn.net/xccccz/article/details/144534406。
# 安装
./install.sh
# 成功!
INSTA-pytorch 的运行示例
准备数据与工作目录
在 insta-pytorch 文件夹下,创建数据目录 /data/nerf ,创建工作目录 /workspace 。
示例将 obama.zip 解压缩并放入数据目录下,并在工作目录下创建名为 obama 的文件夹用以存放结果。
渲染
在命令行中直接渲染:
python main_insta.py data/nerf/obama --workspace workspace/obama -O --tcnn
-O:启用优化编译,加速推理
--tcnn:使用 Tiny-CUDA-NN 作为后端网络
在 GUI (图形界面)中渲染(会弹出一个图形化窗口,实时显示渲染效果):
python main_insta.py data/nerf/obama --workspace workspace/obama -O --tcnn --gui
在前述硬件配置下,每个 Epoch 大约需要处理 1 分钟。每 10 个 Epoch 为一组。在数据集 obama 上共训练了 67 个 Epoch ,总共用时 1 小时 23 分钟。
INSTA-pytorch 的输出结果
checkpoints: ngp.pth(104MB), ngp_ep0066.pth(532MB), ngp_ep0067.pth(536MB)
需要通过 pytorch 读取。
python
import torch
checkpoint = torch.load('ngp.pth', map_location=torch.device('cpu')) # 填入相对路径,以 CPU 形式加载
print(checkpoint) # 查看文件信息
ngp.pth
{'epoch': 60,
'global_step': 90000,
'stats':
{'loss': [ 0.01805239893590847, 0.01664985285207458, 0.014298579431134622, 0.014413842966003537,
0.014891382255545905, 0.014312042499597095, 0.012865289307460167, 0.012439684997935883,
0.012990930920856878, 0.013531960485274806, 0.014405350544322869, 0.011622973702252544,
0.011186358761481, 0.012539275403923135, 0.011445983092831532, 0.011667333505333258,
0.01391479240286062, 0.012891907089499537, 0.01201028176034375, 0.012117284455629944,
0.011181852787469275, 0.01162640495858808, 0.013530750823017326, 0.012473789244403894,
0.010852506655289848, 0.010793325164438672, 0.01076396962530823, 0.010986675291093298,
0.013953961325806247, 0.01109155085071959, 0.010730554903970273, 0.012520627962645869,
0.01327943157751849, 0.013281854526310484, 0.012877508602679126, 0.011717672957035248,
0.010586672795754306, 0.010638146803005778, 0.010568715633373962, 0.010854586938227684,
0.012798278902615244, 0.011422378887334711, 0.011641033282080476, 0.012443393191579962,
0.01231181367568549, 0.013242373886603912, 0.012635613855760168, 0.010644334603444387,
0.00994922863944776, 0.010369753362823673, 0.009634821811942501, 0.009761761311837947,
0.009991973827580158, 0.010702746996473876, 0.010628560772400264, 0.010945432570704952,
0.01159031468092693, 0.011376979947947124, 0.011113864793704001, 0.011265499900653893],
'valid_loss': [ 0.005803338973782957, 0.005777636705897748, 0.005729722324758768, 0.005694216745905578,
0.005681165296118706, 0.00567017582943663], 'results': [0.005803338973782957, 0.005777636705897748,
0.005729722324758768, 0.005694216745905578, 0.005681165296118706, 0.00567017582943663],
'checkpoints': ['workspace/obama/checkpoints/ngp_ep0059.pth', 'workspace/obama/checkpoints/ngp_ep0060.pth'],
'best_result': 0.00567017582943663},
'mean_count': 54395,
'mean_density': 0.17847637832164764,
'model': OrderedDict([ ('aabb_train', tensor([-2., -2., -2., 2., 2., 2.])),
('aabb_infer', tensor([-2., -2., -2., 2., 2., 2.])),
('density_bitfield', tensor([0, 0, 0, ..., 0, 0, 0], dtype=torch.uint8)),
('step_counter', tensor([[51729, 4096], [53595, 4096], [53882, 4096], [79567, 4096],
[54055, 4096], [52499, 4096], [54893, 4096], [55536, 4096],
[52933, 4096], [54776, 4096], [55338, 4096], [51867, 4096],
[58693, 4096], [51239, 4096], [51171, 4096], [53242, 4096]], dtype=torch.int32)),
('encoder.params', tensor([-7.0460e-05, -3.4031e-05, 3.8013e-05, ..., 1.8136e-01, 6.3283e-01, 8.5736e-02])),
('sigma_net.params', tensor([-0.0490, -0.2256, 0.0292, ..., 0.1593, -0.1807, -0.0402])),
('encoder_dir.params', tensor([])),
('color_net.params', tensor([ 1.4230, -0.4238, -1.4831, ..., -0.2303, -0.1507, -0.1388]))
])
}
ngp_ep0067.pth
{'epoch': 67,
'global_step': 100500,
'stats': {'loss':
[0.01805239893590847, 0.01664985285207458, 0.014298579431134622, 0.014413842966003537, 0.014891382255545905,
0.014312042499597095, 0.012865289307460167, 0.012439684997935883, 0.012990930920856878, 0.013531960485274806,
0.014405350544322869, 0.011622973702252544, 0.011186358761481, 0.012539275403923135, 0.011445983092831532,
0.011667333505333258, 0.01391479240286062, 0.012891907089499537, 0.01201028176034375, 0.012117284455629944,
0.011181852787469275, 0.01162640495858808, 0.013530750823017326, 0.012473789244403894, 0.010852506655289848,
0.010793325164438672, 0.01076396962530823, 0.010986675291093298, 0.013953961325806247, 0.01109155085071959,
0.010730554903970273, 0.012520627962645869, 0.01327943157751849, 0.013281854526310484, 0.012877508602679126,
0.011717672957035248, 0.010586672795754306, 0.010638146803005778, 0.010568715633373962, 0.010854586938227684,
0.012798278902615244, 0.011422378887334711, 0.011641033282080476, 0.012443393191579962, 0.01231181367568549,
0.013242373886603912, 0.012635613855760168, 0.010644334603444387, 0.00994922863944776, 0.010369753362823673,
0.009634821811942501, 0.009761761311837947, 0.009991973827580158, 0.010702746996473876, 0.010628560772400264, 0.010945432570704952, 0.01159031468092693, 0.011376979947947124, 0.011113864793704001, 0.011265499900653893,
0.01048828038457175, 0.012298709340592613, 0.012154194890427258, 0.010601344973376222, 0.011349524387572894,
0.010908769454617525, 0.010977187548816911],
'valid_loss':
[0.005803338973782957, 0.005777636705897748, 0.005729722324758768, 0.005694216745905578, 0.005681165296118706,
0.00567017582943663], 'results': [0.005803338973782957, 0.005777636705897748, 0.005729722324758768, 0.005694216745905578,
0.005681165296118706, 0.00567017582943663],
'checkpoints': ['workspace/obama/checkpoints/ngp_ep0066.pth', 'workspace/obama/checkpoints/ngp_ep0067.pth'],
'best_result': 0.00567017582943663},
'mean_count': 55161,
'mean_density': 0.15384350717067719,
'optimizer':
{'state': {
0: {
'step': tensor(100453.),
'exp_avg': tensor([ 0.0000e+00, 0.0000e+00, 0.0000e+00, ..., -8.9741e-10, 8.9797e-10, 7.9431e-10]),
'exp_avg_sq': tensor([0.0000e+00, 0.0000e+00, 0.0000e+00, ..., 2.8178e-17, 3.4009e-17, 1.6745e-17])},
1: {
'step': tensor(100453.), 'exp_avg': tensor([-5.3998e-09, -4.3061e-08, 1.2592e-06, ..., 1.3371e-07, -5.6052e-45, -5.2180e-07]),
'exp_avg_sq': tensor([1.3870e-13, 2.6497e-13, 6.7360e-10, ..., 6.5484e-12, 3.6134e-32, 1.4220e-10])},
2: {
'step': tensor(100453.), 'exp_avg': tensor([]), 'exp_avg_sq': tensor([])},
3: {
'step': tensor(100453.), 'exp_avg': tensor([-5.4121e-06, -4.6916e-06, 9.0397e-06, ..., 0.0000e+00, 0.0000e+00, 0.0000e+00]),
'exp_avg_sq': tensor([6.3201e-09, 1.7109e-10, 1.7991e-08, ..., 0.0000e+00, 0.0000e+00, 0.0000e+00])}},
'param_groups': [
{'lr': 0.0025,
'betas': (0.9, 0.99),
'eps': 1e-15,
'weight_decay': 0,
'amsgrad': False,
'maximize': False,
'foreach': None,
'capturable': False,
'differentiable': False,
'fused': None,
'initial_lr': 0.0025,
'params': [0]},
{'lr': 0.0025,
'betas': (0.9, 0.99),
'eps': 1e-15,
'weight_decay': 0,
'amsgrad': False,
'maximize': False,
'foreach': None,
'capturable': False,
'differentiable': False,
'fused': None,
'initial_lr': 0.0025,
'params': [1]},
{'lr': 0.0025,
'betas': (0.9, 0.99),
'eps': 1e-15,
'weight_decay': 0,
'amsgrad': False,
'maximize': False,
'foreach': None,
'capturable': False,
'differentiable': False,
'fused': None,
'initial_lr': 0.0025,
'params': [2]},
{'lr': 0.0025,
'betas': (0.9, 0.99),
'eps': 1e-15,
'weight_decay': 0,
'amsgrad': False,
'maximize': False,
'foreach': None,
'capturable': False,
'differentiable': False,
'fused': None,
'initial_lr': 0.0025,
'params': [3]}]},
'lr_scheduler': {
'base_lrs': [0.0025, 0.0025, 0.0025, 0.0025],
'last_epoch': 100500,
'verbose': False,
'_step_count': 100501,
'_get_lr_called_within_step': False,
'_last_lr': [0.0025, 0.0025, 0.0025, 0.0025],
'lr_lambdas': [None, None, None, None]},
'scaler': {
'scale': 2048.0,
'growth_factor': 2.0,
'backoff_factor': 0.5,
'growth_interval': 2000,
'_growth_tracker': 1679},
'ema': {
'decay': 0.95,
'num_updates': 67,
'shadow_params':
[tensor([-7.0460e-05, -3.4031e-05, 3.8013e-05, ..., 1.9051e-01, 6.2752e-01, -4.1020e-02]),
tensor([-0.0325, -0.1994, 0.0241, ..., 0.1203, -0.1794, -0.0348]),
tensor([]),
tensor([ 1.4239, -0.4077, -1.4817, ..., -0.2303, -0.1507, -0.1388])],
'collected_params':
[tensor([-7.0460e-05, -3.4031e-05, 3.8013e-05, ..., 1.8136e-01, 6.3283e-01, 8.5736e-02],
requires_grad=True),
tensor([-0.0490, -0.2256, 0.0292, ..., 0.1593, -0.1807, -0.0402],requires_grad=True),
tensor([], requires_grad=True),
tensor([ 1.4230, -0.4238, -1.4831, ..., -0.2303, -0.1507, -0.1388], requires_grad=True)]},
'model': OrderedDict([
('aabb_train', tensor([-2., -2., -2., 2., 2., 2.])),
('aabb_infer', tensor([-2., -2., -2., 2., 2., 2.])),
('density_grid', tensor([[-1., -1., -1., ..., -1., -1., -1.], [-1., -1., -1., ..., -1., -1., -1.]])),
('density_bitfield', tensor([0, 0, 0, ..., 0, 0, 0], dtype=torch.uint8)),
('step_counter', tensor([[52903, 4096], [54378, 4096], [59339, 4096], [55667, 4096], [54438, 4096], [53836, 4096],
[56686, 4096], [55139, 4096], [66525, 4096], [55459, 4096], [54769, 4096], [54962, 4096],
[53925, 4096], [56020, 4096], [55708, 4096], [55806, 4096]], dtype=torch.int32)),
('encoder.params', tensor([-7.0460e-05, -3.4031e-05, 3.8013e-05, ..., 3.0885e-01, 6.5064e-01, -2.4719e-02])),
('sigma_net.params', tensor([ 0.0446, -0.3265, 0.0686, ..., 0.1672, -0.1545, -0.2775])),
('encoder_dir.params', tensor([])),
('color_net.params', tensor([ 1.5695, -0.4921, -1.5962, ..., -0.2303, -0.1507, -0.1388]))
])
}
results:
images(ngp_ep0067_0000_rgb.png~ngp_ep0067_0349_rgb.png), video(空)
输出结果。
run:ngp: events.out.tfevents.1747729455.iZbp1j93ovts7teib9t8gcZ(9MB)
events.out.tfevents 文件需要通过 tensorboard 打开。
安装 tensorboard :
pip install tensorboard
cd 到当前目录后,输入:
tensorboard --logdir=./
或直接输入:
tensorboard --logdir=当前目录的绝对地址
在其输出第一行后回车,用浏览器访问给出的网址(形如 http://localhost:6006/ ),可以浏览目录下 events.out.tfevents 文件中的数据。

validation: (ngp_ep0010_0001_rgb.png~ngp_ep0060_0020_rgb.png)
验证数据。
log_ngp.txt
运行日志。
浙公网安备 33010602011771号