OpenAI CLIP을 사용하여 시맨틱 이미지 검색을 구축하는 방법#
이 가이드에서는 OpenAI CLIP과 Flask를 사용하여 의미 기반 이미지 검색(semantic image search) 엔진을 구축하는 방법을 안내합니다. CLIP의 시각-언어 임베딩(embeddings)과 NumPy 기반의 빠른 코사인 유사도(cosine similarity) 검색을 결합하여, 레이블이나 카테고리 없이 자연어 쿼리로부터 관련 이미지를 검색하는 웹 인터페이스를 구축할 수 있습니다.
Watch: How Similarity Search Works | Visual Search Using OpenAI CLIP and the Ultralytics Package 🎉

Ultralytics Python 패키지는 이 전체 파이프라인을 두 개의 클래스 뒤에 래핑하여, 단 몇 줄의 코드만으로 작동하는 검색 앱을 실행하거나 프로그래밍 방식으로 쿼리를 실행할 수 있도록 합니다. 이 가이드에서는 시맨틱 검색이 유용한 이유, 작동 원리, 웹 앱 실행 방법, 프로그래밍 방식 검색, 그리고 매개변수 설정에 대해 다룹니다.
의미론적 이미지 검색을 사용하는 이유는 무엇입니까?#
CLIP으로 직접 시맨틱 이미지 검색 시스템을 구축하면 다음과 같은 강력한 이점이 있습니다:
- 제로샷 기능(Zero-shot capabilities): 데이터셋을 별도로 학습할 필요가 없습니다. CLIP의 제로샷 학습(zero-shot learning)을 사용하면 자유 형식의 자연어로 모든 이미지 컬렉션을 쿼리할 수 있어 시간과 리소스를 절약할 수 있습니다.
- 인간과 유사한 이해: 키워드 검색과 달리 CLIP은 의미론적 맥락을 이해하며, "자연 속의 행복한 아이" 또는 "밤의 미래 도시 스카이라인"과 같은 추상적, 감정적, 또는 관계적 쿼리에서도 이미지를 검색합니다.
- 레이블이나 메타데이터 불필요: 이 접근 방식은 원시 이미지만 있으면 됩니다. CLIP은 수동 주석 없이도 임베딩을 생성합니다.
- 경량화 및 정확한 검색: NumPy에서 단일 정규화 행렬 곱셈을 수행하면 코사인 유사도에 따라 모든 이미지의 순위가 지정되므로, 수천 개의 임베딩에서 실시간 응답으로 정확한 결과를 얻을 수 있으며 별도의 검색 의존성을 설치하거나 관리할 필요가 없습니다.
- 도메인 간 애플리케이션: 개인 사진 아카이브, 창의적인 영감 도구, 제품 검색 엔진 또는 예술 추천 시스템을 구축하든 동일한 스택을 최소한의 조정으로 활용할 수 있습니다.
의미론적 이미지 검색의 작동 원리#
이 파이프라인은 이미지를 텍스트와 함께 순위가 지정된 결과로 변환하는 세 가지 단계를 처리합니다:
- CLIP은 이미지용 비전 인코더(예: ResNet 또는 ViT)와 언어용 텍스트 인코더(Transformer 기반)를 사용하여 둘 모두를 동일한 멀티모달 임베딩 공간으로 투영합니다. 이를 통해 코사인 유사도(cosine similarity)를 사용하여 텍스트와 이미지 간을 직접 비교할 수 있습니다.
- NumPy는 이미지 임베딩을 단일 배열로 저장하며, 단 한 번의 행렬 곱셈으로 쿼리 임베딩과 비교하여 코사인 유사도가 가장 가까운 벡터를 반환하므로 추가적인 인덱싱 의존성이 필요하지 않습니다.
- Flask는 자연어 쿼리를 제출하고 인덱스에서 의미론적으로 일치하는 이미지를 표시하는 간단한 웹 인터페이스를 제공합니다.

