안녕하세요, 카카오뱅크 데이터기술팀 Logan입니다.

이 글에서는 제가 담당하고 있는 카카오뱅크 FDS(Fraud Detection System) 시스템에 어떻게 AI를 적용하였는지, 그 여정을 간략히 설명드리려 합니다.

FDS 시스템을 생소하게 느끼실 분들이 많을 것 같은데요. FDS를 풀어서 설명하자면, ‘Fraud Detection System’ 이라는 풀네임에서 알 수 있듯이 사기나 이상거래를 탐지하여 고객의 피해를 최소화하는 시스템이라고 할 수 있습니다. 고객의 안전한 금융생활이 무엇보다 중요한 저희 카카오뱅크에서는 자체적으로 FDS를 운영하고 있으며, 수많은 엔지니어와 분석가들이 참여하여 AI를 도입하고 시스템을 고도화하고 발전시키기 위해 노력하고 있습니다.

fds-system-architecture-image
FDS 시스템 아키텍처

FDS의 아키텍처에 대해 간단히 소개해드릴게요. 은행의 거래 데이터가 실시간 스트리밍으로 Kafka에 전달되면, FDS 엔진에서 이벤트 데이터를 변환하여 캐시 계층인 GridGain에 저장한 후 HBase로 영속화합니다. 그리고 고객 정보, 계좌 정보 등을 프로파일링 합니다.

뱅킹 시스템에서 리스크에 대한 평가 요청이 들어오면, FDS 엔진에서는 저장된 프로파일 데이터를 활용하여 FDS 탐지 규칙을 적용합니다. 이러한 Rule 기반 시스템에 대한 간단한 예시를 들어볼게요. 예를 들어 나이가 N살 이상이고 이체 금액이 M원 이상인 경우를 리스크로 파악하는 규칙이 있을 경우, 해당 건이 탐지가 되면 FDS 시스템 클라이언트 화면에 해당 문구가 표시되고, 추가로 영상통화를 통한 인증을 수행하는 흐름으로 이어집니다.

이렇게 고객과 계좌의 정보를 활용해 사기나 이상탐지를 잡아내는 중요한 역할을 하는 FDS 시스템은 기존에는 Rule을 기반으로 운영되었는데요, 여기에 AI를 적용하며 더욱 정교하게 감지할 수 있게 되었습니다.

그 이유를 Rule 기반 시스템의 한계ML(Machine Learning) 모형을 적용한 AI 기반 시스템의 장점을 중심으로 설명드리겠습니다.

FDS 시스템: Rule 기반 vs. AI 기반

Rule 기반 FDS 시스템의 한계

먼저, Rule 기반 FDS 시스템의 한계는 다음과 같습니다.

  1. 신규 사기 유형 대응의 어려움: Rule 기반 시스템은 사전에 정의된 규칙에 따라 동작하기 때문에, 예측하지 못한 상황에 대응하기 어렵습니다. 새로운 유형의 사기나 이상 거래가 발생하면, 이를 탐지하기 위해서는 신규 규칙을 새롭게 개발해야 하므로 빠르게 대응하기 어렵습니다.
  2. 지속적인 룰 개발의 어려움: 새로운 사기 패턴이나 이상 거래를 감지하기 위해서는 규칙을 지속적으로 업데이트해야 합니다. 하지만 규칙을 추가하려면 반드시 담당 부서와의 협의를 위한 커뮤니케이션이 필요하고, 관련 데이터를 추적 및 분석해야 하는 어려움이 있습니다.
  3. 사기유형 학습을 통한 회피: Rule 기반 시스템의 경우에는 사기꾼이 규칙을 이해하고 회피할 가능성이 있습니다. 예를 들어, 사기꾼이 규칙을 피하기 위해 여러 방면으로 시도하는 과정에서 FDS 시스템의 빈틈을 찾아 학습할 수 있습니다.

AI 기반 FDS 시스템의 장점

