파트너십

Twelve Labs와 FiftyOne 플러그인으로 동영상 시맨틱 검색하기

제임스 러

이 튜토리얼에서는 Twelve Labs의 비디오 시맨틱 검색(Video Semantic Search)을 통합하는 FiftyOne 플러그인을 구축하는 과정을 소개합니다. 이를 통해 데이터 사이언티스트는 비디오 데이터셋을 인덱싱하고 FiftyOne 인터페이스에서 직접 자연어 검색 쿼리를 실행하여, 수동으로 검토하지 않고도 원하는 비디오 샘플을 찾아낼 수 있습니다.

이 튜토리얼에서는 Twelve Labs의 비디오 시맨틱 검색(Video Semantic Search)을 통합하는 FiftyOne 플러그인을 구축하는 과정을 소개합니다. 이를 통해 데이터 사이언티스트는 비디오 데이터셋을 인덱싱하고 FiftyOne 인터페이스에서 직접 자연어 검색 쿼리를 실행하여, 수동으로 검토하지 않고도 원하는 비디오 샘플을 찾아낼 수 있습니다.

In this article

No headings found on page

뉴스레터 구독하기

뉴스레터 구독하기

영상 이해 분야의 최신 기술 업데이트, 튜토리얼 및 인사이트를 받아보세요.

영상 이해 분야의 최신 기술 업데이트, 튜토리얼 및 인사이트를 받아보세요.

AI로 영상을 검색하고, 분석하고, 탐색하세요.

2024. 1. 23.

4분

링크 복사하기

이 튜토리얼은 Voxel51의 ML 에반젤리스트인 Daniel Gural과 공동 집필했습니다.

비디오는 작은 페이로드 안에 방대한 데이터가 압축되어 있는 보고와 같습니다. 다른 단일 모달리티와 달리, 비디오는 시간에 따른 변화를 고려해야 하면서도 이미지와 오디오 데이터로 가득 차 있습니다. 데이터 과학자들은 이러한 데이터를 가장 효율적으로 풀어서 비디오 안에 정확히 무엇이 들어있는지 이해하기 위해 수년 동안 연구해 왔습니다.

새로운 시대는 언제나 새로운 도전 과제를 동반합니다. 많은 데이터 과학자와 머신러닝 엔지니어들은 수 테라바이트에 달하는 비디오 중에서 모델 학습에 필수적인 비디오만 골라내야 하는 과제에 직면해 있습니다. 한때는 엄두도 내지 못했던 이 작업이 비디오 이해 기술의 최신 진화인 '비디오 시맨틱 검색(Video Semantic Search)' 덕분에 이제는 아주 간단해졌습니다.

이 튜토리얼에서는 Twelve Labs의 비디오 시맨틱 검색 기술을 활용하여 빠르고 반복 가능한 검색 워크플로우를 생성할 수 있는 FiftyOne 플러그인 구축 방법을 배웁니다. Twelve Labs API를 활용하려는 숙련된 개발자든, 오픈소스 도구인 FiftyOne의 기능을 탐색해 보고 싶은 열정적인 사용자든, 이 튜토리얼은 여러분의 프로젝트에 비디오 시맨틱 검색을 매끄럽게 통합하는 데 필요한 지식과 기술을 제공할 것입니다.

튜토리얼의 완 완성된 결과물은 Semantic Video Search Plugin GitHub 페이지에서 확인할 수 있습니다. 또한, 이 과정을 직접 시연하는 비디오 가이드도 Twelve Labs의 YouTube 페이지 여기에서 시청하실 수 있습니다!

시작하기

시작하기 전에, 플러그인을 구축하는 데 필요한 준비물을 살펴보겠습니다. 다음 항목이 필요합니다:

  1. Twelve Labs 계정: Twelve Labs는 자연어 쿼리를 사용한 시맨틱 검색, 제로샷(Zero-shot) 분류, 비디오 콘텐츠 기반 텍스트 생성 등 다양한 태스크를 지원하는 강력한 비디오 이해용 파운데이션 모델을 구축합니다. 아직 계정이 없다면 무료로 가입하세요!

  2. FiftyOne GitHub 클론 저장소: FiftyOne은 고품질 데이터셋과 컴퓨터 비전 모델을 구축하기 위한 오픈소스 도구로, Voxel51에서 관리하고 있습니다.

  3. FiftyOne Plugins 클론 저장소: FiftyOne은 도구의 기능을 확장하고 맞춤화할 수 있는 강력한 플러그인 프레임워크를 제공합니다. Twelve Labs 플러그인을 관리하고 빌드하기 위한 유틸리티가 포함된 FiftyOne Plugins Management and Development 플러그인을 설치해야 합니다.

  4. 비디오 데이터셋.

