본 문서의 모든 자료는 송호연 Chris 님의 인프런 강의 [머신러닝 엔지니어 실무] 를 요약한 것임을 밝힙니다.
강의 주제 : CI를 잘 세팅해서 리서치코드를 일정하게 유지하자.
01. 리서치 코드의 품질 문제
1. 개인 컴퓨터에 저장되어있는 코드들
2. 복사 붙여넣기로 인한 높은 빈도의 중복 코드
3. 재연 불가능한 연구결과
4. 수 많은 코드 악취, 품질이 굉장히 낮은 코드들
깨진 유리창의 법칙 : 하나의 창이 깨진채로 방치되기 시작하면 다른 유리창도 곧 깨지기 시작할 것
-> 한명의 낮은 품질의 코드 개발자가 있으면 다른 개발자들의 모든 코드에도 영향을 주기 시작함
#1 코드중복
-> 소프트웨어적 취약점이 있는 코드가 복사되면 개발자가 인지하지 못한 취약점이 지속적으로 프로잭트에 남아있게 된다.
#2 코드 재사용성
: train, inference phase에서 동일한 전처리를 사용한다고 했을 때 복사 붙여넣기한 중복 코드를 통해서 구현해 놓았을 경우 train의 전처리가 수정되면 inference에서 수정되지 못하고 서빙되는 문제점이 발생할 수 있다.
-> 라이브러리 추상화를 통한 코드의 기술 부채 감소
#3 너무 많은 global varible
: 항상 같은 input이 들어가면 같은 output이 나와야 한다. 전역변수의 경우 이러한 항등성을 보장할 수 없다.
-> 파라미터를 전달하고 실행하는 형식의 모듈화를 진행
#4 너무 긴 코드
: 코드가 너무 길 경우 가독성이 떨어지고 하나의 파일에 많은 기능이 모여 있을 경우 라이브러리의 추상화가 어렵다.
-> 500줄이 넘지 않는 py 파일등의 규칙을 만들어서 code smell을 지속적으로 탐지
#5 이상하게 꼬여있는 import
: 파이썬의 relative import를 너무 남발하면 프로잭트 단위의 수정이 일어날 경우 참조 관계가 디버깅되지 않는 현상이 발생할 수 있다.
-> PYTHONPATH 환경변수를 이용하여 시작지점을 명시, absolute import 를 사용
[ PEP8 ]
imports are alawys put at the top of the file, just atfer any module comments and docstrings, and before module globals and constants.
Imports should be grouped in the following oeder:
1. Standard library imports.
2. Related third party imports.
3. Local applocation/library specific imports.
You should put a blank line between each group of imports.
#6 명확하지 않은 변수명
: 변수명이 명확하지 않거나 너무 축약된 형식을 사용하면 소통이 어렵고 코드의 재 사용성을 낮추게 된다.
02. 린트와 유닛테스트
린트
: 여러가지 파이썬 린트가 있지만 python black을 기본 린트로 사용한다. flake8도 사용.
- 인덴트
- 네이밍 컨벤션
: mypy 를 통한 타입체크
- 파이썬의 동적 타이핑을 이용하다보면 타입이 꼬여서 버그가 발생하는 경우도 있다. 타입을 채크해 주면 이런 상황을 많이 미연에 방지할 수 있다.
- PEP 484에 type hint 가 추가됨.
- pip install mypy로 설치
- mypy soultion.py 등으로 실행해주면 정적 분석을 통한 파일 분석 가능
03. 지속적인 통합 Continuous Integration
지속적 통합
: 작은 단위의 작업, 빈번한 통합.
black
: pip install black으로 설치 가능, 로컬에서 코드 스타일 검사 밑 적용 가능
# black main.py
Github Actions
: Github을 통한 CI 파이프라인 구축
: /.github/workflows에서 CI workflows 설정 가능
: lint.yml 파일을 수정하여 어떤 환경에서 어떤 linter를 적용할 것인지 설정 가능
: branch를 만들고 Pull requests 를 발행하여 lint를 통과 했는지 아닌지 판단 가능
: repo > Setting > Branches > Add rule > Branch protection rule 에서 lint check 결과에 따른 merge 규칙을 설정 가능
: 기본적으로 main 에는 merge가 되지 않도록, 실험 단위의 branch를 생성, pull requests를 발행 후 lint를 통한 관리
Unittest
: DL, ML research는 unittest가 안된다고 생각하기 쉽지만 적용 가능 함
: coverage.yml 을 이용해서 unittest를 lint 작업에 포함시킬 수 있음
: 적절한 쉘 스크립트 설정을 통해서 unittest 리포트까지 생성 가능
: 실험 설계 -> 브랜치 생성 -> Pull request -> merge -> 브랜치 삭제 의 순서로 단위가 진행됨
댓글