반면에 ML 모형을 적용한 AI 기반 FDS 시스템은 다음과 같은 장점이 있습니다.

  1. 유연성과 적응성: ML 모형은 데이터를 기반으로 패턴을 학습하고, 이를 통해 새로운 사기 패턴이나 이상 거래를 탐지할 수 있습니다. 따라서 ML 모형은 Rule 기반 시스템에서 예측하지 못한 상황에 대응할 수 있는 능력이 있으며, 학습을 통해 시스템이 자동으로 적응할 수 있습니다.
  2. 데이터의 활용: ML 모형이 적용된 FDS는 이미 수집된 다양한 데이터를 활용하여 학습할 수 있습니다. 예를 들어, 로그인 패턴, 이체 패턴, 이체 시간, 사용자의 성별, 직업 등을 종합적으로 고려하고 이를 활용하여 Rule 기반으로는 파악하기 어려운 패턴이나 행동을 탐지할 수 있습니다.
  3. 오탐률과 미탐률 개선: ML 모형을 적용함으로써 시스템의 오탐률과 미탐률을 개선시킬 수 있습니다. ML은 예측 모델을 통해 사기 거래를 사전에 탐지하는데, 이 과정에서 정밀도와 재현율 등의 성능 지표를 사용하여 모델의 성능을 평가하고 개선할 수 있습니다.
  4. 지속적인 성능 개선: ML 모형은 유입되는 데이터를 이용하여 예측 알고리즘을 지속적으로 학습시키며 성능을 개선해 나갈 수 있습니다. 기존 모델의 성능 모니터링을 통해 알고리즘을 업데이트하고, 이를 통해 사기 패턴이나 이상 거래를 더욱 정확하게 탐지할 수 있습니다.

AI 기반 FDS 시스템 개발의 어려움

데이터 엔지니어와 개발자의 관점에서 보면, AI를 적용하기 위해서는 몇 가지 난관을 극복해야 하는데요.

우선 AI를 적용하기 위해서는 데이터사이언티스트(Data Scientist, 이하 DS)와의 협업이 중요합니다. 협업 진행을 위해서는 전처리 알고리즘이 적용된 데이터를 DS에게 제공하는 것이 필요하고, 이를 구현하기 위해서는 DS에게 친숙한 Python으로 작성된 전처리 코드를 Java로 변환해야 합니다.

그런데, 데이터 엔지니어와 개발자들은 통상적으로 모델에 사용된 데이터와 알고리즘이 동작하는 방식을 DS처럼 이해하는데 한계가 있기 때문에, 협업을 위한 커뮤니케이션 비용이 증가하게 됩니다.

우리는 이런 불필요한 비용을 줄이기 위해 각자가 잘하는 부분에 집중해 보기로 하였습니다. DS분들은 이벤트 처리 부분에, 데이터 엔지니어와 개발자는 이벤트 엔지니어링 및 서빙 서버 개발에 집중하여 각자 작업하다가 필요할 때는 함께 모이는 과정을 반복하며 효율성을 높일 수 있었습니다.

또한, 저희는 3가지 단계를 통해 FDS 시스템에 AI를 적용했습니다.

  1. 데이터 실시간 파이프라인을 구축하여 이벤트 전처리
  2. 처리된 데이터는 재활용, 재학습 서빙에 활용하기 위해 Feature Store에 저장
  3. Feature Store를 활용하여 ML 모형을 서빙함으로써 고객에게 처리 결과를 제공

이때 데이터 실시간 파이프라인에서는 Kafka를 통해서 은행 데이터가 실시간으로 흐르게 만들었고, 이벤트 처리를 위해 DS가 전처리를 수행합니다. 전처리는 ML모형의 성능을 높이기 위해 꼭 필요한 작업으로, 데이터를 정제하고 필요한 데이터를 추가 및 제거하여 모형의 예측력에 더 도움이 될 수 있는 데이터 집합을 만들고 이를 숫자나 벡터로 변환하는 방식으로 작업을 수행합니다. 그리고 이런 전처리 결과는 Feature Store에 저장되며 ML 서빙과 추론에 활용됩니다.

이벤트 처리 시스템

이벤트 처리에는 Flink를 사용했습니다.

advantages-and-considerations-of-flink-image
데이터 실시간 파이프라인에서 이벤트 처리를 위해 사용한 Flink

Apache 오픈소스인 Flink는 실시간 처리에 적합한 Native stream이며, Java와 Python을 교차 지원하므로 비교적 쉽게 사용할 수 있다는 장점이 있습니다. 이러한 Flink를 사용하려면 몇 가지 고려해야 될 점들이 있는데요.

먼저, 개발된 시스템을 운영할 때 Session 모드와 Application Cluster 모드의 장단점을 고려하는 것은 중요합니다. Session 모드는 노드를 하나의 Cluster로 묶어 운영하므로 장애 전파 가능성이 높습니다. 반면에 Application Cluster 모드는 각각의 노드를 독립적으로 운영하기 때문에 장애 전파 가능성은 낮지만 여러 포인트들을 관리해야 하는 단점이 있습니다. 이러한 고려 사항을 바탕으로 적절한 모드를 선택해야 합니다.