이미지와 텍스트 모두 동일한 벡터 공간에 위치하므로 검색은 제로샷으로 수행됩니다. 즉, 레이블이나 카테고리가 필요 없으며 이미지 데이터와 좋은 프롬프트만 있으면 됩니다.
의미론적 검색 웹 앱 실행#
SearchApp 클래스는 전체 Flask 인터페이스를 실행합니다. 첫 실행 시 샘플 이미지 세트를 다운로드하고, 임베딩 인덱스를 구축하며, 쿼리를 입력하고 순위가 매겨진 결과를 볼 수 있는 페이지를 제공합니다.
이미지 경로 경고
자체 이미지를 사용하는 경우 이미지 디렉토리에 대한 절대 경로를 제공해야 합니다. 그렇지 않으면 Flask의 파일 제공 제한으로 인해 웹 페이지에 이미지가 표시되지 않을 수 있습니다.
from ultralytics import solutions
app = solutions.SearchApp(
data="images", # replace with a path to build the search engine with your own images
device="cpu", # configure the device for processing, e.g., "cpu" or "cuda"
)
app.run(debug=False) # You can also use `debug=True` argument for testing프로그래밍 방식으로 이미지 검색#
VisualAISearch 클래스는 웹 계층 없이 모든 백엔드 작업을 수행합니다:
- 로컬 이미지에서 임베딩 인덱스를 로드하거나 구축합니다.
- CLIP을 사용하여 이미지 및 텍스트 임베딩(embeddings)을 추출합니다.
- 코사인 유사도를 사용하여 유사도 검색을 수행합니다.
자연어 쿼리로 검색기를 호출하여 유사도 순으로 정렬된 일치하는 이미지 파일 이름 목록을 가져옵니다:
from ultralytics import solutions
searcher = solutions.VisualAISearch(
data="images", # replace with a path to build the search engine with your own images
device="cpu", # configure the device for processing, e.g., "cpu" or "cuda"
)
results = searcher("a dog sitting on a bench")
# Ranked Results:
# - 000000546829.jpg | Similarity: 0.3269
# - 000000549220.jpg | Similarity: 0.2899
# - 000000517069.jpg | Similarity: 0.2761
# - 000000029393.jpg | Similarity: 0.2742
# - 000000534270.jpg | Similarity: 0.2680VisualAISearch 매개변수 구성#
아래 표에는 VisualAISearch에서 사용할 수 있는 매개변수가 요약되어 있습니다:
| 인수 | 유형 | 기본값 | 설명 |
|---|---|---|---|
data | str | 'images' | 유사도 검색에 사용되는 이미지 디렉토리 경로입니다. |
| 인수 | 유형 | 기본값 | 설명 |
|---|---|---|---|
device | str | None | 추론용 장치를 지정합니다(예: cpu, cuda:0 또는 0). 사용자가 모델 실행을 위해 CPU, 특정 GPU 또는 기타 컴퓨팅 장치 중에서 선택할 수 있도록 합니다. |
로컬 파일을 관리하지 않고 프로덕션 규모로 이미지 컬렉션을 검색하려면, CLIP으로 인덱싱하기 전에 Ultralytics 플랫폼(Ultralytics Platform)에서 이미지를 구성하고 버전 관리할 수 있습니다.
결론#
CLIP과 Ultralytics Python 패키지를 사용하면 단 몇 줄의 코드만으로 Flask 웹 앱 또는 프로그래밍 방식의 검색 백엔드로 제로샷 시맨틱 이미지 검색 엔진을 구축할 수 있습니다. 여기에서 data을 자신의 이미지 디렉토리를 가리키도록 설정하여 인덱싱한 다음, 다른 Ultralytics 솔루션(Ultralytics Solutions)을 탐색하여 컴퓨터 비전 워크플로를 확장할 수 있습니다.
FAQ#
CLIP은 어떻게 이미지와 텍스트를 모두 이해합니까?#
CLIP(Contrastive Language Image Pretraining)은 시각적 정보와 언어적 정보를 연결하는 방법을 학습하는 OpenAI가 개발한 모델입니다. 이 모델은 자연어 캡션과 쌍을 이룬 대규모 이미지 데이터셋으로 학습됩니다. 이 학습을 통해 이미지와 텍스트 모두를 공유 임베딩 공간에 매핑할 수 있으므로, 벡터 유사도를 사용하여 직접 비교할 수 있습니다.
CLIP이 AI 작업에서 강력하다고 평가받는 이유는 무엇입니까?#
CLIP이 돋보이는 이유는 일반화 능력 때문입니다. 특정 레이블이나 작업에 대해서만 학습되는 대신, 자연어 그 자체로부터 학습합니다. 이를 통해 "제트 스키를 타는 남자"나 "초현실적인 꿈의 풍경"과 같은 유연한 쿼리를 처리할 수 있으며, 재학습 없이도 분류에서 창의적인 의미론적 검색에 이르기까지 모든 것에 유용합니다.
이미지는 텍스트 쿼리에 대해 어떻게 순위가 매겨지나요?#
CLIP이 이미지를 임베딩으로 변환한 후, Ultralytics 패키지는 이를 L2 정규화하고 단일 NumPy 배열에 저장합니다. 쿼리는 쿼리 임베딩과 모든 이미지 임베딩 간의 코사인 유사도(cosine similarity)를 계산하는 하나의 행렬 곱셈으로 순위가 매겨진 다음 점수가 정렬됩니다. 이 브루트 포스(brute-force) 검색은 일반적인 이미지 컬렉션에 대해 정확하고 빠르며, 설치하거나 관리해야 하는 추가 벡터 데이터베이스 종속성이 없습니다.
CLIP이 OpenAI의 모델인데 왜 Ultralytics Python 패키지를 사용해야 할까요?#
CLIP은 OpenAI에서 개발했지만, Ultralytics Python 패키지는 임베딩 생성, 인덱싱, 코사인 유사도 검색을 몇 줄의 코드만으로 즉시 작동하는 완전한 시맨틱 이미지 검색 파이프라인으로 래핑합니다:
from ultralytics import solutions
searcher = solutions.VisualAISearch(
data="images", # replace with a path to build the search engine with your own images
device="cpu", # configure the device for processing, e.g., "cpu" or "cuda"
)
results = searcher("a dog sitting on a bench")이 고수준 구현은 다음을 처리합니다:
- CLIP 기반 이미지 및 텍스트 임베딩 생성.
- 임베딩 인덱스 생성 및 관리.
- 코사인 유사도를 사용한 효율적인 의미론적 검색.
- 디렉토리 기반 이미지 로딩 및 시각화(visualization).
이 앱의 프론트엔드를 사용자 정의할 수 있습니까?#
네. 현재 설정은 기본 HTML 프론트엔드와 함께 Flask를 사용하지만, 이를 자체 HTML로 대체하거나 React, Vue 또는 기타 프론트엔드 프레임워크를 사용하여 더 동적인 UI를 구축할 수 있습니다. Flask는 사용자 지정 인터페이스를 위한 백엔드 API 역할을 할 수 있습니다.
정적 이미지 대신 비디오를 검색할 수 있습니까?#
직접적으로는 불가능합니다. 간단한 해결 방법은 비디오에서 개별 프레임(예: 1초당 하나)을 추출하여 독립적인 이미지로 취급하고 시스템에 입력하는 것입니다. 이런 방식으로 검색 엔진은 비디오의 시각적 순간을 의미론적으로 인덱싱할 수 있습니다.