준비물이 모두 갖춰졌다면 이제 본격적으로 시작해 보겠습니다! 먼저 FiftyOne에 데이터를 로드하고, Twelve Labs API가 올바르게 구성되었는지 테스트해 보겠습니다.

여기서는 FiftyOne에서 제공하는 quickstart-video 데이터셋을 사용하겠습니다. 빠르고 간편하게 구동할 수 있습니다:

import fiftyone as fo
import fiftyone.zoo as foz

dataset = foz.load_zoo_dataset("quickstart-video")

session = fo.launch_app(dataset)

다음으로 사용할 Twelve Labs API 키와 API URL을 정의했는지 확인하세요. 기존에 생성해 둔 인덱스를 조회하여 API가 잘 설정되어 있는지 간단히 테스트할 수 있습니다. 먼저 키와 URL을 환경 변수로 설정해 보겠습니다:

export TWELVE_API_KEY=<YOUR_API_KEY>

또는

import os

os.environ['TWELVE_API_KEY'] = <YOUR_API_KEY>

그다음, Twelve Labs API를 호출하여 기존 인덱스를 조회하고 우리 변수들이 제대로 유효한지 확인합니다.

import time
import requests
import glob
from pprint import pprint
import os

API_URL = os.getenv("TWELVE_API_URL")
assert API_URL

API_KEY = os.getenv("TWELVE_API_KEY")
assert API_KEY

INDEXES_URL = f"{API_URL}/indexes"

headers = {
	"x-api-key": API_KEY,
	"Content-Type": "application/json"
}

response = requests.get(INDEXES_URL, headers=headers)

API 응답 결과가 실패 메시지가 아닌 성공 메시지를 반환하는지 반드시 확인해 주세요!

비디오 시맨틱 검색 수행하기

성공적으로 연결되었다면, 이제 플러그인이 수행해야 할 단계를 세부적으로 쪼개어 보겠습니다. 우리가 달성해야 할 주요 목표는 다음 세 가지입니다:

  1. 인덱스 생성

  2. 데이터셋 인덱싱

  3. 데이터셋 검색

첫 번째와 두 번째 목표를 하나의 오퍼레이터(operator)로 묶고, 검색을 위한 두 번째 오퍼레이터를 따로 만들 것입니다. 먼저 Jupyter 노트북에서 이 전체 흐름을 시작부터 끝까지 실행해 보겠습니다. 자세한 정보는 FiftyOne 문서Twelve Labs 문서에서 확인할 수 있습니다.

1 - “VideoSearch”라는 이름의 인덱스 생성하기

이 인덱스는 visual, text_in_video, logo 영역에 걸쳐 검색할 수 있도록 지원합니다. 만약 비디오에 오디오 음성이 포함되어 있다면 Twelve Labs의 conversation 옵션도 함께 제공됩니다.

INDEXES_URL = f"{API_URL}/indexes"

INDEX_NAME = "VideoSearch" # Use a descriptive name for your index

headers = {
    "x-api-key": API_KEY
}

data = {
  "engine_id": "marengo2.5",
  "index_options": ["visual",  "text_in_video", "logo"],
  "index_name": INDEX_NAME,
}

response = requests.post(INDEXES_URL, headers=headers, json=data)
INDEX_ID = response.json().get('_id')
print (f'Status code: {response.status_code}')
pprint (response.json())

2 - 데이터셋 인덱싱하기

비디오 파일이 Twelve Labs의 제한 사항을 충족하기 위해 4초 이상인지 검사해야 합니다. 각 비디오를 Twelve Labs로 전송하고 완료 확인 신호를 받은 다음 다음 비디오로 넘어갑니다.

TASKS_URL = f"{API_URL}/tasks"

videos = dataset
for sample in videos:
	if sample.metadata.duration < 4:
    	continue
	else:
    	file_name = sample.filepath.split("/")[-1]
    	file_path = sample.filepath
    	file_stream = open(file_path,"rb")
    
    	headers = {
        	"x-api-key": API_KEY
    	}
    
    	data = {
        	"index_id": INDEX_ID,
        	"language": "en"
    	}
    
    	file_param=[
        	("video_file", (file_name, file_stream, "application/octet-stream")),]
    
    	response = requests.post(TASKS_URL, headers=headers, data=data, files=file_param)
    	TASK_ID = response.json().get("_id")
    	print (f"Status code: {response.status_code}")
    	pprint (response.json())
    
    	TASK_STATUS_URL = f"{API_URL}/tasks/{TASK_ID}"
    	while True:
        	response = requests.get(TASK_STATUS_URL, headers=headers)
        	STATUS = response.json().get("status")
        	if STATUS == "ready":
            	break
        	time.sleep(10)
   	 
    	VIDEO_ID = response.json().get('video_id')
    	sample["Twelve ID"] = VIDEO_ID
    	sample.save()
      
    	print (f"Status code: {STATUS}")
    	print(f"VIDEO ID: {VIDEO_ID}")
    	pprint (response.json())

