본문 바로가기

딥러닝 & 머신러닝/프로젝트

도커 (Docker) 를 활용한 3D Gaussian Splatting (3DGS) 코드 빌드

반응형

3D Gaussian Splatting (3DGS) 에 대한 자세한 논문 리뷰는 아래 제 블로그 글을 참고해주세요.

https://mole-starseeker.tistory.com/158

 

[논문 리뷰] 3D Gaussian Splatting for Real-Time Radiance Field Rendering

이번 포스팅에선 Novel-view synthesis task에서 획기적 방법을 제시한 3D Gaussian Splatting (3DGS) 에 대해 리뷰하겠습니다.3D Scene Reconstruction 3D Scene Reconstruction은 여러 각도에서 촬영한 2D 이미지를 기반으

mole-starseeker.tistory.com


이번 게시물에선 3D Gaussian Splatting (이하 3DGS) 를 Docker (이하 도커) 로 빌드하는 법에 대해 알아보겠습니다. 이를 위해 만든 제 깃허브 주소는 다음과 같습니다: https://github.com/jhcha08/3DGS-Docker

 

GitHub - jhcha08/3DGS-Docker: Dockerized version of the 3D Gaussian Splatting

Dockerized version of the 3D Gaussian Splatting. Contribute to jhcha08/3DGS-Docker development by creating an account on GitHub.

github.com

 

간단한 3DGS 논문 리뷰

 

먼저 3DGS에 대해서 간단히 리뷰해보겠습니다. 3DGS는 SIGGRAPH 2023에 게재되어 큰 화제를 불러왔던 논문입니다. 1080p 해상도의 완전한 scene들을 실시간 (≥ 100 fps) & 고품질로 완성하는 모습을 보여줍니다. 이후 3DGS는 하나의 장르가 되어, 여러 가지 관련 연구들 (e.g. dynamic scene, camera pose-free 등에 대한) 이 쏟아져 나오기 시작합니다.

 

3DGS와 NeRF는 풀고자하는 문제가 같습니다. 즉, 여러 방향에서 촬영힌 이미지와 카메라 pose 값이 있으면, 학습된 방향 이외의 이미지를 생성하는 "Novel-View Synthesis"가 공동의 목표입니다. 그러나 둘은 목표를 이루는 방법이 다릅니다.

 

NeRF 기법들은 voxel, grid, point 등을 interpolation 해서 continuous 한 scene을 구현하고자 합니다. 반면 3DGS의 경우엔 3D 공간 상에 수많은 3D Gaussian 분포를 흩뿌린 후, 이를 조정해 하나의 scene을 구성합니다. 이러한 방법을 통해 기존 NeRF 기법들 대비 높은 성능 및 빠른 렌더링 & 훈련 속도를 달성할 수 있었습니다.

3DGS 공식 깃허브 가이드의 모호함과 불편함

사실 3DGS의 공식 깃허브에 가보시면, 필요한 하드웨어 및 소프트웨어 세팅 등이 설명되어 있습니다. 예를 들어, 소프트웨어 세팅의 경우 아래 이미지에 표시된 것과 같은 툴들이 필요합니다.

 

네.. 무엇이 필요한지만 알려줄 뿐, 구체적인 설치 방법은 설명해주지 않습니다. 소프트웨어 설치 및 코드 빌드 방법을 알려주는 유튜브 영상이 있긴 한데, 해당 영상을 비롯하여 깃허브 Readme 모두 윈도우 (Windows) 기준으로 설명합니다. 

 

예를 들어, 위 그림을 보면, 윈도우에 대해선 Visual Studio 2019가 필요하다고 합니다. 그래서 처음엔 이런 생각을 했습니다. '우분투에선 Visual Studio 2019를 설치할 수가 없는데..? 그럼 우분투에선 C++ compiler for PyTorch extensions 는 어떻게 설치해야 하는거지..?' 나중에 안 것이지만, 우분투에서는 gc++가 Visual Studio 2019를 대신할 수 있습니다.

 

이러한 코드 빌드 가이드의 모호성 때문에, 저는 해당 깃허브의 코드가 무조건 윈도우에서만 실행된다고 생각했습니다. 사실 알고 보면 우분투 (Ubuntu) 에서도 당연히 구동 가능한 코드입니다. 물론, 좀 더 관련 지식 또는 경험이 많으신 분들은, 바로 우분투로 빌드하셨을 수도 있습니다. 그러나 제가 느꼈던 문제점은 이 뿐만이 아니었습니다.

 

