NVP2(2) - Remote Server Connection

구명규·2023년 4월 9일
1

'23 Individual Research

목록 보기
12/19
post-thumbnail

  연구실에서 받은 서버에서 NVP 코드를 원래 사이즈 그대로 돌려보는 과정을 정리해본다.


코드실행 환경설정

  우선 VSCode로 SSH를 통해 랩 서버에 연결한 뒤 내 리눅스 계정을 추가한다. 이후 conda 가상환경까지 생성해 활성화해준다.
(원격 서버에 리눅스 계정을 생성하는 게 처음이라 디스크 공간이 남아있지 않은 디렉토리를 계정의 홈 디렉토리로 설정하는 바람에 반나절을 날렸다. 반드시 'df -h' 커맨드로 디스크의 상태를 확인한 후, 여유 용량이 남아있는 디스크가 마운트된 디렉토리에 계정을 생성할 것.)

---<ssh 공개키 연결>
# ssh 공개키 연결 위한 서버용 공개키 전달
PowerShell -Command type $env:USERPROFILE\.ssh\id_rsa.pub | ssh myungkyu@223.130.130.117 "cat >> .ssh/authorized_keys" 

# 디렉토리 변경 및 마운트된 디스크 확인
 df -h
 cd /mnt/kimmk135
 df -h .

# 우분투 계정 생성
 sudo adduser --home /mnt/kimmk135/myungkyu myungkyu

# 우분투 계정 로그인
 su - myungkyu

# 우분투 계정 로그아웃
 exit

# GPU 환경 확인
 nvidia-smi
 
# 서버 간 파일 이동
 scp /mnt/kimmk135/kmk/ root@223.130.133.237:/mnt/xvdb/kmk

---<conda 가상환경 설정>
# anaconda 설치
 wget https://repo.anaconda.com/archive/Anaconda3-2023.03-Linux-x86_64.sh
 chmod +x Anaconda3-2023.03-Linux-x86_64.sh
 ./Anaconda3-2023.03-Linux-x86_64.sh
## 이후 /root/.bashrc 파일에
## export PATH="/home/myungkyu/anaconda3/bin:$PATH" 추가 후,
## source ~/.bashrc 커맨드로 환경변수 경로 적용

# anaconda 환경 확인
 conda info --envs

# conda 업데이트
 conda update -n base -c defaults conda

# NVP 가상환경 생성
 conda create -n NVP python=3.7.13

# NVP 가상환경 활성화
 conda activate NVP

# NVP 가상환경 삭제
 conda env remove -n NVP

# 가상환경 패키지 리스트
 conda list

  NVP 소스코드를 비롯해 가장 기본적인 PyTorch, tiny-cuda-nn 패키지를 설치해준다.

---<source code  environment package 설치>
# PyTorch 환경 설치
 conda install pytorch=1.11.0=py3.7_cuda11.3_cudnn8.2.0_0 torchvision=0.12.0=py37_cu113 cudatoolkit=11.3.1=h2bc3f7f_2 -c pytorch

# NVP source code 다운로드
 conda install git
 git clone https://github.com/subin-kim-cv/NVP.git

# NVP-S Jockey checkpoint 다운로드
# https://drive.google.com/drive/folders/1jlmrPHjjZtr1WYLFJUOkfmdLavpaCZwr

# tiny-cuda-nn 패키지 설치
 pip install git+https://github.com/subin-kim-cv/tiny-cuda-nn/#subdirectory=bindings/torch

# 기타 패키지 설치
 pip install sk-video
 pip install pytorch_msssim
 pip install opencv-python==4.5.5.64
 pip install pillow=9.0.1
 conda install -c anaconda configargparse
 conda install -c conda-forge tqdm
 conda install tensorboard

*CUDA 버전에 따른 PyTorch 설치 커맨드
https://pytorch.org/get-started/previous-versions/


NVP 기본모델 실행

  HD 화질의 학습 데이터셋을 UVG 홈페이지에서 다운로드 해준 뒤, 압축을 풀고 RGB 비디오로 변환시켜 준다.

---<dataset 다운로드>
# UVG Jockey 비디오 다운로드
 wget https://ultravideo.fi/video/Jockey_1920x1080_120fps_420_8bit_YUV_RAW.7z

# 압축 해제 및 rgb 변환
 conda install -c conda-forge p7zip
 7z x Jockey_1920x1080_120fps_420_8bit_YUV_RAW.7z
 conda install -c conda-forge ffmpeg
 ffmpeg -f rawvideo -vcodec rawvideo -s 1920x1080 -r 120 -pix_fmt yuv420p -i Jockey_1920x1080_120fps_420_8bit_YUV.yuv Jockey_rgb/f%05d.png

  논문에서 제시된 Jockey video에 대한 checkpoint를 활용하여, HD frame에 대한 evaluation을 진행해본다.

---<Evaluation>
# 학습 결과 파일에 대한 쓰기 권한 부여 (root 권한)
 chmod -R 777 ./logs_nvp/nvp_default

# Evaluation without codec compression
 CUDA_VISIBLE_DEVICES=0 python experiment_scripts/eval.py --logging_root ./logs_nvp --experiment_name nvp_default --dataset ./data/Jockey_rgb --num_frames 600 --config ./logs_nvp/nvp_default/config_nvp_s.json --save

# Evaluation with codec compression
# 1. Quantization
 CUDA_VISIBLE_DEVICES=0 python experiment_scripts/compression.py --logging_root ./logs_nvp --experiment_name nvp_default --config ./logs_nvp/nvp_default/config_nvp_s.json
 
# 2. FFmpeg installation & codec compression
 sudo apt install ffmpeg  # root 권한
## 'which ffmpeg' 커맨드로 경로 찾아내어 './bashrc' 파일에
## <export PATH="/usr/bin:$PATH"> line 추가 후 'source ~/.bashrc'로 적용
## 이후 jupyter notebook으로 compression.ipynb 실행
 
# 3. Evaluation
 CUDA_VISIBLE_DEVICES=0 python experiment_scripts/eval_compression.py --logging_root ./logs_nvp --experiment_name nvp_default --dataset ./data/Jockey_rgb --num_frames 600 --config ./logs_nvp/nvp_default/config_nvp_s.json --qscale 2 3 3 --crf 21 --framerate 25 --save

# 4. Video Conversion
 ffmpeg -framerate 25 -i ./logs_nvp/nvp_default/results/f%05d.png -c:v hevc -preset slow -x265-params bframes=0 -crf 21 ./logs_nvp/nvp_default/results/result.mp4

실행 결과

  Codec compression이 포함되지 않은 결과는 아래와 같다.

  • BPP: 0.8753797067901234
  • PSNR: 40.11080559412638

  Codec compression이 포함된 결과는 아래와 같다.

  • Epoch: 144699
  • JPEG qscale: ['2', '3', '3']
  • HEVC framerate: 25
  • HEVC crf: 21
  • BPP: 0.17821575360082303
  • PSNR: 37.014897422790526

  이는 논문에서 제시된 BPP: 0.172, PSNR: 37.03과 일관된 결과로, evaluation이 올바르게 이루어졌음을 확인할 수 있다. 이제 이 결과를 기준으로 실험을 진행하면 된다!


Appendix.1 ffmpeg 오류 해결

  conda에서 ffmpeg를 설치한 뒤 Jupyter Notebook에서 compression.ipynb를 실행했더니 아래와 같은 에러가 발생했다.

Unrecognized option 'x265-params'.
Error splitting the argument list: Option not found

  아래의 커맨드에서 ffmpeg의 버전 차이로 인한 옵션 에러인 것으로 보인다.

!ffmpeg -framerate $framerate -i $src_path -c:v hevc -preset:v slow -x265-params bframes=0 -crf $crf $save_path

  따라서 현재 ffmpeg를 삭제해준 뒤 다른 버전의 ffmpeg를 재설치해주어야 한다. 특히 삭제하는 과정에서 아래와 같이 수동설치된 소스코드도 찾아 삭제해주어야 한다.

