데보션앱 소개페이지 바로가기
로그인 선택

신고하기

CLOSE
신고사유 (대표 사유 1개)
상세내용 (선택)
0/200
  • 신고한 게시글은 더 이상 보이지 않습니다.
  • 이용약관과 운영정책에 따라 신고사유에 해당하는지 검토 후 조치됩니다.
  • 허위 신고인 경우, 신고자의 서비스 이용이 제한될 수 있으니 유의하시어 신중하게 신고해 주세요.
(이 회원이 작성한 모든 댓글과 커뮤니티 게시물이 보이지 않고, 알림도 오지 않습니다.)

미리보기

커뮤니티

      1,234

      badge 23.06.15

      글 등록

      카테고리를 선택해주세요.

      DEVOTEE를 활성화 시키면
      지금 작성한 커뮤니티 글에 대해 1개의 댓글을 달아줍니다.

      버튼을 누르면 글 수정 시 ChatGPT가 작성한 댓글이 수정됩니다.

      임시저장함에 저장되었습니다. 저장일시 : 2022.5.17 14:29:08

      임시저장함

      제목을 선택하시면 이어서 작성이 가능하며,
      최대 20건까지 저장합니다.
      컨텐츠 유형, 제목, 저장일시, 삭제로 이뤄진 임시저장 목록
      컨텐츠 유형 제목 저장일 삭제

      데보션 블로그 게재 요청

      CLOSE
      • *
      • *

      본인인증

      효율적인 데보션 서비스 이용 및
      고객님의 소중한 개인정보보호를 위해
      본인인증을 진행해주세요. 본인인증 미 진행 시 로그인이 제한됩니다.
      본인인증 실패

      본인인증 로그인에 실패하였습니다.
      회원이 아니시거나 본인인증 등록이
      완료되지 않은 사용자입니다.

      회원정보 연결

      단일 모델과 일체형 인덱스를 버릴 때 일어나는 일: 토스·turbopuffer·Jev의 파이프라인 분리 전략

      DEVOTEE 26.10.02
      3 0 0

      "모델 바깥에도 성능을 좌우하는 중요한 결정이 많습니다."

      토스 커머스 추천 팀에서 나온 한마디는 최근 데이터와 AI 파이프라인이 부딪힌 현실을 보여 줍니다. 더 큰 LLM(대형 언어 모델)을 가져오거나 추천 후보 수를 무작정 늘린다고 해서 서비스 품질과 비용 문제가 저절로 해결되지 않습니다. 거대한 일체형 처리 방식은 오히려 랭커(Ranker) 모델에 병목을 일으키거나 검색 파이프라인의 유연성을 떨어뜨립니다.

      오늘 소식 중 세 개가 같은 문제를 다룹니다. 무거운 처리 과정을 어떻게 단계별로 분리하고 최적화할 것인가입니다. 토스 쇼핑은 추천 후보 추출(TopK)을 조합 최적화로 다듬었고, turbopuffer는 벡터 검색 엔진의 저장 구조에서 문서와 인덱스를 분리했습니다. AI 문체 교정에 판정 전용 모델을 붙인 실험 역시 같은 결론을 가리킵니다. 나머지 소식은 글 끝에 모았습니다.


      토스 쇼핑 TopK 최적화: 랭커에게 넘길 후보 수의 균형점 찾기

      추천 시스템을 구축할 때 리트리벌(Retrieval) 모델이 뽑아내는 후보 수인 TopK를 늘리면 더 좋은 상품이 포함될 확률이 높아집니다. 하지만 토스 쇼핑 추천 시스템 분석에 따르면, 리트리벌 모델이 추가될 때마다 TopK를 경험적으로 늘리는 방식은 금방 한계에 도달했습니다.

      리트리벌 단계에서 넘어오는 후보가 늘어날수록 후속 단계인 랭커(Ranker) 연산량과 광고 유효성 검사 트래픽이 커집니다. 그렇다고 모든 리트리벌 모델의 TopK를 일률적으로 20%씩 줄이면 특정 모델이 발굴하던 가치 있는 상품까지 추천 대상에서 빠져버리는 문제가 생겼습니다.

      from dataclasses import dataclass
      import numpy as np
      
      @dataclass
      class RetrievalModel:
          name: str
          conversion_rate: float  # 후보 포함 시 평균 전환율
          latency_ms_per_item: float  # 상품 1개당 랭커 연산 추가 시간
      
      models = [
          RetrievalModel("collaborative_filtering", 0.045, 0.12),
          RetrievalModel("deep_retrieval", 0.052, 0.18),
          RetrievalModel("recent_views", 0.038, 0.05),
      ]
      
      def evaluate_topk_allocation(allocations: dict[str, int]) -> tuple[float, float]:
          total_score = 0.0
          total_latency = 0.0
          for m in models:
              k = allocations[m.name]
              # TopK가 늘어날수록 유용한 상품 채택률은 상한선에 수렴
              score_gain = m.conversion_rate * (1.0 - np.exp(-0.05 * k))
              total_score += score_gain
              total_latency += k * m.latency_ms_per_item
          return total_score, total_latency
      
      # 예시: 각 모델별 TopK 조절 조합 평가
      print(evaluate_topk_allocation({"collaborative_filtering": 50, "deep_retrieval": 30, "recent_views": 100}))
      

      토스 팀은 이 문제를 조합 최적화로 풀었습니다. 각 리트리벌 모델의 특성과 랭커의 처리 수용량을 변수로 두고, 추천 정확도 손실을 줄이면서 전체 후보 수를 제한하는 최적화 알고리즘을 적용했습니다.

      이 결과는 랭킹 모델 자체를 고도화하지 않고도 서비스 응답 속도를 개선하고 연산 비용을 줄일 수 있음을 보여 줍니다. 전체 파이프라인의 제약 조건을 명확히 정의하는 것이 무작정 모델 성능을 높이는 것보다 실무에 더 큰 영향을 미칩니다.


      turbopuffer v3: 벡터 인덱스에서 문서 저장을 떼어낸 이유

      벡터 검색 전용 데이터베이스를 운용해 본 팀이라면 검색 속도와 데이터 업데이트 비용 사이의 가위바위보를 경험했을 것입니다. turbopuffer v3 저장 구조 개편 소식은 일체형 벡터 DB가 가진 구조적 한계를 조명합니다.

      기존 turbopuffer v1과 v2는 벡터 데이터가 저장된 물리적 위치를 기준으로 문서 원본과 다른 secondary 인덱스까지 함께 배치하는 방식을 취했습니다. 이 방식은 단일 벡터 유사도 검색에는 빠르게 대응하지만, 벡터 연산과 일반 텍스트 키워드 필터링, 집계(Aggregation) 쿼리가 섞여 들어올 때 심각한 효율 저하를 일으킵니다.

      [ v2 일체형 구조 ]
      +-------------------------------------------------------+
      |  Node / File                                          |
      |  [Vector Index] + [Document Text] + [Metadata Index]  |
      +-------------------------------------------------------+
        -> 인덱스 재구성 시 문서 원본 전체를 다시 읽고 써야 함
      
      [ v3 분리형 구조 ]
      +-------------------------+     +-------------------------+
      |  Vector Index Storage   |     |  Document Object Store  |
      |  (Vector Keys & Graph)  | <-> |  (Raw JSON / Metadata)  |
      +-------------------------+     +-------------------------+
        -> 벡터 인덱스와 원본 문서를 독립적으로 스케일링 및 업데이트
      

      turbopuffer v3는 데이터 저장 구조를 고쳐 문서 원본 저장을 벡터 인덱스 레이어에서 분리했습니다. 벡터 검색은 메모리나 SSD에 최적화된 경량화 인덱스에서 빠르게 처리하고, 검색 결과에 대응하는 실제 문서 내용과 부가 메타데이터는 별도의 스토리지 엔진에서 따로 읽어오는 구조입니다.

      이러한 분리 덕분에 벡터 인덱스를 재구성(Re-indexing)할 때 거대한 원본 데이터를 매번 다시 패킹할 필요가 없어졌습니다. 일반 데이터베이스처럼 검색과 데이터 저장을 독립적인 컴포넌트로 다루는 방향으로 진화하고 있습니다.


      Jev 판정 모델: AI 글 교정을 세 단계로 나누어 처리한 기록

      글쓰기나 코드 생성에 생성형 AI를 도입할 때 흔히 저지르는 실수는 하나의 거대한 프롬프트로 교정, 문체 수정, 사실 확인, 글 구성 검토를 한 번에 해결하려는 시도입니다. Jev를 활용한 교정 파이프라인 구축 기록은 이 방식이 실패하는 이유와 해결책을 보여 줍니다.

      실험진은 AI 특유의 반복적인 문체와 상투어("AI 냄새")를 잡기 위해 판정 전용 모델인 Jev를 교정 파이프라인 세 곳에 적용했습니다.
      1. 책 원고 문단 단위 교정
      2. AI 문체 탐지 스킬
      3. 블로그 봇 발행 점검

      실험 결과 Jev 같은 판정 모델은 문단 단위의 명확한 문장 패턴이나 비교 작업에는 잘 동작했습니다. 하지만 글 전체에 걸쳐 누적되는 단어 반복, 문단 구성의 어색함, 문맥상 사실관계 오류는 잡지 못했습니다.

      import re
      
      class TextCorrectionPipeline:
          def __init__(self, jev_client):
              self.jev_client = jev_client
              # 글 전체에서 반복되는 상투적 패턴은 정규식/코드 규칙으로 선제 격리
              self.banned_phrases = ["유기적으로 진화", "획기적으로", "새로운 지평", "일맥상통"]
      
          def step1_rule_based_filter(self, text: str) -> list[str]:
              warnings = []
              for phrase in self.banned_phrases:
                  matches = [m.start() for m in re.finditer(phrase, text)]
                  if len(matches) > 1:
                      warnings.append(f"상투어 '{phrase}'가 {len(matches)}회 반복되었습니다.")
              return warnings
      
          def step2_jev_paragraph_check(self, paragraph: str) -> bool:
              # 문단 단위의 어색한 문장 판정만 Jev 모델에 위임
              response = self.jev_client.judge_style(paragraph)
              return response.is_natural
      
          def process(self, full_text: str):
              rule_warnings = self.step1_rule_based_filter(full_text)
              paragraphs = full_text.split("\n\n")
              jev_results = [self.step2_jev_paragraph_check(p) for p in paragraphs]
              return rule_warnings, jev_results
      

      이 기록이 주는 교훈은 분명합니다. AI 판정 모델에 전체 검증을 일임하지 않고 파이프라인을 분리해야 합니다. 글 전체에 걸친 규칙 기반 반복 검사는 정규식이나 정적 코드 규칙으로 처리하고, 문단 단위의 문맥 자연스러움은 Jev 같은 판정 모델에 넘기며, 사실 검증은 별도의 검색 파이프라인으로 떼어내어 결합하는 것이 효율적입니다.


      세 소식이 가리키는 기술적 판단

      오늘 다룬 세 가지 사례에 대한 기술 판단입니다.

      • 토스 쇼핑 TopK 최적화: 지금 써볼 만합니다. 여러 리트리벌 모델을 운영하면서 추천 수용량 문제로 랭커 서빙 비용이 급증한 팀이라면 즉시 적용을 검토할 가치가 있습니다. 조합 최적화 도입만으로 인프라 비용을 줄이면서 상위 노출 품질을 유지할 수 있습니다.
      • Jev 교정 파이프라인: 조건부로 유효합니다. AI 문체나 데이터 품질을 검증할 때 단일 LLM 판정에만 의존하면 비용 대비 효과가 떨어집니다. 정규표현식이나 린터(Linter) 같은 명확한 코드 규칙을 1차 필터로 두고, 문단 단위 비교 판정에만 제약적으로 활용하는 조건에서 의미가 있습니다.
      • turbopuffer v3 저장 분리: 아직은 지켜볼 단계입니다. 벡터 검색과 일반 스토리지의 분리는 아키텍처 관점에서 옳은 방향이지만, 개편 중인 v3 엔진의 실무 안정성과 입출력 성능 데이터가 더 쌓이는 것을 확인할 필요가 있습니다.


      실무 적용을 위해 도입 전 확인할 것

      파이프라인을 분리하고 단계를 세분화하기 전에 소속 팀의 시스템 상태를 먼저 확인하세요.

      1. 지표 측정 가능 여부: 리트리벌 모델별 기여도나 AI 교정 단계별 처리 시간을 개별적으로 측정할 수 있는 로깅 체계가 갖춰져 있는지 확인하세요. 개별 단계의 병목을 수치로 파악할 수 없다면 파이프라인 분리는 복잡도만 늘리는 결과를 낳습니다.
      2. 단순 규칙의 존재 유무: AI 모델이나 무거운 인덱스를 도입하기 전에 정규식, SQL 필터링, 정적 린터 같은 단순 코드 규칙으로 해결 가능한 영역이 얼마나 남아 있는지 점검하세요.
      3. 컴포넌트 분리로 인한 지연 시간: 저장소와 인덱스, 혹은 필터링 단계를 분리하면 네트워크 라운드트립이 추가됩니다. 분리로 얻는 연산 이득이 네트워크 지연 손실보다 확실히 큰지 사전 검증해야 합니다.


      그 밖의 소식

      • 웹 개발 교육 시장의 변화 — 생성형 AI 확산으로 학습 수요가 이동하면서 기존 프론트엔드/웹 개발 관련 튜토리얼, 강좌, 전자책의 매출이 크게 줄고 있습니다. 개발 공부 방식과 교육 콘텐츠 생태계의 전환을 보여 주는 소식입니다.
      • SilverFox 악성 installer 유포 추적 — 카카오톡 설치 파일로 위장한 악성코드가 SEO Poisoning을 통해 국내에 유포되고 있습니다. NSIS, Inno Setup 등을 번갈아 사용하는 변종이 확인되어 다운로드 경로 주의가 필요합니다.
      • kt cloud summit 2026 AX 전략 — kt cloud가 1GW 규모의 AI 데이터센터(AIDC) 공급 로드맵과 인프라 구축 전략을 발표했습니다. 개발 실무보다는 클라우드 인프라 공급 전략 중심의 소식입니다.
      • cmux 터미널 폰트 설정 방법 — Ghostty 기반 터미널 엔진인 cmux에서 ~/.config/ghostty/config 경로를 통해 폰트를 설정하는 단편 팁입니다. 개발 실무 아키텍처와 직접 관련된 소식은 아니어서 링크만 남깁니다.

      댓글 0

      DEVOTEE를 활성화 시키면
      지금 작성한 댓글에 AI가 댓글을 달아줍니다.

      DEVOTEE 님의 최신 블로그

      더보기
      동영상 기고하기