딥러닝 개발환경

8-1. 프로젝트 관리는 Git, Github 으로 하자구요!

Do-Woo-Ner 2020. 3. 11. 17:01

안녕하세요~


이번 시간에는 Git, Github에 대해서 설명드릴까해요~


지난 Jupyter Notebook을 설명하면서 Github에 올려 공유를 할 수 있다고 잠깐 언급한적있었죠?


Github은 jupyter notebook의 내용을 공유할 수 있는 저장소뿐만 아니라 여러 장점을 갖고 있는 클라우드 원격저장소에요. 최근에는 많은 분들께서 자신만의 github을 만들어 포트폴리오를 만들기도 하고, 실제로도 고급 인력들을 채용할때는 논문외에 github이 얼마만큼 활성화되어 있는지도 본다고해요.


그럼 지금부터 git, github이 무엇인지, 왜 개발자들이 github를 이용하는건지에 대해서 다루어 보려고 해요. 




<1. 이전 프로젝트 개발방식의 문제점>


우리부서에서는 회의를 통해 프로그램을 4분기로 하여 만드는것으로 계획했어요.   


<사진1>


이 상황에서 발생할 수 있는 문제점이 뭐가 있을까요?


첫 번째, 과다한 용량을 차지한다

일반적으로 프로그램을 버전별로 개발하다보면 이전 버전들의 내용이 중복될 수 밖에 없어요. 예를들어, 버전2를 만들때는 버전1의 내용이 중복이 되어있겠죠? 그럼 버전별로 아래와 같은 중복된 code들이 만들어 질거에요.


버전1

버전2: 버전1+새로운 기능1

버전3: 버전2(=버전1+새로운 기능1)+새로운 기능2

버전4: 버전3(버전2(=버전1+새로운 기능1)+새로운 기능2)+새로운 기능3


기능을 구현하는데 요구되는 코드양이 적지가 않기 때문에 위와 같이 프로젝트 버전을 따로 관리한다면 굉장히 많은 용량이 필요하게 될거에요. (특히 딥러닝과 같이 'import' 해주어써 써줘야하는 패키지가 엄청 많은 경우라면 더 심하겠죠?)



두 번째, 공유파일을 다루는 경우 생기는 충돌 문제

나와 다른 팀원이 공유된 하나의 파일에 대해서 작업을 한다고 해볼게요. 우연히 동시에 공유된 파일에 접근하여 코드를 편집하기 시작했고, 내가 먼저 프로그램 코드를 편집하고 저장시킨다면 어떤 문제가 일어날까요? 다른 팀원이 작업하고 있는 코드에는 내가 변경했던 코드 내용이 없기 때문에 저장이 되지 않아 작업했던 내용을 날린다던지, 아니면 내가 편집했던 내용들을 덮어버려 내가 편집한 코드 내용을 날려버리던지 둘 중 한명의 노력은 물거품이 되고 말거에요.


<사진2>



세 번째, 책임소재 불분명 & 과거 작업내역 확인 어려움

여러명이 공유된 파일에 대해서 작업을 진행하다보면 누가 잘 못된 코드를 기입했는지, 언제부터 잘 못 된건지 파악하기 힘든경우가 많아요. 당장에는 에러가 나지 않았지만 거의 다 만들때 보니 어떤 특정부분에서 문제가 발생하는 경우가 생겨요. 이때 에러가 나는 코드 부분을 누가 만들었는지 알아야 해당 책임자에게 어떤 알고리즘을 사용했는지 물어보면서 빠르게 수정작업을 할 수 있을거에요. 또한 백업해둔것이 없으면 에러가 나기전으로 돌아가는것도 거의 불가능 할 거에요. 



이렇듯 과거에는 개발자들이 프로젝트를 진행할때 여러므로 어려운 문제가 많았답니다 ㅜㅜ






<2. Git>


<2-1. Git workflow>


위와 같은 문제를 해결해주기 위해 나온 시스템이 Git라는 시스템이에요. Git이란 소스코드의 버전들을 효과적으로 관리하기 위해 개발된 '분산형 버전 관리 시스템(VCS: Version Control System)'이라고 보시면되요. ('클라이언트-서버 버전 관리 시스템'도 있는데 대략적인 설명은 여기 링크를 참고해주세요!)


그렇다면 어떻게 관리를 해주는지 알아보도록 할까요?


<사진3>



1) Working directory


working directory는 현재 컴퓨터에서 작업 중인 작업 디렉토리를 말합니다.




2) Staging area


'add'명령어를 이용하면 working directory에서 작업한 내역들이 staging area로 옮겨집니다. staging area가 존재하는 이유는 프로젝트에 핵심적인 파일(staged 상태)만 관리하고 개발이나 테스트를 위해 임시로 필요한 파일들(moddified 상태)은 관리하지 않음을 명시하기 위해서에요. 



<사진4>



Git은 파일을 commited, Moddified, Staged 세 가지 상태로 관리하는데요.


Moddified ('add' 명령어 전): working directory에서 수정한 파일을 아직 local database에 commit하지 않은 것울 의미

