10/17/2025

Whisper와 Pyannote를 이용한 Speech diarization



디지털 시대의 음성은 회의부터 콘텐츠, 고객센터 등 어디에나 존재하는 정보입니다. 그러나 이런 음성 데이터를 효과적으로 활용하는 것은 생각보다 어려운 과제입니다. 음성 데이터를 활용하기 위해 자동 음성 인식(ASR)과 음성 인식 기술을 활용하여 분석 가능한 구조화된 형식으로 변환합니다.

본 글에서는 로컬 환경에서 사용할 수 있는 OpenAI에서 개발한 음성 인식 모델인 Whisper와 오디오 파일에서 화자를 식별하는 음성 인식 솔루션인 Pyannote에 대해서 살펴 봅니다. 이 두 기술을 결합하여 화자별로 세분화된 정확한 필사본을 생성하는 방법과 주요 활용 분야를 살펴보겠습니다.


자동 음성 인식(ASR) 이해하기

자동 음성 인식(ASR)은 사람의 음성을 텍스트로 변환하는 기술입니다. 오디오 신호를 분석하고 발화 내용을 추출할 수 있는 모델을 기반으로 합니다. ASR은 청각 장애인 접근성 향상, 회의 또는 인터뷰 내용의 녹취, 오디오 및 비디오 콘텐츠 요약 및 색인 생성 등 다양한 분야에 활용됩니다. ASR의 효과는 음질, 억양, 배경 소음 등 여러 요인에 따라 달라집니다.

ASR은 몇 가지 주요 단계를 거칩니다.

  1. 전처리: 오디오 신호를 정리하여 배경 소음을 줄이고 녹음 품질을 개선한 후, 모델에서 사용할 수 있는 형식으로 변환합니다.
  2. 음향 모델링: 주파수와 진폭과 같은 음향적 특징을 오디오 신호에서 추출하여 음성 언어의 기본 단위인 음소를 식별합니다.
  3. 언어 모델링: 알고리즘은 탐지된 음소와 맥락 정보를 기반으로 확률이 높은 단어와 구문을 예측합니다.
  4. 디코딩 및 수정: 잠재적 오류와 언어적 맥락을 고려하여 최종본을 조정합니다.

OpenAI에서 개발한 Whisper는 매우 유명한 ASR 모델입니다. 방대한 다국어 데이터를 기반으로 학습되어 다양한 언어, 억양, 맥락에서 효과적으로 작동합니다.

장정 및 특징은 아래와 같습니다.

  • 높은 정확도: Whisper는 다양한 악센트와 소음이 많은 환경을 잘 처리하여 필사 품질을 향상 시킵니다.
  • 다국어 지원: 여러 언어를 지원하고 자동으로 필사본을 번역할 수 있습니다.
  • 자막 생성: 오디오 및 비디오 콘텐츠에 대한 동기화된 자막을 만들 수 있습니다.
  • 소음 저향성: 배경 소음에 대한 견고성으로 인해 실제 오디오 필사에 매우 효과적입니다.

제한된 데이터 세트에 대한 특정 학습이 필요한 기존 ASR 모델과 다르게, Whisper는 대규모 학습을 기반으로 하여 더 나은 일반화를 가능하게 합니다. 따라서 정확하고 고품질의 트랜스크립션이 필요한 곳에 강력한 도구가 될 수 있습니다.

Hugging Face Transformers 라이브러리를 사용하면 Whisper를 Python 애플리케이션에 쉽게 통합할 수 있습니다. 아래는 Whisper Large-v3-Turbo 모델을 기반으로 한 접근 방식입니다.

  1. 모델 로딩: WhisperAudioTranscriber가 초기화되고 하드웨어 가용성에 따라 컴퓨팅 장치 (GPU, MPS 또는 CPU)가 자동으로 구성됩니다.
  2. 모델 및 프로세서 준비: Whisper 모델과 관련 프로세서는 AutoModelForSpeechSeq25eq 를 사용하여 로드욉니다.
  3. 파이프라인 구성: 파이프라인은 오디오를 1초 중복으로 5초 단위로 분할하고 타임스탬프를 활성화하는 특정 매개변수로 설정됩니다.
  4. 오디오 파일 트랜스크립션: transcribe(audio_path) 메소드를 호출하면 트랜스크립션이 실행되고 연관된 타임스템프와 함께 텍스트가 반환됩니다.

아래는 이 접근 방식을 보여주는 코드입니다.

https://gist.github.com/giljae/6de980451e522e3f5a8e12113f622d92
import torch
from transformers import AutoModelForSpeechSeq2Seq, AutoProcessor, pipeline
class WhisperAudioTranscriber():
def __init__(self, model_name="openai/whisper-large-v3-turbo"):
# Configure the device for computation
if torch.cuda.is_available():
self.device = "cuda:0"
self.torch_dtype = torch.float16
elif torch.backends.mps.is_available():
self.device = "mps"
self.torch_dtype = torch.float16
else:
self.device = "cpu"
self.torch_dtype = torch.float32
# Load the model and processor
try:
self.model = AutoModelForSpeechSeq2Seq.from_pretrained(
model_name,
torch_dtype=self.torch_dtype,
low_cpu_mem_usage=True,
use_safetensors=True,
)
self.model.to(self.device)
self.processor = AutoProcessor.from_pretrained(model_name)
# Configure the pipeline for automatic speech recognition
self.pipe = pipeline(
"automatic-speech-recognition",
model=self.model,
tokenizer=self.processor.tokenizer,
feature_extractor=self.processor.feature_extractor,
torch_dtype=self.torch_dtype,
device=self.device,
return_timestamps=True,
generate_kwargs={"max_new_tokens": 400},
chunk_length_s=5,
stride_length_s=(1, 1),
)
except Exception as e:
raise
def transcribe(self, audio_path: str) -> tuple:
try:
# Perform transcription with timestamps
result = self.pipe(audio_path)
transcription = result['text']
timestamps = result['chunks']
return transcription, timestamps
except Exception as e:
return None, None

위 코드는 매개변수로 전달된 오디오 파일의 자동 트랜스크립션을 허용합니다. Whisper의 타임스펨프 기본 지원 기능은 오디오 세그먼트를 다른 도구와 쉽게 정렬할 수 있도록 하여, 대화에 대한 시간적 추적이 필요한 요건에 유용합니다.


Diarization: 화자 식별 하기

Diarization은 오디오 녹음을 분할하여 여러 화자를 식별하는데 사용되는 기술입니다. 대화를 구조화하고 "누가, 언제, 말하는가" 라는 질문에 답합니다.

화자 식별은 회의, 인터뷰, 전화, 영화 등 다양한 상황에서 유용합니다. 각 발화 부분을 해당 발화자와 연결하여 필사본의 가독성을 높이고 오디오 데이터의 심층 분석을 용이하게 합니다.

이 기법은 아래의 단계를 거칩니다.

  1. 세분화: 오디오는 화자 변경을 기준으로 더 작은 세그먼트로 나뉩니다.
  2. 특징 추출: 세그먼트를 분석하여 음향 매개변수(톤, 주파수, 강도)를 기반으로 고유한 음성 지문을 추출합니다.
  3. 식별: 일부 응용 프로그램에서는 음성 인식과 Diarization을 결합하여 각 화자에게 이름이나 역할을 부여할 수 있습니다.

