지난 글에서 그림 하나에서 값을 뽑는 이야기를 했다. 영상은 그림이 수만 장 이어진 것이니 같은 문제가 수만 배로 늘어난 것처럼 보이지만, 실제로 부딪히는 문제는 다르다. 모델에 넣을 수 있는 그림은 몇 장뿐이고, 그 몇 장을 어디서 뽑느냐가 답을 정한다.
30fps로 찍은 10분짜리 영상은 프레임이 18,000장이다. 프레임 한 장이 이미지 토큰 수백 개를 먹으니 전부 넣는 것은 어떤 모델로도 불가능하다. 그러니 비디오 이해를 붙인다는 것은 대부분 어떤 열여섯 장을 고를 것인가를 정하는 일이다.
토큰 예산이 시간 해상도를 정한다
먼저 숫자를 세어 보자. 모델마다 다르지만 이미지 한 장이 대략 250800 토큰쯤 된다고 잡으면, 프레임 32장은 8,00025,000 토큰이다. 컨텍스트가 128K라도 대화 기록과 지시문을 빼고 나면 영상에 쓸 수 있는 것은 그 안쪽이다.
여기서 나오는 결론이 하나 있다. 프레임 수를 정하면 시간 해상도가 자동으로 정해진다.
10분 영상에 32장이면 간격이 18.75초다. 18.75초보다 짧은 사건은 존재 자체가 확률에 맡겨진다. 3초짜리 사건이 잡힐 확률은 대략 다. "영상에서 누가 넘어지는 장면 찾아 줘" 같은 요청이 자꾸 실패하는 이유가 여기 있다. 모델이 못 본 것이 아니라 그 프레임을 아예 안 준 것이다.
그러므로 설계의 첫 질문은 모델 선택이 아니라 이것이다. 찾아야 하는 사건이 몇 초짜리인가. 몇 분 단위의 주제 파악이면 균등 샘플링으로 충분하고, 몇 초짜리 사건 탐지면 다른 구조가 필요하다.
균등 샘플링은 기본값이지 정답이 아니다
가장 흔한 방식은 영상 길이를 프레임 수로 나눠 같은 간격으로 뽑는 것이다. 구현이 쉽고 편향이 없어서 기본값으로 좋다. 다만 무엇을 놓치는지는 알고 써야 한다.
대안은 장면 전환 지점을 먼저 찾아 그 앞뒤로 뽑는 것이다. 인접한 두 프레임의 색 히스토그램 차이가 임계값을 넘으면 장면이 바뀐 것으로 보는 방식이 오래 쓰였고, PySceneDetect 같은 도구가 이걸 그대로 해 준다. 편집된 영상 — 유튜브 콘텐츠, 강의, 뉴스 — 에서는 이 방식이 균등보다 확실히 낫다. 컷이 바뀌는 자리가 곧 내용이 바뀌는 자리이기 때문이다.
반대로 고정 카메라로 찍은 CCTV나 회의 녹화에서는 장면 전환이 거의 없다. 여기서 전환 기반 샘플링을 쓰면 한 구간에 프레임이 몰리거나 아예 아무 데서도 안 뽑힌다. 이런 영상에는 균등 샘플링에 움직임 크기(프레임 간 차이의 총량)를 얹어 "움직임이 많은 구간에 더 촘촘히" 뽑는 방식이 맞다.
정리하면 이렇다.
| 영상 성격 | 맞는 샘플링 |
|---|---|
| 편집된 콘텐츠·강의·뉴스 | 장면 전환 기반 |
| 고정 카메라·CCTV·회의 녹화 | 균등 + 움직임 가중 |
| 화면 녹화·튜토리얼 | 화면 변화 감지(픽셀 차이) 기반 |
| 무엇을 찾을지 미리 아는 경우 | 값싼 탐지기로 후보를 먼저 좁힌 뒤 그 구간만 |
마지막 줄이 실무에서 가장 자주 쓰인다. "안전모 미착용"을 찾는다면 값싼 사람 검출기를 전 프레임에 돌려 사람이 있는 구간만 남기고, 그 구간에서만 VLM을 부른다. 무거운 모델을 부르는 횟수가 수십 분의 일로 준다.
시간 정보는 저절로 남지 않는다
프레임 열여섯 장을 순서대로 넣으면 모델이 순서를 안다고 생각하기 쉽지만, 실제로는 어느 프레임이 몇 초 지점인지를 모른다. 그래서 "몇 분에 그 장면이 나오나요"라고 물으면 그럴듯한 시각을 지어낸다.
방법은 단순하다. 프레임마다 그 시각을 텍스트로 함께 넣는다.
parts = []
for t, frame in sampled_frames: # t는 초 단위
parts.append({"type": "text", "text": f"[{t // 60:02d}:{t % 60:05.2f}]"})
parts.append({"type": "image", "source": encode(frame)})
parts.append({"type": "text", "text": "각 장면에 무슨 일이 있었는지 시각과 함께 적어 주세요."})
이렇게 하면 모델이 답에 시각을 적을 근거가 생긴다. 프레임 위에 타임코드를 그려 넣는 방법도 쓰이는데, 글자를 읽어야 하는 만큼 텍스트로 주는 편이 안전하다.
샘플링 간격도 알려 준다. "이 프레임들은 18.75초 간격으로 뽑은 것이며 그 사이는 보지 못했습니다"라는 한 줄을 넣으면, 모델이 사이에 일어난 일을 단정하지 않고 "확인할 수 없다"고 답하는 비율이 올라간다.
오디오 트랙을 버리지 않는다
영상 이해를 시각 문제로만 잡으면 절반을 버리는 것이다. 강의·회의·인터뷰·리뷰 영상에서 정보의 대부분은 말에 있다. 프레임 열여섯 장으로는 못 담는 내용이 자막 한 페이지에 다 들어 있는 경우가 흔하다.
실무 구성은 대개 이렇다. 오디오를 먼저 음성 인식에 넣어 시각이 붙은 텍스트를 얻고, 그 텍스트와 샘플링한 프레임을 함께 모델에 준다. 텍스트는 이미지보다 압도적으로 싸므로 — 1분 분량 말이 대략 150 토큰이고 프레임 한 장이 400 토큰이다 — 자막을 통째로 넣어도 프레임 몇 장 값이 안 된다.
그리고 자막에는 시각이 이미 붙어 있다. 자막에서 관심 구간을 먼저 찾고 그 구간의 프레임만 뽑는 방식이 값싸고 정확하다. "발표자가 가격표를 보여 준 부분"을 찾는다면, 자막에서 "가격"이 나온 시각을 찾아 그 앞뒤 10초만 프레임으로 뽑으면 된다.
긴 영상은 두 번 본다
한 시간이 넘어가면 프레임을 아무리 잘 골라도 한 번에 안 들어간다. 이때 쓰는 구조가 얕게 한 번, 깊게 한 번이다.
1차에서 영상을 3060초 토막으로 자르고 토막마다 프레임 몇 장과 자막으로 한 줄 요약을 만든다. 이 요약에는 시작·끝 시각이 붙는다. 한 시간짜리 영상이면 요약 60120줄이 되고, 이건 텍스트라 전부 컨텍스트에 들어간다.
2차에서는 질문을 받아 요약만 보고 후보 토막을 두세 개로 좁힌 뒤, 그 토막만 초당 두 장 정도로 촘촘히 뽑아 다시 읽는다. 1차의 시간 해상도로는 못 봤던 짧은 사건이 여기서 보인다.
이 구조는 멀티모달 RAG와 뼈대가 같다. 요약이 색인이고 원본 프레임이 본문이다. 다른 점은 색인 단위가 문서가 아니라 시간 구간이라는 것뿐이다.
비용 차이가 크다. 한 시간 영상을 초당 두 장으로 전부 읽으면 프레임 7,200장이고, 요약 파이프라인은 1차에 480장 남짓, 2차에 120장 정도다. 열 배 넘게 싸고, 무엇보다 한 번에 들어간다.
평가는 답만 보지 않는다
비디오 질의응답을 평가할 때 답의 내용만 채점하면 두 가지를 놓친다.
첫째, 근거 시각의 정확도다. "언제 상자가 떨어졌나요"에 "00:22쯤"이라고 답했다면 그 시각이 맞았는지를 따로 재야 한다. 보통 정답 구간과 예측 구간의 겹침 비율(temporal IoU)을 쓰고, 임계값 0.5 정도에서 맞았다/틀렸다를 가른다. 근거 시각을 안 내는 파이프라인은 이 평가를 아예 못 한다 — 그래서 앞에서 시각을 함께 뽑으라고 한 것이다.
둘째, 샘플링을 바꿨을 때의 변화다. 같은 질문·같은 모델로 프레임 8장·16장·32장을 각각 돌려 정확도를 재 보면, 어느 지점에서 곡선이 평평해지는지 보인다. 그 지점이 그 영상 종류에 필요한 시간 해상도이고, 그보다 더 넣는 것은 돈만 쓰는 것이다. 모델을 바꿔 보기 전에 이 곡선부터 그린다. 정확도가 프레임 수에 따라 계속 올라가고 있다면 문제는 모델이 아니라 샘플링이다.
여기에 멀티모달 평가에서 다룬 것과 같은 주의가 그대로 적용된다. 자막만으로도 맞힐 수 있는 문제가 섞여 있으면 시각 능력을 재는 게 아니다. 프레임을 다 빼고 자막만 줬을 때의 점수를 함께 재 보면, 그 차이가 실제로 영상을 봐서 얻은 몫이다.
정리
- 비디오 이해의 실제 설계 변수는 모델이 아니라 몇 장을 어디서 뽑을 것인가다
- 프레임 수가 시간 해상도를 정한다. 간격보다 짧은 사건은 존재 자체가 확률에 맡겨진다
- 균등 샘플링은 기본값이고, 편집된 영상은 장면 전환 기반, 고정 카메라는 움직임 가중이 낫다
- 프레임마다 시각을 텍스트로 함께 넣는다. 안 그러면 모델이 시각을 지어낸다
- 오디오 자막은 싸고 시각이 붙어 있다. 자막에서 구간을 먼저 좁히고 그 구간만 프레임으로 뽑는다
- 한 시간이 넘는 영상은 토막 요약으로 색인을 만들고, 고른 토막만 촘촘히 다시 읽는다
- 평가는 답과 함께 근거 시각을 재고, 프레임 수에 따른 정확도 곡선을 먼저 그린다
읽어주셔서 감사합니다. 😊