3 - 데이터셋 검색 쿼리 실행하기

예를 들어, “sunny day(화창한 날)”를 검색하면 이 쿼리와 일치하는 검색 결과들을 얻을 수 있습니다.

prompt = "sunny day"
SEARCH_URL = f"{API_URL}/search"

headers = {
	"x-api-key": API_KEY
}

data = {
	"query": prompt,
	"index_id": INDEX_ID,
	"search_options": ["visual", "text_in_video", "logo"],
}

response = requests.post(SEARCH_URL, headers=headers, json=data)



워크플로우가 성공적으로 테스트되고 검증되었다면, 이제 이를 FiftyOne 플러그인에 이식할 차례입니다! 기본 코드를 다듬는 데 도움이 되는 FiftyOne 스켈레톤 오퍼레이터를 구축해 볼 텐데요. 다행히 FiftyOne Management & Development Plugin을 활용하면 훨씬 간편합니다! `build operator skeleton` 오퍼레이터의 도움을 받아 필요한 모든 커스텀 코드 블록을 손쉽게 구성할 수 있습니다.

플러그인 빌드를 위한 시작 지점을 확보한 후, `build plugin component` 오퍼레이터를 적용하여 나머지 입력 필드와 알림 메시지들을 채워 넣습니다. 이 작업은 플러그인에 추가하고 싶은 UI 모듈을 탐색하는 아주 쉽고 훌륭한 방법입니다. 모든 코드는 Python으로 작성되어 제공되므로, 포함하고 싶은 로직에 맞춰 매우 손쉽게 수정하고 실험해 볼 수 있습니다.

스켈레톤 코드가 완성되고 Twelve Labs 워크플로우를 정의했다면 마지막 단계는 이들을 모두 결합하는 것입니다! 적절한 코드를 두 오퍼레이터에 구현한 후, 앱을 저장 및 새로고침하여 우리가 만든 플러그인을 테스트해 보세요!

결론

개발자들은 Twelve Labs의 비디오 시맨틱 검색 서비스를 활용하여 소셜 미디어, 브랜드 인사이트, 팟캐스트, 사용자 생성 콘텐츠(UGC)를 포함해 다양한 산업군에 걸친 무궁무진한 유스케이스를 개척할 수 있습니다. 이 강력한 도구는 맥락 기반의 비디오 콘텐츠 검색과 효과적인 비디오 분석을 가능하게 하며, 교육 콘텐츠 검색, 기업 지식 관리, 그리고 동영상 편집 스위트 플랫폼에 매우 가치 있는 솔루션이 되어 줍니다.

Twelve Labs는 비디오 이해에 특화된 혁신적인 AI 파운데이션 모델을 구축하는 선구적인 스타트업입니다. 우리의 최신 비디오-언어 파운데이션 모델인 Pegasus-1과 강력한 Video-to-text API 라인업은 비디오 데이터를 총체적으로 이해할 수 있는 최첨단 솔루션을 제공합니다. 파트너사인 Voxel51은 데이터 탐색 및 시각화를 위한 최고의 오픈소스 플랫폼인 FiftyOne을 제공하여, 개발자들이 Twelve Labs의 비디오 시맨틱 검색 기능을 프로젝트에 한층 더 깊이 있게 통합하도록 돕고 있습니다.

다음 단계는 무엇인가요?

  • 퀵스타트 가이드를 살펴보고 Twelve Labs와 함께 놀라운 비디오 앱 빌드를 시작해보세요.

  • Twelve Labs Playground를 직접 경험해 보세요. 가입 시 10시간 분량의 무료 비디오 크레딧이 기본 제공됩니다.

  • 우리의 공식 X (Twitter)LinkedIn을 팔로우하세요.

  • 동료 개발자 및 유저들과 교류할 수 있는 공식 Discord 커뮤니티에 참여하세요.

이 튜토리얼은 Voxel51의 ML 에반젤리스트인 Daniel Gural과 공동 집필했습니다.

비디오는 작은 페이로드 안에 방대한 데이터가 압축되어 있는 보고와 같습니다. 다른 단일 모달리티와 달리, 비디오는 시간에 따른 변화를 고려해야 하면서도 이미지와 오디오 데이터로 가득 차 있습니다. 데이터 과학자들은 이러한 데이터를 가장 효율적으로 풀어서 비디오 안에 정확히 무엇이 들어있는지 이해하기 위해 수년 동안 연구해 왔습니다.

