Unverified Commit 8340e19d authored by Ruilong Li(李瑞龙)'s avatar Ruilong Li(李瑞龙) Committed by GitHub
Browse files

0.5.0: Rewrite all the underlying CUDA. Speedup and Benchmarking. (#182)

* importance_sampling with test

* package importance_sampling

* compute_intervals tested and packaged

* compute_intervals_v2

* bicycle is failing

* fix cut in compute_intervals_v2, test pass for rendering

* hacky way to get opaque_bkgd work

* reorg ING

* PackedRaySegmentsSpec

* chunk_ids -> ray_ids

* binary -> occupied

* test_traverse_grid_basic checked

* fix traverse_grid with step size, checked

* support max_step_size, not verified

* _cuda and cuda; upgrade ray_marching

* inclusive scan

* test_exclusive_sum but seems to have numeric error

* inclusive_sum_backward verified

* exclusive sum backward

* merge fwd and bwd for scan

* inclusive & exclusive prod verified

* support normal scan with torch funcs

* rendering and tests

* a bit clean up

* importance_sampling verified

* stratified for importance_sampling

* importance_sampling in pdf.py

* RaySegmentsSpec in data_specs; fix various bugs

* verified with _proposal_packed.py

* importance sampling support batch input/output. need to verify

* prop script with batch samples

* try to use cumsum  instead of cumprod

* searchsorted

* benchmarking prop

* ray_aabb_intersect untested

* update prop benchmark numbers

* minor fixes

* batched ray_aabb_intersect

* ray_aabb_intersect and traverse with grid(s)

* tiny optimize for traverse_grids kernels

* traverse_grids return intervals and samples

* cub not verified

* cleanup

* propnet and occgrid as estimators

* training print iters 10k

* prop is good now

* benchmark in google sheet.

* really cleanup: scan.py and test

* pack.py and test

* rendering and test

* data_specs.py and pdf.py docs

* data_specs.py and pdf.py docs

* init and headers

* grid.py and test for it

* occ grid docs

* generated docs

* example docs for pack and scan function.

* doc fix for volrend.py

* doc fix for pdf.py

* fix doc for rendering function

* docs

* propnet docs

* update scripts

* docs: index.rst

* methodology docs

* docs for examples

* mlp nerf script

* update t-nerf script

* rename dnerf to tnerf

* misc update

* bug fix: pdf_loss with test

* minor fix

* update readme with submodules

* fix format

* update gitingore file

* fix doc failure. teaser png to jpg

* docs in examples/
parent e547490c
...@@ -117,6 +117,11 @@ venv.bak/ ...@@ -117,6 +117,11 @@ venv.bak/
# vscode # vscode
.vsocde .vsocde
benchmarks/
outputs/ outputs/
data data
\ No newline at end of file
benchmarks/*
!benchmarks/barf
!benchmarks/kplanes
!benchmarks/tensorf
!benchmarks/tineuvox
\ No newline at end of file
[submodule "examples/pycolmap"] [submodule "examples/pycolmap"]
path = examples/pycolmap path = examples/pycolmap
url = https://github.com/rmbrualla/pycolmap.git url = https://github.com/rmbrualla/pycolmap.git
\ No newline at end of file
[submodule "benchmarks/tensorf"]
path = benchmarks/tensorf
url = https://github.com/liruilong940607/tensorf.git
branch = nerfacc
[submodule "benchmarks/barf"]
path = benchmarks/barf
url = https://github.com/liruilong940607/barf.git
branch = nerfacc
[submodule "benchmarks/tineuvox"]
path = benchmarks/tineuvox
url = https://github.com/liruilong940607/tineuvox.git
branch = nerfacc
[submodule "benchmarks/kplanes"]
path = benchmarks/kplanes
url = https://github.com/liruilong940607/kplanes.git
branch = nerfacc
include nerfacc/cuda/csrc/include/* include nerfacc/cuda/csrc/include/*
include nerfacc/cuda/csrc/* include nerfacc/cuda/csrc/*
include nerfacc/_cuda/csrc/include/*
include nerfacc/_cuda/csrc/*
...@@ -16,19 +16,14 @@ ...@@ -16,19 +16,14 @@
https://www.nerfacc.com/ https://www.nerfacc.com/
NerfAcc is a PyTorch Nerf acceleration toolbox for both training and inference. It focuses on efficient volumetric rendering of radiance fields, which is universal and plug-and-play for most of the NeRFs. NerfAcc is a PyTorch Nerf acceleration toolbox for both training and inference. It focus on
efficient sampling in the volumetric rendering pipeline of radiance fields, which is
universal and plug-and-play for most of the NeRFs.
With minimal modifications to the existing codebases, Nerfacc provides significant speedups
in training various recent NeRF papers.
**And it is pure Python interface with flexible APIs!**
Using NerfAcc, ![Teaser](/docs/source/_static/images/teaser.jpg?raw=true)
- The `vanilla NeRF` model with 8-layer MLPs can be trained to *better quality* (+~0.5 PNSR)
in *1 hour* rather than *days* as in the paper.
- The `Instant-NGP NeRF` model can be trained to *equal quality* in *4.5 minutes*,
comparing to the official pure-CUDA implementation.
- The `D-NeRF` model for *dynamic* objects can also be trained in *1 hour*
rather than *2 days* as in the paper, and with *better quality* (+~2.5 PSNR).
- Both *bounded* and *unbounded* scenes are supported.
**And it is a pure Python interface with flexible APIs!**
## Installation ## Installation
...@@ -62,11 +57,17 @@ pip install nerfacc -f https://nerfacc-bucket.s3.us-west-2.amazonaws.com/whl/tor ...@@ -62,11 +57,17 @@ pip install nerfacc -f https://nerfacc-bucket.s3.us-west-2.amazonaws.com/whl/tor
## Usage ## Usage
The idea of NerfAcc is to perform efficient ray marching and volumetric rendering. So NerfAcc can work with any user-defined radiance field. To plug the NerfAcc rendering pipeline into your code and enjoy the acceleration, you only need to define two functions with your radiance field. The idea of NerfAcc is to perform efficient volumetric sampling with a computationally cheap estimator to discover surfaces.
- `sigma_fn`: Compute density at each sample. It will be used by `nerfacc.ray_marching()` to skip the empty and occluded space during ray marching, which is where the major speedup comes from. So NerfAcc can work with any user-defined radiance field. To plug the NerfAcc rendering pipeline into your code and enjoy
- `rgb_sigma_fn`: Compute color and density at each sample. It will be used by `nerfacc.rendering()` to conduct differentiable volumetric rendering. This function will receive gradients to update your network. the acceleration, you only need to define two functions with your radience field.
- `sigma_fn`: Compute density at each sample. It will be used by the estimator
(e.g., `nerfacc.OccGridEstimator`, `nerfacc.PropNetEstimator`) to discover surfaces.
- `rgb_sigma_fn`: Compute color and density at each sample. It will be used by
`nerfacc.rendering` to conduct differentiable volumetric rendering. This function
will receive gradients to update your radiance field.
A simple example is like this: An simple example is like this:
``` python ``` python
import torch import torch
...@@ -76,50 +77,39 @@ import nerfacc ...@@ -76,50 +77,39 @@ import nerfacc
radiance_field = ... # network: a NeRF model radiance_field = ... # network: a NeRF model
rays_o: Tensor = ... # ray origins. (n_rays, 3) rays_o: Tensor = ... # ray origins. (n_rays, 3)
rays_d: Tensor = ... # ray normalized directions. (n_rays, 3) rays_d: Tensor = ... # ray normalized directions. (n_rays, 3)
optimizer = ... # optimizer optimizer = ... # optimizer
estimator = nerfacc.OccGridEstimator(...)
def sigma_fn( def sigma_fn(
t_starts: Tensor, t_ends:Tensor, ray_indices: Tensor t_starts: Tensor, t_ends:Tensor, ray_indices: Tensor
) -> Tensor: ) -> Tensor:
""" Query density values from a user-defined radiance field. """ Define how to query density for the estimator."""
:params t_starts: Start of the sample interval along the ray. (n_samples, 1).
:params t_ends: End of the sample interval along the ray. (n_samples, 1).
:params ray_indices: Ray indices that each sample belongs to. (n_samples,).
:returns The post-activation density values. (n_samples, 1).
"""
t_origins = rays_o[ray_indices] # (n_samples, 3) t_origins = rays_o[ray_indices] # (n_samples, 3)
t_dirs = rays_d[ray_indices] # (n_samples, 3) t_dirs = rays_d[ray_indices] # (n_samples, 3)
positions = t_origins + t_dirs * (t_starts + t_ends) / 2.0 positions = t_origins + t_dirs * (t_starts + t_ends)[:, None] / 2.0
sigmas = radiance_field.query_density(positions) sigmas = radiance_field.query_density(positions)
return sigmas # (n_samples, 1) return sigmas # (n_samples,)
def rgb_sigma_fn( def rgb_sigma_fn(
t_starts: Tensor, t_ends: Tensor, ray_indices: Tensor t_starts: Tensor, t_ends: Tensor, ray_indices: Tensor
) -> Tuple[Tensor, Tensor]: ) -> Tuple[Tensor, Tensor]:
""" Query rgb and density values from a user-defined radiance field. """ Query rgb and density values from a user-defined radiance field. """
:params t_starts: Start of the sample interval along the ray. (n_samples, 1).
:params t_ends: End of the sample interval along the ray. (n_samples, 1).
:params ray_indices: Ray indices that each sample belongs to. (n_samples,).
:returns The post-activation rgb and density values.
(n_samples, 3), (n_samples, 1).
"""
t_origins = rays_o[ray_indices] # (n_samples, 3) t_origins = rays_o[ray_indices] # (n_samples, 3)
t_dirs = rays_d[ray_indices] # (n_samples, 3) t_dirs = rays_d[ray_indices] # (n_samples, 3)
positions = t_origins + t_dirs * (t_starts + t_ends) / 2.0 positions = t_origins + t_dirs * (t_starts + t_ends)[:, None] / 2.0
rgbs, sigmas = radiance_field(positions, condition=t_dirs) rgbs, sigmas = radiance_field(positions, condition=t_dirs)
return rgbs, sigmas # (n_samples, 3), (n_samples, 1) return rgbs, sigmas # (n_samples, 3), (n_samples,)
# Efficient Raymarching: Skip empty and occluded space, pack samples from all rays. # Efficient Raymarching:
# ray_indices: (n_samples,). t_starts: (n_samples, 1). t_ends: (n_samples, 1). # ray_indices: (n_samples,). t_starts: (n_samples,). t_ends: (n_samples,).
with torch.no_grad(): ray_indices, t_starts, t_ends = estimator.sampling(
ray_indices, t_starts, t_ends = nerfacc.ray_marching( rays_o, rays_d, sigma_fn=sigma_fn, near_plane=0.2, far_plane=1.0, early_stop_eps=1e-4, alpha_thre=1e-2,
rays_o, rays_d, sigma_fn=sigma_fn, near_plane=0.2, far_plane=1.0, )
early_stop_eps=1e-4, alpha_thre=1e-2,
)
# Differentiable Volumetric Rendering. # Differentiable Volumetric Rendering.
# colors: (n_rays, 3). opaicity: (n_rays, 1). depth: (n_rays, 1). # colors: (n_rays, 3). opaicity: (n_rays, 1). depth: (n_rays, 1).
color, opacity, depth = nerfacc.rendering( color, opacity, depth, extras = nerfacc.rendering(
t_starts, t_ends, ray_indices, n_rays=rays_o.shape[0], rgb_sigma_fn=rgb_sigma_fn t_starts, t_ends, ray_indices, n_rays=rays_o.shape[0], rgb_sigma_fn=rgb_sigma_fn
) )
...@@ -132,6 +122,8 @@ optimizer.step() ...@@ -132,6 +122,8 @@ optimizer.step()
## Examples: ## Examples:
See full benchmarking here: https://www.nerfacc.com/en/latest/examples/
Before running those example scripts, please check the script about which dataset is needed, and download the dataset first. You could use `--data_root` to specify the path. Before running those example scripts, please check the script about which dataset is needed, and download the dataset first. You could use `--data_root` to specify the path.
```bash ```bash
...@@ -139,38 +131,80 @@ Before running those example scripts, please check the script about which datase ...@@ -139,38 +131,80 @@ Before running those example scripts, please check the script about which datase
git clone --recursive git://github.com/KAIR-BAIR/nerfacc/ git clone --recursive git://github.com/KAIR-BAIR/nerfacc/
``` ```
### Static NeRFs
Instant-NGP on NeRF-Synthetic dataset with better performance in 4.5 minutes.
``` bash ``` bash
# Instant-NGP NeRF in 4.5 minutes with reproduced performance! # Occupancy Grid Estimator
# See results at here: https://www.nerfacc.com/en/latest/examples/ngp.html python examples/train_ngp_nerf_occ.py --scene lego --data_root data/nerf_synthetic
python examples/train_ngp_nerf.py --train_split train --scene lego # Proposal Net Estimator
python examples/train_ngp_nerf_prop.py --scene lego --data_root data/nerf_synthetic
``` ```
Instant-NGP on Mip-NeRF 360 dataset with better performance in 5 minutes.
``` bash ``` bash
# Vanilla MLP NeRF in 1 hour with better performance! # Occupancy Grid Estimator
# See results at here: https://www.nerfacc.com/en/latest/examples/vanilla.html python examples/train_ngp_nerf_occ.py --scene garden --data_root data/360_v2
python examples/train_mlp_nerf.py --train_split train --scene lego # Proposal Net Estimator
python examples/train_ngp_nerf_prop.py --scene garden --data_root data/360_v2
``` ```
Vanilla MLP NeRF on NeRF-Synthetic dataset in an hour.
``` bash
# Occupancy Grid Estimator
python examples/train_mlp_nerf.py --scene lego --data_root data/nerf_synthetic
```
TensoRF on Tanks&Temple and NeRF-Synthetic datasets (plugin in the official codebase).
``` bash
cd benchmarks/tensorf/
# (set up the environment for that repo)
bash script.sh nerfsyn-nerfacc-occgrid 0
bash script.sh tt-nerfacc-occgrid 0
```
### Dynamic NeRFs
T-NeRF on D-NeRF dataset in an hour.
``` bash
# Occupancy Grid Estimator
python examples/train_mlp_tnerf.py --scene lego --data_root data/dnerf
```
K-Planes on D-NeRF dataset (plugin in the official codebase).
```bash ```bash
# D-NeRF for Dynamic objects in 1 hour with better performance! cd benchmarks/kplanes/
# See results at here: https://www.nerfacc.com/en/latest/examples/dnerf.html # (set up the environment for that repo)
python examples/train_mlp_dnerf.py --train_split train --scene lego bash script.sh dnerf-nerfacc-occgrid 0
``` ```
TiNeuVox on HyperNeRF and D-NeRF datasets (plugin in the official codebase).
```bash ```bash
# Instant-NGP on unbounded scenes in 20 minutes! cd benchmarks/tineuvox/
# See results at here: https://www.nerfacc.com/en/latest/examples/unbounded.html # (set up the environment for that repo)
python examples/train_ngp_nerf.py --train_split train --scene garden --auto_aabb --unbounded --cone_angle=0.004 bash script.sh dnerf-nerfacc-occgrid 0
bash script.sh hypernerf-nerfacc-occgrid 0
bash script.sh hypernerf-nerfacc-propnet 0
``` ```
Used by: ### Camera Optimization NeRFs
BARF on the NeRF-Synthetic dataset (plugin in the official codebase).
```bash
cd benchmarks/barf/
# (set up the environment for that repo)
bash script.sh nerfsyn-nerfacc-occgrid 0
```
### 3rd-Party Usages:
- [nerfstudio](https://github.com/nerfstudio-project/nerfstudio): A collaboration friendly studio for NeRFs. - [nerfstudio](https://github.com/nerfstudio-project/nerfstudio): A collaboration friendly studio for NeRFs.
- [sdfstudio](https://autonomousvision.github.io/sdfstudio/): A unified framework for surface reconstruction..
- [instant-nsr-pl](https://github.com/bennyguo/instant-nsr-pl): NeuS in 10 minutes. - [instant-nsr-pl](https://github.com/bennyguo/instant-nsr-pl): NeuS in 10 minutes.
- [modelscope](https://github.com/modelscope/modelscope/blob/master/modelscope/models/cv/nerf_recon_acc/network/nerf.py): A collection of deep-learning algorithms.
- [Representing Volumetric Videos as Dynamic MLP Maps, CVPR 2023](https://github.com/zju3dv/mlp_maps)
## Common Installation Issues ## Common Installation Issues
<details> <details>
<summary>ImportError: .../csrc.so: undefined symbol</summary> <summary>ImportError: .../csrc.so: undefined symbol</summary>
If you are installing a pre-built wheel, make sure the Pytorch and CUDA version matchs with the nerfacc version (nerfacc.__version__). If you are installing a pre-built wheel, make sure the Pytorch and CUDA version matchs with the nerfacc version (nerfacc.__version__).
...@@ -179,10 +213,10 @@ Used by: ...@@ -179,10 +213,10 @@ Used by:
## Citation ## Citation
```bibtex ```bibtex
@article{li2022nerfacc, @article{li2023nerfacc,
title={NerfAcc: A General NeRF Accleration Toolbox.}, title={NerfAcc: Efficient Sampling Accelerates NeRFs.},
author={Li, Ruilong and Tancik, Matthew and Kanazawa, Angjoo}, author={Li, Ruilong and Hang Gao and Tancik, Matthew and Kanazawa, Angjoo},
journal={arXiv preprint arXiv:2210.04847}, journal={TBD},
year={2022} year={2023}
} }
``` ```
Subproject commit 90440d975fc76b3559126992b2fbce27dd02456f
Subproject commit b97bc2eefc18f00cd54833800e7fc1072e58be51
Subproject commit f2d350873c54f249e64b6e745919b6a94bf54f1d
Subproject commit 0999858745577ff32e5226c51c5c78b8315546c8
.. _`Occupancy Grid`: .. _`Estimators`:
Occupancy Grid Estimators
=================================== ===================================
.. currentmodule:: nerfacc .. currentmodule:: nerfacc
.. autoclass:: ContractionType .. autoclass:: OccGridEstimator
:members:
.. autoclass:: Grid
:members: :members:
.. autoclass:: OccupancyGrid .. autoclass:: PropNetEstimator
:members: :members:
nerfacc.exclusive\_prod
=======================
.. currentmodule:: nerfacc
.. autofunction:: exclusive_prod
\ No newline at end of file
nerfacc.exclusive\_sum
======================
.. currentmodule:: nerfacc
.. autofunction:: exclusive_sum
\ No newline at end of file
nerfacc.importance\_sampling
============================
.. currentmodule:: nerfacc
.. autofunction:: importance_sampling
\ No newline at end of file
nerfacc.inclusive\_prod
=======================
.. currentmodule:: nerfacc
.. autofunction:: inclusive_prod
\ No newline at end of file
nerfacc.inclusive\_sum
======================
.. currentmodule:: nerfacc
.. autofunction:: inclusive_sum
\ No newline at end of file
nerfacc.pack\_data nerfacc.pack\_info
================== ==================
.. currentmodule:: nerfacc .. currentmodule:: nerfacc
.. autofunction:: pack_data .. autofunction:: pack_info
\ No newline at end of file \ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment