딥러닝 프로젝트 100% 재현을 위한 Git-LFS와 Gitlab

딥러닝 프로젝트 100% 재현을 위한 Git-LFS와 Gitlab

부제: GitHub의 1GB 한계를 넘어 개인 Gitlab서버로 LFS 마음껏 쓰기

들어가며

딥러닝 프로젝트를 하다보면 종종 마주치는 문제가 있다.

“어라? 이거 파일 어디다 뒀더라? (있긴 있는데 어딨는지 모르겠네)”

“ipynb파일은 있는데 weight 파일이 없어… (다른 서버에 있나?)”

“아 이거 코드 copy 하고 나서 수정할걸 ㅠㅠ”

ML/DL 프로젝트가 아니라 파이썬, js등으로 하던 웹 개발 프로젝트에서는 전혀 느껴보지 못했던 이슈였다. (사실 프로젝트의 시작이 git init 이었으니, 무슨 말이 더 필요할까.)

하지만 데이터 분석에서는 ‘일단 결과를 보는게 중요해~’ 라는 악마의 속삭임에 넘어가는 경우가 종종 있다. ‘이거만 수정하면 될 것 같은데…’ 물론, 당연히 수정하고 나면 높은 확률로 망한다.

그러고서는 실수로라도 rm -rf ./checkpoints/ 같은 명령어가 들어있었다면 이전에 기껏 학습시켜둔 모델 파일을 통채로 날려버리는 경우도 허다하다.

사실 이정도만 되어도 양반인데(다시 학습시키면 되니까), 만약 random seed를 고정하지 않고 학습시켰다면 그야말로 끔찍한, 논문은 썼는데 리비전하려니 재현이 안되는..! 상황이 연출된다.

그렇다면 이런 질문이 나온다.

“그거 그냥 전부 github에 올리면 되는거 아니에요?”

네, 안됩니다! (단호박)

우선 Github등 여러 git 서비스들은 자체적으로 하나의 Repo에 보통 1GB 용량 제한을 두고 있고, 이로 인해 모델 weight들을 올려서 관리한다는 것은 아주아주아주아주 작은 모델만 가능하다.

특히나 모델같은 경우에는 pickle을 이용해 binary 파일로 관리하는데, 이런 binary 파일은 git에서는 통채로(99%) 파일이 바뀌는 것으로 트래킹이 되기 때문에 버전 관리에서 어마어마하게 큰 용량을 차지하게 된다.

따라서 아래의 Git-LFS가 등장한다.

GIT-LFS, 큰 파일의 히스토리를 git으로.

Git-LFS는 git의 하나의 애드온이다. LFS: Large File Storage로, 소스코드가 아닌 여러 큰 애셋들(특히 바이너리 파일 등)을 관리하기 위해 등장했다.

Git LFS icon

다만 git과는 별도로 동작하기 때문에 git lfs 서비스를 먼저 설치해야 한다.

https://git-lfs.github.com/

Github에서 제공하는 git lfs. OS에 맞게 받아서 설치해주자.

설치한 뒤 아래 명령어를 한번만 터미널에서 입력하면 시스템 전체에서 git lfs 명령어를 사용할 수 있다.

(간혹가다가 이걸 Repo단위로 오해하는 경우가 있는데, 이 명령어는 ‘시스템단위’의 명령어다.)

1
git lfs install

그 이후에 cd 등을 통해 원하는 git으로 관리되는 프로젝트의 Root에 들어가 아래와 같이 원하는 확장자/이름을 포함하는 요소를 트래킹하도록 만든다.

1
git lfs track "*.pkl"

위와같이 입력하면 .pkl 이라는 확장자를 가진 모든 파일이 트래킹 된다.

git 프로젝트 최상단에서 입력해주면 하위 폴더를 비롯해 새로 생성되는 파일 역시 저 조건에 충족만 되면 Git lfs로 트래킹이 가능하다.

딥러닝 모델을 위한 Lfs track

딥러닝 프로젝트를 할 때 주로 쓰는 Tensorflow, PyTorch 라이브러리에서 쓰는 모델 파일들의 확장자를 정리해 보았다. (제보 환영합니다!)