또한, 체크포인트(Checkpoints) 는 중간중간에 저장하여 장애 발생 시 복원을 위한 기준점 역할을 합니다. 저장 공간을 사용하므로 저장 개수와 크기를 고려해야 합니다. 재시작 관련 설정도 영향을 받으므로 리소스 사용량을 고려하여 설정해야 합니다. 재시작 전략은 임계점 방식과 백오프 방식을 고려하여 설정해야 합니다.

다음으로, 노드 실패(Node Failure) 에 관련된 경우를 생각해 봅시다. 예를 들어 작업 노드가 3대일 때 2개 노드가 가득 차 있고 나머지 한 노드가 절반만 차 있는 경우, 절반만 차 있는 노드가 실패하면 나머지 두 노드로 작업이 이동됩니다. 그러나 나머지 노드에 이미 자원이 다 차있다면, 작업은 실행되지 않을 수 있습니다. 따라서 항상 노드의 가용성과 자원을 고려하여 운영해야 합니다.

마지막으로, 이벤트 처리한 데이터를 적절한 전처리 저장소에 저장하여 관리해야 합니다. 우리는 Flink를 통해 이벤트 처리 후 전처리 저장소에 저장합니다.

Feature Store

fds-feature-store-image
전처리된 데이터를 저장하는 Feature Store

이제 Feature Store에 대해서 말씀드리겠습니다. Feature Store는 앱 개발자나 DS가 모형을 학습시키거나 실제로 서빙하기 위해 사용하는 데이터 저장소입니다. 즉, 전처리된 데이터들을 저장하고, 이를 활용하여 모형을 학습하고 예측하는 데 사용되는 저장공간이죠. Feature Store를 사용함으로써 전처리 과정의 일관성을 유지할 수 있으며, 코드 관리도 편리해집니다. 또한, 다른 모형 개발이나 환경에서도 전처리 작업에 재활용할 수 있다는 장점이 있습니다.

Online Feature Store는 실시간성 데이터를 다루는 데 사용되며, 휘발성이 높고 업데이트가 자주 발생하는 특성을 가지고 있습니다. 이러한 특성으로 인해 우리는 고속 저장소가 적합한 Redis를 선정하였고, Redis를 사용함으로써 Feature Store의 데이터를 빠르게 저장하고 조회하는데 활용할 수 있었습니다.

Feature Store 키 설계하기

한편, Feature Store 목적에 맞는 데이터를 저장하기 위한 키 설계가 필요합니다.

제안된 키 설계 규칙은 다음과 같습니다.

CSTNO:{number}:XFEPE_X

   1. CSTNO: 고객번호를 의미합니다.
   2. XF: FDS에서 온 이벤트를 의미하는 키로, 이 값은 해당 이벤트가 FDS에서 온 것임을 나타냅니다.
   3. EPE: 이벤트명의 앞글자를 의미하며, 해당 이벤트가 ELFF(전기통신금융사기)에 관련된 것임을 나타냅니다.
   4. _H: 데이터가 해시 형식으로 저장된다는 의미입니다.

이러한 규칙을 통해 테이블 키만으로 어떤 피처가 들어가는지 유추할 수 있고, 피처 목록의 분류 및 검색에도 활용할 수 있습니다.

Real-Time Stream 시스템

Real-Time Stream 시스템의 아키텍처

real-time-stream-system-image
한눈에 보는 Real-Time Stream 시스템의 아키텍처

Real-Time Stream 시스템의 아키텍처에 대해서 설명드리겠습니다. 먼저, 은행 데이터가 SDA(Stream Data Adapter) 시스템으로 들어옵니다. SDA 시스템에서는 필요한 이벤트를 필터링하고, 암호화된 정보를 복호화하여 Kafka로 전달합니다. Kafka를 Flink가 구독하고, DS들은 이벤트를 통해 전처리 작업을 수행합니다. 전처리된 데이터가 다시 Kafka로 전달되면, Feature Store 핸들러는 Redis 형식에 맞게 키와 값을 가공하여 Redis에 제공합니다.

이렇게 구성된 Real-Time Stream 아키텍처는 개발자와 DS가 각자의 역할에 집중할 수 있도록 함으로써 업무 효율성을 향상시키기 위해 도입되었습니다. 데이터 엔지니어로서, DS분들이 이벤트 처리에 집중할 수 있도록 기반 시스템을 구축하기 위해 노력했습니다.

데이터 실시간 파이프라인의 이벤트 메시지 규약과 정의

