Hidden Technical Debt in Machine Learning Systems
Part of Advances in Neural Information Processing Systems 28 (NIPS 2015)
Abstract
Machine learning offers a fantastically powerful toolkit for building useful complexprediction systems quickly. This paper argues it is dangerous to think ofthese quick wins as coming for free. Using the software engineering frameworkof technical debt, we find it is common to incur massive ongoing maintenancecosts in real-world ML systems. We explore several ML-specific risk factors toaccount for in system design. These include boundary erosion, entanglement, hidden feedback loops, undeclared consumers, data dependencies, configurationissues, changes in the external world, and a variety of system-level anti-patterns.
Introduction
ML 관련 업무가 수년간 경험이 쌓이고 있다 보니 실제 시스템에 점점 통합이 되어가고 있는 추세입니다.
ML 시스템 개발 및 배포는 비교적 쉽고 빠르지만 해당 시스템을 유지하고 관리하는 비용은 매우 큽니다.
이에 대해서는 1992년 Ward Cunningham 이 설명한 기술 부채 (Technical debt) 이론으로 설명될 수 있습니다.
- 재정 부채와 유사하게 기술 부채를 감내해야 할 만한 전략적 이유가 소프트웨어 공학에서도 존재합니다.
- 모든 부채가 나쁘다고 할 수는 없지만 소프트웨어에서의 기술 부채는 지속적으로 관리되어야 합니다.
- 이를 위해 리팩토링, 단위 테스트, 미사용 코드 삭제, 종속성 제거, API 강화, 문서화 등의 작업을 통해 기술 부채를 줄여가야 합니다.
- 이때의 목표는 새로운 기능을 추가하는 것이 아니라 향후 개선을 위해 오류가 발생할 수 있는 가능성을 줄여 유지 보수성을 향상하는 것이 목적이 됩니다.
- 이에 대한 지불을 미루게 된다면 복리 이자를 내야 합니다. 감춰진 부채는 교묘히 숨어들어 있기 때문에 무척이나 위험합니다.
이 논문에서는 ML 시스템은 전통적으로 다루었던 코드의 유지 관리 문제 외에도 ML과 관련된 고유의 문제들로 인한 기술 부채가 존재하고 있음을 이야기합니다.
- 게다가 대부분의 문제점들이 코드 수준이 아닌 시스템 수준에 머무르기 때문에 이를 감지하기가 더 어렵습니다.
소프트웨어 공학에서 이야기하는 추상화(abstraction)의 경계가 ML 시스템에서는 미묘하게 무너지게 됩니다.
- 기존에 알려진 코드 수준의 기술 부채 제거 방식으로는 이 문제를 해결하기 어렵습니다.
이 논문이 이러한 문제를 해결하기 위한 새로운 알고리즘을 제안하는 것이 아닙니다.
- 대신 이 문제들이 얼마나 어려운 트레이드 오프(trade-off) 문제인지를 이해하고 장기적으로 고려해야 할 대상임을 이해시키는데 목적을 둡니다.
여기서는 시스템 레벨에서 상호 작용 및 인터페이스에 중점을 둡니다.
- 시스템 레벨에서는 ML 모델이 추상화 영역의 경계를 무너뜨릴 수 있습니다.
- 입력 값들을 재사용 한다거나 또는 연쇄 과정을 만들어내는 경우 의도하지 않은 시스템 결합이 생겨날 수 있습니다.
- ML 패키지는 블랙박스처럼 취급되는데 그 결과 이를 위한 “접착 코드(glue code)” 또는 보정 레이어 (calibration layer)가 필요해지게 됩니다.
- 외부 환경의 변화는 모델이나 입력 값에 변화를 주기 때문에 시스템의 결과에 영향을 미치게 됩니다.
Complex Models Erode Boundaries (복잡한 모델의 경계 침식)
전통적인 소프트웨어 엔지니어링은 강력한 추상층 경계를 이용하여 캡슐화, 모듈화 과정을 거쳐 유지보수가 쉬운 코드를 생성합니다.
- 엄격한 추상층 경계(abstraction boundaries)는 주어진 컴포넌트로부터 데이터의 입력과 출력의 불변성과 논리적 일관성을 표현하는데 도움을 줍니다.
안타깝게도 ML 시스템은 의도된 행동을 규정하여 엄격한 추상화 경계를 강제하는 방법을 적용하기 어렵습니다.
문제는, 실제로 ML 시스템을 사용하는 가장 큰 이유가 외부 데이터에 의존하지 않고 소프트웨어 로직에서 원하는 동작을 효과적으로 구현할 수 없기 때문입니다.
결과적으로 추상적 경계가 무너지기 시작하면 기술 부채가 증가할 수 있습니다.
이 섹션에서는 이러한 현상이 왜 발현되는지를 다루고 있습니다.
Entanglement (얽힘 현상)
ML 시스템은 입력 신호를 혼합하여 개선을 불가능하게 합니다.
예를 들어 모델 내의 피쳐(feature) 를 x1x1, …xnxn 개 사용하는 시스템에서 x1x1의 입력 분포가 변경되면 나머지 n−1n−1 개의 피쳐의 중요도, 가중치 등이 모두 변경돼야 할 수도 있습니다.
- 이는 모델의 배치 스타일을 사용하던 온라인 방식으로 학습하던 상관없이 동일하게 적용됩니다.
이는 새로운 피쳐 xn+1xn+1 을 추가한다거나 혹은 임의의 피쳐 xjxj를 제거할 때에도 동일하게 적용됩니다.
모든 입력은 서로 독립적이지 않습니다. 이를 우리는 CACE 현상이라고 부릅니다.
CACE 원리 (Changing Anything Changes Everything.)
- 하나가 변하면 전체가 변한다는 의미입니다.
- 이는 입력 시그널의 변경뿐만 아니라 사용하는 하이퍼 파라미터, 학습을 위한 설정, 샘플링 방법, threshold 결정, 데이터 선택 등 모든 가능한 변경들로부터 발생할 수 있습니다.
이를 통합할 수 있는 한 가지 쉬운 방법은 앙상블(ensemble)을 도입하는 것입니다.
- 이 방법은 특정한 경우에는 아주 잘 동작합니다.
- 문제 정의상 문제가 서브 태스크로 나뉠 수 있는 경우에 적용하기 좋습니다.
- 물론 대부분의 경우에도 앙상블은 잘 동작합니다. 각 모델의 에러는 서로 연관성이 없기 때문입니다.
- 하지만 앙상블 모델은 기본적으로 모델 사이의 강한 얽힘을 가지게 됩니다.
- 따라서 개별 구성 요소를 개선하더라도 전체 성능이 오히려 나빠질 수 있습니다. (다른 컴포넌트들이 강하게 연관되어 있는 경우에 발생할 수 있습니다.)
두 번째 대안으로 발생할 수 있는 예측 행동을 찾는 것에 주력하는 것입니다.
- 고차원 정보를 시각화할 수 있는 Tool을 활용하여 다차원 공간을 나누어 분석합니다.
Correction Cascades (수정 전파)
문제 AA 에 대한 모델 mama 가 존재할 때, AA와 유사하지만 새로운 문제 A′A′ 를 해결해야 하는 상황을 가정해 봅시다.
이 경우 모델 mama 의 결과를 입력으로 하여 m′ama′ 를 만들어내는 것을 고려하게 됩니다. (빠른 문제 해결을 위해)
하지만 이 경우 새로운 시스템은 mama에 종속적이게 됩니다.
- 향후 개선 시에 비싼 비용을 치르게 됩니다.
만약 모델 m′ama′ 를 가지고 문제 A′′A″ 를 해결해야 한다면 더 복잡한 상황이 되고 맙니다.
이런 시스템을 구성하고 나서 개별 구성 요소의 품질 향상을 진행할 때 수정 전파가 데드락을 만들어낼 수도 있습니다.
이에 대한 보완 전략은 각각의 문제 사례를 구분하거나, 같은 모델에 이런 상관관계를 직접적으로 학습할 수 있는 피쳐를 추가하는 것입니다.
Undeclared Consumers
예측 모델 mama 의 출력 결과가 로그 등에 기록되어 누구나 접속 가능한 환경에 노출될 수 있는 환경을 생각해 봅시다.
만약 어떤 ML 시스템이 이를 입력 값으로 활용하게 되면 이를 undeclared 되었다고 합니다. 암묵적으로 어떤 모델의 출력 값이 다른 모델의 입력값으로 활용되는 상태입니다.
좀 더 고전적인 소프트웨어 엔지니어링 분야 이서는 이를 가시성 부채(visiblity debt)라고 부릅니다.
이는 다른 모델에 숨겨진 강한 종속성을 만들어내기 때문에 최고로 비싼 비용이여 최악의 위험성을 내포합니다.
만약 모델 mama 가 개선되면 모든 다른 파트에 영향을 주게 됩니다.
- 경험적으로 이러한 강 결합은 운영 비용을 빠르게 증가시키고 문제를 어렵게 만들어 냅니다.
게다가 이 문제는 숨겨진 피드백 루프 (hidden feedback loop)를 만들어냅니다. (이는 뒤에 설명합니다.)
숨겨진 고객(undeclared consumer)을 찾아내는 것은 매우 어렵습니다.
- 엄격한 접근 제약이 없는 경우 엔지니어들은 (특히 마감이 다가올 때) 가장 손쉬운 정보를 활용하기 때문입니다.
코드 의존성보다 데이터 의존성 비용이 더 크다
의존성 부채(dependency debt)는 전통적으로 코드 레벨에서 발생하는 부채 문제였습니다.
하지만 ML 시스템에선 데이터 의존성 문제가 더 큰 문제입니다. 게다가 더 발견하기 어렵습니다.
코드에 의한 의존성 부채는 정적 분석 Tool 등을 활용하여 제거할 수 있습니다. 하지만 데이터에 의한 의존성 부채는 아쉽게도 현재 이런 Tool들이 없습니다.
불안정한 데이터 의존성 (Unstable Data Dependencies)
종종 편리함에 다른 시스템으로부터 생성되는 시그널을 입력 데이터로 활용합니다.
하지만 일부 입력 신호는 불안정하여 시간지 지남에 따라 정성적 또는 정량적으로 값이 변경됩니다.
입력에 대한 엔지니어링 소유권과 일을 소비하는 모델의 엔지니어링 소유권이 다른 경우에도 명시적으로 발생합니다.
- 이 경우 입력 영역이 언제든지 업데이트될 수 있습니다. 입력 신호에 대한 개선조차도 소비 쪽에서는 이에 대한 진단 및 처리 비용이 많이 발생할 수 있는 유해한 영향을 줄 수 있으므로 매우 위험합니다.
- 예를 들어 이전에 사용하던 입력 신호가 잘못된 calibration을 사용한다는 것을 깨닫고 이를 보정했다고 생각해 봅시다. 하지만 이미 이를 소비하는 시스템은 잘못된 calibration에 적합하도록 구성되어 있으며 이를 수정 시 큰 영향을 미치게 됩니다.
이에 대한 보완 전략은 불완전한 데이터에 대한 버저닝(versioning) 관리입니다.
- 예를 들어, 주기적으로 변경되는 단어 주제 클러스터가 있다고 해봅시다.
- 시간이 지남에 따라 이를 변경되도록 구성하는 대신 고정된 버전을 작성하고 새로 업데이트될 버전을 완전히 검증한 뒤 이를 대체하는 것이 합리적일 수 있습니다.
- 물론 이러한 버전 관리는 내부적으로 부실하게 관리될 가능성이 있고 시간이 지남에 따라 동일한 신호 정보를 포함한 여러 버전을 만들어낼 수 있다는 단점이 있습니다.
즉, 동일한 정보를 가진 여러 클러스터가 생겨나더라도 이를 유지해야 하는 비용이 발생합니다.
활용도가 낮은 데이터에 대한 종속성 (Underutilized Data Dependencies)
코드 레벨에서 활용도가 낮은 종속성이 의미하는 것은 불필요한 패키지를 사용하는 것을 의미합니다.
데이터 관점에서 활용도가 낮은 종속성이란 모델링 관점에서 거의 이득이 없는 입력 신호를 의미합니다.
이로 인해 ML 시스템은 변경에 취약할 수 있으며 비록 큰 영향 없이 제거 가능할 지라도 큰 문제가 되는 경우가 있습니다.
- 예를 들어 제품 코드 체계를 관리하는 데 있어 이전 코드 체계에서 신규 체계로 전환을 가능하도록 기능을 제공하는 시스템이 있다고 해봅시다.
- 일단 신제품은 새로운 숫자 형태로 코드를 읽게 되지만 구형 제품은 두 정보가 존재할 가능성이 큽니다.
- 모델을 개발할 때 구형 코드를 피쳐로 활용하는 것으로 구현하는 것이 쉽습니다.
- 1년 후 구형 코드 방식은 폐기되고, ML 시스템 개발자에게는 악몽이 시작됩니다.
활용도가 낮은 데이터는 다음과 같이 발생합니다.
Legacy Features
이게 가장 흔한 경우인데 모델 개발 초기에 사용되다가 시간이 지남에 따라 다른 피쳐에 의해 중복된 정보를 내포하게 되는 경우입니다.
Bundled Features
때로는 마감 기한에 쫒겨 일단 피쳐를 다 때려 넣었더니 좋은 결과가 나온 경우입니다. 이 경우 모든 피쳐를 한 번에 추가하여 실제로는 불필요한 피쳐가 포함될 수 있습니다.
e-Features
ML 연구자들이 그러는 것처럼 실제로는 매우 적은 이득만을 주는 피쳐임에도 모두 다 모델에 포함을 시키는 경우입니다.
Correlated Features
종종 두 개의 피쳐가 강한 상관관계를 보이지만 그중 하나가 좀 더 직접적인 원인이 되는 경우입니다.
많은 ML 방법론들이 이를 구분하기가 어렵습니다. 그냥 둘 다 선택을 하거나 아니면 직접적인 원인 대신 다른 피쳐를 선택하게 되는 경우입니다.
활용도가 낮은 데이터에 대한 종속성을 파악하는 방법은 철저한 평가 후 판단될 수 있습니다.
불필요한 기능을 식별하고 제거하기 위해서는 정기적으로 이를 실행해서 확인해야 합니다.