본문으로 바로가기
본문으로 바로가기

머신 러닝

The machine learning data layer

머신 러닝 실무자의 시간 중 80%는 데이터를 정제하는 데 쓰인다는 이야기를 들어 본 적이 있을 것입니다. 이러한 이야기가 실제인지 여부와 상관없이, 처음부터 끝까지 머신 러닝 문제의 중심에는 언제나 데이터가 있다는 점은 변함이 없습니다. RAG 파이프라인을 구축하든, 파인튜닝을 수행하든, 자체 모델을 학습하든, 모델 성능을 평가하든, 각 문제의 근원에는 데이터가 있습니다.

데이터를 관리하는 일은 까다롭고, 그 결과 머신 러닝 데이터 문제의 특정 일부분을 해결해 생산성을 높이도록 설계된 도구들이 폭발적으로 늘어났습니다. 이러한 도구들은 종종 범용 솔루션 위에 구축된 추상화 계층의 형태를 띠며, 특정 하위 문제에 적용하기 더 쉽도록 보이게 하는, 다소 의견이 반영된 인터페이스를 제공합니다. 결과적으로 이는 특정 작업의 사용 편의성과 단순성을 위해, 범용 솔루션이 제공하는 유연성을 줄이는 방향으로 작용합니다.

이러한 접근 방식에는 몇 가지 단점이 있습니다. 일반적인 범용 솔루션과 이를 보조하는 애플리케이션 코드의 조합과 달리, 특화된 도구·제품·서비스를 연쇄적으로 도입하면, 필요 이상으로 아키텍처가 복잡해지고 데이터 비용이 증가할 위험이 있습니다. 각 단계를 위해 하나의 도구나 서비스만 사용하는 식으로, 끝이 없는 도구 목록을 갖게 되기 쉽습니다.

이러한 위험에는 두 가지 공통적인 측면이 있습니다:

  1. 학습, 유지 관리, 전환 비용

머신 러닝 아키텍처가 다양한 도구와 컴포넌트로 과도하게 복잡해지면, 학습하고 관리하기 어렵고 단편화된 환경이 조성되며, 장애 지점이 늘어나고 비용이 눈덩이처럼 불어납니다.

  1. 데이터 중복 및 전송 비용

머신 러닝 파이프라인에서 여러 개의 분리되어 있으면서도 영역이 겹치는 데이터 시스템을 사용하는 경우, 시스템 간에 데이터를 이리저리 옮기느라 불필요하고 종종 큰 비용이 드는 오버헤드가 발생할 수 있습니다.

이러한 절충 관계(trade-off)를 잘 보여 주는 예가 벡터 데이터베이스입니다. 벡터 데이터베이스는 벡터를 저장하고 검색하는, 매우 특정한 머신 러닝 작업을 위해 설계되었습니다. 일부 아키텍처에서는 올바른 선택일 수 있지만, 다른 아키텍처에서는 기술 스택에 불필요하게 새로운 구성요소를 추가하는 것일 수 있습니다. 통합·관리해야 하고, 데이터 입출력이 필요한 또 하나의 시스템이기 때문입니다. 대부분의 최신 범용 데이터베이스는 기본적으로(또는 플러그인을 통해) 벡터를 지원하며, 더 광범위하고 횡단적인 기능을 제공합니다. 다시 말해, 그런 아키텍처에서는 벡터를 처리하기 위해 굳이 새로운 데이터베이스를 도입할 필요가 없을 수 있습니다. 핵심은 벡터 전용 편의 기능(예: 내장 임베딩 모델)이 업무에 필수적인지, 그리고 그 비용을 감수할 가치가 있는지에 달려 있습니다.

데이터 탐색

머신러닝 문제, 목표, 그리고 성공 기준을 정의한 이후의 일반적인 첫 단계는 모델 학습과 평가에 사용될 관련 데이터를 탐색하는 것입니다.

이 단계에서 데이터는 그 특성, 분포, 그리고 관계를 이해하기 위해 분석됩니다. 이러한 평가와 이해 과정은 반복적인 성격을 가지며, 종종 데이터셋 전반에 걸쳐 여러 건의 애드혹 쿼리를 실행하게 됩니다. 이때 쿼리 응답성이 매우 중요하며, 그 외에도 비용 효율성, 정확도 등의 요소가 중요합니다. 기업이 머신러닝 목적을 위해 저장하는 데이터량이 증가함에 따라, 보유한 데이터를 살펴보는 일 자체가 점점 더 어려워집니다.