일반적인 접근 방식은 신경망 기반 모델, 가우시안 혼합 모델(GMN), 스펙트럼 클러스터링과 같은 비지도 클러스터링 방법이 있습니다.

우리는 심층 신경망 모델을 활용하여 화자를 식별하는 Pyannote로 테스트를 진행합니다. 오디오 처리 파이프라인에 원활하게 통합되도록 설계되었고, 배경 소음이나 중복되는 음성을 포함된 오디오에서도 음성 분할 및 식별을 수행할 수 있습니다.

Pyannote는 아래의 특징을 지닙니다.

  • 정확도: Pyannote는 딥러닝을 활용하여 화자 감지를 합니다.
  • 적응성: 회의, 통화 등 다양한 유형에 사용할 수 있습니다.
  • 모듈성: Pyannote는 Whisper와 같은 도구와 완벽하게 통합되어 화자 식별이 가능합니다.
  • 호환성: 다양한 오디오 포맷을 지원하고, API 혹은 파이썬 스크립트를 통해 기존 애플리케이션에 통합할 수 있습니다.

Pyannote의 음성 분할 구현은 pyannote.audio 라이브러리를 사용하여 진행됩니다. 다음은 Pyannote Speaker Diarization 3.1 모델을 기반으로 한 접근 방식입니다.

  1. 모델 로링: 클래스 인스턴스느 ㄴHugging Face PyannoteDiarizer에서 분할 모델을 초기화하고 로드합니다.
  2. 분할 실행: diarize(audio_path) 메소드에서는 오디오 파일을 분석하여 서로 다른 화자를 식별하고 음성 기여도를 세분화합니다.

위 접근 방식을 구현한 코드는 아래와 같습니다.

https://gist.github.com/giljae/6de980451e522e3f5a8e12113f622d92

from pyannote.audio import Pipeline
from pyannote.audio.pipelines.utils.hook import ProgressHook
import torch
class PyannoteDiarizer:
def __init__(self, hf_token: str):
try:
self.pipeline = Pipeline.from_pretrained(
"pyannote/speaker-diarization-3.1",
use_auth_token=hf_token
)
self.device = torch.device("cuda" if torch.cuda.is_available() else "mps" if torch.backends.mps.is_available() else "cpu")
self.pipeline.to(self.device)
except Exception as e:
self.pipeline = None
def diarize(self, audio_path: str):
if self.pipeline is None:
return None
try:
with ProgressHook() as hook:
diarization = self.pipeline(audio_path, hook=hook)
return diarization
except Exception as e:
return None

위 코드는 오디오에서 화자를 세분화하여 Whisper에서 생성된 트랜스크립션을 해당 세그먼트에 맞추는 것을 더 쉽게 해줍니다.


오디오 세그먼트에 맞춰 트랜스크립션 정렬 하기

음성 텍스트 변환을 오디오 세그먼트에 맞추려면 변환된 각 단어나 구문을 해당 화자와 일치시켜야 합니다. 대화에서 중복, 중단 또는 독백 등은 이런 작업을 복잡하게 만들며, 변환 데이터와 화자 식별 간의 정확한 동기화를 요구합니다.

예를 들어서, Whisper는 타임스탬프가 포함된 대본을 생성합니다.

  • (0초에서 3초까지) 안녕하세요.
  • (3초에서 5초까지) 네 안녕하세요.

Pyannote는 아래와 같이 화자를 식별하고 오디오를 세분화 합니다.

  • SPEAKER_00: (0초에서 3초까지)
  • SPEAKER_01: (3초에서 5초까지)

정렬은 이런 정보를 병합하여 전사된 각 문장을 올바른 화자와 연결하고 대화를 정확하게 표현하는 것입니다.

이 단계를 정말 중요합니다. 그 이유는 아래와 같습니다.

  1. 향상된 이해력: 적절하게 정렬된 트랜스크립션은 누가 언제 말하는지 명확하게 식별합니다. 여러 사람이 대화하는 경우 텍스트를 더 이해하기 쉽게 만듭니다.
  2. 동기화된 자막 생성: 정확한 정렬은 일관된 자막을 만들고 접근성과 사용자 경험을 개선하는데 중요합니다. (비디오 서비스)
  3. 쉬운 인덱싱 및 검색: 잘 세분화된 텍스트를 통해 특정 화자나 대화의 특정 부분을 검색할 수 있어 미디어 분석에 유용합니다.
  4. 대화 분석 및 상호작용 추적: 정렬은 참가자 간의 대화 방향, 방해, 교환을 식별하여 토론의 역학을 더 잘 이해하는데 도움이 됩니다.
  5. 최적화된 자동 회의 요약: 회의나 컨퍼런스와 같은 전문적인 환경에서, 필사본을 오디오 세그먼트에 정확하게 연결하면 체계적이고 유용한 보고서를 쉽게 생성할 수 있습니다.

오디오 세그먼트에 맞춰 트랜스크립션을 정렬하는 것은 단순히 시간을 맞추는 것을 넘어 오디오 데이터를 효과적으로 활용하고 향상시키는데 중요한 역할을 합니다.

생각해보면 간단해 보일 수 있지만, 음성 텍스트와 오디오 세그먼트를 정렬하는 작업은 복잡하며, 자동 음성 인식(Whisper)과 화자 분류(Pyannote) 데이터를 병합하는데 필요합니다. 목표는 정확한 타임스탬프를 유지하면서 각 테스트 세그먼트를 해당 화자에게 할당하는 것입니다.

정렬은 Whisper가 제공한 세그먼트와 Pyannote가 감지한 세그먼트 간의 시간 교차 접근법으로 진행합니다.

  1. 전사 및 이중화 세그먼트 추출
    1. Whisper는 연관된 타임스탬프가 있는 세그먼트로 나뉜 트랜스크립션을 생성합니다.
    2. Pyannote는 오디오를 분할하고 각 시간 간격에 스피커 식별자를 할당합니다.
  2. 화자와 일치하는 전사 세그먼트
    1. Whisper에서 생성된 각 세그먼트에 대해 Pyannote에서 가장 잘 대응하는 세그먼트 식별
    2. 전사 세그먼트와 감지된 화자 세그먼트 간의 가장 큰 시간적 중복을 기반으로 합니다.
  3. 특수 사례 처리
    1. 전사 세그먼트 분할시 정의된 범위를 넘으면 마지막으로 감지된 세그먼트의 끝을 고려하여 정렬을 조정
    2. 여러 화자가 겹치는 경우, 알고리즘은 전사 세그먼트와 가장 긴 교차 기간을 가진 화자를 선택
  4. 동일한 스피커의 연속 세그먼트 병합
    1. 동일한 화자 속하는 연속된 세그먼트는 과도한 텍스트 단편화를 피하기 위해 병합됩니다.

위의 접근법을 파이썬으로 구현합니다.

  • 각 요소 화자, 시작 및 종료 타임스탬프, 해당 텍스트가 align() 목록을 반환합니다.
  • find_best_match() 는 주어진 전사 세그먼트와 시간적으로 가장 많이 중복되는 전사 세그먼트를 검색합니다.
  • merge_consecutive_segments()는 동일한 화자에 속하는 인접한 세그먼트를 병합하여 정렬된 트랜스스크립션의 일관성을 개선합니다.

