Search
🔵

deer.7.1.1. title: 더 좋고 빠르고 기능추가가 간편한 좋은 모델 만들기, MLOps

🚀 prev note
♻️ prev note
🚀 next note
♻️ next note
17 more properties
@5/17/2021 회사의 칸반에서 @12/14/2021, 10:21:00 PM 에 이동된 내용

문제 상황

이런 태스크를 해야겠다고 생각하게 된 계기

젯슨을 뺏기면서, 해야 하는 일들을 정리해 보았다. 굉장히 많은 칸반이 있었고, 이것들 중 상당히 많은 것들은 결국 비슷한 문제로부터 시작된 것 같다는 생각이 들었고, 굉장히 많이 흩어져 있던 칸반을 제거하고 이것 하나로 통폐합했다. 이것을 기준으로, 서브 태스크들을 새로운 칸반으로 만들어 실행하려고 한다.

지난 태스크를 진행하면서 느낀 점 예시

<bisenet v2 : 모델이 정상적으로 돌아가고 있는게 맞는지, 학습 중인 모델 가중치 뽑아서 검증 한번 해보기>
e.g. :
1. tensorflow 1 의 시스템의 복잡도가 너무 높다. 2. tensorboard 는 google colab google drive Web I/O 를 하며 결과값을 시각화하고 있는데 이것이 굉장히 느리다. 3. 현재 모델의 성능이 만족스럽지 못하다. 제대로 된 해결을 하려면 - tensorflow 1 → tensorflow 2 로 넘어가주거나, pytorch 를 사용해야 한다. - 특히 린함을 원하는데 tensorflow 1 을 사용하는 것은 바보 짓이다. - 같은 맥락에서 시스템은 최대한 간단하게 만들어야 하고, 시스템 복잡도는 최대한 바로바로 정리한다. - 딥러닝을 위한 컴퓨터가 필요할지 고민해야 한다. 예를 들어 COLAB 에서 코드 외부적인 방해요소들이 너무 많아 생각보다 많은 시간이 들어간다.

나의 태스크들에 있어서 대표적인 문제들

태스크들이 공통적으로 해결하고자 하는 문제는 다음과 같다.
성능 (그리고 속도)
메모리
소프트웨어 시스템의 복잡도
그리고, 린한 문제접근-해결 방식

구체적으로 현재 우리의 상황을 설명하면

bisenet v2 모델의 성능이 좋지 않다. 또 하나 간과하면 안 되는 것이, 우리가 가진 데이터는 '초양질'의 데이터가 아니다. 현재 데이터와 현재 모델과 현재 기법들로 돌린 결과는, 20 개 남짓한 class 에 대한 accuracy 40% 정도 수준이다. 물론 필드에 아직 나가 본 것은 아니지만, 어쨌든, 이정도 수준으로는 땅을 제대로 따는 것 자체가 쉽지 않을 수 있다. 보통 필드는 가상보다 훨씬 더 어려우니까.
우선 내가 예상하기로는, bisenet v2 자체가 가질 수 있는 복잡도가 너무 낮다.
그렇게 추론하는 이유는, 일반적인 모델들이 다루는 태스크들에 비해 우리가 풀고자 하는 태스크는 이런 특징을 가지고 있기 때문이다.
굉장히 고해상도의 이미지이다.
데이터의 절대적인 양이 모자라다. 하지만, 각 태스크마다 가지고 있는 데이터의 수는 적은 것이 맞지만, Aihub 덕분에 국내에 잘 맞는 데이터셋을 태스크마다 몇만장씩 확보할 수 있게 됐다. 이것들이 합쳐지면 상당히 좋은 성능을 확보할 수 있을 것이다.
(장기적인 이야기) 이 모델의 문제가 해결된 다음부터는...
만약 bisenet v2 모델의 문제라면, 다른 모델을 사용해야 할 수 있다.
bisenet v2 모델을 만든 프레임워크 자체가 조잡하다. bisenet v2 모델이 tensorflow 1 기반이다. tensorflow 1 이 전체 시스템 복잡도를 지나치게 높인다. 전체 시스템 복잡도를 낮추어야, coral 보드같은 저전력 고효율 TPU 보드, GPU 보드에도 쉽게 올려줄 수 있다.
현재 상태는 성능 효율과 메모리 효율이 좋지 않다. bisenet v2 모델과 yolo v4 모델의 backbone 은 상당히 많은 task 를 공유한다. 하지만 지금 모델은 개별 backbone 을 사용하고 있고, 이것은 memory 를 차지하는 양이 두 배가 됨을 의미한다.
비슷한 태스크를 독립적인 모델로 돌린다는 것 자체가 크나큰 사치이다.
특히, yolo 모델의 경우 혼자서 거의 15GB 가 넘는 메모리를 차지해 버린다.
달리 말하면, bisenet v2 모델이 가질 수 있는 메모리가 yolo 모델에 비해 너무 작다는 것을 의미하고, 그것은 복잡한 환경을 모델 안에 모두 담지 못하고 있을 수 있다. 이것은 다른 모델들을 실험해 보면서 이것이 문제인지 알 수 있다.
이렇게 비정상적이라고 여겨질 만큼 많은 메모리를 잡아먹는 문제가, TensorRT 문제인지, 그냥 모델 자체가 무거운 것인지도 알기 어렵다. (아직 yolov4 가 어떻게 구현되어 있는지 내부를 알지 못하고 있다.)
TensorRT 문제인 경우
할 수 있는 액션 1. 정말 tensorflow 1 의 tensorRT 와 호환되지 않는 문제 때문에 메모리가 튀겨지는 것이 맞는지 확인해 보아야 하는데, 이것을 알아보기 위해서는 tensorflow 2 의 tensorRT 로 포팅을 해서, 정상적으로 돌아가는지 확인을 해 보아야 한다. 결국 tensorflow 1 으로 엮여 있는 시스템을 리팩토링해야 한다.
모델 자체가 무거운 경우
할 수 있는 액션 1. 모델의 무게와 성능 사이에서 적절한 밸런스를 가진 모델을 찾아 끼운다.
할 수 있는 액션 2. 모델을 수정해서 재학습시킨다.
할 수 있는 액션 3. 클라우드에서 돌린다.
그래서, 이렇게 하는 것이 좋을 것 같다.
1.
tensorflow 2 모델만 사용한다.
2.
모델들을 빠르고 효율적으로 서칭하고 실험한다. (아래 원칙, 앞으로 진행할 태스크 e.g. ) (high-level 도구들을 활용한 Meta-Learning),
3.
동일한 기능을 하는 모델의 요소들을 하나로 합친다. (Multitask-Learning)
4.
perception 시스템을 최대한 간단하고 명료하게 모델 포팅이 쉽게 지속적으로 관리한다.
5.
이 명료성을 루돌프 시스템 전체로 확장해 나간다.

