메뉴 바로가기 검색 및 카테고리 바로가기 본문 바로가기

“ML 팀의 기술 부채, 리팩터링 없이 성공 없다” - 현실에서의 기술 부채 관리

프로그램은 사람이 읽을 수 있도록 작성되어야 하며, 기계가 실행하기 위한 것은 부차적입니다.

_해럴드 애빌슨Harold Abelson, 『컴퓨터 프로그램의 구조와 해석』(인사이트, 2016) 저자

 

 

ML 종사자로서 우리는 코드가 예상보다 훨씬 더 빠르게 지저분해질 수 있다는 것을 알고 있습니다. 일반적으로 ML 모델을 훈련시키는 코드는 자동 테스트 없이 긴 노트북이나 스크립 트에 붙여진 반복적인 코드로 구성되며, print문이나 예쁘게 인쇄된 데이터프레임, 데이터 시각화 등 부수적인 효과로 가득 차 있습니다.

 

이는 ML 교육용 노트북에서는 괜찮을 수 있지만, 실제 프로젝트에서는 유지보수가 불가능한 수준의 혼란과 인지 부하를 초래하며, 진행을 중단시키는 요인이 됩니다. 좋지 않은 코딩 습관과 디자인의 부재는 코드를 이해하기 어렵게 만들고, 따라서 변경하기 매우 어렵게 만듭니다. 결국 기능 개발과 모델 개선을 점차 어렵고, 오류가 발생하기 쉬우며, 느리게 만듭니다.

 

다행히 더 나은 방법이 있습니다. 지금부터 문제투성이의 지저분하며 취약한 코드베이스를 읽기 쉽고, 테스트가 가능하며, 유지보수를 할 수 있고, 발전이 가능한 솔루션으로 리팩터링 하는 데 도움이 되는 기술을 공유할 것입니다. 

 

우리의 목표는 디자인 패턴을 활용해 완벽하게 설계된 코드를 작성할 수 있게 하는 것이 아닙니다. 그것은 물리적으로나 경험적으로 불가능합니다. 오히려 목표는 여러분과 여러분의 팀이 기술 부채를 확인하고 아이디어를 지속 가능한 속도로 실행할 수 있도록 솔루션을 점진적이고 정기적으로 개선하는 기술을 갖추는 것입니다.

 

우리는 기술 부채의 비용과 테스트, 디자인, 리팩터링 기술을 사용하여 기술 부채를 점진적 이고 주기적으로 줄일 수 있는 방법을 논의할 것입니다.

 

 

 

잘되는 머신러닝 팀의 비밀 3부작

3부. ML 팀의 기술 부채, 리팩터링 없이 성공 없다 - 현실에서의 기술 부채 관리

 

 

 

현실에서의 기술 부채 관리

 

업무는 공기와 같아서 ‘리팩터링을 해야 할까요?’라고 질문하기도 전에 빈 공간을 빠르게 채웁니다. 항상 ‘일을 완수’하고 ‘무언가를 배포해야 한다’는 ‘납품 압박’과 성과를 내야 한다는 ‘사회적 압력’은 기술 부채를 갚는 데 필요한 시간과 에너지를 빼앗아 갑니다.

 

프로젝트에서 이러한 압박에 대한 두 가지 반응을 보았습니다. 극단적으로는 기능 전달에만 집중하고 다른 것은 전혀 신경 쓰지 않는 ML 종사자도 있었습니다. 이들은 개선 기회를 포기할 뿐만 아니라, 빠르게 움직이기 위해 더 많은 부채를 떠안게 될 가능성이 큽니다.

 

반대로, 카드 작업 시 리팩터링에 지나치게 몰두하여 작업 범위가 크게 확장되고 작업 중인 카드에 상당한 지연을 초래하는 열성적인 사람들도 있었구요.

 

사실 코딩과 리팩터링은 본질적으로 사회적 활동이며 사회구조적 힘에 의존합니다. 기술 부채를 효과적으로 관리하려는 ML 종사자는 팀 내에서 바람직한 행동에 대한 사회적 계약을 수립하고 문제와 해결 방법에 대한 공통된 견해를 만들어 나가야 합니다.

 

