周记(2025春第14周)

使用 INSTA-pytorch 处理人头模型

INSTA-pytorch 简介

Instant Volumetric Head Avatars(INSTA)

该项目原有一个 C++ 版本(https://github.com/Zielon/INSTA),其论文也是基于 C++ 撰写的。本实验采用它的 Python 适配版本。

有关 INSTA 的学习笔记

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 安装出现的问题

  1. requirements.txt 中 pysdf 安装的相关问题,网上已有现成资料或询问 ChatGPT。

  2. 高版本的 CUDA 可能不适用 C++14。尝试将所有 setup.py 文件中的 C++14 替换为 C++17。

  3. CUDA版本太高。先前独立安装了最新版本 12.9 的 CUDA,但编译时要求适用 pytorch 的版本为 12.6 的 CUDA。被迫卸载后降级,且更换环境变量指向。降级后依然报错,故强制使其指向 pytorch 适配的 CUDA 以确保正常编译。

  4. tinycudann 安装时不反馈任何错误或警告,只是卡在那里?这只是正常的安装过程,多等等!一开始发现安装过程中长时间无反应,以为可能是哪里的死循环错误,后发现这仅仅是因为其安装耗时比较长。

  5. 执行 ./scripts/install_ext.sh 的过程中一直报 C++17 不兼容错,查阅资料后发现因为高版本的 CUDA 可能不适用 C++14。尝试将所有 setup.py 文件中的与 C++14 相关的语句替换为 C++17 相关,具体方法见下面的代码块。

  6. 最后安装时报错宏 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 文件中的数据。

image

validation: (ngp_ep0010_0001_rgb.png~ngp_ep0060_0020_rgb.png)

验证数据。

log_ngp.txt

运行日志。

posted on 2025-05-14 22:23  汐寻  阅读(65)  评论(0)    收藏  举报