Staged ('add' 명령어 후, 'commit' 명령어 전): 현재 수정한 파일을 곧 commit할 것이라고 표시한 상태

Commited ('commit' 명령어 후): 수정한 파일이 local database에 안전하게 저장됐다는 것을 의미




3) Local repo(sitory)


'commit' 명령어를 이용하면 staging area에 파일들을 최종적으로 local 컴퓨터에 저장하게되요.


그런데 프로그래밍을 하시다보면 다른 사람들의 코드 or 프로그램을 다운 받아서 쓰는 경우가 있는데 이럴때 마주하는 사이트가 github 사이트에요. Github이 뭐길래 다들 그곳에다 코드를 올리고 다운받는건지 지금부터 알아보도록 할게요!


'Commit' 후에는 최근 commit을 한 부분부터 과거에 commit한 이력까지 볼 수 있게 됩니다.


<사진5>


이렇게 commit한 시간대별로  버전A, 버전B, 버전C, 버전D가 저장되면 버전들별로 중복되는 부분을 제외하고 각 버전의 변경된 사항들만 기록하기 때문에 용량을 크게 차지하지도 않게 됩니다!



4) remote repo


remote repo는 뒷 부분에서 Github과 같이 설명하도록 할게요! 






<2-2. Branch>


프로그램을 개발하고 1/4분기에서 버전1을 출시했다고 가정해볼게요. 이미 1년짜리 프로젝트 계획을 모두 세워뒀기 때문에 계획에 따라 버전2를 만들려고해요.  



그런데 사용자들이 원래 계획했던것과는 다르게 다양한 요구들을 할 수 있어요. 또한 사용자들이 버전1을 사용하다가 버그를 발견하여 수정을 해달라고 요청할수도 있겠죠?


그렇다면 원래의 계획을 무시하고 버전 수정하고 기능도 추가하고 해야할까요? 그런데 이렇게 하면 원래 계획했던 아키텍처에 벗어나 나중에는 걷잡을 수 없는 문제가 나타날 수 있어요. 그래서 원래 계획하려고 했던 버전2를 만드는 작업을 하고, 계획에 없던 기능을 추가하려는 작업도 하고, 요청을 받은 버그수정하는 작업도 해야하는데, 이럴때마다 따로 코드를 저장하고 폴더를 구성해주면 굉장히 복잡하고 비효율적일 거에요.


보통 이러한 작업들(원래계획, 기능추가, 버그수정)은 버전1이라는 공유파일을 이용하여 각가 맡은 역할(원래계획, 기능추가, 버그수정)에 따라 별도로 진행되게 됩니다. 


Git은 공유파일을 각자 독립적인 작업 영역(저장소) 안에서 마음대로 소스코드를 변경할 수 있게 해주는 기능을 제공하는데, 이 기능을 'branch'라고 합니다. 이렇게 만들어지는 각각의 브랜치 (릴리스 branch, 기능추가 branch, 버그수정 branch)는 다른 브랜치의 영향을 받지 않기 때문에, 여러 작업을 동시에 진행할 수 있어요.

<사진6>


Git은 기본적으로 중복되는 부분에 대해서는 모두 공유를 하는 상태이고, 자신들이 변경한 내용들만 따로 저장되는 방식이기 때문에 각각의 branch들끼리 병합(merge)함으로써 작업한 내용을 다시 새로운 하나의 branch로 만들 수 있게 되요!


<사진7>



1) Master branch


저장소를 처음 만들면, git은 'master'라는 이름의 만들어 줍니다. 다른 branch를 만들어주지 않는 이상 모든 작업은 'master'작업에서 이루어지게 됩니다.













<3. Github>


이전 'Git worlflow' 부분에서 'remote'에 대해 언급하지 않았었죠? 지금부터 이 부분에 대해서 언급을 해보려고 해요.


우리가 local에 우리가 작업했던 내용들을 'commit', 'branch' 등의 기능을 통해 관리한다는 사실은 이미 알고 있어요. 


Git은 버전관리를 위한 '소프트웨어'이고, git으로 저장된 내용들을 다른 서버로 저장시킬 수 있는데 이때 저장되는 장소를 Github이라고 해요. Git에서 클라우드 형태로 파일 저장소를 무료로 제공해주는거죠. 앞서 Docker에서도 도커 이미지를 Docker hub에 배포하면 여러사람들이 접근해서 다운 받아 쓸 수 있다고 했었죠? Github도 마찬가지에요!


이때 local repo에서 'push'라는 명령어를 입력하면 local 작업물들이 github에 저장되게 되는거죠. Github을 사용하게 되면 git의 장점을 그대로 갖고있는것과 별개로 추가적인 장점들이 있어요.





1) 코드를 원격으로 백업

 

Github은 내 코드들을 원격으로 백업하는 용도로 사용할 수 있어요. Git의 장점이 그대로 적용된다는 사실을 아신다면 그냥 하드에다가 코드를 버전별로 저장해서 관리하는것 보다 훨씬 효율적인 백업이 되겠죠?