이는 분석 및 평가용 쿼리가 전통적인 데이터 시스템에서는 규모가 커질수록 지루할 정도로 느리거나, 아예 감당하기 어려울 정도로 느려지기 때문입니다. 일부 대형 서비스는 쿼리 시간을 줄이기 위해 상당히 높은 비용을 부과하며, 쿼리당 과금 또는 스캔한 바이트 수 기반 과금 방식으로 애드혹 평가를 사실상 억제하기도 합니다. 엔지니어는 이러한 제약을 우회하기 위해 데이터의 일부 하위 집합만을 로컬 머신으로 내려받아 작업하는 방식으로 타협할 수밖에 없습니다.

반면 ClickHouse는 실시간 데이터 웨어하우스로, 사용자는 분석 연산에 대해 업계 선도적인 쿼리 속도의 이점을 누릴 수 있습니다. 또한 ClickHouse는 초기부터 높은 성능을 제공하며, 중요한 쿼리 가속 기능을 더 높은 가격 티어 뒤에 숨기지 않습니다. ClickHouse는 Iceberg, Delta Lake, Hudi와 같은 일반적인 포맷을 지원하여, 객체 스토리지나 데이터 레이크에 있는 데이터에 직접 쿼리할 수도 있습니다. 이는 데이터가 어디에 존재하든 ClickHouse가 머신러닝 워크로드를 위한 통합 액세스 및 연산 계층 역할을 할 수 있음을 의미합니다.

ClickHouse는 또한 페타바이트 단위의 데이터까지 확장 가능한 다양한 미리 구현된 통계 및 집계 함수 모음을 제공하므로, 복잡한 연산을 수행하는 간단한 SQL을 쉽게 작성하고 유지 관리할 수 있습니다. 가장 세밀한 정밀도의 데이터 타입과 코덱을 지원하므로, 데이터의 세분성을 줄여야 할지에 대해 고민할 필요가 없습니다.

SQL 쿼리를 사용해 ClickHouse 내에서 직접 데이터를 변환하거나 삽입 이전에 변환을 수행할 수도 있지만, ClickHouse는 chDB를 통해 Python과 같은 프로그래밍 환경에서도 사용할 수 있습니다. 이를 통해 내장형 ClickHouse를 Python 모듈로 노출하여 노트북 환경에서 대용량 데이터 프레임을 변환하고 조작하는 데 활용할 수 있습니다. 데이터 엔지니어는 따라서 변환 작업을 클라이언트 측에서 수행하고, 그 결과를 중앙 집중식 ClickHouse 인스턴스의 피처 테이블(feature table)로 구체화하여 저장할 수 있습니다.

데이터 준비 및 특징 추출

그다음 데이터는 정제되고 변환되며, 모델을 학습하고 평가하는 데 사용될 특징을 추출하기 위해 준비됩니다. 이 구성 요소는 때때로 특징 생성(feature generation) 또는 특징 추출(feature extraction) 파이프라인이라고도 하며, 새로운 도구가 자주 도입되는 머신 러닝 데이터 계층의 또 다른 일부입니다. Neptune, Hopsworks 같은 MLOps 솔루션은 이러한 파이프라인을 오케스트레이션하는 데 사용되는 다양한 데이터 변환 제품들의 예시를 제공합니다. 그러나 이들은 실제로 동작하는 데이터베이스와는 분리된 도구이기 때문에 취약해지기 쉽고, 수동으로 수정해야 하는 중단을 유발할 수 있습니다.

반대로, 데이터 변환은 ClickHouse 내에서 직접 materialized views를 통해 손쉽게 수행할 수 있습니다. 이는 새로운 데이터가 ClickHouse 소스 테이블에 삽입될 때 자동으로 트리거되며, 도착하는 즉시 데이터를 추출·변환·수정하는 작업을 쉽게 수행할 수 있게 해 줍니다. 이로써 사용자가 개별 파이프라인을 직접 만들고 모니터링할 필요가 없어집니다. 이러한 변환에 메모리에 모두 담기 어려운 전체 데이터셋에 대한 집계가 필요할 때, ClickHouse를 활용하면 로컬 머신의 데이터 프레임으로 이 단계를 억지로 맞춰 동작시키려 애쓸 필요가 없습니다. 한편 로컬에서 평가하는 것이 더 편리한 데이터셋의 경우, ClickHouse localchDB는 Pandas 같은 표준 Python 데이터 라이브러리와 함께 ClickHouse를 활용할 수 있게 해 주는 훌륭한 대안입니다.