새로운 시대는 언제나 새로운 도전 과제를 동반합니다. 많은 데이터 과학자와 머신러닝 엔지니어들은 수 테라바이트에 달하는 비디오 중에서 모델 학습에 필수적인 비디오만 골라내야 하는 과제에 직면해 있습니다. 한때는 엄두도 내지 못했던 이 작업이 비디오 이해 기술의 최신 진화인 '비디오 시맨틱 검색(Video Semantic Search)' 덕분에 이제는 아주 간단해졌습니다.

이 튜토리얼에서는 Twelve Labs의 비디오 시맨틱 검색 기술을 활용하여 빠르고 반복 가능한 검색 워크플로우를 생성할 수 있는 FiftyOne 플러그인 구축 방법을 배웁니다. Twelve Labs API를 활용하려는 숙련된 개발자든, 오픈소스 도구인 FiftyOne의 기능을 탐색해 보고 싶은 열정적인 사용자든, 이 튜토리얼은 여러분의 프로젝트에 비디오 시맨틱 검색을 매끄럽게 통합하는 데 필요한 지식과 기술을 제공할 것입니다.

튜토리얼의 완 완성된 결과물은 Semantic Video Search Plugin GitHub 페이지에서 확인할 수 있습니다. 또한, 이 과정을 직접 시연하는 비디오 가이드도 Twelve Labs의 YouTube 페이지 여기에서 시청하실 수 있습니다!

시작하기

시작하기 전에, 플러그인을 구축하는 데 필요한 준비물을 살펴보겠습니다. 다음 항목이 필요합니다:

  1. Twelve Labs 계정: Twelve Labs는 자연어 쿼리를 사용한 시맨틱 검색, 제로샷(Zero-shot) 분류, 비디오 콘텐츠 기반 텍스트 생성 등 다양한 태스크를 지원하는 강력한 비디오 이해용 파운데이션 모델을 구축합니다. 아직 계정이 없다면 무료로 가입하세요!

  2. FiftyOne GitHub 클론 저장소: FiftyOne은 고품질 데이터셋과 컴퓨터 비전 모델을 구축하기 위한 오픈소스 도구로, Voxel51에서 관리하고 있습니다.

  3. FiftyOne Plugins 클론 저장소: FiftyOne은 도구의 기능을 확장하고 맞춤화할 수 있는 강력한 플러그인 프레임워크를 제공합니다. Twelve Labs 플러그인을 관리하고 빌드하기 위한 유틸리티가 포함된 FiftyOne Plugins Management and Development 플러그인을 설치해야 합니다.

  4. 비디오 데이터셋.

준비물이 모두 갖춰졌다면 이제 본격적으로 시작해 보겠습니다! 먼저 FiftyOne에 데이터를 로드하고, Twelve Labs API가 올바르게 구성되었는지 테스트해 보겠습니다.

여기서는 FiftyOne에서 제공하는 quickstart-video 데이터셋을 사용하겠습니다. 빠르고 간편하게 구동할 수 있습니다:

import fiftyone as fo
import fiftyone.zoo as foz

dataset = foz.load_zoo_dataset("quickstart-video")

session = fo.launch_app(dataset)

다음으로 사용할 Twelve Labs API 키와 API URL을 정의했는지 확인하세요. 기존에 생성해 둔 인덱스를 조회하여 API가 잘 설정되어 있는지 간단히 테스트할 수 있습니다. 먼저 키와 URL을 환경 변수로 설정해 보겠습니다:

export TWELVE_API_KEY=<YOUR_API_KEY>

또는

import os

os.environ['TWELVE_API_KEY'] = <YOUR_API_KEY>

그다음, Twelve Labs API를 호출하여 기존 인덱스를 조회하고 우리 변수들이 제대로 유효한지 확인합니다.

import time
import requests
import glob
from pprint import pprint
import os

API_URL = os.getenv("TWELVE_API_URL")
assert API_URL

API_KEY = os.getenv("TWELVE_API_KEY")
assert API_KEY

INDEXES_URL = f"{API_URL}/indexes"

headers = {
	"x-api-key": API_KEY,
	"Content-Type": "application/json"
}

response = requests.get(INDEXES_URL, headers=headers)

API 응답 결과가 실패 메시지가 아닌 성공 메시지를 반환하는지 반드시 확인해 주세요!

비디오 시맨틱 검색 수행하기

성공적으로 연결되었다면, 이제 플러그인이 수행해야 할 단계를 세부적으로 쪼개어 보겠습니다. 우리가 달성해야 할 주요 목표는 다음 세 가지입니다:

  1. 인덱스 생성

  2. 데이터셋 인덱싱

  3. 데이터셋 검색