태스크를 진행하면서 지킬 원칙

시스템의 복잡도는 최대한 줄인다.
아래의 상황들을 확인하지 않으면, 그것을 메꾸기 위해 또다른 분기가 생긴다. 예를 들어, yolo v4 는 tensorflow 2 기반이며, uint8 최적화가 되지 않고, bisenet v2 는 tensorflow 1 기반이며 float16 최적화가 강제된다면, <최적화 옵션> <프레임워크 버전 옵션> 같은 것들이 모든 상황에서 적절히 작동하도록 만들어야 하기 때문이다. high level 에서 일어나는 일은 high level 에서 끝나야 한다. 프레임워크단에서 발생하는 디버깅에 너무 많은 시간을 쏟을 수 없다.
(2021년에는) tensorflow 2 이외의 프레임워크는 도입하지 않는다.
tensorflow 2 를 사용하는 이유는, pytorch 보다 모델의 자유도는 굉장히 떨어지지만, 우리는 앞으로도 말하겠지만 복잡한 모델이 아니라 최대한 있는 그대로의 모델을 사용할 것이기 때문에, 그 정도는 충분히 직접 구현 가능하다고 판단했다. 게다가 tensorflow 2 는 pytorch 보다 TensorRT 최적화나 int8 양자화 등에서 압도적으로 편리하다.
모델을 실험할 때에는, 모델의 구조를 크게 변경하지 않는다. 한계가 나타난다면 모델의 복잡도를 높이지 말고, 데이터를 수집하고 정제한다.
쓸데없는 잔가지를 추가한다거나 하는 실험적인 도전들은 가치있지만 시스템의 복잡도를 높인다. 다른 더 좋은 backbone 으로 우리의 모델을 바꾸고자 할 때, 그리고 새로운 태스크가 동일한 backbone 에 붙으려고 할 때 이것들은 또다시 거대한 짐이 될 수 있다.
엄밀한 실험은 시간과 복잡도를 줄여 준다. 모든 모델을 실험할 때마다 반드시 아래 사항을 확인한다. 자세한 내용은 수정될 수 있기 때문에 별도의 글로 관할 것이다. . 아래는 그 예시이다.
e.g.
코드는 최대한 재사용하고, 하나의 함수는 하나의 기능만 수행하도록 만든다.
현재 streamer 클래스만 보아도, 상속구조가 아니기 때문에 굉장히 더럽다. 그리고, 디버깅이 굉장히 까다로운 데다가, 중요한 결함이 있을 때에는 segmentationstreamer._callback, segmentationstreamer._callback_register, detectionstreamer._callback, detectionstreamer._callback_register 을 모두 수정해야 한다. 하지만 이건 딱, 모델이 두 개 있을 때 이렇다는 것이고, 브랜치가 나누어져 있다. 이것을 묻고 돌아가도록 만드는 것은 린한 것이 아니라, 오히려 여기저기 터지는 코드를 고치는 시간이 더 걸린다는 사실을 알게 됐다.
다른 모듈들에 의해 inference time 이 영향을 받지 않게, 이런 변인 통제를 쉽게 해서 성능을 빠르게 측정할 수 있도록 함수를 포장해야 한다. 예를 들어, end-to-end inference pipeline 의 시간을 측정할 때, 코드 A 가 input 에 inference time 이 영향을 받고, A 다음에 이어 오는 B 는 큰 상관 없다면, A 를 싸서 하나의 함수, B 를 싸서 하나의 함수로 만들어 부분 추적이 가능하도록 만들어야 한다.
복잡한 시스템을 만들어야 할 때는 반드시 시뮬레이터 역할을 하는 소프트웨어를 만든다.
COLAB 에서 모든 실험을 마친 뒤 파일만 불러와서 로컬 실행시간을 비교해 본다.
디버그 툴을 배우는 시간이 디버깅하는 시간보다 짧다.
tensorboard
tensor
커밋 태그를 관리한다.
ROS2 를 염두해 두고, Custom launch 파일을 최소화하는 등의 생각을 가지고 있는다.