Training and evaluation

이 시점에서는 피처가 학습, 검증, 테스트 세트로 분할되어 있습니다. 이러한 데이터 세트는 버전 관리되며, 각 단계에서 활용됩니다.

파이프라인의 이 단계에서는 머신 러닝 데이터 레이어에 또 다른 특화 도구인 feature store를 도입하는 경우가 일반적입니다. feature store는 일반적으로 모델 학습, 추론, 평가를 위한 데이터 관리를 위해 특화된 편의 기능을 제공하는 데이터베이스 추상화 레이어입니다. 이러한 편의 기능의 예로는 버전 관리, 접근 제어, 그리고 피처 정의를 자동으로 SQL 문으로 변환하는 기능 등이 있습니다.

피처 스토어와 관련하여 ClickHouse는 다음과 같은 역할을 수행할 수 있습니다:

Data source - ClickHouse는 Iceberg 및 Delta Lake와 같은 데이터 레이크 포맷을 포함하여 70개가 넘는 서로 다른 파일 포맷의 데이터를 쿼리하거나 수집할 수 있으므로, 데이터를 장기적으로 보관하거나 쿼리하는 데 이상적인 저장소입니다. 객체 스토리지를 사용하여 스토리지와 컴퓨트를 분리함으로써, ClickHouse Cloud는 데이터를 무기한 보관하면서도 컴퓨트를 축소하거나 완전히 유휴 상태로 만들어 비용을 최소화할 수 있게 합니다. 유연한 코덱과 컬럼 지향 스토리지, 디스크 상의 데이터 정렬을 결합하여 압축률을 극대화함으로써 필요한 스토리지를 최소화합니다. 객체 스토리지 상의 데이터를 제자리에서 쿼리하기 위한 내장 함수를 사용하여 ClickHouse를 데이터 레이크와 손쉽게 결합할 수 있습니다.

Transformation engine - SQL은 데이터 변환을 선언하는 자연스러운 수단을 제공합니다. 여기에 ClickHouse의 분석 및 통계 함수를 결합하면 이러한 변환은 간결하면서도 최적화됩니다. ClickHouse가 데이터 저장소로 사용되는 경우 ClickHouse 테이블에 적용될 뿐만 아니라, 테이블 함수는 디스크나 객체 스토리지에 Parquet 등의 포맷으로 저장된 데이터, 또는 Postgres와 MySQL과 같은 다른 데이터 저장소에 저장된 데이터에 대해 SQL 쿼리를 작성할 수 있게 해줍니다. 완전 병렬화된 쿼리 실행 엔진과 컬럼 지향 스토리지 포맷이 결합되어, ClickHouse는 페타바이트(PB) 규모의 데이터에 대한 집계를 수 초 안에 수행할 수 있으며, 메모리 내 데이터 프레임에서 수행하는 변환과 달리 메모리 제약에서 비교적 자유롭습니다. 더 나아가, materialized view는 데이터가 삽입되는 시점에 데이터를 변환할 수 있게 하여, 쿼리 시점에서 데이터 적재 시점으로 연산 부하를 이전합니다. 이러한 뷰는 데이터 분석과 요약에 적합한 다양한 분석 및 통계 함수를 동일하게 활용할 수 있습니다. 기존 ClickHouse 분석 함수만으로는 부족하거나 커스텀 라이브러리를 통합해야 하는 경우, User Defined Functions (UDFs)를 활용할 수도 있습니다.

Offline feature store

Offline feature store는 모델 학습에 사용됩니다. 일반적으로 feature 자체는 (위 섹션에서 설명한 대로) 배치 처리 데이터 변환 파이프라인을 통해 생성되며, 이러한 feature의 가용성에 대해 엄격한 지연 시간 요구 사항이 없는 경우가 대부분입니다.

