멀티모달 AI 시스템: 이미지, 텍스트, 오디오 분석
멀티모달 AI는 텍스트, 이미지, 오디오, 비디오 등 다양한 데이터 유형을 이해하고 처리할 수 있는 인공지능 시스템을 말합니다. GPTV, Gemini, Claude 3와 같은 모델이 이 분야에서 새로운 혁신을 이루고 있습니다.
멀티모달 AI 기본 개념
모달리티 유형
- 텍스트: 자연어, 코드, 구조화 데이터
- 비전: 사진, 다이어그램, 스크린샷
- 오디오: 음성, 음악, 환경음
- 비디오: 움직이는 이미지 + 오디오의 조합
왜 멀티모달인가?
- 인간의 의사소통은 본질적으로 멀티모달임
- 단일 모달리티로는 놓치는 컨텍스트 정보 존재
- 더 풍부한 의미 추출 가능
- 실제 응용 사례에 적합
비전-언어 모델
아키텍처 접근 방식
1. 대비 학습(Contrastive Learning, CLIP 방식)
1Image Encoder → Image Embedding 2Text Encoder → Text Embedding 3Contrastive Loss: Match(image, text)
2. 생성 기반(GPTV 방식)
Image → Vision Encoder → Visual Tokens Visual Tokens + Text Tokens → LLM → Response
3. 크로스-어텐션 융합
Image Features ←Cross-Attention→ Text Features
비전 인코더 유형
| Encoder | Architecture | Resolution | Feature |
|---|---|---|---|
| ViT | Transformer | 224-1024 | 패치 기반 |
| CLIP ViT | Transformer | 336 | 대비 학습 |
| SigLIP | Transformer | 384 | Sigmoid loss |
| ConvNeXt | CNN | Flexible | 효율적 |
이미지 토크나이제이션
패치 임베딩(Patch Embedding):
224×224 image → 14×14 patch grid → 196 visual tokens Each patch: 16×16 pixel → Linear projection → Embedding
가변 해상도(Variable Resolution):
1Anyres approach: 21. Divide image into tiles 32. Encode each tile separately 43. Add global thumbnail 54. Concatenate all tokens
멀티모달 LLM 구현
GPTV 사용 예시
1from openai import OpenAI 2import base64 3 4client = OpenAI() 5 6def encode_image(image_path): 7 with open(image_path, "rb") as f: 8 return base64.b64encode(f.read()).decode('utf-8') 9 10response = client.chat.completions.create( 11 model="gpt-4-vision-preview", 12 messages=[ 13 { 14 "role": "user", 15 "content": [ 16 {"type": "text", "text": "Analyze this image"}, 17 { 18 "type": "image_url", 19 "image_url": { 20 "url": f"data:image/jpeg;base64,{encode_image('image.webp')}", 21 "detail": "high" # low, high, auto 22 } 23 } 24 ] 25 } 26 ], 27 max_tokens=1000 28)
Claude 3 Vision
1from anthropic import Anthropic 2import base64 3 4client = Anthropic() 5 6with open("image.webp", "rb") as f: 7 image_data = base64.standard_b64encode(f.read()).decode("utf-8") 8 9message = client.messages.create( 10 model="claude-3-opus-20240229", 11 max_tokens=1024, 12 messages=[ 13 { 14 "role": "user", 15 "content": [ 16 { 17 "type": "image", 18 "source": { 19 "type": "base64", 20 "media_type": "image/jpeg", 21 "data": image_data 22 } 23 }, 24 {"type": "text", "text": "What is in this image?"} 25 ] 26 } 27 ] 28) 29## 오디오 처리 30 31### 음성-텍스트 변환 (STT) 32 33**Whisper 모델:** 34```python 35from openai import OpenAI 36 37client = OpenAI() 38 39with open("audio.mp3", "rb") as audio_file: 40 transcript = client.audio.transcriptions.create( 41 model="whisper-1", 42 file=audio_file, 43 language="en" 44 ) 45 46print(transcript.text)
텍스트-음성 변환 (TTS)
1response = client.audio.speech.create( 2 model="tts-1-hd", 3 voice="alloy", # alloy, echo, fable, onyx, nova, shimmer 4 input="Hello, I am an AI assistant." 5) 6 7response.stream_to_file("output.mp3")
실시간 오디오 파이프라인
1Microphone → VAD → Chunking → STT → LLM → TTS → Speaker 2 ↓ 3 Voice Activity 4 Detection
비디오 이해
프레임 샘플링 전략
1. 균일 샘플링:
1def uniform_sample(video_path, num_frames=8): 2 cap = cv2.VideoCapture(video_path) 3 total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT)) 4 indices = np.linspace(0, total_frames-1, num_frames, dtype=int) 5 6 frames = [] 7 for idx in indices: 8 cap.set(cv2.CAP_PROP_POS_FRAMES, idx) 9 ret, frame = cap.read() 10 if ret: 11 frames.append(frame) 12 13 return frames
2. 키프레임 추출:
1def extract_keyframes(video_path, threshold=30): 2 # Finding keyframes with Scene change detection 3 pass
Video-LLM 파이프라인
1Video → Frame Sampling → Per-frame Encoding → Temporal Aggregation → LLM 2 ↓ 3 Audio Extraction → STT → Text
모달리티 융합
얼리 퓨전
모델 입력 단계에서 모달리티 결합:
[CLS] [IMG_1] ... [IMG_N] [SEP] [TXT_1] ... [TXT_M] [SEP]
레이트 퓨전
각 모달리티를 독립적으로 처리 후 결과 결합:
1Image → Image Model → Image Features ─┐ 2 ├→ Fusion Layer → Output 3Text → Text Model → Text Features ────┘
크로스-모달 어텐션
모달리티 간 어텐션:
1Q = Text Features 2K, V = Image Features 3Cross_Attention(Q, K, V) = softmax(QK^T/√d)V
OCR 및 문서 이해
Document AI 파이프라인
1def process_document(image_path): 2 # 1. Layout Detection 3 layout = detect_layout(image) # Headings, paragraphs, tables 4 5 # 2. OCR 6 text_regions = ocr_extract(image) 7 8 # 3. Structure Understanding 9 structured_doc = parse_structure(layout, text_regions) 10 11 # 4. LLM Analysis 12 analysis = llm_analyze(structured_doc) 13 14 return analysis
테이블 추출
1response = client.chat.completions.create( 2 model="gpt-4-vision-preview", 3 messages=[{ 4 "role": "user", 5 "content": [ 6 {"type": "image_url", "image_url": {"url": table_image_url}}, 7 {"type": "text", "text": "Extract this table in JSON format"} 8 ] 9 }] 10)
엔터프라이즈 멀티모달 활용
1. 문서 처리
- 인보이스/영수증 OCR
- 계약서 분석
- 양식 데이터 추출
2. 비주얼 검색
- 제품 이미지 기반 검색
- 유사 이미지 찾기
- 시각적 Q&A
3. 콘텐츠 모더레이션
- 부적절한 이미지 탐지
- 브랜드 로고 확인
- 텍스트 + 이미지 일관성 검사
4. 고객 지원
- 스크린샷 분석
- 시각적 문제 해결
- 음성 기반 지원
성능 최적화
이미지 전처리
1def optimize_image(image_path, max_size=1024, quality=85): 2 img = Image.open(image_path) 3 4 # Resize 5 if max(img.size) > max_size: 6 ratio = max_size / max(img.size) 7 new_size = tuple(int(d * ratio) for d in img.size) 8 img = img.resize(new_size, Image.LANCZOS) 9 10 # Compress 11 buffer = io.BytesIO() 12 img.save(buffer, format="JPEG", quality=quality) 13 14 return buffer.getvalue()
배치 처리
1async def batch_image_analysis(images, batch_size=5): 2 results = [] 3 for i in range(0, len(images), batch_size): 4 batch = images[i:i+batch_size] 5 tasks = [analyze_image(img) for img in batch] 6 batch_results = await asyncio.gather(*tasks) 7 results.extend(batch_results) 8 return results
비용 관리
토큰 계산 (Vision)
1GPTV Token Cost: 2- Low detail: 85 token/image 3- High detail: 85 + 170 × tile_count 4 5Example (2048×1024, high): 6Tiles: ceil(2048/512) × ceil(1024/512) = 4 × 2 = 8 7Tokens: 85 + 170 × 8 = 1445 tokens
최적화 전략
- 디테일 수준 조절: 필요하지 않다면 "high" 사용을 피하세요
- 이미지 크기 축소: 토큰 수 감소
- 캐싱: 동일한 이미지를 반복 분석하지 않기
- 배치 처리: API 호출 횟수 감소
결론
멀티모달 AI는 인공지능이 인간과 유사한 이해 능력에 가장 가까워지는 접근 방식입니다. 이미지, 텍스트, 오디오 모달리티의 결합은 더 강력하고 유용한 AI 애플리케이션을 가능하게 합니다.
Veni AI는 멀티모달 AI 솔루션을 개발하고 있습니다. 프로젝트가 있다면 언제든지 문의하세요.