첫 번째와 두 번째 목표를 하나의 오퍼레이터(operator)로 묶고, 검색을 위한 두 번째 오퍼레이터를 따로 만들 것입니다. 먼저 Jupyter 노트북에서 이 전체 흐름을 시작부터 끝까지 실행해 보겠습니다. 자세한 정보는 FiftyOne 문서Twelve Labs 문서에서 확인할 수 있습니다.

1 - “VideoSearch”라는 이름의 인덱스 생성하기

이 인덱스는 visual, text_in_video, logo 영역에 걸쳐 검색할 수 있도록 지원합니다. 만약 비디오에 오디오 음성이 포함되어 있다면 Twelve Labs의 conversation 옵션도 함께 제공됩니다.

INDEXES_URL = f"{API_URL}/indexes"

INDEX_NAME = "VideoSearch" # Use a descriptive name for your index

headers = {
    "x-api-key": API_KEY
}

data = {
  "engine_id": "marengo2.5",
  "index_options": ["visual",  "text_in_video", "logo"],
  "index_name": INDEX_NAME,
}

response = requests.post(INDEXES_URL, headers=headers, json=data)
INDEX_ID = response.json().get('_id')
print (f'Status code: {response.status_code}')
pprint (response.json())

2 - 데이터셋 인덱싱하기

비디오 파일이 Twelve Labs의 제한 사항을 충족하기 위해 4초 이상인지 검사해야 합니다. 각 비디오를 Twelve Labs로 전송하고 완료 확인 신호를 받은 다음 다음 비디오로 넘어갑니다.

TASKS_URL = f"{API_URL}/tasks"

videos = dataset
for sample in videos:
	if sample.metadata.duration < 4:
    	continue
	else:
    	file_name = sample.filepath.split("/")[-1]
    	file_path = sample.filepath
    	file_stream = open(file_path,"rb")
    
    	headers = {
        	"x-api-key": API_KEY
    	}
    
    	data = {
        	"index_id": INDEX_ID,
        	"language": "en"
    	}
    
    	file_param=[
        	("video_file", (file_name, file_stream, "application/octet-stream")),]
    
    	response = requests.post(TASKS_URL, headers=headers, data=data, files=file_param)
    	TASK_ID = response.json().get("_id")
    	print (f"Status code: {response.status_code}")
    	pprint (response.json())
    
    	TASK_STATUS_URL = f"{API_URL}/tasks/{TASK_ID}"
    	while True:
        	response = requests.get(TASK_STATUS_URL, headers=headers)
        	STATUS = response.json().get("status")
        	if STATUS == "ready":
            	break
        	time.sleep(10)
   	 
    	VIDEO_ID = response.json().get('video_id')
    	sample["Twelve ID"] = VIDEO_ID
    	sample.save()
      
    	print (f"Status code: {STATUS}")
    	print(f"VIDEO ID: {VIDEO_ID}")
    	pprint (response.json())

3 - 데이터셋 검색 쿼리 실행하기

예를 들어, “sunny day(화창한 날)”를 검색하면 이 쿼리와 일치하는 검색 결과들을 얻을 수 있습니다.

prompt = "sunny day"
SEARCH_URL = f"{API_URL}/search"

headers = {
	"x-api-key": API_KEY
}

data = {
	"query": prompt,
	"index_id": INDEX_ID,
	"search_options": ["visual", "text_in_video", "logo"],
}

response = requests.post(SEARCH_URL, headers=headers, json=data)



워크플로우가 성공적으로 테스트되고 검증되었다면, 이제 이를 FiftyOne 플러그인에 이식할 차례입니다! 기본 코드를 다듬는 데 도움이 되는 FiftyOne 스켈레톤 오퍼레이터를 구축해 볼 텐데요. 다행히 FiftyOne Management & Development Plugin을 활용하면 훨씬 간편합니다! `build operator skeleton` 오퍼레이터의 도움을 받아 필요한 모든 커스텀 코드 블록을 손쉽게 구성할 수 있습니다.

플러그인 빌드를 위한 시작 지점을 확보한 후, `build plugin component` 오퍼레이터를 적용하여 나머지 입력 필드와 알림 메시지들을 채워 넣습니다. 이 작업은 플러그인에 추가하고 싶은 UI 모듈을 탐색하는 아주 쉽고 훌륭한 방법입니다. 모든 코드는 Python으로 작성되어 제공되므로, 포함하고 싶은 로직에 맞춰 매우 손쉽게 수정하고 실험해 볼 수 있습니다.