class SpeakerAligner():
def align(self, transcription, timestamps, diarization):
speaker_transcriptions = []
# Find the end time of the last segment in diarization
last_diarization_end = self.get_last_segment(diarization).end
for chunk in timestamps:
chunk_start = chunk['timestamp'][0]
chunk_end = chunk['timestamp'][1]
segment_text = chunk['text']
# Handle the case where chunk_end is None
if chunk_end is None:
# Use the end of the last diarization segment as the default end time
chunk_end = last_diarization_end if last_diarization_end is not None else chunk_start
# Find the best matching speaker segment
best_match = self.find_best_match(diarization, chunk_start, chunk_end)
if best_match:
speaker = best_match[2] # Extract the speaker label
speaker_transcriptions.append((speaker, chunk_start, chunk_end, segment_text))
# Merge consecutive segments of the same speaker
speaker_transcriptions = self.merge_consecutive_segments(speaker_transcriptions)
return speaker_transcriptions
def find_best_match(self, diarization, start_time, end_time):
best_match = None
max_intersection = 0
for turn, _, speaker in diarization.itertracks(yield_label=True):
turn_start = turn.start
turn_end = turn.end
# Calculate intersection manually
intersection_start = max(start_time, turn_start)
intersection_end = min(end_time, turn_end)
if intersection_start < intersection_end:
intersection_length = intersection_end - intersection_start
if intersection_length > max_intersection:
max_intersection = intersection_length
best_match = (turn_start, turn_end, speaker)
return best_match
def merge_consecutive_segments(self, segments):
merged_segments = []
previous_segment = None
for segment in segments:
if previous_segment is None:
previous_segment = segment
else:
if segment[0] == previous_segment[0]:
# Merge segments of the same speaker that are consecutive
previous_segment = (
previous_segment[0],
previous_segment[1],
segment[2],
previous_segment[3] + segment[3]
)
else:
merged_segments.append(previous_segment)
previous_segment = segment
if previous_segment:
merged_segments.append(previous_segment)
return merged_segments
def get_last_segment(self, annotation):
last_segment = None
for segment in annotation.itersegments():
last_segment = segment
return last_segment


잠재적 활용

이렇게 해서 나온 결과물은 LLM에서 활용할 수 있는 형식으로 분석, 색인 및 구조화를 용이하게 하여 오디오 및 비디오 콘텐츠를 효율적으로 활용할 수 있게 합니다.

저의 경우는 현재 고객 서비스 전화 통화를 분석하여 사용자 만족도 및 대응 서비스 품질 그리고 고객 인사이트를 파악하려고 합니다. 이 부분은 감정 분석 영역이며 다음과 같은 이점이 있습니다.

  • 키워드와 긍정적 또는 부정적 표현을 식별
  • 각 통화에 만족도 점수 부여 가능
  • 주의가 필요한 전화는 관리자에게 표시

위 케이스외에도 다양한 분야에 활용이 가능합니다.

  • 청각 장애인을 위한 접근성
  • 콘텐츠 인덱싱 및 검색
  • 자동 번역
  • 음성 지원 기능 개선

LLM의 등장으로 음성 정보를 텍스트 형식으로 변환하는 것은 대규모 처리, 분석 및 활용에 필수적인 요소가 되었습니다.

끝으로, 음성 인식과 화자 분류 기술이 발전했음에도 여전히 몇 가지 과제가 남아 있습니다. 어려운 점은 다음과 같습니다.

  • 배경 소음 및 소리 장애: 시끄러운 환경에서는 음성 신호가 왜곡되기에 정확도가 떨어질 수 있습니다.
  • 액센트와 언어적 변형: ASR 모델은 신뢰도에 영향을 줄 수 있는 광범위한 액센트의 사투리를 이해할 수 있어야 합니다.
  • 중복된 말투: 여러 화자가 동시에 말할 때, 음성을 구분하는데 어려움을 겪습니다. 때로는 문장의 일부를 잘못된 화자에게 매칭합니다.
  • 긴 대화에서 화자 인식: 긴 대화에서 같은 화자에게 세그먼트를 할당하면 일관성을 잃을 수 있습니다. 특히 억양이 바뀌거나 맥락이 바뀔 때 그렇습니다.

ASR 및 Diarization 기술은 언제가는 지금보다 효율성과 정확성을 향상시킬 것이라고 생각합니다. 아마 아래의 영역이 개선되지 않을까 합니다.

  • 액센트와 배경 소음 처리
  • 더 나은 맥락적 이해를 위한 ASR + LLM 융합
  • 임베디드 및 모바일 시스템에 배포 가능한 최적화
  • 더욱 견고한 다국어 모델
  • 실시간 상호작용 및 AI의 대화 참여

Whisper와 Pyannote를 함께 사용하면 화자별 분할이 가능하기에 다양한 상황에서 유용하게 활용할 수 있습니다. 로컬 배포 또는 IDC에서 사용하면 데이터 기밀성이 더욱 강화될 것입니다.

포크 받은 코드는 https://github.com/monocleface/EchoInStone에 올려두었습니다. 아직 정확도가 높진 않습니다. 차근차근 해결해야 할 것 같아요.

10/16/2025

Pyenv vs. uv

이제까지 블로그에 글을 작성할때는 평어체를 사용했었다. 경어체? 평어체? 고민이 많았는데., 본 글부터는 경어체를 사용할 생각이다.

파이썬 개발자는 다양한 프로젝트에서 여러 파이썬 버전을 사용할 경우가 자주 발생합니다. 이런 상황을 해결하기 위해서는 크게 두 가지 도구가 있습니다. pyenvuv 입니다. 본 글에서는 각 도구들의 접근 방식을 이해하고 어떤 도구를 사용해야 할지 결정을 내리는데 도움을 주고자 합니다.

디자인 철학

pyenv

pyenv는 "한 가지 일만 잘하자"라는 유닉스 원칙을 계승합니다. 해당 도구의 목적은 파이썬 인터프리터 설치 및 버전 전환을 관리하는 것입니다. 파이썬 버전을 선택한 후, 개발자는 pip 및 venv와 같은 익숙한 도구를 사용하여 패키지 관리 및 파이썬 가상 환경을 구축할 수 있습니다.

pyenv는 파이썬 명령을 가로채서 활성화되어 있는 파이썬 버전으로 자동 전달하는 shell shims을 통해 동작합니다.

uv

uv는 파이썬 버전 관리를 통합된 개발 툴킷으로 제공함으로써 근본적으로 다른 접근 방식을 취합니다. 단순히 인터프리터를 관리하는 것이 아니라 단일 인터페이스를 통해 설치, 환경 생성, 종속성 해결 및 패키지 관리 등을 처리합니다.

uv는 유닉스 방식의 철합보다 워크플로우를 통합하여 편의성과 성능을 우선시합니다.

설치 및 플랫폼 지원

크로스 플랫폼

pyrnv는 Unix 계열 시스템용으로 설계되었기에 Linux와 MacOS에서 잘 동작됩니다. 그러나 Windows 지원을 위해서는 pyenv-win이 필요합니다. 기능적으로는 같게 동작되지만, 플랫폼에 따라 동작 및 유지 관리 측면에서 차이가 발생하게 됩니다.

반면, uv는 처음부터 크로스 플랫폼 도구로 개발되었습니다. Windows, macOS, Linux에서 동일한 명령어가 동일하게 작동합니다. 플랫폼별 조정이나 별도의 설명서가 필요하지 않습니다.

Python 설치 방법

