본문 바로가기

개발회고록

부스트캠프 - 최종프로젝트 회고록

약 1달간의 준비를 하고 12.27일 날 최종 프로젝트가 완료되었습니다. 계획을 해서 실행하기로 한 부분을 실제로 다 했기에 , 완성이라는 경험을 얻고 가는 의미 있는 프로젝트였다고 생각합니다. 이 프로젝트에서 제 개인적으로 다음에 보완해야 할 점을 적어볼까 합니다.  (적다 보니까 두서없이 적은 거 같아서 죄송합니다.)

 

2022-01/03- 어떻게 이 문제를 고칠려 하는지 추가

CI / CD pipeline에 대한 이해


부스트캠프에서, 1달간의 최종 프로젝트를 경험하면서 어떤 문제를 풀기 위해 정의하고 이 문제를 푸는  ML system을 만들기 위해 들어가는 시간이 많이 들어가지 않았습니다.branch(서버)를 github repository로 관리를 했습니다. 솔직하게 말하면, 저는 git의 목적을 잘 모른 채 남들이 사용하니까 사용했던 거 같습니다.프로젝트 당시에는 CI/CD에 대한 개념이 정립이 안 되어 있었기에 git을 그저 push, pull, merge를 쓰기 위해 사용했습니다.feature branch, staging branch, main branch로 나눠서 CI/CD를 자동화를 시도해야 했지만, 서버의 여유분이 없기는 했습니다.여러 서버에서 관리하지는 않더라도, 환경을 build하고 코드를 build하고 다양한 test까지는 하지 않더라도 환경을 build하고 코드를 build하고 간단한 unit test 코드 정도는 작성했으면 좋았을 것으로 생각합니다.Production 환경에서 build를 해보지 않고, test를 해보지 않고 merge 되는 코드가 많았기에 소위 말하는 "merge hell" 이 엄청나게 발생했습니다.CI/CD를 같이 공부하고 build, 코드 build, test 과정을 자동화하는 게 그 당시에는 상당히 큰 비용으로 생각이 되었습니다.하지만, 지금 와서 보면, "merge conflict"를 수정하는데 더 많은 시간을 들였다고 생각됩니다. 만약, 지금 다시 2주 전으로 간다면, 프로젝트 하던 것을 멈추고 무조건 CI/CD를 공부하자고 강력하게 주장했을 거 같습니다. 그리고, 제가 개발 속도가 제일 빠르다고 생각하기에, 추가적인 업무로 test 코드 작성과  CI/CD를 github action을 이용한 자동화까지 setting을 해서 더 빠른 개발을 했을 거 같습니다.

위 문제점을 해결하기 위해서

이때의 교훈을 바탕으로, 저는 부스트캠프가끝나고 git을 공부하기 시작했고, git 은 Version Control System(VCS) 을 구축하기 위한 tool에 불과하고, 이 VCS는 CI에서 version을 자유롭게 참조하기 위해서 사용하는 system이라고 생각이 들었습니다. CI는 "한 번에 merge 하면 힘들 것을 조금씩 나눠서 조금씩만 아프자"라는 방식으로 이해가 되었습니다. 그러므로, build-test-(merge or conflict)-deploy 과정이 반복적으로 일어나고 이를 자동화를 하는것이 CI automation이라는 것을 알게 되었습니다. 그리고, github action을 공부하기 시작하면서, main branch 에 push, pull request event가 발생했을 때 혹은 cron schedule로 정해진 시간에 미리 정의해둔 동작을 수행하게 할 수 있는 것을 알게 되었습니다. 

 

Docker(Container)를 이용한 환경관리