스켈레톤 코드가 완성되고 Twelve Labs 워크플로우를 정의했다면 마지막 단계는 이들을 모두 결합하는 것입니다! 적절한 코드를 두 오퍼레이터에 구현한 후, 앱을 저장 및 새로고침하여 우리가 만든 플러그인을 테스트해 보세요!

결론

개발자들은 Twelve Labs의 비디오 시맨틱 검색 서비스를 활용하여 소셜 미디어, 브랜드 인사이트, 팟캐스트, 사용자 생성 콘텐츠(UGC)를 포함해 다양한 산업군에 걸친 무궁무진한 유스케이스를 개척할 수 있습니다. 이 강력한 도구는 맥락 기반의 비디오 콘텐츠 검색과 효과적인 비디오 분석을 가능하게 하며, 교육 콘텐츠 검색, 기업 지식 관리, 그리고 동영상 편집 스위트 플랫폼에 매우 가치 있는 솔루션이 되어 줍니다.

Twelve Labs는 비디오 이해에 특화된 혁신적인 AI 파운데이션 모델을 구축하는 선구적인 스타트업입니다. 우리의 최신 비디오-언어 파운데이션 모델인 Pegasus-1과 강력한 Video-to-text API 라인업은 비디오 데이터를 총체적으로 이해할 수 있는 최첨단 솔루션을 제공합니다. 파트너사인 Voxel51은 데이터 탐색 및 시각화를 위한 최고의 오픈소스 플랫폼인 FiftyOne을 제공하여, 개발자들이 Twelve Labs의 비디오 시맨틱 검색 기능을 프로젝트에 한층 더 깊이 있게 통합하도록 돕고 있습니다.

다음 단계는 무엇인가요?

  • 퀵스타트 가이드를 살펴보고 Twelve Labs와 함께 놀라운 비디오 앱 빌드를 시작해보세요.

  • Twelve Labs Playground를 직접 경험해 보세요. 가입 시 10시간 분량의 무료 비디오 크레딧이 기본 제공됩니다.

  • 우리의 공식 X (Twitter)LinkedIn을 팔로우하세요.

  • 동료 개발자 및 유저들과 교류할 수 있는 공식 Discord 커뮤니티에 참여하세요.

이 튜토리얼은 Voxel51의 ML 에반젤리스트인 Daniel Gural과 공동 집필했습니다.

비디오는 작은 페이로드 안에 방대한 데이터가 압축되어 있는 보고와 같습니다. 다른 단일 모달리티와 달리, 비디오는 시간에 따른 변화를 고려해야 하면서도 이미지와 오디오 데이터로 가득 차 있습니다. 데이터 과학자들은 이러한 데이터를 가장 효율적으로 풀어서 비디오 안에 정확히 무엇이 들어있는지 이해하기 위해 수년 동안 연구해 왔습니다.

새로운 시대는 언제나 새로운 도전 과제를 동반합니다. 많은 데이터 과학자와 머신러닝 엔지니어들은 수 테라바이트에 달하는 비디오 중에서 모델 학습에 필수적인 비디오만 골라내야 하는 과제에 직면해 있습니다. 한때는 엄두도 내지 못했던 이 작업이 비디오 이해 기술의 최신 진화인 '비디오 시맨틱 검색(Video Semantic Search)' 덕분에 이제는 아주 간단해졌습니다.

이 튜토리얼에서는 Twelve Labs의 비디오 시맨틱 검색 기술을 활용하여 빠르고 반복 가능한 검색 워크플로우를 생성할 수 있는 FiftyOne 플러그인 구축 방법을 배웁니다. Twelve Labs API를 활용하려는 숙련된 개발자든, 오픈소스 도구인 FiftyOne의 기능을 탐색해 보고 싶은 열정적인 사용자든, 이 튜토리얼은 여러분의 프로젝트에 비디오 시맨틱 검색을 매끄럽게 통합하는 데 필요한 지식과 기술을 제공할 것입니다.

튜토리얼의 완 완성된 결과물은 Semantic Video Search Plugin GitHub 페이지에서 확인할 수 있습니다. 또한, 이 과정을 직접 시연하는 비디오 가이드도 Twelve Labs의 YouTube 페이지 여기에서 시청하실 수 있습니다!

시작하기

시작하기 전에, 플러그인을 구축하는 데 필요한 준비물을 살펴보겠습니다. 다음 항목이 필요합니다:

  1. Twelve Labs 계정: Twelve Labs는 자연어 쿼리를 사용한 시맨틱 검색, 제로샷(Zero-shot) 분류, 비디오 콘텐츠 기반 텍스트 생성 등 다양한 태스크를 지원하는 강력한 비디오 이해용 파운데이션 모델을 구축합니다. 아직 계정이 없다면 무료로 가입하세요!

  2. FiftyOne GitHub 클론 저장소: FiftyOne은 고품질 데이터셋과 컴퓨터 비전 모델을 구축하기 위한 오픈소스 도구로, Voxel51에서 관리하고 있습니다.

  3. FiftyOne Plugins 클론 저장소: FiftyOne은 도구의 기능을 확장하고 맞춤화할 수 있는 강력한 플러그인 프레임워크를 제공합니다. Twelve Labs 플러그인을 관리하고 빌드하기 위한 유틸리티가 포함된 FiftyOne Plugins Management and Development 플러그인을 설치해야 합니다.

  4. 비디오 데이터셋.