1
2
3
4
5
6
7
8
9
10
11
12
git lfs track "*.pkl" # 피클 
git lfs track "*.model" # TF/Keras
git lfs track "*.h5" # TF
git lfs track "*.pb" # TF
git lfs track "*.ckpt" # TF
git lfs track "*.pt" # Pytorch
git lfs track "*.pth" # Pytorch
git lfs track "*.bin" # TF/PyTorch
git lfs track "*.zip" # 데이터셋
git lfs track "*.tar" # 데이터셋
git lfs track "*.tar.gz" # 데이터셋
git lfs track "*.targz" # 데이터셋

물론 모델 파라미터를 저장할 때 이상한 이름으로 저장하면 위에 해당하지 않겠지만, 일상적으로 저장하는 확장자들은 대부분 커버할 수 있다고 생각한다.

개인 서버의 필요성: LFS는 유료 서비스다.

물론 git들도 유료서비스이긴 하지만, 대부분 Public Repo에 대해서는 무료로 제공해주고 있다. 하지만 LFS는 무료 제공량이 있기는 하지만, 굉장히 적다.

아래는 github의 LFS 가격 안내 페이지인데, Storage와 Bandwidth 각각 1GB까지만 무료인 것을 알 수 있다.

Github Git LFS Storage. 저장/전송 각각 1G만 무료다.

사설 Git Server를 만들자: Gitlab docker 이미지!

Github은 가장 대중적인 오픈소스 커뮤니티이고 git 서버 서비스이지만, 아쉽게도 커스텀으로 설치하는 옵션은 Github Enterprise에만 지원한다. 따라서 차선책으로 Gitlab을 고려할 수 있다.

Gitlab Docker image

https://docs.gitlab.com/omnibus/docker/

Gitlab은 친절하게 ‘모든 설정이 완료된’ Docker image로 서비스를 쓸 수 있도록 배포해준다.

따라서 설치를 원하는 디렉토리에 들어가, 아래 명령어만 실행하면 설치가 끝난다.

단, 앞선 부분에서 이부분에_도메인을_넣으면됩니다 대신 서버 IP에 연결된 도메인 이름(ex: beomi.github.io 등)을 넣어주어야 한다. 이부분이 이후 Gitlab에서 글로벌하게 사용하는 서버 주소가 되기 때문.

1
2
3
4
5
6
7
8
9
10
11
export GITLAB_HOME=$(pwd)
sudo docker run --detach \
--hostname 이부분에_도메인을_넣으면됩니다 \
--env GITLAB_OMNIBUS_CONFIG="gitlab_rails['lfs_enabled'] = true;" \
--publish 30443:443 --publish 30080:80 --publish 30022:22 \
--name gitlab \
--restart always \
--volume $GITLAB_HOME/gitlab/config:/etc/gitlab \
--volume $GITLAB_HOME/gitlab/logs:/var/log/gitlab \
--volume $GITLAB_HOME/gitlab/data:/var/opt/gitlab \
gitlab/gitlab-ce:latest

약간의 시간(5분)이 지난 뒤 http://도메인이름:30080 에 들어가면 초기 id/pw(관리자용)를 입력해 계정을 생성해 사용할 수 있다.

분명히 공식 문서에서는 GITLAB_OMNIBUS_CONFIG 설정 없이도 git lfs가 기본으로 활성화되어있다고 말 하지만 정작 실행해보면 왜인지 LFS가 안되어있어서 수동으로 활성화 env를 넣어주었다.

나머지는 동일!

git lfs track 명령어를 통해 .gitattribute파일이 정상적으로 생성되고 이 파일이 git을 통해 잘 관리되고 있다면 이제 더이상의 문제는 없다!

자연스럽게 git addgit commit -m 으로 커밋을 완료해보자.

만약 Git LFS만 업로드하고 싶다면

git 대신 git lfs 명령어를 쓰면 된다.

1
2
3
4
git lfs push

# 땡기고 싶다면
git lfs pull

완성!

실제로 완성해서 쓰고 있는데 성능이 좋다. 인터넷을 기가비트(1G)로 쓰고 있어서 학교 서버 등에서 사용할 때에도 충분히 빠른 속도가 나오는 편.

(아래는 Transformers 라이브러리를 이용한 간단한 예제들을 정리하는 레포다.)

완성해서 실제로 쓰고 있는 Gitlab 서버

:30080 포트가 보기 싫다면.. Reverse Proxy를 사용해보세요!

사실, 앞선 설명에서는 모두 30080, 30443 처럼 HTTP/HTTPS/SSH를 위한 ‘이상한 포트’ 대역을 사용했지만, 위 스크린샷을 보면 git.jblee.kr 처럼 기본 포트만 사용하는 것을 볼 수 있다.