그렇다면 프로젝트에서 기술 부채를 잘 관리하기 위해 어떻게 해야할까요?

 

기술 부채 관리 기법

다음은 효과적인 기술 부채 관리와 제품 제공의 균형을 맞추기 위해 실제 프로젝트에 적용하는 몇 가지 기법입니다.

 

1. 부채를 가시화하기

부채를 가시화하는 것은 부채를 갚아내기 위한 첫 번째 단계입니다. 유용한 정보 라디에이터는 기술 부채 ‘벽’입니다. 모든 부채를 한곳에 모아두면 ‘가치’와 ‘노력’이라는 두 가지 축을 따라 각 부채를 모으고 정렬할 수 있습니다. 

 

기술 부채 벽은 부채를 가시화하고 팀이 지속적으로 가장 중요한 부채를 상환하는 데 도움을 줍니다. (출처: 『잘되는 머신러닝 팀엔 이유가 있다』 p.341)

 

또한 가시성을 공유하면 팀이 기술 부채 관리에 대한 공동 책임 의식을 가지게 됩니다.

 

경험상, 팀원들에게 며칠 동안 작업 중에 관찰한 문제를 적어달라고 요청하고 이를 모아 기술 부채 벽에 정리하면 새로운 기술 부채 벽을 쉽게 시작할 수 있습니다. 그 후, 누구든지 새로운 기술 부채를 발견하거나 생성하면 비동기적으로 벽에 추가해 팀의 인식을 높일 수 있습니다. 

 

실행 측면에서는 필요한 노력이 적은 부채는 향후 관련 스토리 카드에 포함될 수 있습니다. 높은 노력이 필요한 부채는 다른 기능 개발 카드처럼 자체 스토리 카드를 가질 수 있으며, 이에 따라 우선순위가 매겨져 다가오는 스프린트에 추가됩니다.

 

시간이 지나면서 이 관행은 팀이 낭비, 즉 이자 지불에 낭비되는 시간을 파악하고 기술 부채를 점진적이고 정기적으로 상환함으로써 낭비를 제거하는 데 도움이 됩니다.

 

 

2. 80/20 규칙

많은 팀이 리팩터링에 시간을 할애할지, 기술 부채를 갚을지에 대해 논쟁하는 것을 보았습니다. 우리 경험에 따르면 대략적인 80/20 규칙이 도움이 될 수 있습니다. 각 스토리 카드에 대해 80%의 시간을 기능 제공과 스토리 완료에 집중하고, 20%의 시간을 기술 부채 상환에 투자하면 팀이 지속 가능하고 예측 가능한 속도로 기능을 계속 제공할 수 있습니다.

 

특정 기술 부채 작업이 많은 노력이 필요하고 가치가 높을 경우, 팀은 스프린트 수준에서 80/20 규칙을 적용할 수 있습니다. 스프린트에 할당된 노력의 80%를 스프린트 목표와 새로운 기능 전달에 집중하고, 20%(일반적으로 카드 한두 개)를 기술 부채를 갚는 데 집중하세요.

 

이 두 가지 방법 모두 과거에 솔루션 품질을 향상시키는 데 효과적이었습니다. 경험상 빈번 하고 반복적인 개선이 며칠 또는 몇 주에 걸친 ‘대규모 리팩터링’보다 더 나은 결과를 가져왔습니다.

 

 

3. 저렴하고 안전하게 해결하기

기술 부채를 다룰 때 우리는 종종 두 가지 시나리오 중 하나에 직면하게 됩니다. 

 

첫 번째는 기술 부채를 상환하는 데 시간이 많이 걸리고 솔루션이 너무 복잡해서 압도당하는 경우입니다. 이 시나리오에서는 팀이 올바른 일을 하고자 하지만(‘기술 부채 카드’를 생성) 이 카드는 종종 우선순위가 낮은 백로그 카드 무덤 깊숙이 강등되어 다시는 보이지 않게 됩니다. 이는 기술 부채의 악순환을 강화합니다.

 