pyenv는 소스 코드로부터 컴파일하여 파이썬을 설치합니다. 이 방식은 유연성이 좋지만, 빌드 도구가 필요하고 시간이 소요됩니다. 시스템 종속성이 누락되면 컴파일이 실패할 수 있습니다.
uv는 미리 빌드된 파이썬 바이너리를 다운로드 합니다. 설치 속도가 빠릅니다.

버전 선택

pyenv

pyenv는 파이썬 명령어를 가로채기 위해 셀 환경을 수정합니다. pyenv local 3.11을 입력하면 해당 디렉토리의 파이썬 3.11이 자동으로 사용됩니다. 따라서 기존 스크립트와 워크플로우 수정 없이 동작됩니다.

uv

uv는 명확한 접근 방식을 취합니다. 파이썬 버전을 설치한다고 해서 자동으로 실행되는 것이 아닙니다. 아래중 하나를 수행해야 합니다.
  • uv run python 또는 uv run script.py
  • 생성된 가상 환경 활성화
명시적으로 요청하지 않는 한 uv가 파이썬에 간섭하는 것을 방지하지만, 워크플로우 조정이 필요합니다.

워크플로우 영향도

pyenv와 uv 중 어떤 것을 선택하느냐에 따라 개발 관행이 달라집니다.

pyenv를 사용한 워크플로우

  1. 필요한 Python 버전을 설치: pyenv install 3.12
  2. 프로젝트 버전 설정: pyenv local 3.12
  3. 가상 환경 생성: python -m venv .venv
  4. 환경 활성화: source .venv/bin/activate
  5. 종속성 설치: pip install -r requirements.txt

uv를 사용한 워크플로우

  1. 프로젝트 초기화: uv init
  2. 종속성 추가: uv add requests pandas
  3. 실행 코드: uv run script.py

상황별 선택 기준

pyenv 선택 상황

  • 주로 Unix 계열 시스템에서 작업
  • 기존 워크플로우와 통합되는 도구를 선호할 때
  • 파이썬 컴파일 및 사용자 정의에 대한 제어가 필요할 때
  • 전체 툴체인을 변경하는 것이 불가능한 환경에서 작업할 때

uv 선택 상황

  • 윈도우즈를 포함한 여러 플랫폼에서 작업
  • 빠른 속도를 원할 때 (환경 설정 및 패키지 설치)
  • 통합 툴킷 채택이 가능한 새로운 프로젝트
  • 여러 도구를 단일 인터페이스로 통합할 때

어떤 도구가 적합할까요?

10/13/2025

허깅페이스(Hugging Face)란?

AI에 조금이라도 관심이 있다면 허깅페이스(Hugging Face)에 대해 들어봤을것이다. 오늘은 허깅페이스에 대해서 알아보자.

허깅페이스는 자연어 처리(NLP) 및 머신러닝(ML) 분야의 기술을 발전시키기 위한 오픈소스 플랫폼이자 커뮤니티이다. 개발자와 연구자가 머신러닝 전문 지식 없이도 고급 AI 모델을 구축하고 미세 조정할 수 있도록 라이브러리, 모델, 데이터세트 및 도구등으로 구성된 생태계를 제공하고 공유하는 공간이다. AI와 관련된 모든 것을 아우르는 허브라고 생각하면 되지만, 조금 다른 점이 존재한다. 바로 협업과 개방성을 기반으로 구축되었다는 점이다.

2016년 챗봇 회사로 설립된 허깅페이스는 처음엔 대화형 AI에 집중했다. 그러다가 트랜스포머의 잠재력을 알게되고 자연어 처리 도구와 라이브러리 개발레 집중하게되었다.

허깅페이스는 사전 훈련된 방대한 모델과 데이터세트 저장소로 알려져 있다. 클라우드 기반 플랫폼인 허깅페이스 허브는 90만개 이상의 사전 훈련된 모델과 9만개 이상의 데이터세트를 보유하고 있다. 이 리소스는 누구나 무료로 사용할 수 있기에 AI 실무자들에게는 꼭 필요한 자료이다. 자연어 처리부터 컴퓨터 비전 그리고 기타 AI 관련 작업을 수행할 때 유용한 정보를 찾을 수 있다.

허깅페이스의 가장 큰 특징은 Transformer 라이브러리이다. 이 라이브러리는 BERT, GPT 등과 같은 고급 모델의 구현을 제공한다. 이 라이브러리를 이용해서 프로젝트를 진행할 경우 많은 시간을 절약할 수 있다. 모델을 처음부터 구축하는 대신, 다른 사람들의 작업을 활용하여 특정 요구에 맞게 모델을 미세 조정하는데 집중할 수 있다.

그외에 사용자가 머신러닝 애플리케이션을 제작, 배포 및 시연할 수 있는 Space 기능도 제공한다. Space는 개발자가 데모를 쉽게 제작하고 다른 사용자와 작업을 공유할 수 있도록 해준다. 특히 프로젝트에 대한 협업이나 피드백이 필요할 때 유용하다.

허깅페이스의 가장 큰 이점은 커뮤니티와 오픈소스 협업이다. AI 개발의 민주화라는 신념으로 플랫폼이 구축되었기에 최첨단 도구와 리소스를 전 세계 사용자에게 제공함으로써 공정한 경쟁의 장을 조성하는데 기여하고 있다. 노련한 연구자 혹은 취미로 하는 사람이든 누구나 동일한 도구를 활용하고 동일한 프로젝트에 기여할 수 있다.

자, 그럼 허깅페이스를 어떻게 사용해야 할까?

우선 수천 개의 모델과 데이터 세트를 찾을 수 있는 허깅페이스 허브를 검색하는 것이다. 예를 들어서 오픈 소스 언어 모델을 다운로드하여 로컬 PC에서 실행할 수 있다.

처음에는 Transformers 라이브러리만 사용했지만, 현재는 다른 기능도 사용중이다.

  • Transformers: 모든 모델에 접근할 수 있는 Python 라이브러리이다. 몇 줄의 코드만 작성하면 강력한 결과를 얻을 수 있다.
  • Model Hub: 바로 사용 가능한 AI 모델의 거대한 온라인 카탈로그이다. "summarization", "translation" 과 같은 작업을 검색하면 효과적인 모델을 찾을 수 있다.
  • Space: 데모를 완성하고 다른 사람들에게 보여주고 싶다면, Space를 사용하면 공유 가능한 웹앱으로 만들 수 있다. 복잡한 배포나 백엔드 설정 없이 업로드하고 실행만 하면 된다.
  • AutoTrain: 나의 데이터를 기반으로 모델을 미세 조정할 때 유용하다. 훈련 코드를 직접 작성할 필요없이, 모든 것을 자동으로 처리해준다.

허깅페이스는 단순한 플랫폼이 아니라 커뮤니티이다. 사람들이 모여 아이디어를 공유하고, 프로젝트를 함께 하며, AI의 한계를 뛰어넘는 공간이다.

아직 참여하지 않았다면, 바로 참여해보자! => https://huggingface.co/

 



9/18/2025

Text to SQL이 왜 잘 안될까?

LLM(Large Language Model)의 등장으로 데이터 접근 방식도 변해야 한다고 생각한다. 데이터베이스 분야외에 다른 분야는 LLM을 위한 변화가 이미 시작되었다.

프론트엔드 관점에서는 Perplexity, GPT 검색과 같은 AI 에이전트 및 스크래퍼를 지원하기 위해 명확한 제목, 구조화된 섹션, 풍부한 스니펫을 통해 "LLM 검색"이 가능하도록 설계되어가고 있다.