이 큰 그림이 해결해 줄 수 있는 칸반 또는, 이 큰 그림이 병목을 해소하는 것에 도움이 될 것이라고 생각한 칸반들

(속도, 메모리)
(속도, 메모리, 시스템 복잡도)
(시스템 복잡도)
(시스템 복잡도)
(속도, 시스템 복잡도)
(성능)
(속도, 메모리, 시스템 복잡도)
(성능, 시스템 복잡도) → 이게 만약 tensorflow 2 구현이었다면, 7일도 안 돼서 끝났을 것! 물론, 직접 다 짜보면서 tensorflow 내부에 대해 이해하는 요소들도 많았지만 과연 그것이 그 시간을 그 타이밍에 쏟는 의미가 있었을까? 싶었다.

참고자료 메모

유튜브에 이것저것 찾아보던 도중 발견한 동아리. 만약 다음에 시니어가 아니더라도 누군가를 뽑아야 한다면 이렇게 자율주행 동아리에서 찾아보는 것도 좋지 않을까 하는 생각이 들었어.
성능, 린한 문제접근-해결 방식과 관련된 내용
제품을 목표로 하는 머신러닝 리서치 팀이라면 누구나 가지고 있을 딜레마가 아닐까. 엄밀함도 중요하지만, 속도도 중요하다. 아무래도 trade-off 가 아닐까 싶다. 하지만 실험을 꼼꼼하게 기록해 놓고, 실험의 순서를 잘 설정하고, 다른 데이터를 통해 다시 테스트를 잘 해 보고, 변인을 잘 통제하는 것이 중요하다. 때로는 엄밀하게 실험하는 것이 결국 시간을 아끼게 해준다.
성능, 소프트웨어 시스템의 복잡도와 관련된 내용
복잡도를 높이면서 성능을 높이는 시도들이 많다. 하지만 그런 시도들은 과연 능사가 아닐 수 있다. 프레임워크의 복잡도가 높아지면 예상하지 못한 결과가 많이 나타난다. 새로운 기술이 나왔을 때 이후작업의 효율도 떨어뜨린다. 복잡도의 증가만큼 성능이 증가하는지 잘 생각해 보아야 한다.
소프트웨어 시스템의 복잡도, 린한 문제접근-해결 방식과 관련된 내용
처음에는 시간도 많이 쓰고, 데이터셋 만드는데도 돈을 많이 쓰고... 작동할 수 있는 최소한의 돌아가는 상태만 만들어놓고 이것을 관찰하고 해결하는 방식으로 접근했다면 지금보다 훨씬 더 좋지 않았을까 하는 생각이 있다.
성능, 소프트웨어 시스템의 복잡도, 린한 문제접근-해결 방식과 관련된 내용

생각 시행착오

MLOps 지금 필요한가?
TensorFlow Hub, 우리에게 린함을 선물할 수 있을까?
어쨌든 이 태스크에 대한 걱정.
이런 노력을 통해 과연, "충분히 줄어들 수 있는" 부분일까? 왜냐하면, 전용 하드웨어가 없는 상황에서 (젯슨 포함) 많은 현역 자율주행 엔지니어들은 엣지에서 일어나는 딥러닝 연산을 [성능, 메모리, 소프트웨어 시스템 복잡도 모두에서] 딱히 긍정적으로 여기지 않는다. 그런데 우리가 최적화를 시키고 multi-task 모델을 만들고 하는 노력들이 과연 성공할 수 있을까? 에 대한 막연한 두려움이 있다.
이 시도가 실패하는 케이스의 예를 들면, 아예 모델들을 Jetson 에서 다른 알고리즘들과 함께 온보드에서 돌린다는 것이 아예 말도 안 되는 발상이었던 것이다. 지금부터라도 완전히 다른 방식의 접근을 해야 하는 것일까? 클라우드를 사용하거나 엣지 가속기인 CORAL 등과 같은 전용 하드웨어들을 사용하는 것과 같이.. 이런 선택지들은 Map 방식인가 pure vision 방식인가와 같이 상당히 커다란 갈림길일지도 모른다. (물론 현재 고민해야 할 부분들은 아닐 수 있다.)
하려고 하는 태스크가 너무 린하지 못한 것 아닐까? 린하지 못하다는 것은 달리 말하면, 어떤 일은 지연되는 것이기도 하고, 실패했을 경우 비용이 크다는 것을 의미하기도 한다. 또, 2주 단위로 필드에 돌리면서 어떤 결과를 받아보지 못할 수 있다.
to
1.