여러 소스에서 데이터를 읽고 SQL 쿼리를 통해 변환을 적용하는 기능을 통해, 이 쿼리의 결과를 INSERT INTO SELECT SQL 문을 사용해 ClickHouse에 영구 저장할 수 있습니다. 변환이 종종 엔터티 ID별로 그룹화되고 결과로 여러 개의 컬럼을 반환하므로, ClickHouse의 스키마 추론 기능은 이 결과에서 필요한 타입을 자동으로 감지하여 이를 저장하기 위한 적절한 테이블 스키마를 생성합니다. 난수 생성 및 통계 샘플링 함수는 데이터가 모델 학습 파이프라인에 공급될 수 있도록, 초당 수백만 행 규모로 데이터를 효율적으로 반복 처리하고 확장할 수 있게 해줍니다.

Feature는 종종 특정 시점에서 어떤 엔터티와 feature에 대한 값을 나타내는 타임스탬프를 포함한 테이블로 표현됩니다. 앞서 설명했듯이, 학습 파이프라인은 종종 특정 시점과 그룹별 feature 상태를 필요로 합니다. ClickHouse의 희소 인덱스는 시점 기반(point-in-time) 쿼리와 feature 선택 필터를 충족하기 위해 데이터를 빠르게 필터링할 수 있게 합니다. Spark, Redshift, BigQuery와 같은 다른 기술은 특정 시점에서 feature 상태를 식별하기 위해 느린 상태 유지 윈도우 방식에 의존하는 반면, ClickHouse는 ASOF (as-of-this-time) LEFT JOIN 쿼리와 argMax 함수를 지원합니다. 이 방식은 구문을 단순화할 뿐만 아니라, 정렬 및 병합 알고리즘을 사용하여 대규모 데이터셋에서도 매우 높은 성능을 제공합니다. 이를 통해 feature 그룹을 빠르게 구성할 수 있으며, 학습 이전 데이터 준비 시간을 줄일 수 있습니다.

Online feature store

온라인 feature store는 추론에 사용되는 최신 버전의 피처를 저장하고, 이를 실시간으로 적용하는 데 사용됩니다. 이는 이러한 피처가 실시간 머신 러닝 서비스의 일부로 사용되므로, 지연 시간을 최소화하여 계산해야 함을 의미합니다.

실시간 분석(real-time analytics) 데이터베이스인 ClickHouse는 낮은 지연 시간으로 매우 높은 동시성의 쿼리 워크로드를 처리할 수 있습니다. 이는 데이터가 일반적으로 비정규화되어야 함을 의미하지만, 이는 학습 시와 추론 시 모두 사용되는 피처 그룹의 저장 방식과 잘 맞습니다. 중요한 점은 ClickHouse가 로그 구조 머지 트리(log-structured merge tree)를 기반으로 높은 쓰기 워크로드 하에서도 이러한 쿼리 성능을 제공할 수 있다는 것입니다. 이러한 특성은 피처를 최신 상태로 유지해야 하는 온라인 스토어에 필수적입니다. 피처는 이미 오프라인 스토어에 존재하므로, 동일한 ClickHouse 클러스터 내에서나 remoteSecure 등의 기존 기능을 통해 다른 인스턴스의 새 테이블로 손쉽게 구체화(materialize)할 수 있습니다. 정확히 한 번만 처리되는(exactly-once) Kafka Connect 기능 또는 ClickHouse Cloud의 ClickPipes를 통한 Kafka 통합을 사용하면, 스트리밍 소스에서 스트리밍 데이터를 소비하는 작업도 간단하고 신뢰성 있게 수행할 수 있습니다.

많은 현대 시스템에서는 오프라인 스토어와 온라인 스토어가 모두 필요하며, 여기서 두 개의 특화된 feature store가 필요하다고 쉽게 결론 내리기 쉽습니다. 그러나 이렇게 하면 두 스토어를 동기화 상태로 유지해야 하는 추가적인 복잡성이 발생하며, 여기에는 두 스토어 간 데이터 복제 비용도 포함됩니다.

ClickHouse와 같은 실시간 데이터 웨어하우스는 오프라인 및 온라인 피처 관리를 모두 지원하는 단일 시스템입니다. ClickHouse는 스트리밍 데이터와 과거 데이터를 효율적으로 처리하며, 실시간 추론과 오프라인 학습을 위한 피처를 제공할 때 신뢰할 수 있는 무제한의 확장성, 성능, 동시성을 제공합니다.