AI가 콘텐츠를 더 효과적으로 요약, 추출을 할 수 있게 하기 위함이다.

백엔드 관점에서는 백엔드에서 만들어지는 API 디자인은 AI 에이전트가 분석하고 사용할 수 있도록 명확한 주소와 메타데이터를 갖춘 MCP과 같은 프로토콜로 전환되고 있다.

프론트엔드, 백엔드를 지나 이제 데이터베이스의 차례이다.


레거시 데이터베이스에서 작업한 경험이 있으신 분들은 아마 알고 있을 것이다. 데이터베이스는 자가 설명적이지 않다. 데이터베이스의 스키마를 보고 무엇을 의미하는지 알기가 어렵다.

Fullname이라면 유추할 수 있지만, 축약어를 사용한다면 더더욱 판단하기가 어렵다.

예를 들어, order라는 테이블이 있다고 하면 이 테이블이 고객의 주문서를 담고 있는 것인지, 구매 주문서인지 이름만 봐서는 판단하기 어렵다. 이는 데이터베이스가 안고 있는 오래된 문제이다.

이제는 LLM이 데이터베이스에서 제공하는 맥락만으로 데이터에 대한 이해를 해야 한다. 사람도 헷갈리는데 혼란스럽지 않을까?

여기서 "Text to SQL"의 허점이 발생한다. 지금은 사용자가 자연어를 사용하여 데이터를 뽑는 시대가 열리고 있다.

"지난 분기 각 매장의 총 수익을 보여주세요." 라고 질문을 하면,

위에 맞는 적절한 SQL 쿼리를 실행하고 그 결과를 차트에 표시해야 한다. 이런 상황을 고려하지 않은 LLM 태생 이전에 디자인한 데이터베이스로 이 질문에 대한 정확한 SQL을 만들 수 있을까?

생각보다 이 문제는 어려운 문제이다.

누군가는 이렇게 얘기할 수 있다. LLM에 데이터베이스의 전체 스키마를 전달하고, SQL 쿼리를 생성하도록 요청하면 되지 않느냐고...

테이블 이름, 컬럼명 그리고 관계에 대한 정보가 있어도 LLM은 사용자의 질문에 정확하게 답변하는 SQL쿼리를 생성하지 못할 수 있다. 

대부분의 데이터베이스 스키마에서 테이블과 컬럼명은 그 자체로 설명적이지 않기 때문이다. 때로는 개발자 조차도 스키마 이해에 어려움을 겪기 때문에 AI가 이해할 수 있을 것이라고 기대할 순 없다.

위에서 언급한 대로 고객 주문과 구매 주문이 각각 어떤 테이블에 있는지 이해하지 못하면 파악할 수 없다. 이 상황은 데이터베이스가 클수록 상황은 더 나빠진다.

일반적인 코드 생성 문제와는 달리 이 문제는 단순하게 텍스트 설명에서 코드를 생성하는 것 이상이다. 모델은 데이터베이스 구조, 데이터 유형, 테이블 간의 관계 등을 알고 있어야 하기 때문이다.

비즈니스의 전문화된 용어를 데이터베이스의 구조로 번역하는 방법에 대해 모델을 훈련시켜야 할 수 도 있다. 모델이 전반적인 비즈니스를 이해하고, 데이터 구조를 이해한 상태에서 사용자의 질문에 답할 수 있어야 하는 경우가 대부분이기 때문이다.

어떤 상황에서 LLM이 힘들어하는지 살펴보자.

LLM은 필드 이름의 의미가 중요하다. 이름이 모호하면 추측하게 되고, 잘못된 이해를 할 수 있다. 예를 들어 "가치"라는 필드가 있으면, 이 필드는 "원화"라는 의미도 담고 있어야 한다. "가치_원" 으로 표현되어야 LLM이 이해할 수 있을 것이다.

일관된 데이터 형식도 중요하다.
"구매날짜 = 2025-09-18"
"주문날짜 = 2025/09/18"

위 처럼 데이터 형식이 서로 다르면, 일관된 형태로 답을 하기가 어렵다.

그리고 회사내부에서 사용하는 용어, 지표, 명명 규칙을 LLM은 알지 못한다.

1. 재구매 고객: 최소 3개월 이상 구매한 고객
2. 이탈 고객: 3개월 이상 로그인을 안한 고객

회사내에서는 위 용어에 대해 정의를 내렸지만, 데이터베이스에서는 해당 데이터가 존재하지 않는다. 여러 데이터를 기반으로 애플리케이션 계층에서 계산을 해야 하기 때문이다.

이럴 경우 LLM은 추론할 수 없다. 이런 용어의 논리를 명확하게 정리하지 않으면, LLM은 올바른 의견을 낼 수 없다.

반면, LLM의 등장 이전에 우리가 해왔던 것들을 생각해보자.

이전 에도 작성했지만, SQL과 코드에서 필드 이름을 축약어를 선호했기에 짧은 이름을 주로 사용한다. 가독성보다 최적화를 선택했다.

여러가지 이유, 제약이 있을테고, 이는 타당한 엔지니어링 결정일 수 있지만 스키마를 의미적으로 추론하기 어렵게 만든 것은 사실이다.

그럼 우리는 앞으로 어떻게 해야 할까?

MCP 스타일 표준 관점에서 접근을 해야 할 것이다. 기계가 이해할 수 있는 친화적인 스키마 설계가 필요하다.

즉, 데이터베이스를 설계하는 방식에 변화가 필요하다. 아래처럼 우선 시작해봐야하지 않을까?

  • 설명이 드러나는 명확한 이름과 일관된 형식 사용
  • 의미론적 관계를 반영
  • 기계가 이해할 수 있는 메타데이터 추가
  • 컨텍스트가 저장된 벡터DB를 이용한 추론

끝으로, Text to SQL에서 질의에 대한 답이 이상하다면, LLM의 문제로 바라볼 것이 아니라. 스키마 설계를 의심해야 한다. 우리는 LLM을 염두해서 설계하지 않았기 때문이다.

Text to SQL에서 정확도를 높이려면 시스템이 접근할 수 있는 정보의 범위를 좁히는 것도 중요하다. 성공적인 Agent는 엄격한 범위 설정이 중요하다. 정확성이 입증된 후에만 확대하는 것이 효과적이다.

다음 글에서는 스키마 설계에 대한 부분을 다룰 생각이다.

9/02/2025

사람들은 AI로 분류된 제품을 싫어한다.


포스팅 제목이 자극적이라고 생각할 수 있지만, 내가 한 말은 아니기에 오해 마시라.

흥미로운 연구 논문이 있다. 워싱턴 주립대와 템플 대학교의 연구원들은 제품에 AI 기능을 추가했을 때의 효과에 대한 연구를 발표했다. 

100명의 참여자로 구성된 두 개의 그룹을 만들고, 가상 광고를 이용하여 "AI" 가 붙은 제품이나 "AI 기반" 제품을 구매할 의향이 더 높은지, 아니면 "첨단 기술"이나 "신기술"이 붙은 제품을 구매할 의향이 더 높은지를 측정했다.

"AI 관련 문구를 본 그룹은 다른 그룹에 비해 광고 된 제품이나 서비스를 사용/구매하거나 적극적으로 찾고 싶은 가능성이 낮았다."