2) 다른 사람들의 코드를 open source로 공유하여 쓸 수 있어요.


저같은 경우에도 프로젝트를 위해 옥스퍼드에서 matlab으로 구현한 딥러닝 tool을 사용할때가 있었는데, 에러나 모르는 부분이 생길때마다 관련 개발자에게 메일을 남기거나 github에 있는 Q&A 부분에 관련 질문들을 올려서 빠르게 답변을 받고 서로 관련 코드를 수정했던 기억이 있어요.






3) 포트폴리오의 역할도 할 수 있어요.


전문인력을 뽑을때 방법은 다양해요. 아는 지인을 통해서 소개를 받거나, 면접을 통해 프로젝트 내용들을 들어보는거죠. 그런데 내 눈으로 코딩을 짜는 모습을 본것이 아니기 때문에 인력을 뽑아도 되나 망설이실거에요. 그리고 만들었던 프로젝트들의 성능도 실제로 뛰어난건지도 모르는 일이구요.


그래서 github을 이용하면 자신을 좀 더 신뢰감있게 표현할 수 있게되요. 즉, 자신이 github을 만들고 운영하면 실제로 이 사람이 프로젝트한 코드 내용들이나 관련 설명들을 전부 볼 수 있기 때문에 신뢰감이 더 높아지는거죠. 만약 스타(facebook에 좋아요와 같은 기능) or folk (다른 사람들이 자신의 github 코드를 가져다 쓴 횟수)의 수가 많아지면 여러곳에서 작업을 같이 하자고 연락이 올 수도 있을거에요.


<사진8>


하지만 자신이 작성한 코드가 이상하다면 오히려 안좋게 사용될 수 있겠죠? 면접관들이 github 코드를 보고 '별로 code를 잘 못짜는거 같네...'하고 면접도 보기전에 서류 탈락할 수도 있을테니까요ㅜㅜ 







4) 코드 블로그 만들기 (with jupyter notebook 연동)


제가 운영하고 있는 이 블로그에는 한 가지 문제점이 있어요.


예를들어 VGG 이론을 설명하는 내용들은 충분히 블로그에서 글로 작성할 수 있는데, 코딩에 대한 설명을 하려고 하면 아래와 같이되요.



"두개 이상의 확률 변수가 서로 관계를 가지며 존재하는 경우를 생각해보자, 예를 들어 학교에 있는 학생의 키와 몸무게를 측정하는 경우, 한명의 학생 w에 대해 두개의 자료 (x,y)가 한 쌍으로 나오게 된다. 이렇게 취득한 자료를 확률변수 X와 Y로 볼때, 이를 묘사하기 위한 확률 분포를 결합확률분포(Joint Probability Distribution)이라고 한다."


import scipy.stats as st

import numpy as np


mu=[0,0]

.

.


뭔가 조금 읽기에도 불편하고, 코드가 한 두 줄도 아니라 ....


그래서 일반적으로는 code에 대한 설명을 할때에는 주석을 붙이긴 하지만 앞서 설명드린 jupyter notebook을 통해서 code를 보기 좋게 설명할 수 있다고 말씀드린바있죠? Github은 jupyter notebook과 연동이 가능하기 때문에 jupyter notebook에서 code를 설명해주는 글을 작성하고 github에 올릴 수 있어요. 즉, "github=code 블로그"가 되는거죠!


<사진9>








지금까지 Git과 Github이 무엇이고, 왜 쓰는것이 좋은건지를 말씀드렸어요.


다음글에서는 실제로 git과 github을 어떻게 사용하는지에 대한 글을 올리도록 할게요!











[글 레퍼런스]

https://backlog.com/git-tutorial/kr/intro/intro1_1.html

https://backlog.com/git-tutorial/kr/stepup/stepup1_1.html

https://www.opentutorials.org/module/3963/24425

https://opentutorials.org/module/3733

https://www.youtube.com/playlist?list=PLuHgQVnccGMA8iwZwrGyNXCGy2LAAsTXk

https://rogerdudler.github.io/git-guide/index.ko.html

https://git-scm.com/book/ko/v2/%EC%8B%9C%EC%9E%91%ED%95%98%EA%B8%B0-Git-%EA%B8%B0%EC%B4%88


[사진 레퍼런스]

사진1

https://en.wikipedia.org/wiki/File:Application-default-icon.svg

사진2

https://backlog.com/git-tutorial/kr/intro/intro1_1.html

사진3

https://www.opentutorials.org/module/3963/24425

사진4

https://backlog.com/git-tutorial/kr/intro/intro1_4.html

사진5

https://backlog.com/git-tutorial/kr/intro/intro1_3.html

사진6

https://backlog.com/git-tutorial/kr/stepup/stepup1_1.html

사진7

https://backlog.com/git-tutorial/kr/stepup/stepup1_1.html

사진8

https://github.com/tensorflow/models/tree/master/research/object_detection

사진9

https://github.com/youngji-cho/ipython-notebook/blob/master/2017-04-03-%EB%B2%A1%ED%84%B0%EC%99%80%20%ED%96%89%EB%A0%AC.ipynb