지난번에는 'V-JEPA 2로 무엇을 할 수 있을지 시도해보기'라는 주제로 V-JEPA 2를 직접 구동하여 영상의 특징 표현을 활용한 실험을 진행했습니다. 이번에는 그 연장선으로, 실용적인 도구로 만든다면 무엇이 가능할지 시험해 보았습니다.
만든 것은 예시로 삼고 싶은 2초 분량의 영상 구간을 선택하면, 현재 가지고 있는 영상에서 유사한 특징을 가진 구간을 찾아주는 'JEPA-ScenePick'이라는 도구입니다. 단순히 영상을 설명하게 하거나 특정 사건을 인식하게 하는 것이 아니라, '이 장면과 비슷한 구간은 어디에 있는지'를 찾는 것을 목표로 합니다.
코드와 설정 방법은 GitHub 리포지토리에 올려두었습니다.
Mac에서 로컬 영상을 선택하고 검색용 인덱스를 만듭니다. 다음으로, 예시로 삼고 싶은 영상의 2초 구간을 선택하여 검색하면, 유사한 후보들이 원본 영상의 시간 정보와 함께 표시됩니다. 후보들을 재생하며 비교하고, 보존(keep) 또는 보류(hold)를 기록한 후, 마지막에 참조 목록을 JSON 파일로 출력할 수 있습니다.
대략적인 과정은 다음과 같습니다.
- 영상을 선택하고 검색 방식을 결정하여 인덱스 생성
- 예시로 삼고 싶은 2초 구간을 선택하여 검색
- 표시된 후보들을 재생하며 비교
- 남기고 싶은 후보를 기록하고, 참조 목록을 JSON으로 출력
인덱싱과 검색에 사용하는 방식은 V-JEPA 2와 Color + Motion 중에서 선택할 수 있습니다. Color + Motion은 OpenCV를 사용하여 색상 분포와 프레임 간의 차이를 이용하는 가벼운 베이스라인입니다. V-JEPA 2 준비가 되어 있지 않은 상태에서 사용할 수 있는 방식으로 자동으로 전환되지는 않습니다.
영상에서 2초 길이의 창(window)을 만들고, 시작 위치를 0.5초씩 이동시키면서 특징을 추출합니다. V-JEPA 2를 선택한 경우, 각 창에서 64개의 프레임을 가져와 인코더에 입력하고, 출력 토큰을 평균하여 창별 특징 벡터로 요약합니다. Color + Motion의 경우 8개의 프레임을 사용합니다. 추출된 특징량과 영상의 시간 정보 등은 SQLite에 저장됩니다.
검색 시에는 예시 구간 역시 인덱싱 때와 동일한 방식으로 특징량을 만듭니다. 이 특징량과 이미 인덱스 된 창들의 특징량을 코사인 유사도(cosine similarity)로 비교하여 점수가 높은 후보들을 나열합니다. 같은 영상 내에서 시간적으로 가까운 후보들은 간격을 두어 표시하고, 바로 붙어 있는 창들만 결과로 채워지지 않도록 했습니다.
V-JEPA 2는 학습 시 잠재 표현(latent representation)을 예측하는 모델이지만, 이 도구에서는 예측기(predictor)의 출력이나 예측 오차를 이상도(anomaly score)로 사용하지 않았습니다. 인코더가 내놓는 특징을 가져와 특징 벡터들 간의 근접성을 조사하고 있습니다. 점수는 검색상의 유사도를 의미하며, 정답일 확률은 아닙니다.
화면은 HTML, CSS, JavaScript로 만들었고, Python 표준 라이브러리 기반의 HTTP 서버를 통해 조작합니다. 인덱싱이나 검색처럼 무거운 처리는 같은 Python 프로세스 내의 별도 스레드에서 작동하며, 동시에 실행되는 작업은 하나입니다. 특징량이나 검색 상태, 후보의 채택 여부는 로컬 SQLite에 저장됩니다.
UI 서버는 127.0.0.1에서 대기하고, 모델 추론 역시 로컬에서 진행합니다. 의존 패키지 설치 시에는 PyPI로 통신이 발생합니다. 검색 시 추론 대상으로 외부 클라우드를 사용하는 구조가 아닙니다.
리포지토리의 README에는 Python 3.12 또는 3.13을 사용할 절차를 안내하고 있습니다. 우선 V-JEPA 2 모델을 준비하지 않고 Color + Motion으로 화면을 테스트해 볼 수 있습니다.
git clone https://github.com/daikubo-jb/JEPA-ScenePick.git
cd JEPA-ScenePick
python3 -m venv .venv
...
브라우저에서 로컬 화면이 열리면 영상을 선택하고 인덱스를 생성합니다. 검색 방식에서 Color + Motion을 선택하면 2초 예시 구간부터 검색할 수 있습니다.
V-JEPA 2를 사용할 경우에는 PyTorch 같은 추가 의존성 외에도 별도로 준비해야 하는 jepa-risk-detection loader와 로컬 체크포인트(checkpoint)가 필요합니다. 이들은 이 리포지토리에 포함되어 있지 않기 때문에, 공개 리포지토리를 clone만 했다고 해서 V-JEPA 2의 추론까지 완료되지는 않습니다. README에 기재된 준비 절차와 라이선스 조건을 확인해 주십시오. V-JEPA 2의 체크포인트도 자동 다운로드되지 않습니다.
샘플 합성 영상으로 테스트했을 때, 이미지와 같습니다. 오른쪽에는 유사 후보들이 목록 형태로 표시됩니다.
スクリーンショット 2026-10-12 10.42.56.png
합성된 테스트용 영상과 가지고 있는 스키 영상을 가지고 시도해 본 결과, 비슷한 장면을 감지할 수 있을 것 같습니다.
개인적인 취미로 겨울에 스키를 탈 때 영상을 찍기 때문에, 이걸로 한번 시험해 보려고 합니다. 활강하는 부분을 특정해서 하이라이트 같은 것을 만드는 데 좋을 것 같습니다.
검색 대상은 고정된 2초 구간이며, 예시와 특징이 가까운 구간을 순위화합니다. 비슷하다는 점수가 높더라도 같은 물체나 같은 사건이 담겨있다고는 할 수 없습니다. 영상 내용을 문장으로 검색하거나, 경기의 플레이 또는 사고를 판정하거나, 자동으로 볼거리 영상을 만드는 기능은 없습니다. 실제 영상을 사용한 정량적 평가 또한 아직 진행하지 않았습니다.
검색 결과의 참조 JSON에는 비디오의 로컬 경로가 포함되어 있습니다. 공유할 때는 내용을 확인해 주십시오. 또한, 리포지토리의 고유 코드인 MIT 라이선스는 외부 로더(loader), 의존 패키지(dependency package), 모델 체크포인트(model checkpoint)에 적용되지 않습니다.
지난번 'JEPA를 직접 사용해 보기'에서 한 단계 더 나아가, 비디오 특징을 사용하여 유사한 구간을 찾는 로컬 도구를 만들었습니다. V-JEPA 2를 분류기나 예측 오차로 사용하는 것이 아니라, 인코더 특징의 검색에 사용하는 구성입니다. 예시를 선택하고 후보를 재생하는 흐름까지는 만들었지만, 어떤 영상에서도 기대했던 후보가 발견될지는 앞으로 소재와 평가 방법을 늘려 확인해 볼 필요가 있습니다.