두 번째 시나리오에서는 리팩터링이 빠르고 저렴하며 안전합니다. 높은 테스트 커버리지가 리팩터링이 예상대로 작동했음을 알려줍니다. 이 시나리오에서는 ‘스카우트 규칙’을 쉽게 실천하고 부채를 갚아 나갈 수 있습니다. 기술 부채에 대한 카드가 필요하더라도 오류와 문제 해결에 얽매이지 않고 꾸준히 문제를 해결할 수 있습니다.

 

예를 들어, 과거 프로젝트에서 코드베이스에 타이틀 표기법 대신 파이썬 스타일의 스네이크 표기법으로 작성된 속성이 있었습니다. 이 속성은 데이터 수집 파이프라인, 피처 엔지니어링, ML 모델 훈련, ML 모델 API, 몇 가지 테스트 케이스 등 여러 곳에서 참조되었습 니다. 하지만 전체 ML 시스템이 높은 테스트 커버리지를 가지고 있었기 때문에 IDE 단축키를 사용해 단 한 시간 만에 변경을 수행할 수 있었습니다. 리팩터링이 완료되자 모든 테스트가 통과되었고, 우리는 변경 사항을 커밋했으며, CI 파이프라인의 모든 테스트가 통과되어 변경 사항이 문제없이 운영 환경에 배포되었습니다.

 

 

4. 기술 부채 상환의 가치 입증하기

기술 부채 작업이 반복적으로 우선순위에서 밀려나는 상황에서는 기술 부채를 줄이는 것의 가치를 정량화하고 입증함으로써 팀이나 의사 결정자에게 행동에 대한 동기를 부여할 수 있습니다. 그 예로, 테스트되지 않은 API 엔드포인트가 있다고 가정해 봅시다. 개발 및 테스트 중 각 풀 리퀘스트가 병합되기 전에 해당 엔드포인트를 수동으로 테스트하는 데 소요되는 시간을 정량화할 수 있습니다. 또는 해당 엔드포인트와 관련된 운영 결함의 수를 매일 또는 매주 세고, 해당 결함을 해결하는 데 소요된 시간을 측정할 수 있습니다.

 

그리고 기술 부채를 갚으면 수동 테스트에서 절약한 시간, 운영 결함의 감소, 더 빠른 전달 속도 등 팀으로서 얻은 이점을 보여줄 수 있습니다. 이러한 효율성 향상은 정량화될 수 있으 며, 기술 부채를 줄이는 데 시간을 투자하는 것이 어떻게 더 생산적인 개발 주기에 직접적으로 기여하는지 보여줄 수 있습니다.

 

 

부채에 대한 긍정적인 관점: 시스템 상태 평가

 

이러한 기술 부채 관리 관행을 개별 팀 수준에서 조직 또는 기업 수준으로 확장하려면 팀이 주요 차원에서 현재 상태를 정기적으로 추적하고 최적이 아닌 영역에서 정기적으로 진전을 이루는 방법을 어느 정도 공식화할 필요가 있습니다.

 

이와 관련하여 유용한 기법 중 하나는 모든 팀이 간단하고 명확한 RAG 분류를 사용하여 소유하고 있는 시스템의 상태를 평가하는 정기적인 시스템 상태 평가 연습을 하는 것입니다. 이는 REA 그룹이 선구적으로 도입한 기법으로, 수십 개의 제품 엔지니어링 팀을 관리하고 모범 사례로 이끄는 데 유용하게 활용되고 있습니다.

 

REA 그룹의 시스템 상태 평가에 관한 문서에 자세히 설명된 대로 평가 차원은 개발, 운영, 아키텍처의 세 가지 범주로 그룹화됩니다. 각 카테고리에는 다음과 같은 세 가지 핵심 질문으로 요약할 수 있는 여러 차원이 포함되어 있습니다.

 

1. 개발

코드베이스를 설정하고 이해하며 자신 있게 변경할 수 있나요?

 

2. 운영

시스템을 배포하고 이해하며 그 의존성을 파악하고 재해 복구를 처리하며, 설정된 서비스 수준 계약 (SLA)에 맞춰 성능을 발휘하는지 파악할 수 있나요?

 

3. 아키텍처