# 가상환경 내 ffmpeg 삭제
 conda uninstall ffmpeg

# conda uninstall 후에도 ffmpeg가 설치되어 있다면 'which ffmpeg'로 경로 찾아
# '/usr/local/bin'와 '/usr/bin' 등에 수동 설치된 소스코드도 찾아 삭제
 cd /usr/local/bin
 rm ffmpeg
 cd /usr/local/bin
 rm ffmpeg

# base에서 sudo apt로 ffmpeg를 새로 설치
 sudo apt install ffmpeg
## 4.4.3 version의 ffmpeg가 설치된다

## base에서 설치한 ffmpeg가 가상환경 내에서도 왜 잡히는지는 아직도 의문...

  사실 가상환경 내에서 원하는 ffmpeg를 설치하려고 온갖 방법을 시도해보다가 숱한 실패를 겪은 사람으로서 왜 base에만 설치된 ffmpeg가 가상환경 안에서도 잡히는 건지 아직 잘 모르겠다ㅎ;;

++ ffmpeg 패키지를 삭제하면 torchvision 패키지도 자동으로 삭제되는데(처음엔 몰랐지;;), 이후 torchvision=0.12.0=py37_cu113 버전을 설치해주면 ffmpeg=4.3이 자동으로 설치되며 앞선 4.4.3 버전을 덮어씌운다. 이렇게 되면 encoder-decoder 간의 ffmpeg 버전이 달라지며 압축파일이 제대로 읽히지 않는 에러가 발생한다(비정상적인 모델 성능을 보고 알게 되었다). 그렇다고 4.3 버전으로 encoding을 시도하자니 또다시 option error가 발생하고, 자동으로 설치된 4.3 버전을 삭제하고 evaluation을 진행하자니 torchvision이 기존의 ffmpeg를 인식하지 못하더라..
   \text{ }\text{ }\text{ }도무지 영문을 몰랐던 나는 갑자기 버전이 바뀌어버린 ffmpeg를 4.4.3 버전으로 재설치하고, 왠지 모르게 삭제돼있는 torchvision은 다시 설치하면서 ffmpeg=4.3까지 원래대로 돌려놓는, 미친 무한루프에 빠져버렸고, 날씨 좋았던 주말을 그렇게 홀랑 날려먹었다...
   \text{ }\text{ }\text{ }결국엔 torchvision을 conda에서 최신 버전으로 설치하고, 기존 ffmpeg=4.4.3의 설치경로를 환경변수에 추가해주어 torchvision이 정상적으로 ffmpeg를 인식하도록 해주는 해결책을 찾아 제대로 돌릴 수 있었다 ㅜ.ㅜ


Appendix.2 tmux 사용 방법

  원격 서버에 접속한 뒤 코드가 실행 중인데 terminal을 종료해도 서버의 작업이 끊기지 않고, 여러 개의 terminal을 띄워 많은 작업을 동시다발적으로 진행할 수 있게 해주는 tmux 프로그램의 사용법을 정리해본다.

  기본적으로 tmux는 가장 큰 실행단위이자 attach/detach가 가능한 session, 한 세션을 구성하는 (웹 브라우저의 탭 같은 느낌의) window, 각 window의 화면이 분할되어 생성되는 pane으로 구성됨을 알고 있도록 하자.

Session 관련 명령

# 세션 생성 (이름은 숫자로 생성됨)
$ tmux

# 이름을 지정하여 세션 생성
$ tmux new -s <session_name>
$ tmux new-session -s <session_name>

# 세션 이름 수정
<Ctrl-B> $

# 세션 detach
<Ctrl-B> d

# 세션 리스트보기
$ tmux ls

# 세션 attach
$ tmux attach -t <session number 혹은 session name>

# 세션 종료, 세션의 마지막 윈도우, 마지막 팬에서 실행
$ exit