이 단계에서 별도의 feature store 제품을 사용하는 것과 실시간 데이터 웨어하우스를 직접 활용하는 것 사이의 트레이드오프를 고려할 때, 버저닝과 같은 편의 기능은 테이블 또는 스키마 설계와 같은 오래된 데이터베이스 패러다임을 통해 구현할 수 있다는 점을 강조할 가치가 있습니다. 피처 정의를 SQL 문으로 변환하는 기능과 같은 다른 기능은, 제약이 많은 의견 기반의 추상화 계층에 두기보다는 애플리케이션 또는 비즈니스 로직의 일부로 두는 편이 더 큰 유연성을 제공할 수 있습니다.

추론

모델 추론은 학습된 모델을 실행하여 출력을 얻는 과정입니다. 추론이 데이터베이스 작업(예: 새 레코드 삽입 또는 레코드 쿼리)에 의해 트리거될 때, 추론 단계는 전용 잡이나 애플리케이션 코드로 관리할 수 있습니다.

반면 데이터 계층 자체에서 이를 관리할 수도 있습니다. ClickHouse User Defined Functions (UDFs)는 삽입 시점 또는 쿼리 시점에 ClickHouse에서 직접 모델을 호출할 수 있도록 합니다. 이를 통해 들어오는 데이터를 모델에 전달하고, 출력을 받은 뒤, 수집된 데이터와 함께 이 결과를 자동으로 저장할 수 있으며, 이 과정에서 별도의 프로세스나 잡을 따로 실행할 필요가 없습니다. 또한 이 단계를 관리하기 위한 단일 인터페이스로 SQL만 사용하면 됩니다.

벡터 스토어

벡터 스토어는 벡터를 저장하고 조회하는 데 최적화된 특정 유형의 데이터베이스로, 일반적으로 텍스트나 이미지와 같이 어떤 데이터 조각의 의미를 수치적으로 표현한 임베딩을 저장합니다. 벡터는 오늘날 생성형 AI 시대의 핵심에 있으며, 수많은 애플리케이션에서 사용됩니다.

벡터 데이터베이스의 기본 연산은 수학적 측정 기준에 따라 서로 가장 “가까운” 벡터를 찾는 「유사도 검색(similarity search)」입니다. 벡터 데이터베이스는 이러한 검사, 즉 벡터 비교를 가능한 한 빠르게 수행하도록 설계된 특정 기법을 사용하기 때문에 인기를 얻고 있습니다. 이러한 기법은 일반적으로 입력 벡터를 저장된 모든 벡터와 직접 비교하는 대신, 벡터 비교를 근사(approximate)하는 방식을 사용함을 의미합니다.

하지만 이러한 새로운 범주의 도구에는 한 가지 문제가 있습니다. ClickHouse를 포함한 많은 범용 데이터베이스가 기본으로 벡터를 지원하며, 종종 이러한 근사 접근 방식의 구현도 내장하고 있다는 점입니다. 특히 ClickHouse는 고성능 대규모 분석을 위해 설계되어, 비근사(non-approximate) 벡터 비교를 매우 효율적으로 수행할 수 있습니다. 이는 속도를 희생하지 않으면서 근사값에 의존할 필요 없이 정밀한 결과를 얻을 수 있음을 의미합니다.

관측성

머신 러닝 애플리케이션이 프로덕션에 배포되면 로그와 트레이스 데이터를 포함한 다양한 데이터를 생성하며, 이는 모델의 동작, 성능, 그리고 개선이 필요한 잠재적인 영역에 대한 유용한 통찰을 제공합니다.

SQL 기반 관측성은 ClickHouse의 또 다른 핵심 사용 사례이며, ClickHouse는 대안 대비 비용 효율성이 10~100배 뛰어난 것으로 알려져 있습니다. 실제로 많은 관측성 제품이 내부에서 ClickHouse를 기반으로 구축되어 있습니다. 최고 수준의 수집 속도와 압축 비율을 통해 ClickHouse는 어떤 규모에서도 머신 러닝 관측성을 구현할 수 있도록 높은 비용 효율성과 매우 빠른 속도를 제공합니다.