Multimodal RAG
이미지·PDF·비디오 멀티모달 검색
Multimodal RAG
이미지·PDF·비디오 멀티모달 검색
텍스트 너머의 데이터를 검색한다
이미지·표·비디오·관계 — 데이터 형태에 맞는 RAG 확장 전략
텍스트 너머의 RAG
왜 특수 데이터인가 · 두 가지 확장
특수 데이터 RAG
텍스트 청킹·임베딩만으로는 닿지 않는 데이터 — 형태에 맞춘 RAG 확장
특수 데이터 RAG
문서 밖의 정보 — 이미지·표·비디오·음성, 그리고 엔티티 간 관계까지 검색 대상으로
- 이미지·표 — 메뉴 비교표, 차트
- 비디오·음성 — 영상 강의, 상담 녹음
- 관계 — 엔티티 간 연결과 의존
- 전략 — 데이터 형태가 파이프라인을 결정
표준 RAG 파이프라인(문서 → 청킹 → 임베딩 → 검색)은 앞 모듈에서 완성했습니다.
이 모듈은 그 파이프라인이 못 다루는 데이터를 다룹니다.
벡터 검색이 놓치는 질문
"예약금 환불 규정이 어떻게 되나요?"는 restaurant-policy.pdf 청크로 풀렸습니다 — 다음 두 부류는 같은 방법으로 풀리지 않습니다
형태의 문제 — 이미지 속 정보
"가격 비교표에서 디너 가격은 얼마야?"
- 메뉴 비교표·차트는 이미지 — 텍스트로 추출되지 않으면 검색에서 통째로 누락
- 비디오·음성은 아예 인덱싱 대상이 아님 — 존재하지만 찾을 수 없는 지식
관계의 문제 — 연결된 지식
"트라토리아 벨라와 페어링 가능한 와인 전부 알려줘"
- 벡터 검색은 유사 문서 몇 개만 반환 — 실제 페어링 가능한 와인은 12개
- "런치를 디너로 바꾸면 뭐가 달라져?" — 코스 간 의존 관계 정보가 필요
검색이 실패하는 원인은 모델이 아니라 데이터 형태입니다 — 이미지는 벡터에 없고, 관계는 청크에 없습니다.
두 가지 확장 — 형태에 맞는 해법
문제의 성격이 다르면 해법도 두 갈래
벡터 스토어·Knowledge Base 같은 기반은 그대로 둡니다.
인덱싱과 검색 방식을 데이터 형태에 맞게 바꾸는 것이 이 모듈의 주제입니다.
Multimodal RAG
이미지·표 인덱싱 · 비디오·음성 · Data Automation
Multimodal RAG
텍스트뿐 아니라 이미지·표·비디오·음성을 함께 인덱싱하고 검색하는 RAG
Multimodal RAG
텍스트 질문 하나로 이미지 속 표, 영상 속 설명까지 찾아냅니다
- 이미지·표 — Vision 추출 또는 멀티모달 임베딩
- 비디오·음성 — Transcribe + 타임스탬프 청킹
- 자동화 — Bedrock Data Automation 파싱
- 검색 — 텍스트 쿼리로 이미지까지
파이프라인의 뼈대는 그대로 — 바뀌는 것은 인덱싱 앞단뿐입니다.
특수 포맷을 벡터 공간에 올리는 방법만 익히면 됩니다.
두 가지 인덱싱 경로 — 변환 vs 직접 임베딩
이미지를 벡터 공간에 올리는 두 경로 — 규모와 정확도 요구가 갈림길
Vision 캡셔닝 → 텍스트 임베딩
변환 후 인덱싱
- Vision 모델이 이미지를 캡션·마크다운 표로 변환
- 기존 텍스트 RAG 파이프라인과 그대로 호환
- 변환 프롬프트를 도메인에 맞게 커스터마이즈 가능
- 인제스트가 느리고 비용 높음 — 이미지마다 LLM 호출
상세하고 정밀한 이미지 설명이 검색 품질을 좌우할 때 — 캡션 프롬프트가 재현율을 결정합니다.
멀티모달 임베딩
직접 인덱싱
- Nova Multimodal Embeddings가 이미지·비디오·오디오를 직접 벡터화
- 모든 모달리티를 하나의 통합 의미 공간에 — 텍스트 쿼리로 비디오 검색
- 인제스트가 빠르고 비용 효율 — LLM 호출 없음
- 이미지 입력 쿼리 시 지연도 유리
대규모·범용 크로스모달 검색의 기본 선택 — AWS 공식 비교 기준 인제스트 비용·속도 우위입니다.
갈림길은 규모가 아니라 설명의 정밀도입니다 — 도메인 특화 설명이 필요하면 캡셔닝, 대규모 범용 크로스모달 검색이면 멀티모달 임베딩.
멀티모달 임베딩 모델 — Titan vs Nova
직접 임베딩 경로의 모델 선택 — 모달리티 커버리지와 차원이 가르는 기준
| 항목 | Titan Multimodal G1 | Nova Multimodal Embeddings |
|---|---|---|
| 모달리티 | 텍스트 + 이미지 2종 | 텍스트 · 이미지 · 문서 이미지 · 비디오 · 오디오 5종 |
| 출력 차원 | 1,024 · 384 · 256 | 3,072 · 1,024 · 384 · 256 |
| 텍스트 입력 | 최대 256 토큰 (영어) | 최대 8K 토큰 |
| 세그멘테이션 | 없음 | 비동기 API가 긴 비디오·오디오·텍스트 자동 분할 |
| 용도 최적화 | 없음 | embeddingPurpose — 인덱스·검색·분류·클러스터링별 |
신규 구축은 Nova Multimodal Embeddings가 기본 — 5개 모달리티를 하나의 통합 의미 공간에 올려, 텍스트 질문으로 비디오 구간까지 찾습니다. Knowledge Base 임베딩 모델로도 선택할 수 있습니다(멀티모달 리트리벌).
이미지 속 표를 꺼내는 코드 — Vision 추출
가격 비교표 이미지를 마크다운 표로 변환해 기존 벡터 스토어에 추가
import boto3
bedrock = boto3.client("bedrock-runtime", region_name="us-east-1")
def extract_table_from_image(image_path: str) -> str:
with open(image_path, "rb") as f:
image_bytes = f.read()
# ① 이미지와 텍스트를 한 메시지로 전달 — Vision 모델이 표를 읽음
response = bedrock.converse(
modelId="us.anthropic.claude-sonnet-4-6",
messages=[{"role": "user", "content": [
{"image": {"format": "png", "source": {"bytes": image_bytes}}}, # ② 표·차트는 PNG
{"text": "이 가격 비교표를 마크다운 테이블로 변환해주세요. 모든 숫자를 정확하게 포함하세요."}, # ③ 추출 프롬프트
]}],
)
# ④ 반환된 마크다운 표 → 기존 텍스트 임베딩 파이프라인에 그대로 추가
return response["output"]["message"]["content"][0]["text"]
- bedrock.converse — 이미지+텍스트를 한 메시지로. 요청당 이미지 20개 · 이미지당 3.75MB·8,000px 제한 — 대용량은 S3 URI 소스로
- "format": "png" — 표·차트는 PNG가 텍스트 추출 정확도가 높음 (사진은 JPEG)
- 프롬프트 — "모든 숫자를 정확하게". 검색 최적화 캡션이 재현율을 좌우
- 인덱싱 — 추출된 마크다운 표는 평범한 텍스트 — 기존 벡터 스토어에 그대로 추가
표 이미지가 검색 가능한 텍스트로
Vision 추출의 입력과 출력 — 이미지였던 표가 임베딩 가능한 마크다운이 되는 순간
| 코스 | 평일 | 주말 |
|---|---|---|
| 런치 | 45,000 | 55,000 |
| 디너 | 89,000 | 99,000 |
→
converse
Vision
비디오·음성 — 트랜스크립트 + 타임스탬프
영상과 녹음을 검색 가능한 텍스트로 — 구간까지 짚어주는 답변
-
1
변환
Amazon Transcribe로 음성을 텍스트로 — 한국어 포함 100+ 언어, 화자 분리·자동 언어 감지 지원.
-
2
청킹
트랜스크립트를 60초 단위로 분할 — 비디오 1시간이면 약 60개 청크, 임베딩 비용은 미미.
-
3
메타데이터
각 청크에 start_time·end_time과 원본 파일 경로를 기록 — 출처 추적의 재료.
-
4
답변
"2분 30초~3분 30초 구간에서 설명합니다" — 프론트엔드에서 해당 구간 점프 링크 생성.
파이프라인 자체는 텍스트 RAG와 같습니다 — 차이를 만드는 것은 타임스탬프 메타데이터입니다.
파싱 자동화 — Bedrock Data Automation
PDF의 표·이미지·텍스트를 자동 구조화 — Knowledge Base 파싱 전략으로 직접 연결
import boto3
bedrock_agent = boto3.client("bedrock-agent", region_name="us-east-1")
# ① Knowledge Base 데이터 소스에 Data Automation 파싱 전략 연결
bedrock_agent.create_data_source(
knowledgeBaseId="KB-RESTAURANT-001",
name="terms-with-tables",
dataSourceConfiguration={
"type": "S3",
"s3Configuration": {"bucketArn": "arn:aws:s3:::restaurant-docs"},
},
vectorIngestionConfiguration={"parsingConfiguration": {
# ② 파서 지정 — 인제스트 시 자동 파싱
"parsingStrategy": "BEDROCK_DATA_AUTOMATION",
# ③ MULTIMODAL — 텍스트 + 표 + 이미지를 모두 구조화 추출
"bedrockDataAutomationConfiguration": {"parsingModality": "MULTIMODAL"},
}},
)
- create_data_source — S3 원본을 Knowledge Base에 연결하면서 파싱 전략까지 선언. 별도 전처리 파이프라인 불필요
- parsingStrategy — 파서 선택: BDA(완전관리형·페이지 과금) vs 파운데이션 모델 파서(추출 프롬프트 커스터마이즈·토큰 과금)
- parsingModality — MULTIMODAL이면 표·이미지까지 구조화, TEXT_ONLY는 표를 평문으로 뭉침. 이미지 원본은 Supplemental Data Storage(S3)에 저장돼 출처로 반환 — Knowledge Base 생성 후 추가 불가
이미지·표·비디오는 멀티모달로, 관계는 그래프로 — 형태에 맞게 확장