이 외에도, 개발 환경을 통일하지 못해서 Docker를 이용해 production 서버 환경을 관리했으면 환경에 의한 불일치를 해소하지 않았을까 생각합니다. Poetry를 이용해서 서버 환경을 통일해서 관리할 생각이었는데, poetry에 환경을 설정하는 부분도 있고, pip로 local에 환경을 설정하는 부분도 각자 다양해서 4명이 같은 환경에서 개발하지 못했던 거 같습니다. 팀원 중 누군가가 발언권이 강한 게 아니고 수평적인 관계기 때문에, pip을 금지하는 것을 할 수는 없었습니다.
개발하다가, 개발 환경에 변화가 생기면 docker의 경우 원격 저장소의 이미지를 update하고 이를 팀원들에게 알린 후 이미지를 새로 받아서 개발을 진행하면 되지만, 개발환경을 어떻게 관리하자는 명확한 기준이 없으면 서로가 편한 대로 개발을 해서 환경이 달라질 수밖에 없습니다. Docker 역시 그 당시에 공부를 안 했기에 poetry면 충분하겠지라는 안일한 생각을 하고 있었습니다.

위 문제점을 해결하기 위해서

이때를 교훈 삼아 google cloud에 instance를 생성해서 개발환경을 세팅하는 법을 연습했습니다. google cloud에 compute engine을 생성 후 google cloud에서 제공해주는 deeplearning vm image를 instance에 적용했습니다. scratch부터 시도하려면 NVIDIA GPU 드라이버부터 세팅을 하고, docker를 깔고, python, pytorch, huggingface 이미지를 각각 받아야 했습니다. gcloud vm image를 사용하면 pytorch , Cuda 11.0 이상이 자동으로 설치되어서 이를 이용해서 machine을 설정하고 실제로 GPU 38gb를 모델 학습하는 데 사용했습니다. 하지만, 대부분 container로 이러한 환경을 관리하겠지만, gcloud vm image를 사용해서 개발환경을 setting하는것은 gcloud에서만 가능하기에 대중적인 docker image로 pytorch GPU 환경을 설정하는 것이 필요해 보이고, 앞으로 시도할 예정입니다.

 

프로그래밍 언어에 대한 이해

부스트캠프 최종프로젝트에서, 위의 것 다음으로 가장 시간이 많이 소요된 부분은 pytorch, python의 함수를 알지 못해서 구글링을 통해 검색하는 시간과 이미 자동화가 되어있는, 즉 메소드와 클래스로 구현된 기능들을 scratch부터 구현하는 데 시간이 오래 걸렸습니다. 예를 들자면, python을 이용해서 어떤 string으로 시작되는지를 찾는 함수로 startswith, 그와 유사하게  endswith가 있습니다. 이러한 함수의 존재를 몰라서 이와 유사한 기능을 하도록 구현하는 시간이 꽤 많았습니다. 어떻게, 메소드 혹은 클래스로 구현되어있는지를 미리 기억해서 알고 있었다면, 즉, scratch부터 구현하지 않고 자동화를 할 수 있었다면 개발 시간을 좀 더 단축할 수 있었을 것으로 생각합니다. 

이 외에도 moduel, package 단위로 관리할 때 python 은 realtive import 를 사용할 수 있습니다. . .. 을 이용해서 module의 path를 소위 말하는 하드코딩하지 않아도 module, package의 위치가 module(python 파일로 봐도 무방합니다)을 기준으로 어디에 있는지에 따라, . .. 을 사용할 수 있습니다. 이 realtive import의 장점으로는 package의 내부가 변하지 않으면 이 pacakge가 어떤 환경에서 라도 module의 위치를 수정해줄 필요가 없다는 것입니다. 단점은 , realtive import의 성질을 이해하지 못하는 사람이 이 코드를 보면 해석하기 어렵다는 것입니다. 팀원들이 보통 이해를 못하는 부분이 라고 생각이 든 부분이 있었습니다. 어떤 module 기준에서, relative import는  그 module이 속해 있는 package의 level보다 더 상위 레벨의 pacakge를 참조할 수 없습니다. 쉽게 말하면, ..은되는데 ...은 안됩니다.  저는 이 realtive import 에 대해 지식이 있었지만 , 그렇지 못한 팀원들도 있었습니다. 제가 relative import로 전체 프로젝트를 package화 했는데 , 이 부분을 이해못한 팀원이 어떻게든 해결해보고자 hardcoding으로 absolute path로 바꿔버렸습니다. 이 때 좀 많이 당황스러웠지만, project 마감 기한이 얼마 안남았기에 그냥 넘어갔던거 같습니다.

위 문제점을 해결하기 위해서