공식 깃허브의 가이드에 따라 코드 빌드 시 cuda, cudnn, torch 등의 버전 맞추는게 여간 까다로운 일이 아니었습니다. 즉, compatibility 문제가 너무 불편했습니다. 특히 submodules에 diff-gaussian-rasterization와 simple-knn라는 코드들이 있는데, 해당 모듈들을 설치할 때 compatibility 이슈가 가장 많이 발생했습니다. 위 그림은 관련한 이슈 목록들 중 일부입니다. 무수한 Fail들이 보이네요.. 수치 상 이슈 절반 정도는 관련 에러에 대한 문의라고 보시면 될 것 같습니다.

 

이러한 submodule 빌드 실패 문제가 저한테도 계속 발생해서 굉장히 애를 많이 먹었습니다. 그리고 해결 방법도 매우 까다로웠습니다. 예를 들어 윈도우 빌드 기준으로 했을 때, CUDA SDK는 C++ compiler 설치 이후에 설치해야 됐고, 이 CUDA SDK는 깃허브의 가이드에서 명시한 11.8 버전이 아니라 11.7 버전을 설치해야하는 등..

도커를 활용한 3DGS 코드 빌드

저는 평소 코드 사용 시에 도커를 활용합니다. 도커를 사용하면 새로운 깃허브 코드를 빌드할 때마다, 호스트 서버에 덕지덕지 여러 버전의 라이브러리와 패키지들을 설치할 필요가 없습니다. 그래서 저는 도커를 사용해 3DGS 코드를 빌드해보기로 했습니다. 공식 깃허브에서는 conda 사용을 권장했지만, 개념적으로 보면 conda나 도커나 비슷합니다.

 

기본적인 도커 사용법은 다음과 같습니다: python, torch, cuda 등의 기본적인 사용환경이 세팅된 도커 이미지를 pull 해오고, 추가적으로 필요한 라이브러리와 패키지들을 설치하는 명령어를 Dockerfile에 작성한 뒤, build 해서 customized된 도커 이미지 생성 후, 컨테이너를 run시킨 후 접속해서 코드를 사용하면 됩니다.

 

아래에서 직접 3DGS 코드를 도커로 빌드해보며 사용법을 익혀보겠습니다. 터미널에서 간단한 명령어를 실행시키는 과정이 대부분입니다. 이 방법은 conda 가상환경이나 기타 위에서 언급한, 복잡한 과정의 소프트웨어 설치가 필요없습니다.

 

1. VScode 기준, 왼쪽 메뉴에서 Extensions 클릭 후 docker를 검색한 뒤, 맨 위 Docker를 Install 합니다.

 

2. docker hub에 있는 도커 이미지 중 하나를 pull 해서, 우리가 활용할 수 있도록 하는 것입니다. 여기서는 Nvidia에서 제공하는 이미지를 사용하겠습니다. 여기엔 대표적으로 python 3.8, torch 1.13.0, cuda 11.7가 설치되어 있습니다. 이 중 torch는 정확히 1.13.1이 필요한 관계로, 나중에 따로 또 설치할 예정입니다.

docker pull nvcr.io/nvidia/pytorch:22.06-py3

 

명령어를 실행하면 아래처럼 도커 이미지를 pull 해오는 과정이 보입니다. 시간 소요가 꽤 있습니다.

 

참고로, 이곳에 접속하면 Nvidia 제공 도커 이미지들의 각 릴리즈 별 라이브러리 및 패키지 버전을 확인할 수 있습니다.

 

3. 제가 3DGS 코드를 도커로 빌드하기 위해 만든 깃허브를 git clone합니다.

git clone https://github.com/jhcha08/3DGS-Docker --recursive

 

4. 도커 빌드를 위해 git clone 해온 폴더 경로로 접속합니다.

cd 3DGS-Docker

 

5. Dockerfile에 아래 내용을 작성합니다. 3DGS를 구동시키기 위해, 제가 시행착오를 거쳐 구성한 필수 라이브러리 및 패키지 설치 명령어들이 있습니다. 사실, 위에서 git clone 해온 제 깃허브에 아래 내용의 Dockerfile이 이미 있긴 합니다.