특히, 자동차나 의료 관련 서비스와 같은 고위험 제품의 경우에 더욱 높았다고 한다. 연구를 시작하기 전에 연구원들은 AI 라벨이 사람들의 제품 구매 가능성을 낮추는 것이 아니라 오히려 높일 것이라고 생각했지만, 정 반대의 결과가 나온 것이다.

연구자들이 저위험군으로 분류한 품목, TV나 일반적인 상품의 경우에는 차이가 적었다고 한다.

연구진들은 의사결정이 머리보다는 가슴으로 하는 것으로 보인다고 밝혔다. 즉, 대부분 감정에 기반을 둔 의사결정을 한다는 이야기이다. 부정적인 시각을 가진 사람들은 AI기반 제품과 서비스를 신뢰하지 않았으며, 특히 AI가 어떤 기능을 하는지 이해하지 못하거나 안전에 위험을 초래할 수 있는 제품이나 서비스는 신뢰하지 않았다.

AI 도구를 한 번 이상 사용해 본 사람들은 그 도구들이 얼마나 신뢰할 수 없는지 잘 알고 있다. 어떤 일을 할 때 인간보다 뛰어나지만, 실패할 때는 비인간적인 방식으로 실패하곤 한다. 이런 부분이 무섭게 느껴질 수 있다.

현 시점에 "AI"는 마법의 키워드가 되었기에., 거의 모든 앱/서비스에는 AI 기능이 탑재되어 있다. 때로는 정말 유용하지만, 어쩔때는 귀찮을 수도 있고, 제품의 성능을 저하시키기도 한다.

AI에 대한 부정적인 태도의 원인을 파악하기 위해 추가적인 프로젝트를 진행한다고 했지만, 개인정보에 대한 우려도 있을것이라 추측한다고 했다.

예를 들어, 스마트 냉장고의 경우는 고가이고, 소프트웨어 업데이트가 필요하고, 식습관을 추적할 경우 개인정보 보호에 문제가 발생할 수 있다. 대부분의 사람들은 냉장고에 AI가 탑재되는 의미를 이해하지 못할 수 도 있다.

기업들은 자사 제품에 AI를 적용하는데 앞으로 더 적극적으로 나설것이다. AI기반 서비스/기기는 이론적으로는 매력적이지만, AI를 이용한 구체적인 장점이 명확하고 가치가 있어야 할 것이다.

오늘은 회사 앞 편의점을 가기위해 횡단보도를 건너는데., 횡단보도 전봇대 앞에 AI 피트니스라는 광고판이 보였다. 처음에는 무슨 세미나를 하는지 알았는데., 알고 보니 피트니스 홍보였다. 이 광고판을 제작할 때, AI가 피트니스 모객을 위해서 큰 도움이 될 것이라고 생각했을까? 이미 내 주변에는 "AI"라는 용어를 많이 쓰고 있다.

프로그래머가 비즈니스 문제를 해결해야 할까?


대부분의 조직은 R&R로 나눠져있다. 그리고 업계에 만연하는 것중 프로그래머는 비즈니스 문제 해결에 관여해서는 안된다는 얘기가 있다. 비즈니스 니즈에 집중하는 것이 프로그래밍의 순수한 기술적 본질을 훼손한다는 이야기이다.

나는 이런 관점에 반대한다.

일반적으로 개발자는 크게 3개의 레벨(주니어, 미들, 시니어)로 구분한다. 각 레벨에 대한 정의를 해보자.

  • 주니어: 논란의 여지가 없는 레벨이다. 이론을 배웠고, 이제 업무를 시작하려는 레벨이다.
  • 미들: 기술 스택에 대해 이해하는 숙련된 레벨이다.
  • 시니어: 다양한 경험을 갖추고 있고, 기술 스택에 대한 경험도 많으며, 업계 전반의 폭넓은 이해를 갖추고 있어야 한다.

원하던 원치 않든, 프로그래머는 비즈니스 문제를 해결한다. 사업은 수익을 창출해야 하고, 여기에는 급여 지급도 포함된다. 수익을 창출하려면 문제(비즈니스 과제)를 해결해야 한다. 간접적이던 직접적이던 비즈니스에 "가치"를 부여하여 문제를 해결해야 한다.

몇 가지 예를 들어보자. 새로운 웹사이트를 만들어야 한다고 가정해보자. 업무 흐름은 아래와 같을 것이다.

현업 요구사항 -> 프로젝트 관리자 -> IT 실무자로 이어지는 업무 흐름에서 두 가지 접근 방식이 존재한다.

  • 사례 #1: 요구사항 대로 그냥 코딩 - 모든 사람이 책임 범위내에서 일한다. 프로젝트 관리자는 현업과 논의하고 티겟을 만들고, 시니어는 아키텍처를 설계하고, 주니어는 미들과 개발을 한다.
  • 사례 #2: 업무 시작 전에 프로젝트 관리자, 시니어, 현업등이 비즈니스 문제를 심도 있게 논의하는 회의를 여러 차례 진행한다. 단순히 문제 해결 방법 뿐만 아니라, 비즈니스, 개발자, 디자이너 등 모든 사람이 참여해서 효과적으로 문제를 해결하는 방법을 논의한다. 모두에게 효과적인 방안을 찾은 후에야 개발이 시작된다.

사례#1 에서는 모두가 "그냥 코딩"만 한다. 비즈니스 문제는 비효율적으로 해결된다. 마감일이 정해져 있으면, 허술한 해결책을 찾고, 책임을 전가하고, 장황하게 수정 작업을 하고, "새로운 요구사항"을 추가하는 상황이 발생한다. 이는 사람들이 요구대로만 했기 때문이다. 모두가 자신의 범위내에서 "톱니바퀴"처럼 일했고, 비즈니스 문제 해결에는 참여하지 않았다.

사례#2에서는 항상 발생하는 대부분의 잠재적 문제가 상호작용을 통해 해결된다. 필요한 것을 오해할 수 있기 때문에 개발자가 프로젝트 구현 방식을 근본적으로 변경할 수도 있다는 점은 당연한 것이다. 물론 역량에 따라 크게 달라지겠지만, 문제는 훨씬 줄어들 것이다. 이 시나리오에서 비즈니스 문제는 효과적으로 해결된다.

사례#1과 사례#2의 주요 차이점은 무엇일까?

구현 방식이 아니라 팀워크이다. 여기서 팀이란 단순히 프로젝트내에서 무언가를 구현하는 코더 몇 명이 아니라 참여하는 구성원 전체를 의미한다. 사례#2에서는 모두가 좋은 결과를 얻기 위해 함께 노력한다는 점이 존재한다. 물론 세상은 완벽하지 않지만., 가정적으로 그렇다.

이유는 모르겠지만, 사람들은 종종 문제 해결을 영업과 연관 짓는다. 프로그래머는 "어떻게" 판매될지 생각하는 것이 아니라, "무엇"이 판매될지를 생각해야 한다. 최종 제품의 품질은 아키텍처, 속도, 로직, 디자인 등에 따라 달라진다. 여러가지 것들이 제품의 품질에 담긴다.

본 글의 서두에서 프로그래머는 원하든 원치 않든 비즈니스 문제를 해결한다고 언급했다. 다시 한번 생각해본다. 프로그래머가 비즈니스 문제를 해결해야 할까?

그래야 한다고 생각한다. 역량, 직책 그리고 경험 측면에서 해결해야 한다.

프로그래머가 영업을 해야 할까? 물론 아니다. 그러나 영업이 안고 있는 비즈니스 문제를 해결해주어야 한다.