시놀로지 NAS에서 Reverse proxy를 쓰는 방법

DSM에서는 몇번의 클릭만으로 아래와 같이 Reverse proxy를 만들어 쓸 수 있다.

시놀로지 Reverse Proxy 메뉴

‘추가’를 눌러 아래와 같이 원하는 도메인을 설정해 주면 된다. 외부에서 http://git.jblee.kr:80으로 들어오는 요청을 http://localhost:30080 으로 Proxy해준다. (프로토콜은 모두 HTTP로.)

같은 방식으로 https://git.jblee.kr:443https://localhost:30443 으로 Proxy 해주면 된다. (당연히 프로토콜은 모두 HTTPS로 한다. 그리고 HTTP/2를 활성화 시키는 것이 성능에 훨씬 더 유리하다.)

Reverse Proxy 설정: HTTP의 경우

http 대신 안전한 https 를 사용하고 싶다면

시놀로지 NAS에 설치한 경우 인증서 설정법

DSM의 ‘제어판’ - ‘보안’ - ‘인증서’ 메뉴에서 아래와 같이 ‘추가’를 눌러 새 주소에 대해 새로운 인증서를 받는다.

시놀로지 NAS 인증서 메뉴. 새롭게 추가한 인증서가 보인다.

위 스크린샷의 ‘구성’을 누르면아래와 같이 시스템 서비스 별, 그리고 Reverse proxy 별로 다른 인증서를 지정할 수 있는데, 이 때 Reverse Proxy로 생성해 준 도메인을 눌러 새 인증서를 아래와 같이 매칭시켜주면 끝난다.

NAS 인증서 구성하기. '인증서' 드롭다운에서 새로 발급받은 인증서를 선택한다.

일반 리눅스 버전에 설치한 경우

/etc/gitlab/gitlab.rb 파일을 수정해야 한다.

1
docker exec -it gitlab vim /etc/gitlab/gitlab.rb

위 명령어로 도커 내부에 들어가 gitlab.rb 파일을 수정해준다.

외부에서 직접 수정해줘도 되지만, 권한이 꼬이는 것을 방지하기 위해 docker exec를 통해 도커 내부에서 수정하는 것을 권장한다.

해당 파일에서 letsencrypt 부분을 찾아 주석(#)을 해제해 주자. 가장 첫 줄은 https:로 시작하는 도메인 풀 주소를 적어주면 된다. (단 이때 비정규포트(ex: 30443)등은 지원하지 않는다. 그래서 Reverse proxy로 받은 주소를 적어줘야 한다.)

1
2
3
4
5
6
7
# 아래 주석 해제 후 값 변경 [필수]
external_url "https://git.jblee.kr" # 꼭 https 로 시작하기
# 아래 주석 해제 [11이하버전은 필수, 이상은 기본값으로 true]
letsencrypt['enable'] = true

# 메일로 갱신 알람을 받고 싶다면 적어주면 된다. [옵션]
letsencrypt['contact_emails'] = ['foo@email.com']

만약 매번 자동 갱신되는 것까지 고려한다면.. 사실 매번 리뉴얼 하는 것은 매우 귀찮으니, 이렇게 자동으로 리뉴얼되게 해 두는 것이 훨씬 쉽다.

gitlab.rb 파일 중 아래와 같이 주석 해제하고 설정해주면 된다.

1
2
3
4
letsencrypt['auto_renew'] = true
letsencrypt['auto_renew_hour'] = 0
letsencrypt['auto_renew_minute'] = 30
letsencrypt['auto_renew_day_of_month'] = "*/20"

위 세팅으로는 매월 20일 0시 30분에 리뉴얼을 시도한다. Let’s Encrypt는 한번 갱신에 90일의 기간을 주기 때문에, 위와 같은 세팅으로 무한히 연장해서 쓸 수 있다.

Gitlab 버전을 업그레이드해야 한다면

만약 깃랩을 쓰다 보안/기능의 이슈로 업그레이드 해야한다면 아래 명령어로 쉽게 새 이미지를 받고 새로 띄울 수 있다.

1
2
3
4
docker pull gitlab/gitlab-ce:latest
docker stop gitlab
docker rm gitlab
# 그리고 나서 docker run ~~~

References

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×