따라서, 저는 부스트캠프가 끝난 이후에 부스트캠프의 python, pytorch 기본 실습 코드와, 공식 python, pytorch docs 등 여러 문서에서 제공해주는 tutorial을 매일 진행하고 있습니다. 이러한, 코드들을 숙달이 되도록 외워서 이러한 부분에서 시간을 줄이고자 노력하고 있습니다.

 

basic tool에 대한 이해

위와 같이 자동화에 관심을 가지게 되면서, linux, shell의 명령어를 어떻게 사용해야 할지 알게 되었습니다. 제가 하는 작업 수준에서 고려하면, linux, shell같은 CLI와 GUI 두 가지의 interface를 통해서 같은 일을 전부 할 수 있습니다.
하지만, GUI에서는 오래 걸리는 작업을 CLI에서는 명령어를 통해서 더 쉽고 빠르게 할 수 있다고 생각이 발전하게 되었습니다. 예를 들어, ab/cd/dk/ss.py 라는 파일을 만들려면 GUI에서는 디렉토리를 3번 만드는 과정을 반복하고 ss.py 파일을 만들어야 합니다. shell에서는 mkdir -p ab/cd/ef && touch $_/ss.py 를 이용하면 한 번에 해결이 됩니다. 수정을 해야한다면, touch 대신 vi를 사용해도 될 것입니다. 그뿐만 아니라, 저는 window에서 WSL을 install 해서 사용하는 유저인데 window에서도 linux와 같이 자동화할 부분이 많다고 느꼈습니다. 팀원에게 메시지를 보내거나, Readme 을 작성할 때 단어를 잘못 적으면 backspace를 연타했었는데, Ctrl + backspace를 사용하면 한 번에 단어를 지울 수 있습니다. 그리고, 어떤 단어를 수정하고, 문서의 끝으로 이동할 때 end 키를 이용하면 마우스를 이동하지 않고도 이동을 할 수 있어서 많은 반복적인 작업을 단축할 수 있다는 생각이 들었습니다.

 

마무리

이번 프로젝트를 하면서 느낀 것은 어떤 특정한 problem이 주어졌을 때 ML Engineer가 이를 ML을 이용해서 해결하려고 한다면 프로젝트의 개발 속도는 ML지식만이 큰 영향을 끼치지 않을 것이라고 생각했습니다.  모델은 프로젝트의 극히 일부라고 많이 들었는데, 그게 무엇인지 진짜 제대로 느낀 거 같습니다. 그리고 , ML지식은 문제마다 필요한 게 매번 다를 것입니다. ML은 ML의 domain에만 국한된 게 아니라, statistics, linear algebra, calculus , 등등 여러 기초 학문이 엮여있습니다. 태평양에서 수영을 하는 것과 비슷한 거 같습니다. 하지만, 엔지니어링은 software engineering이라는  domain의 지식만 있으면 된다고 느꼈습니다. ML, Software Engineering 2개를 같은 시간을 공부한다고 했을 때 , 들이는 노력에 비해 얻는 지식은 엔지니어링 쪽이 더 많을 거 같고 , 엔지니어링에서 얻은 지식이 생산성 면에서는 좀 더 critical 하지 않을까라고 느꼈습니다.(그리고 , 많이 들었습니다.) 제가 여기서 , ML능력이라 칭한 것은 , 문맥을 보면 아셨겠지만, Research 능력을 말한 것입니다. Research 능력은 천천히 base를 잘 다져서 기르는 게 맞다고 생각합니다. 사람에 따라 다르지만, 저는 Engineering 능력이 부족한 사람이기에, 지금은 Engineering을 메인으로 하면서 , ML을 서브로 공부하는 게 취업뿐만 아니라 앞으로의 커리어에도 도움이 되지 않을까 생각이 들었습니다. 또한, ML을 메인으로 공부하다가 Engineering을 main으로 공부하면 새로운 insight를 얻게 되는 것 도 덤이라고 생각합니다 

 

 

 

깃허브 블로그 : Woongjoon_AI (woongjoonchoi.github.io)

깃허브 영어 블로그: Woongjoon_AI2

링크드인 : LinkedIn

 

위 링크들도 많이 봐주시면 감사하겠습니다.