FROM nvcr.io/nvidia/pytorch:22.06-py3

# Prevent interactive prompts during package installation
ENV DEBIAN_FRONTEND=noninteractive

# Install required packages
RUN apt-get update && apt-get install -y \
    wget \
    curl \
    nano \
    git \
    libx11-6 \
    libgl1-mesa-glx \
    g++ \
    libglew-dev \
    libassimp-dev \
    libboost-all-dev \
    libgtk-3-dev \
    libopencv-dev \
    libglfw3-dev \
    libavdevice-dev \
    libavcodec-dev \
    libeigen3-dev \
    libxxf86vm-dev \
    libembree-dev \
    colmap \
    imagemagick \
    ffmpeg \
    meshlab && \
    rm -rf /var/lib/apt/lists/*

# Install Python packages
RUN pip install plyfile tqdm torch==1.13.1

# Command to run the container
CMD ["/bin/bash"]

 

6. pull 해온 도커 이미지와 작성한 Dockerfile 기반으로, custormized된, 즉, 저희만의 도커 이미지를 빌드합니다.

docker build -t 3dgs_docker .

 

명령어를 실행하면 아래처럼 '3dgs_docker' 라는 이름의 도커 이미지를 빌드하는 과정을 확인 가능합니다. (*아래 이미지에서, 제가 실험할 땐 git clone 해온 폴더 경로가 gaussian-splatting이었기 때문에 경로가 ~/gaussian-splatting으로 나타나는데, 위 과정을 따른다면 ~/3DGS-Docker로 경로가 나타납니다.)

 

7. 3dgs_docker라는 이름으로 빌드된 이미지를 가지고, 3dgs_container라는 이름의 도커 컨테이너를 실행시킵니다. 아래처럼 docker run 명령어 실행 시, 다양한 옵션을 줄 수가 있습니다. 특히, -v $(pwd):/workdir 라는 옵션은 현재의 경로 (여기선 ~/3DGS-Docker) 를 도커 컨테이너에서 /workdir 이라는 경로에 마운트해서 실행하겠다는 뜻입니다.

docker run -it \
  --name 3dgs_container \
  --shm-size 32G \
  --network host \
  --gpus '"device=0"' \
  -v $(pwd):/workdir \
  3dgs_docker /bin/bash

 

8. 이제 VScode 왼쪽 메뉴의 Docker 탭으로 들어가, 아래 그림처럼 containers 메뉴를 찾고, 그 안에서 3dgs_container로 이름지어진 컨테이너를 우클릭 합니다. 여기서 Attach Visual Studio Code를 통해 컨테이너에 접속 후, Open Folder를 통해 workdir 디렉토리를 찾아서 접속하면, 저희가 작업하고자 하는 3DGS 코드 환경이 나옵니다.

 

9. 이제 pip install을 통해 submodules를 설치합니다.

pip install submodules/diff-gaussian-rasterization
pip install submodules/simple-knn

 

여기까지가 도커를 활용한 3DGS 코드 빌드 방법이었습니다! 따라오느라 고생 많으셨습니다. 이제 기본적인 것들은 모두 끝냈으니, 3DGS 모델 훈련과 렌더링을 해보면 좋을 것 같습니다.

3DGS 모델 훈련 및 렌더링

3DGS 모델 훈련을 위해서는 camera parameter가 필요합니다. camera parameter는 크게 extrinsic 정보와 intrinsic 정보로 나눌 수 있는데, 전자는 초점거리, 렌즈의 중심 좌표 등 카메라 외부 정보를 뜻하고, 후자는 각 장면을 촬영한 카메라의 위치 좌표 등을 뜻합니다. 이에 대해서는 더 자세한 게시물로 찾아뵙도록 하겠습니다.

 

이러한 camera parameter들은 COLMAP 등의 SfM (Structure-from-Motion) 알고리즘을 이용해 추출이 가능합니다. 공식 3DGS 코드에선 COLMAP 기반의 convert.py를 이용해 해당 과정을 수행하는데, 제가 개발한 깃허브 코드에선 안타깝게도 convert.py 동작이 아직 안되고 있습니다. 해당 과정을 수행할 수 있도록 작업 중에 있으니 양해 부탁드립니다.

 

대신, NeRFStudio의 ns-process-data 커맨드를 이용하거나, DIM (Deep Image Matching) 깃허브를 사용하면 COLMAP과 같은 형태의 camera parameter output을 생성할 수 있습니다. camera parameter를 추출할 때, 전자의 경우 COLMAP을 기반으로 수행하며, 후자의 경우엔 딥러닝 기반의 feature extraction & matching 기법을 사용합니다.

 

COLMAP 또는 NeRFStudio, DIM 등을 사용하면 database.db, cameras.bin, images.bin, points3D.bin 파일이 생성됩니다. 이제 아래처럼 colmap 폴더를 생성하고, 그 안에 이 파일들을 아래처럼 위치시킵니다. 사용하는 SfM 알고리즘에 따라 해당 과정이 자동으로 되는 경우도 있습니다. DIM의 경우엔 수동으로 위치시켜줘야 합니다. 언급한 .bin 파일들 및 database.db에는 모두 촬영 카메라의 정보 및 해당  카메라로 촬영한 각 이미지들에 대한 정보가 들어있습니다.

colmap
├── database.db
├── sparse
│   └── 0
│       └── cameras.bin
│       └── images.bin
│       └── points3D.bin
└── images
    └── image1.png
    └── image2.png
    └── ...

 

이처럼 colmap 폴더를 완성했으면, 훈련 및 렌더링 할 준비가 완료됐습니다. 훈련을 위해선 아래 명령어를 실행합니다.

python train.py -s /workdir/path/to/your/colmap

 

실행하면 아래처럼 훈련 과정이 보입니다. 저는 훈련에 450장의 이미지를 사용하고, 결과는 output 폴더에 랜덤한 문자열 (여기선 1bd57b08-5) 로 저장됩니다. 7000 iter, 20000 iter에서 한 번씩 evaluation 하도록 했고, 20000 iter에서 훈련 종료하도록 했습니다. 이러한 하이퍼 파라미터들은 train.py의 메인 함수 선언 (if __name__ == "__main__") 아래에서 세팅 가능합니다.

 

훈련이 완료되면, 저장된 모델 가중치를 사용해 렌더링을 할 수 있습니다. 렌더링 하면 .mp4 결과를 확인할 수 있습니다.

python render.py -m /workdir/output/result

마무리

지금까지 3DGS에 대해 간단히 리뷰해보고, 코드를 도커로 빌드한 뒤, 3DGS 모델을 훈련하고 렌더링하는 과정까지 성공적으로 수행했습니다. 이 중 가장 어려웠던 부분은 3DGS를 도커로 빌드하는 과정이었습니다.

 

처음에는 윈도우 환경에서 어렵사리 3DGS를 빌드해 사용했지만, 더 좋은 GPU가 있는 원격 서버를 활용하지 못하는 점이 아쉬웠습니다. 그래서 우분투 환경에서 3DGS 코드를 도커로 빌드해보고자 했습니다. 그러나 대부분의 깃허브들이 Dockerfile을 제공하거나, 아니면 누군가 만든 Dockerfile이 있는 것과 달리, 3DGS에는 관련 자료를 찾기 어려웠습니다.

 

결국 제가 직접 도커로 빌드를 시도했습니다. 처음엔 너무나 까다로운 설치 과정들이 많아, 도커를 활용한 코드 빌드에 실패에 실패를 거듭했습니다. 하지만 여러 번의 실패를 겪은 끝에 마침내 성공했습니다. 이 과정이 쉽지 않았지만, 성공하고 나니 무척이나 시원하고 뿌듯한 마음입니다.

 

이번 경험을 통해 얻은 도커 버전 3DGS 빌드 방법은, 빠르게 발전하는 3DGS 기반 오픈 소스들을 도커로 손쉽게 빌드할 수 있는 중요한 기술이 되었습니다. 실제로, 저는 3DGS 뿐만 아니라 4DGS 코드도 도커로 빌드하여 활용하고 있습니다. 부디 많은 분들에게 제 게시물이 3DGS를 도커로 쉽게 빌드하고 활용하는 데에 도움이 되기를 바랍니다.

반응형