준비물이 모두 갖춰졌다면 이제 본격적으로 시작해 보겠습니다! 먼저 FiftyOne에 데이터를 로드하고, Twelve Labs API가 올바르게 구성되었는지 테스트해 보겠습니다.

여기서는 FiftyOne에서 제공하는 quickstart-video 데이터셋을 사용하겠습니다. 빠르고 간편하게 구동할 수 있습니다:

import fiftyone as fo
import fiftyone.zoo as foz

dataset = foz.load_zoo_dataset("quickstart-video")

session = fo.launch_app(dataset)

다음으로 사용할 Twelve Labs API 키와 API URL을 정의했는지 확인하세요. 기존에 생성해 둔 인덱스를 조회하여 API가 잘 설정되어 있는지 간단히 테스트할 수 있습니다. 먼저 키와 URL을 환경 변수로 설정해 보겠습니다:

export TWELVE_API_KEY=<YOUR_API_KEY>

또는

import os

os.environ['TWELVE_API_KEY'] = <YOUR_API_KEY>

그다음, Twelve Labs API를 호출하여 기존 인덱스를 조회하고 우리 변수들이 제대로 유효한지 확인합니다.

import time
import requests
import glob
from pprint import pprint
import os

API_URL = os.getenv("TWELVE_API_URL")
assert API_URL

API_KEY = os.getenv("TWELVE_API_KEY")
assert API_KEY

INDEXES_URL = f"{API_URL}/indexes"

headers = {
	"x-api-key": API_KEY,
	"Content-Type": "application/json"
}

response = requests.get(INDEXES_URL, headers=headers)

API 응답 결과가 실패 메시지가 아닌 성공 메시지를 반환하는지 반드시 확인해 주세요!

비디오 시맨틱 검색 수행하기

성공적으로 연결되었다면, 이제 플러그인이 수행해야 할 단계를 세부적으로 쪼개어 보겠습니다. 우리가 달성해야 할 주요 목표는 다음 세 가지입니다:

  1. 인덱스 생성

  2. 데이터셋 인덱싱

  3. 데이터셋 검색

첫 번째와 두 번째 목표를 하나의 오퍼레이터(operator)로 묶고, 검색을 위한 두 번째 오퍼레이터를 따로 만들 것입니다. 먼저 Jupyter 노트북에서 이 전체 흐름을 시작부터 끝까지 실행해 보겠습니다. 자세한 정보는 FiftyOne 문서Twelve Labs 문서에서 확인할 수 있습니다.

1 - “VideoSearch”라는 이름의 인덱스 생성하기

이 인덱스는 visual, text_in_video, logo 영역에 걸쳐 검색할 수 있도록 지원합니다. 만약 비디오에 오디오 음성이 포함되어 있다면 Twelve Labs의 conversation 옵션도 함께 제공됩니다.

INDEXES_URL = f"{API_URL}/indexes"

INDEX_NAME = "VideoSearch" # Use a descriptive name for your index

headers = {
    "x-api-key": API_KEY
}

data = {
  "engine_id": "marengo2.5",
  "index_options": ["visual",  "text_in_video", "logo"],
  "index_name": INDEX_NAME,
}

response = requests.post(INDEXES_URL, headers=headers, json=data)
INDEX_ID = response.json().get('_id')
print (f'Status code: {response.status_code}')
pprint (response.json())

2 - 데이터셋 인덱싱하기

비디오 파일이 Twelve Labs의 제한 사항을 충족하기 위해 4초 이상인지 검사해야 합니다. 각 비디오를 Twelve Labs로 전송하고 완료 확인 신호를 받은 다음 다음 비디오로 넘어갑니다.

TASKS_URL = f"{API_URL}/tasks"

