Capstone 12 — 비디오 이해 파이프라인(Video Understanding Pipeline) — 장면(Scene), QA, 검색(Search)
2026년 들어 Twelve Labs는 Marengo와 Pegasus를 제품으로 출시했고, VideoDB는 비디오를 위한 CRUD-for-video 응용 프로그래밍 인터페이스(API)를 공개했습니다. AI2의 Molmo 2는 공개 비전-언어 모델(Vision-Language Model; VLM) 체크포인트(checkpoint)를 발표했고, Gemini long-context는 몇 시간짜리 비디오를 외부 도움 없이(native) 그대로 읽어 들입니다. TimeLens-100K는 대규모 시간 위치 추정(temporal grounding) 데이터셋을 정의했습니다. 그 결과 2026년의 파이프라인 형태는 거의 정착되었습니다. 장면 분할(scene segmentation), 장면별 캡션(caption)과 임베딩(embedding) 생성, 자막 정렬(transcript alignment), 다중 벡터 색인(multi-vector index), 그리고 (start, end) 타임스탬프(timestamp)와 프레임 미리보기(frame preview)로 답하는 질의(query)가 그 골격입니다. 이 캡스톤(capstone)은 100시간 분량의 비디오를 수집(ingest)해 공개 벤치마크(benchmark)를 통과시키고, 개수 세기(counting)와 행동(action) 유형 질문에서의 환각(hallucination)을 측정하는 것을 목표로 합니다.
유형: Capstone
언어: Python (파이프라인), TypeScript (사용자 인터페이스; UI)
선수 지식: Phase 4 (컴퓨터 비전; CV), Phase 6 (음성; speech), Phase 7 (트랜스포머; transformers), Phase 11 (LLM 엔지니어링), Phase 12 (멀티모달; multimodal), Phase 17 (인프라; infrastructure)
활용되는 Phase: P4 · P6 · P7 · P11 · P12 · P17
예상 시간: 약 30시간
문제
긴 형식 비디오 QA(long-form video QA)는 2026년 규모에서 가장 많은 대역폭(bandwidth)을 요구하는 멀티모달 문제입니다. Gemini 2.5 Pro는 두 시간짜리 비디오를 별도 전처리 없이 그대로 읽어 들일 수 있지만, 100시간 분량의 비디오를 질의 가능한 말뭉치(corpus)로 만들려면 여전히 장면 단위 색인(scene-level index)이 필요합니다. 운영 환경의 표준 형태는 장면 분할(TransNetV2 또는 PySceneDetect), 비전-언어 모델(Gemini 2.5, Qwen3-VL-Max, Molmo 2 등)을 사용한 장면별 캡션 생성, 단어 단위 타임스탬프(word timestamp)를 포함하는 Whisper-v3-turbo 기반 자막 정렬, 그리고 캡션·프레임 임베딩(frame embedding)·자막(transcript)을 나란히 저장하는 다중 벡터 색인을 결합한 구조입니다. 질의 파이프라인(query pipeline)은 (start, end) 타임스탬프와 프레임 미리보기를 포함해 답을 돌려줍니다.
벤치마크로는 공개된 ActivityNet-QA와 NeXT-GQA, 그리고 직접 구성한 100개 질의 데이터셋(custom set)을 함께 사용합니다. "방에 몇 명이 들어오는가?"처럼 개수를 세야 하는 질문(counting question)이나 "요리사가 젓기 전에 먼저 붓는가?"처럼 행동 순서를 묻는 질문(action-type question)에서 환각이 잘 발생한다는 점은 잘 알려진 난제(known-hard failure class)입니다. 이 캡스톤은 그 실패 양상을 명시적으로 측정하도록 요구합니다.
개념
수집 단계에서는 세 가지 파이프라인이 병렬로 실행됩니다. 장면 분할은 비디오를 장면 단위로 자르고, 비전-언어 모델 캡션 생성(VLM captioning)은 각 장면마다 캡션과 키프레임(keyframe) 기반의 프레임 임베딩을 만듭니다. 자동 음성 인식 정렬(ASR alignment)은 단어 단위 타임스탬프를 생성합니다. 이 세 흐름(stream)은 (scene_id, time range)를 기준으로 합쳐집니다(join). 각 장면은 다중 벡터 색인(Qdrant)에 캡션 임베딩(caption embedding), 키프레임 임베딩(keyframe embedding), 자막 임베딩(transcript embedding)이라는 세 종류의 벡터를 갖습니다.
질의 시점에는 자연어 질문이 세 벡터 전체를 향해 동시에 실행되고, 결과는 상호 순위 융합(Reciprocal Rank Fusion; RRF)으로 병합됩니다. 이어서 TimeLens 계열의 시간 위치 추정 어댑터(temporal-grounding adapter)가 가장 유력한 장면 안에서 (start, end) 구간(window)을 더 좁힙니다. 마지막으로 비전-언어 모델 합성기(VLM synthesizer; Gemini 2.5 Pro 또는 Qwen3-VL-Max)는 질의·상위 장면·잘라낸 프레임(cropped frame)을 받아 인용된 타임스탬프와 프레임 미리보기가 포함된 답변을 만들어 냅니다.
환각 측정이 핵심입니다. "몇 명의 사람이 들어왔는가?"처럼 개수를 세는 질문과 "요리사가 젓기 전에 먼저 붓는가?"처럼 행동 순서를 묻는 질문은 매우 불안정한 것으로 잘 알려져 있습니다. 묘사형 질문(descriptive question)과는 별도로 정확도를 따로 보고해야 합니다.
아키텍처
video file / URL
|
v
PySceneDetect / TransNetV2 (scene segmentation)
|
+--- per-scene keyframe --- VLM caption + frame embedding
| (Gemini 2.5 Pro / Qwen3-VL-Max / Molmo 2)
|
+--- audio channel --- Whisper-v3-turbo ASR + word timestamps
|
v
multi-vector Qdrant: {caption_emb, keyframe_emb, transcript_emb}
|
query:
dense queries against all three -> RRF merge -> top-k scenes
|
v
TimeLens / VideoITG temporal grounding (refine start/end within scene)
|
v
VLM synth: query + top scenes + frame previews
|
v
answer + (start, end) timestamps + frame thumbs + citations
스택
- 장면 분할(scene segmentation): 2024-26년 기준 최첨단(state-of-the-art)인 TransNetV2, 혹은 고전적인 PySceneDetect를 사용합니다.
- 자동 음성 인식(Automatic Speech Recognition; ASR): 단어 단위 타임스탬프를 함께 산출하는 faster-whisper 기반 Whisper-v3-turbo를 사용합니다.
- 비전-언어 모델 캡션 생성 및 응답기(captioner and answerer): Gemini 2.5 Pro, Qwen3-VL-Max, Molmo 2 가운데 하나를 선택해 사용합니다.
- 시간 위치 추정(temporal grounding): TimeLens-100K로 학습한 어댑터(adapter) 또는 VideoITG를 사용합니다.
- 색인(index): 캡션 · 프레임 · 자막을 분리해 다중 벡터 형태로 저장할 수 있도록 다중 벡터 지원이 있는 Qdrant를 사용합니다.
- 사용자 인터페이스(UI): HTML5 비디오 플레이어(video player)와 장면 썸네일(scene thumbnail)을 갖춘 Next.js 15를 사용합니다.
- 평가(eval): ActivityNet-QA, NeXT-GQA, 그리고 직접 손으로 라벨링(labeling)한 100개 질의 모음을 함께 사용합니다.
- 환각 벤치마크(hallucination benchmark): 개수 세기와 행동 유형 부분집합(subset)에 직접 라벨을 부여해 따로 측정합니다.
직접 만들기
-
수집 워커(ingest walker). YouTube URL 또는 로컬 MP4 파일을 받습니다. 필요하면 720p로 다운스케일(downscale)합니다. {video_id, file_path}를 저장합니다.
-
장면 분할(scene segmentation). TransNetV2 또는 PySceneDetect를 실행해 [{scene_id, start_ms, end_ms, keyframe_path}] 형태의 결과를 만듭니다. 100시간 기준 약 6천~8천 개의 장면을 목표로 합니다.
-
음성 인식 단계(ASR pass). 오디오 채널에 Whisper-v3-turbo를 실행해 단어 단위 타임스탬프를 내보내고(export), 장면별 자막 조각(transcript slice)으로 분할합니다.
-
비전-언어 모델 캡션 생성(VLM captioning). 장면마다 키프레임과 짧은 캡션 템플릿(caption template)을 Gemini 2.5 Pro 또는 Qwen3-VL-Max에 보냅니다. 캡션과 프레임 임베딩을 함께 만듭니다.
-
다중 벡터 색인(multi-vector index). 세 개의 이름 있는 벡터(named vector)를 갖는 Qdrant 컬렉션(collection)을 만듭니다. 페이로드(payload)에는 {video_id, scene_id, start_ms, end_ms, keyframe_url}을 함께 저장합니다.
-
질의(query). 자연어 질문을 캡션·프레임·자막 세 갈래의 밀집 질의(dense query)로 동시에 실행합니다. 상호 순위 융합(RRF)으로 병합한 뒤 상위 5개(top-k=5) 장면을 고릅니다.
-
시간 위치 추정(temporal grounding). 상위 장면에 TimeLens 계열 어댑터를 적용해 장면 안에서의 (start, end) 구간을 더 좁힙니다.
-
비전-언어 모델 합성(VLM synth). 질의와 상위 세 개(top-3) 장면 클립(이미지 혹은 짧은 영상 클립), 자막을 Gemini 2.5 Pro에 보냅니다. (video_id, start_ms, end_ms) 형식의 인용을 의무화합니다.
-
평가(eval). ActivityNet-QA와 NeXT-GQA로 측정합니다. 100개 질의로 구성한 자체 데이터셋을 만듭니다. 전체 정확도와 함께 부류별(개수 세기, 행동, 묘사) 세부 결과(per-class breakdown)를 보고합니다.
사용해보기
$ video-qa ask --url=https://youtube.com/watch?v=X "첫 1분 동안 교차로를 지나가는 자동차는 몇 대인가요?"
[scene] 23개 장면 감지
[asr] 자막 추출 완료, 4분 12초
[index] 69개 벡터 기록 (장면 23개 × 3)
[query] 상위 장면: 장면 3 [01:32-01:54], 신뢰도 0.84
[ground] 좁힌 구간: [00:12-00:58]
[synth] gemini 2.5 pro, 1.4초
answer: 00:12부터 00:58 사이에 5대의 자동차가 교차로를 지나갑니다.
citations: [scene 3: 00:12-00:58]
[frame preview at 00:14, 00:27, 00:44, 00:51, 00:57]
산출물 만들기
outputs/skill-video-qa.md가 이 캡스톤의 제출 산출물입니다. YouTube URL 또는 업로드된 비디오가 주어지면, 파이프라인은 장면을 색인하고 타임스탬프 인용이 함께 붙은 답변을 돌려줘야 합니다.
| 가중치 | 평가 항목 | 측정 방법 |
|---|
| 25 | 시간 위치 추정 IoU | 검증용(held-out) 위치 추정 데이터셋에서 교집합 대 합집합 비(Intersection-over-Union; IoU) |
| 20 | QA 정확도 | NeXT-GQA와 자체 100개 질의 데이터셋 |
| 20 | 수집 처리량 | 1달러당 색인한 비디오 시간(hours of video per dollar) |
| 20 | UI와 인용 경험(UX) | 타임스탬프 링크, 썸네일 스트립(thumbnail strip), 특정 프레임으로 바로 이동(jump-to-frame) 기능 |
| 15 | 환각 비율 | 개수 세기와 행동 유형 정확도를 따로 보고 |
| 100 | | |
연습문제
-
(쉬움) 캡션 생성 단계에서 Gemini 2.5 Pro를 Qwen3-VL-Max로 교체합니다. 사람이 평가한 50개 장면 표본에서 캡션 품질 차이(quality delta)를 보고합니다.
-
(중간) 장면별 프레임 임베딩을 다중 벡터가 아닌 한 개의 풀링된 벡터(pooled vector)로 축소합니다. 그에 따른 검색 성능 저하(retrieval regression)를 측정합니다.
-
(중간) "엄격한 개수 세기 모드(counting strict mode)"를 구현합니다. 합성기가 세어야 하는 각 사례(instance)를 타임스탬프와 함께 추출하고, 사용자가 클릭으로 검증하게 합니다. 사용자 검증이 환각을 얼마나 줄이는지 측정합니다.
-
(중간) 수집 비용(ingest cost)을 벤치마크합니다. 세 가지 비전-언어 모델 선택지에 대해 1달러당 색인한 비디오 시간을 비교하고, 비용 대비 성능의 균형점(sweet spot)을 고릅니다.
-
(어려움) 화자 분리(speaker diarization) 자막을 추가합니다. 오디오에 pyannote 화자 분리를 실행하고, 화자별 자막을 임베딩합니다. "Alice가 X에 대해 뭐라고 말했는가?" 같은 질의가 동작함을 시연합니다.
핵심 용어
| 용어 | 흔한 설명 | 실제 의미 |
|---|
| 장면 분할(Scene segmentation) | "샷 감지(shot detection)" | 샷 경계(shot boundary)를 기준으로 비디오를 장면 단위로 자르는 작업이다. |
| 다중 벡터 색인(Multi-vector index) | "캡션 + 프레임 + 자막" | 표현 방식별로 이름이 부여된 벡터를 함께 갖는 Qdrant 컬렉션이다. |
| 시간 위치 추정(Temporal grounding) | "정확히 언제 일어났는가" | 질의 답변에 대응하는 (start, end) 구간을 더 정밀하게 좁히는 과정이다. |
| 프레임 임베딩(Frame embedding) | "시각 표현(visual representation)" | 키프레임을 벡터로 임베딩한 결과이며, 장면의 시각적 유사도 검색에 사용된다. |
| 상호 순위 융합(Reciprocal Rank Fusion; RRF) | "여러 순위 목록을 섞는 방법" | 여러 개의 순위 목록을 합치는 고전적인 하이브리드 검색(hybrid retrieval) 전략이다. |
| 개수 세기 환각(Counting hallucination) | "잘못 세기" | "X가 몇 개인가" 부류의 질문에서 비전-언어 모델이 흔히 보이는 알려진 실패 양상이다. |
| ActivityNet-QA | "비디오 QA 벤치마크" | 긴 형식 비디오 QA 정확도를 측정하는 대표 벤치마크이다. |
더 읽을거리