8/20/2025

Data Lake, Data Mesh, Data Fabric 주요 차이점



우리는 효과적인 의사 결정을 위해 데이터에 기반한 인사이트에 의존한다. 그래서 데이터 관리를 위한 적절한 프레임워크나 플랫폼을 선택하는 것이 매우 중요하다. 오늘날 가장 널리 사용되는 것은 Data Lake, Data Mesh, Data Fabrrc 등이 있다.

위에서 언급한 3가지의 주요 차이점을 이해하면 데이터 환경을 최적화학고 목표에 맞게 조정할 수 있다. 본 글에서는 가지에 대해서 비교하고 장단점을 간략하게 설명하려고 한다.


Data Lake란 무엇인가?

Data Lake는 방대한 양의 정형, 반정형 혹은 비정형 데이터를 정제되지 않은 원본 데이터 그대로 모두 한곳에 모아두는 거대한 저장소이다. 마치 도시 전체의 모든 물을 한 호수에 모아두는 것과 같다. 현재 툴들은 이 개념에 트랜잭션 제어 및 스키마를 결합한 레이크하우스로 진화하고 있다.


특징

  1. 모든 데이터가 한 곳에 모이기에 중앙 집중형이다.
  2. 데이터를 저장할 때 스키마(데이터 구조)를 미리 정의하지 않아도 된다. 데이터를 사용할 때 스키마를 적용한다. 이 방식을 Schema-on-read라고 한다.

장점

  1. 다양한 종류의 데이터를 한 곳에 모아서 분석하기 좋다.
  2. 분석각가 선호하는 다양한 도구를 사용할 수 있다.
  3. 데이터가 증가함에따라 효율적으로 확장된다.

단점

  1. 데이터가 너무 많고 정리가 안 되어 있으면, Data Swamp에 빠질 수 있다. 필요한 데이터를 찾거나 분석하기 어려울 수 있다. 그래서 체계적으로 정리하고 사용가능하게 유지하기 위한 거버넌스가 필요하다.
  2. 대규모 저장, 관리 및 분석은 비용이 많이 들 수 있다.
  3. 적절한 메타데이터 관리 및 거버넌스가 없다면, 관리가 어려운 저장소가 될 수 있다.

Data Mesh란 무엇인가?

Data Mesh는 데이터를 한곳에 모으지 않고, 각 데이터를 생성하는 곳에서 직접 관리하고 책임지는 분산형 아키텍처이다. 마치 동네마다 식수를 관리하는 정수장이 있는 것과 같다. 데이터의 소유권을 분산하여, 데이터를 사용하는 사람이 필요할 때 쉽게 접근하고 사용할 수 있게 만드는 개념이다.


특징

  • 소유권 분산: 데이터는 데이터를 가장 잘 아는 팀이 소유하고 관리한다.
  • 데이터를 상품처럼 취급: 각 팀은 대ㅔ이터를 잘 가공해서, 다른 팀이 쉽게 사용할 수 있는 “데이터 상품”으로 만들어 제공한다. 이 데이터 제품은 품질이 보장되고, 문서화되어 있으며 접근하기 쉬워야 한다.
  • 셆프 서비스: 데이터를 생성하고 소비하는 곳이 필요한 도구를 직접 사용할 수 있도록 도구를 제공한다.
  • 연합 통제: 중앙에서 모든 것을 통제하는 대신, 각 팀이 자율적으로 운영하되, 공통의 규칙과 표준을 준수한다.

장점

  1. 데이터 소유권이 명확하여 책임 소재가 분명하다.
  2. 데이터 소비자가 필요한 데이터를 더 빠르고 쉽게 찾고 사용할 수 있다.
  3. 거대한 중앙 집중 관리가 아니기에 민첩성이 높아진다.

단점

  1. 초기 도입이 복잡하고 어렵다.
  2. 조직 문화와 구조의 변화가 필수적이다.
  3. 공통의 표준을 유지하지 못하면 데이터 파편화가 발생할 수 있다.

Data Fabric

Data Fabric은 데이터가 어디에 있든 상관없이, 마치 하나의 논리적인 통로처럼 연결해서 사용할 수 있게 해주는 개념이다. 마치 여기저기 흩어져 있는 물탱크들을 하나의 거대한 파이프 시스템으로 연결해서, 어디서든 원하는 물을 끌어다 쓸 수 있게 하는 것과 같다.


특징

  • 데이터 카탈로그: 모든 데이터의 위치와 정보를 메타데이터 형태로 관리한다.
  • 데이터 가상화: 실제 데이터를 복제하지 않고, 마치 한 곳에 있는 것처럼 논리적으로 연결하여 실시간으로 접근하게 해준다.
  • AI 및 ML: 데이터를 자동으로 분류하고, 메타데이터를 생성하며, 데이터 흐름을 최적화하는데 사용된다.

장점

  • 데이터가 물리적으로 분산되어 있더라도 쉽게 접근하고 통합할 수 있다. (실시간 분석)
  • 기존 인프라를 크게 바꾸지 않고도 도입이 가능하다.
  • 데이터 이동을 최소화하여 데이터 보안과 거버넌스를 강화할 수 있다.

단점

  • 기술적으로 꽤 복잡하고, 구현 비용이 높을 수 있다.
  • 중앙 거버넌스와 각 데이터 소유자 간의 균형을 맞추려고 할 때 병목이 발생할 수 있다.
  • 도구 통합이 어려울 수 있다.

지금까지 3가지 기술에 대해서 알아보았다. 요약하면 아래와 같다.

  • Data Lake: 데이터를 저장하는 방식에 대한 개념이고 모든 데이터를 한곳에 모은다.
  • Data Mesh: 데이터를 관리하는 조직 및 문화에 대한 개념이다. 데이터 소유권을 분산시키고, 데이터를 상품처럼 다룬다.
  • Data Fabric: 데이터를 기술적으로 연결하는 솔루션에 대한 개념이다. 데이터가 어디에 있든 통합해서 사용할 수 있게 한다.

위에서 언급한 이 세 가지 개념은 서로 배타적이지 않고 상호 보완적이다. 예를 들어서 Data Lake를 기반으로 Data Mesh를 구축하거나, Data Fabric 기술을 활용하여 Data Mesh를 구현할 수 있다.

  • Data Lake는 데이터의 물리적 저장 공간을 제공
  • Data Mesh는 이 데이터를 누가 어떻게 책임지고 관리할지에 대한 조직적 접근 방식을 제시
  • Data Fabric은 데이터가 어디에 있든 간에 쉽게 접근하고 연결하는 기술적 솔루션을 제공

사용 사례

Data Lake

Twitter의 경우 방대한 양의 트윗 데이터, 사용자의 상호 작용 등의 데이터를 Lake에 저장한다. 이 원시 데이터 저장소는 피드 알고리즘 개선, 인기 트윗 파악 등의 분석을 지원한다.

Tesla의 경우는 Data Lake를 사용하여 차량, 제조 공정 및 충전 인프라의 센서 데이터를 저장한다. 포괄적인 데이터 수집을 통해 자율주행, 유지 보수 예측 및 운영 최적화를 위한 ML 학습데이터롤 사용된다.


Data Mesh

Uber는 분산형 소유권 체계를 이용해 여러 부서가 데이터를 독립적으로 관리한다. 승차 매칭, 운전자 온보딩, 결제 처리 등 각 영역별 자율적으로 데이터를 관리한다.