videos = dataset
for sample in videos:
	if sample.metadata.duration < 4:
    	continue
	else:
    	file_name = sample.filepath.split("/")[-1]
    	file_path = sample.filepath
    	file_stream = open(file_path,"rb")
    
    	headers = {
        	"x-api-key": API_KEY
    	}
    
    	data = {
        	"index_id": INDEX_ID,
        	"language": "en"
    	}
    
    	file_param=[
        	("video_file", (file_name, file_stream, "application/octet-stream")),]
    
    	response = requests.post(TASKS_URL, headers=headers, data=data, files=file_param)
    	TASK_ID = response.json().get("_id")
    	print (f"Status code: {response.status_code}")
    	pprint (response.json())
    
    	TASK_STATUS_URL = f"{API_URL}/tasks/{TASK_ID}"
    	while True:
        	response = requests.get(TASK_STATUS_URL, headers=headers)
        	STATUS = response.json().get("status")
        	if STATUS == "ready":
            	break
        	time.sleep(10)
   	 
    	VIDEO_ID = response.json().get('video_id')
    	sample["Twelve ID"] = VIDEO_ID
    	sample.save()
      
    	print (f"Status code: {STATUS}")
    	print(f"VIDEO ID: {VIDEO_ID}")
    	pprint (response.json())

3 - 데이터셋 검색 쿼리 실행하기

예를 들어, “sunny day(화창한 날)”를 검색하면 이 쿼리와 일치하는 검색 결과들을 얻을 수 있습니다.

prompt = "sunny day"
SEARCH_URL = f"{API_URL}/search"

headers = {
	"x-api-key": API_KEY
}

data = {
	"query": prompt,
	"index_id": INDEX_ID,
	"search_options": ["visual", "text_in_video", "logo"],
}

response = requests.post(SEARCH_URL, headers=headers, json=data)



워크플로우가 성공적으로 테스트되고 검증되었다면, 이제 이를 FiftyOne 플러그인에 이식할 차례입니다! 기본 코드를 다듬는 데 도움이 되는 FiftyOne 스켈레톤 오퍼레이터를 구축해 볼 텐데요. 다행히 FiftyOne Management & Development Plugin을 활용하면 훨씬 간편합니다! `build operator skeleton` 오퍼레이터의 도움을 받아 필요한 모든 커스텀 코드 블록을 손쉽게 구성할 수 있습니다.

플러그인 빌드를 위한 시작 지점을 확보한 후, `build plugin component` 오퍼레이터를 적용하여 나머지 입력 필드와 알림 메시지들을 채워 넣습니다. 이 작업은 플러그인에 추가하고 싶은 UI 모듈을 탐색하는 아주 쉽고 훌륭한 방법입니다. 모든 코드는 Python으로 작성되어 제공되므로, 포함하고 싶은 로직에 맞춰 매우 손쉽게 수정하고 실험해 볼 수 있습니다.

스켈레톤 코드가 완성되고 Twelve Labs 워크플로우를 정의했다면 마지막 단계는 이들을 모두 결합하는 것입니다! 적절한 코드를 두 오퍼레이터에 구현한 후, 앱을 저장 및 새로고침하여 우리가 만든 플러그인을 테스트해 보세요!

결론

개발자들은 Twelve Labs의 비디오 시맨틱 검색 서비스를 활용하여 소셜 미디어, 브랜드 인사이트, 팟캐스트, 사용자 생성 콘텐츠(UGC)를 포함해 다양한 산업군에 걸친 무궁무진한 유스케이스를 개척할 수 있습니다. 이 강력한 도구는 맥락 기반의 비디오 콘텐츠 검색과 효과적인 비디오 분석을 가능하게 하며, 교육 콘텐츠 검색, 기업 지식 관리, 그리고 동영상 편집 스위트 플랫폼에 매우 가치 있는 솔루션이 되어 줍니다.

Twelve Labs는 비디오 이해에 특화된 혁신적인 AI 파운데이션 모델을 구축하는 선구적인 스타트업입니다. 우리의 최신 비디오-언어 파운데이션 모델인 Pegasus-1과 강력한 Video-to-text API 라인업은 비디오 데이터를 총체적으로 이해할 수 있는 최첨단 솔루션을 제공합니다. 파트너사인 Voxel51은 데이터 탐색 및 시각화를 위한 최고의 오픈소스 플랫폼인 FiftyOne을 제공하여, 개발자들이 Twelve Labs의 비디오 시맨틱 검색 기능을 프로젝트에 한층 더 깊이 있게 통합하도록 돕고 있습니다.

다음 단계는 무엇인가요?

  • 퀵스타트 가이드를 살펴보고 Twelve Labs와 함께 놀라운 비디오 앱 빌드를 시작해보세요.

  • Twelve Labs Playground를 직접 경험해 보세요. 가입 시 10시간 분량의 무료 비디오 크레딧이 기본 제공됩니다.

  • 우리의 공식 X (Twitter)LinkedIn을 팔로우하세요.

  • 동료 개발자 및 유저들과 교류할 수 있는 공식 Discord 커뮤니티에 참여하세요.