# 세션 종료, 세션 밖에서 실행
$ tmux kill-session -t session_name

Window 관련 명령

# 세션 생성과 함께 윈도우 생성
$ tmux new -s -n

# 윈도우 이름 변경
<Ctrl-B> ,

# 윈도우 종료
<Ctrl-B> &
<Ctrl-D>

# 다음 윈도우(Next Window)로 이동
<Ctrl-B> n

# 이전 윈도우(Previous Window)로 이동
<Ctrl-B> p

# 마지막 윈도우(Last Window)로 이동
<Ctrl-B> l

# 특정 윈도우로 이동 (몇 번째 윈도우인지)
<Ctrl-B> 0-9

# 특정 윈도우로 이동 (이름으로 이동)
<Ctrl-B> f

# 윈도우 리스트 보기
<Ctrl-B> w

Pane 관련 명령

# 세로 화면 분할
<Ctrl-B> %

# 가로 화면 분할
<Ctrl-B> "

# 열 너비 동일하게
<Ctrl-B> Alt+2

# 행 너비 동일하게
<Ctrl-B> Alt+1

# autoresize
<Ctrl-B> Space

# 팬 이동 - 화면에 나오는 숫자로 이동
<Ctrl-B> q

# 팬 이동 - 순서대로 이동
<Ctrl-B> o

# 팬 이동 - 방향키로 이동
<Ctrl-B> <방향키>

# 팬 삭제
<Ctrl-D>
<Ctrl-B> x

# 팬 사이즈 조절 - 현재 포커스된 팬 전체화면(한번 더 실행하면 윈상복구)
<Ctrl-B> z

# 팬 사이즈 조절 [Ctrl] + b 를 누른 후 :
<Ctrl-B> :
resize-pane -L or -R or -U -D

# 팬 레이아웃 변경 (다양한 레이아웃으로 자동 전환)
<Ctrl-B> spacebar

Pane 관련 명령

# 스크롤 모드 전환
<Ctrl-B> [   (q로 해제)

Appendix.3 GPU 사용 관리

  'nvidia-smi' 커맨드를 이용하여 현재 사용 중인 서버의 GPU 상태를 확인할 수 있다.

  위 그림에서 보면, 서버에 할당돼있는 GPU는 Tesla V100-SXM2-32GB 모델 두 대임을 확인할 수 있다. GPU의 전체 이름과 UUID 값을 알고 싶다면 'nvidia-smi --list-gpus' 커맨드를 사용하면 된다.

  tmux 프로그램 등을 통해 여러 대의 GPU를 동시다발적으로 사용하기 위해서는 1)GPU의 메모리 사용량을 확인하고, 2)코드 상에서 적절한 GPU를 할당해주는 것이 필요하다.

  우선 GPU의 메모리 사용량을 확인하는 방법은 간단하다. 앞선 'nvidia-smi' 커맨드를 입력한 뒤, 각 GPU의 Memory-Usage란을 확인하여 현재 GPU에서 사용 중인 메모리의 값을 확인하면 된다. 위 그림에서는 각 GPU가 전체 32,510MiB(32GB) 중 28,847MiB를 사용하고 있음을 확인할 수 있다. 또한, Volatile GPU-Util란에서는 GPU의 실시간 사용률을 확인할 수 있으며, 하단의 Processes란에서는 각 GPU를 사용하고 있는 process들의 명단을 확인할 수 있다.

  사용 가능한 GPU를 확인했다면, 아래 코드를 통해 특정 모델이나 변수 등을 GPU에 올려놓고 연산을 진행시킬 수 있다.

import os
os.environ['CUDA_VISIBLE_DEVICES'] = '0'
device = torch.device("cuda")
VARIABLE_TO_BE_LOADED_ON_GPU.to(device)

  이 때, 'os.environ['CUDA_VISIBLE_DEVICES']'에 부여되는 번호는 GPU의 index로, 메모리 여유가 있는 GPU의 번호를 입력하면 된다.


References

profile
K'AI'ST 학부생까지의 기록

0개의 댓글