Netflix는 시청자 참여 패턴, 콘텐츠 성과 지표, 추천 효과 등을 포함하는 데이터 세트를 관리하는 독립적인 팀을 운영하고 있다. 이런 방법으로 개인화된 시청 경험을 제공하는 “데이터 상품”을 만든다.


Data Fabric

Cisco는 여러 데이터 소스를 통합하여 시장 동향을 분석하고, 제품을 개선하며, 고객 지원을 강화한다. 엔지니어링, 영업 및 지원 부서 전반에 실시간 인사이트를 제공하는 동시에 다양한 데이터 소스에 걸쳐 일관된 거버넌스 및 보안 정책을 유지한다.

Visa는 결제 처리 서비스 전반의 데이터를 통합하여 사기 탐지를 강화하고 규제 준수를 보장한다. 실시간 거래 모니터링을 지원하고 패턴 분석 및 위험 평가를 위한 과거 데이터에 대한 접근도 제공한다.


결론

위 사용 사례를 보면, 각 개념별 어떤 상황에서 사용해야 하는지가 대략적으로 나온다. 시나리오를 하나 만들어보자.

어떤 기업이 있다고 가정해보자. 이 기업은 여러 곳에서 생산되는 모든 데이터를 한 곳에 모아 분석하고 싶었다. 그래서 저렴한 대량의 원시 데이터를 저장할 수 있는 Data Lake를 구축했다. 즉, 모든 데이터는 중앙 호수에 모였다.

이렇게 사용하다보니, 데이터의 양이 기하급수적으로 늘어났다. 그러다가 Data Swamp로 변해갔다. 어떤 데이터가 유용한지, 누가 데이터를 소유하고 있는지 불분명해졌고, 데이타의 품질도 낮아졌다. Data Lake를 관리하는 조직은 모든 부서의 요청을 처리하느라 업무 부하가 커져갔다.

위 문제를 해결하기 위해 Data Mesh라는 새로운 개념을 도입하게 되었다. 생산되는 데이터에 대한 책임은 각 담당 부서에서 지고, 이 데이터를 “데이터 상품”으로 만들어 제공하기 시작했다. 다른 부서가 데이터를 원하면 중앙팀을 거치지 않고 해당 부서가 직접 제공하는 잘 정리된 데이터 제품을 사용하게 되었다.

Data Mesh를 도입했지만, 여전히 각 부서의 데이터가 서로 다른 시스템에 흩어져 있었다. 같이봐야 하는 상황들이 발생했지만, 쉽지 않았다. 이 문제를 해결하기 위해 Data Fabric을 도입했다. Data Fabric은 “데이터 상품”을 찾고 통합하여 필요한 곳에 제공하는 역할을 담당하게 되었다. LLM Agent와 같은 최신 기술이 모든 데이터 소스에 손쉽게 접근할 수 있게 되었다.

즉, Data Lake에 Data Mesh라는 구조를 보강하고, 그 구조를 원활하게 작동시키는 기술 레이어로 Data Fabric을 활용하는 것이 복잡한 데이터 환경에서 가장 이상적이고 일반적인 모델이 되어 가고 있다고 생각한다.

결국 데이터 플랫폼의 목표는 사용자가 원하는 시점에 필요한 데이터를 제공하는 것이다. Silo되게 관리가 되어 왔고, 이런 문제를 해결하기 위해 Data Lake에 몇 년전부터 주목을 했던 것 같다. 데이터를 한곳에 모았으니 이제 모든걸 다 할 수 있을지 알았다.

그러다가 Data Lake가 모든 문제를 해결할 수 있는 만능 열쇠가 아니라는 것을 알게 되었다. 우선 데이터를 복제해야 하기에 인프라에 막대한 투자 비용이 필요했고, 하나의 호수에서 어떠한 데이터든 찾을 수 있다는 발상은 좋았지만, 일부 전문가만이 원천 데이터를 가공하여 유의미한 인사이트를 얻을 수 있었다. 데이터를 한곳에 모아서 제공한다는 취지는 좋았지만, 활용면에서는 유용하지 못했기 때문이다.

데이터 플랫폼의 목표는 앞에서 언급한 것과 같이 “데이터를 원하는 사용자에게 원하는 시점에 필요한 데이터를 제공”하는 것이다. 여기서 원하는 사용자는 데이터 전문가가 아닌 일반인도 포함된다. 따라서 Data Lake는 사용자에게 전문적인 역량을 요구하기에 Gap이 발생하게 된다.

그래서 Data Mesh라는 개념이 나왔다. 데이터를 생산하는 조직이 소유권을 가지며 관리하는 전략이다. 해당 데이터 전문가도 해당 데이터를 다루는 곳에 분산 배치할 수 있게 된다. 각 조직에서 생산하는 데이터에 대해서는 빠르게 데이터 상품을 만들 수 있었고, 각 부서의 도메인 지식을 살린 데이터 관리 전략을 수립할 수 있게 되었다. 중앙화된 데이터 플랫폼을 통하지 않기에., 데이터의 실시간성을 확보할 수 있었다.

이렇게 사용하다보니, 다시 전사 데이터에 대한 Needs가 생겼다. 서로 다른 조직 간에 데이터를 조회하고 공유할 수 있도록 데이터 가상화나 데이터 페더레이션이 필요했다. 그렇다고 다시 Data Lake로 회귀할 순 없었다. 이미 경험한 과정이기 때문이다. 그래서 Data Fabric으로 전사 데이터를 물리적으로 통합하는 대신, 기존에 저장된 데이터 저장소들을 유기적으로 연결 할 수 있는 데이터 가상화 기술을 활용했다. 단일화된 데이터 가상화 플랫폼에서 데이터를 필요로 하는 사용자가 손쉽게 검색하고 빠르게 획득할 수 있는 파이프라인을 만들면서 데이터 사일로를 방지했다. 물리적 통합이 아닌 논리적 통합인 것이다.

데이터를 복제하지 않기에, 저장 관점에서는 비용 효율적이기도 했다. 보안적으로도 이점이 있다. 논리적인 통합이기에 가상 레이어에서 단일 통로로만 접근이 가능하기에 이력, 활동 내역등을 효과적으로 관리할 수 있게 되었다. 그러나 단점도 존재했다. 데이터의 실시간성을 확보할 순 있지만, 원천 데이터 저장소에 부하를 가할 수 있기 때문이다.

결론적으로, 배치와 실시간이라는 두 가지 데이터 처리 요구 사항에 맞춰 활용해야 할 것으로 판단된다. Data Lake가 대용량 데이터의 안정적인 배치 처리를 위한 기반이라면, Data Fabric은 분산된 데이터의 실시간 통합 및 분석을 위한 기반으로 생각된다.

이 모든게 원활하게 동작되려면, 데이터 카탈로그가 잘 구성되어야 할 것이다. 잘 관리된 메타데이터는 데이터들 간의 전사적 연결성을 보여줄 수 있기에 매우 중요한 요소다. 메타 데이터가 잘 관리된다면, 자동화할 수 있다면, 실시간성 확보와 품질를 확보할 수 있을 것이다.

Data Lake를 통해 장기적인 분석을 위한 “진실의 원천”을 Data Fabric으로 실시간 의사결정을 위한 “즉각적인 통찰”을 얻는 것이 장점을 모두 활용할 수 있는 방안이라 생각한다. 단 메타 데이터가 잘 구성되어 있어야 할 것이다.