데이터 실시간 파이프라인에서는 이벤트 메시지에 대한 규약과 정의가 필요합니다. 여기서 이벤트 메시지의 구조는 크게 ‘메타 정보(meta data)‘와 ‘페이로드(payload)‘로 구분됩니다.

  • 메타 정보는 UUID 값, 이벤트명, 버전, 그리고 UTC 프로세스 이벤트 시간(메시지 발행 시간)을 포함합니다.
  • 페이로드에는 전처리된 이벤트 데이터가 포함되어 있습니다. 이벤트 메시지 라이브러리를 제공하는 Java를 사용하여, 의존성을 받고 메시지를 손쉽게 사용할 수 있도록 하였습니다.

또한, Flink를 더 편하게 사용할 수 있도록 도와주는 자체 개발한 flink-dachery 라이브러리를 사용했는데요. 해당 라이브러리를 사용하면 Kafka의 발행과 구독 기능을 손쉽게 추가 가능하며, 설정 파일을 글로벌로 관리할 수 있고, 그 외 여러 유용한 유틸리티를 사용할 수 있습니다.

그리고, 사내 장애 알림 시스템과 연동하여 장애 보고가 자동으로 이루어질 수 있도록 구성하였습니다.

부분적인 배치 처리

지금까지 실시간 처리에 대해서만 말씀드렸는데요. 부분적인 배치 처리도 꼭 필요합니다.

FDS 시스템에는 실시간 처리가 필요하지 않은 데이터도 있습니다. 대표적으로 고객데이터는 자주 바뀌지 않는 데이터로, 실시간 처리보다는 배치를 통한 처리가 적합합니다. 우리는 이런 배치 처리를 위해 데이터웨어하우스에서 분석 클러스터로 데이터를 이동시키고, Apache Airflow를 활용하여 배치 처리를 수행합니다. 이렇게 24시간마다 고객 정보를 Redis에 저장하고 있습니다.

ML 서빙

ML 서빙의 4가지 요건

ML 서빙에 앞서, 저희가 선정한 ML 서빙의 4가지 요건을 설명드리면 다음과 같습니다.

  1. 200ms 미만 응답
  2. 분산 환경 고려: Kubernetes 및 AWS 환경을 고려하여 ML 서빙 시스템 설계
  3. 셀프서비스 가능: 개발자 리소스를 절약하기 위해 유용한 운영 툴을 활용
  4. JVM 기반 ML 추론: Java 언어를 사용하고 있으므로 JVM 기반 ML 추론이 가능한 라이브러리 선정

이러한 요건 선정의 연장선으로, 기술을 선정하는 데 있어 고려한 3가지를 말씀드리겠습니다.

첫 번째로 gRPC 사용을 고려했는데요. gRPC는 구글에서 만든 RPC 프로토콜로써, 직렬화가 빠르고 용량이 적다는 장점 때문에 네트워크 효율성을 높일 수 있습니다. ML 서빙 시스템이 확장될수록 gRPC가 더욱 빛을 발할 것으로 기대합니다.

두 번째로 Spring Cloud를 고려했습니다. Spring Cloud는 분산 환경에서 다양한 툴킷을 제공하여 개발을 용이하게 해주는 프레임워크입니다. 해당 스펙은 SpringBoot 3과 Java 1.17을 사용하며, Webflux를 기반으로 개발하고 있습니다.

마지막으로 JVM 기반으로 추론을 하기 위해 아마존이 개발한 DJL(Deep Java Library) 을 사용하기로 결정했습니다. 간단한 자체 리서치를 통해, DJL이 여러 라이브러리와 비교해서 성능이 더 뛰어나다는 결과를 얻을 수 있었습니다. 뿐만 아니라, DJL은 TensorFlow, ONNX, LightGBM, PyTorch 등과 호환되며, 실제 ML 성능 테스트 결과에서도 10ms 정도의 응답 속도를 보여주었습니다.

분산시스템은 Reactive하게!

reactive-system-structure-image
Reactive System의 구조 (참고: Reactive 선언문)

분산시스템 개발 컨셉으로 우리는 Reactive System을 채택하였습니다. 보다 자세한 내용은 Reactive 선언문을 통해 확인하실 수 있습니다.

응답성(Responsive)

  • 응답성을 지향한다는 것은 수단과 방법을 가리지 않고 응답이 이루어진다는 것을 의미하며, 유연성, 탄력성, 메시지 구동을 통해서 달성할 수 있습니다.

유연성(Elastic)

  • 시스템의 작업량의 변화에도 응답성이 유지되는 것을 유연성이라고 합니다. 이러한 유연성은 장애상황의 대응에도 연결될 수 있는데요. 예를 들어 Circuit breaker, Fail Back, Recovery, Retry, DLQ(Dead Letter Queue) 등의 메커니즘을 사용하여 장애상황에 적절히 대응할 수 있습니다.