시스템이 명확하게 정의된 인터페이스를 가진 단일 책임을 캡슐화하고 있나요?

 

일반적인 개발 과정을 예시로 들면, 쉽게 변경 가능한 소프트웨어는 기능을 빠르게 제공하고 결함이나 취약점에 신속하게 대응할 수 있게 하므로 평가 차원은 시스템의 변경 가능성과 관련이 있습니다. 팀은 다음과 같은 차원에 따라 소유한 각 시스템을 평가합니다.

 

■ 코드 가독성 또는 품질 점수

■ 개발 환경 설정 자동화

■ 자동 테스트의 존재 여부 및 범위

■ 지속적 통합(CI) 파이프라인의 존재 여부와 적용 범위

■ 고객, 소비자, 데이터 보호를 위한 적절한 조치

■ 디자인 문서와 의사 결정 기록 문서

 

구글의 <ML 테스트 점수> 논문에서도 시간이 지남에 따라 시스템을 측정하고 개선하기 위해 ML 테스트 점수 평가표를 사용하는 유사한 접근 방식에 대해 설명합니다. 이는 전반적인 테스트 견고성에 대한 점수표를 제공하고 팀이 모범 사례를 채택하도록 장려하는 데 큰 성공을 거둔 구글의 테스트 인증 프로그램에서 영감을 얻었습니다.

 

조직에서 ML 제품을 작업하는 팀을 위한 평가표를 만들어 보세요.  『잘 되는 머신러닝 팀엔 이유가 있다』의 사례를 한 페이지 분량으로 요약하여 주요 범주를 다루고, 각 범주에 대해 건강한 시스템의 차원을 나열할 수 있습니다.  시작점으로 아래의 평가표 예시를 활용해 보세요. 기술 리더, 종사자, 제품 관리자와 같은 관련 이해관계와 함께 상태 평가표를 공동으로 정의하고 팀에 명확한 목표와 개선 경로를 제시하세요. 우선 아래 평가표로 간단하게 시작하고, 사용하면서 팀에 맞게 발전시켜 보세요.

 

출처: 『잘되는 머신러닝 팀엔 이유가 있다』 p.346

 

더 자세한 내용은 『잘 되는 머신러닝 팀엔 이유가 있다』P.346~P.348에서  확인할 수 있습니다.
 

 

많은 팀이 기술 부채와 운영 결함을 쌓아두고 방치하는 실수를 저지릅니다. 이는 결국 생산 라인을 사실상 멈추게 만듭니다. 항상 리팩터링은 너무 어렵고 위험해 보여 백로그에 쌓이기만 하고, 결국 압박→서두름→부채의 악순환을 강화합니다.

 

이에 많은 팀이 기술 부채에 대해 분석만 하다가 아무것도 하지 않는 ‘분석 마비’ 상태에 빠지기도 합니다. 인간은 현상 유지 편향을 가지기 때문에, 기술 부채에 대해 아무것도 하지 않는 경우가 많습니다. 역설적이게도, 아무것도 하지 않는 것이 결국 기술 부채의 부담을 계속 증가시키는 결과를 낳습니다. 이 악순환을 끊기 위해 여러분은 이 글에서 다룬 기술과 원칙을 실제 프로젝트에 적용하여 좋은 것을 쉽게 만들 수 있습니다.

 

열역학 제2법칙은 우주가 무질서로 향한다고 말합니다. 우리의 코드베이스도 예외가 아닙니다. 우리는 이 장에서 배운 기술들이 여러분이 기술 부채를 효과적으로 관리하고 코드베이스와 시스템을 지속적으로 개선하는 데 도움을 줄 것이라고 믿습니다. 

 

이를 통해 여러분과 팀은 건강한 시스템을 개발하는 리듬과 문화를 형성하고, 가치를 전달하는 속도를 유지할 수있을 것입니다. 지금 당장 팀 내 기술 부채 벽을 만들어보세요. 이 작은 시작이 악순환을 끊는 전환점이 될 수 있습니다.


위 콘텐츠는『잘되는 머신러닝 팀엔 이유가 있다』내용을 재구성하여 작성하였습니다.

댓글

댓글 입력