탄력성(Resilient)

  • 탄력성은 시스템이 장애에 직면하더라도 응답성을 유지하는 것을 의미합니다. 이때 탄력성은 Scale Out과 Scale Up을 통해 달성할 수 있습니다. 예를 들어, Kubernetes와 같은 도구를 활용하여 On-premise 환경에서도 탄력성을 유지할 수 있습니다. 현재는 성능 테스트 및 예상 트래픽 추정을 통해 여유 장비를 확보해 두는 정도로 대응하고 있습니다만, 향후에는 좀 더 자동화된 도구를 활용하는 방식으로 개선할 예정입니다.

메시지 구동(Message Driven)

  • 메시지 구동은 MSA나 도메인 주도 설계(DDD, Domain Driven Design)와 관련이 있으며, 시스템 간 상호작용과 협력을 통해 역할과 책임을 분리합니다. 메시지 전달에는 Kafka, RPC 등 다양한 방법을 사용할 수 있으나, 비동기 Non-blocking 방식을 사용해야 합니다.

ML 서빙 분산 아키텍처

ml-serving-distributed-architecture-image
ML 서빙 분산 아키텍처의 구조

ML 서빙 분산 아키텍처는 다음과 같은 구성 요소를 가집니다.

  1. Discovery Server: On-premise 환경에서 서버의 위치 정보를 알기 위해 사용되며, 서버가 시작될 때 디스커버리 서버에 등록됩니다.
  2. Gateway Server: FDS 클라이언트에 동일한 URL을 제공하기 위해 사용됩니다. Routing 기능을 제공하여 Canary 배포를 할 수 있고, 필터 기능이나 인증 기능을 추가할 수 있습니다.
  3. Config Server: 분산환경에서 서버의 설정 정보를 중앙화하는 역할을 하며 오브젝트 스토리지를 활용하여 파일 다운로드 및 동적 파일 교체를 가능하게 합니다. Gateway Server의 Router 파일이나 서버의 앱 설정 파일과 같은 Config 옵션을 서버 재시작 없이 동적으로 변경할 수 있습니다.

ML 서빙은 Spring Cloud가 제공하는 대부분의 유틸 라이브러리들을 사용하여 분산환경에 대응하고 있습니다. 간단하게 흐름을 설명드리자면 FDS가 게이트웨이를 호출하고, Discovery Server를 통해 등록된 ML Server에서 ML 서빙을 수행합니다. ML Server는 Redis에 저장된 전처리된 정보를 활용하여 추론을 수행하고, 결과를 FDS 클라이언트에 제공합니다.

추가로, Config Server는 서버의 동기화 작업을 지원하며, Kafka를 통해 특정 서버나 그룹의 설정 정보를 동적으로 갱신할 수 있습니다.

모니터링

monitoring-tools-image
사용된 모니터링 툴

분산 시스템에서의 모니터링은 매우 중요합니다. 여러 대의 서버가 동작하다 보면 발생하는 문제들도 다양해지기 때문입니다. 우리는 현재 Kafka를 사용하여 설정 값과 기타 정보를 모니터링하고 있습니다.

또한 사내 장애 알림 시스템을 연동해서 사용하고 있는데요. 모든 서버에서는 Prometheus로부터 시간이 지남에 따라 변화하는 매트릭 데이터(예: 메모리 사용률, CPU 사용률 등)를 수집하고 있으며, Grafana를 통해 확인하고 있습니다. Zipkin은 네트워크 관찰 도구인 tracing을 사용하여 네트워크 성능 문제나 장애 발생 시 어떤 서버에 문제가 생긴 것인지 모니터링할 수 있습니다.

마무리하며

ML을 이용하여 FDS 시스템을 고도화하는 과정에는 많은 카뱅인들의 도움이 있었는데요. 프로젝트를 진행하며 부족한 리소스로 어려움을 겪기도 하였지만, 바쁜 가운데서도 해당 프로젝트를 아낌없이 지원해 주신 멋진 동료들 덕분에 더욱 완성도 높은 결과물을 낼 수 있었던 것 같습니다.

아직은 부족한 점이 많지만, ML모델 적용을 시도해 볼 수 있는 영역은 무궁무진합니다. 앞으로도 FDS 시스템처럼 같지만 다른 카카오뱅크만의 ML 모델이 적용된 AI 시스템을 구축하고 확장해 나가는데 기여하겠습니다.