clip-retrieval

FSA·2024년 3월 15일
0

vision

목록 보기
1/25
post-custom-banner

1. 개요

  • 이 글에서는 CLIP 임베딩을 계산하고, 그걸 이용해서 검색 시스템을 만드는 방법에 대해 설명하고 있어.
  • 아래 모든 과정을 통틀어, 기본적인 의미 기반 검색 시스템을 만들 수 있어. 의미 기반 검색에 대해 더 배우고 싶다면, 내 미디엄 포스트를 읽어보는 것도 좋아.


1.1. clip index

  • 'clip index'는 생성된 임베딩들(텍스트나 이미지에서 추출된 임베딩)로부터 효율적인 검색 인덱스를 만들어.
  • 이 인덱스는 대량의 데이터 속에서 특정 임베딩을 빠르게 찾을 수 있게 해줘.
  • 쉽게 말하자면, 많은 책들 속에서 네가 찾고자 하는 책을 빠르게 찾아주는 도서관의 카탈로그 같은 거라고 할 수 있어.

1.2. clip filter

  • 'clip filter'는 앞서 만든 'clip index'를 사용해서, 데이터를 필터링할 수 있게 해.
  • 예를 들어, 네가 특정 주제나 특성을 가진 이미지나 텍스트만을 찾고 싶다면, 'clip filter'를 통해 그 조건에 맞는 데이터만 골라낼 수 있어.

1.3. clip back

  • 'clip back'은 'clip index'를 활용하여, Flask라는 파이썬 기반의 웹 프레임워크를 사용해 서버를 구축하고, 그 서버에서 인덱스를 호스팅해.
  • 이렇게 하면 인터넷을 통해 어디서든 그 clip index에 접근할 수 있게 되지.
  • 간단히 말해서, 네가 만든 도서관 카탈로그를 인터넷에 올려서 누구나 사용할 수 있게 하는 것과 비슷해.

1.4. clip front

1.5. 'clip end2end'

  • img2dataset, 인퍼런스, 인덱스 그리고 백엔드와 프론트엔드까지, 모든 걸 시작부터 끝까지 쉽게 할 수 있게 해주는 거야.

2. ClipClient

2.1. API 초기화

  • 초기화할 때 몇 가지 매개변수를 지정할 수 있어:

    • backend_url: 백엔드의 URL이야. (필수)
    • indice_name: 사용할 인덱스의 이름을 명시해야 해. (필수)
    • aesthetic_score: 미적 평가 점수로, aesthetic-predictor에 의해 평가됐어. 기본값은 9야.
    • use_mclip: 다국어 버전의 CLIP을 사용할지의 여부야. 기본값은 False.
    • aesthetic_weight: 미적 점수의 가중치야. 기본값은 0.5야.
    • modality: 인덱스에서 이미지나 텍스트 중 어떤 것을 검색할지 선택해. Multimodal.IMAGE 또는 Multimodal.TEXT 중 하나야. 기본값은 Multimodal.IMAGE.
    • num_images: API에서 반환할 이미지의 수야. 기본값은 40이야.
    • deduplicate: 이미지 임베딩으로 결과의 중복을 제거할지 여부야. 기본값은 true.
    • use_safety_model: 안전하지 않은 이미지를 제거할지 여부야. 기본값은 true.
    • use_violence_detector: 폭력적인 이미지를 제거할지 여부야. 기본값은 true.
  • (초기화 예): 기본 매개변수로 호스팅된 백엔드에 Laion5B를 질의하려면:

    • 인터넷 상에 위치한 특정 서버('호스팅된 백엔드')에, 'Laion5B'라는 데이터베이스를 사용하여 정보를 요청하려고 할 때, 사전에 설정된 기본 옵션(이걸 '기본 매개변수'라고 부름)을 사용하는 방법에 대해 설명
    • Laion5B는 매우 큰 이미지와 텍스트 데이터를 포함하는 데이터베이스이고,
    • indice_name="laion5B-L-14"에서 indice_name은 이 데이터베이스 내에서 특정한 인덱스(데이터를 정리하고 검색하기 위한 구조)를 지정하는 데 사용되는 키워드 인자
    • 데이터베이스에서 '인덱스'는 데이터를 효율적으로 조회하고 검색할 수 있도록 돕는 데이터 구조나 방식
    • 대규모 데이터베이스인 Laion5B는 여러 인덱스를 가질 수 있으며, 이들 각각은 데이터를 다루는 데 있어 특정한 목적이나 최적화를 제공
    • 예를 들어, 인덱스는 데이터의 특정 부분집합을 대상으로 하거나, 특정 유형의 쿼리를 더 빠르게 처리하도록 설계될 수 있어요.
    • "laion5B-L-14"라는 인덱스 이름은, Laion5B 데이터베이스 안에서
    • 특정한 설정, 구조화 방식, 또는 최적화를 가진 인덱스를 가리키는 것으로 보여요.
from clip_retrieval.clip_client import ClipClient, Modality

client = ClipClient(url="https://knn.laion.ai/knn-service", indice_name="laion5B-L-14")

2.2. 텍스트로 질의하기

  • 제공한 텍스트와 유사한 캡션을 가진 이미지를 찾을 수 있어.
results = client.query(text="an image of a cat")
results[0]
# 출력: {'url': 'https://example.com/kitten.jpg', 'caption': 'an image of a kitten', 'id': 14, 'similarity': 0.2367108941078186}

2.3. 이미지로 질의하기

제공된 이미지와 유사한 캡션을 가진 이미지도 찾을 수 있어. 이미지는 로컬 경로나 URL을 통해 전달할 수 있어.

cat_results = client.query(image="cat.jpg")
dog_results = client.query(image="https://example.com/dog.jpg")

2.4. 임베딩으로 질의하기

제공된 클립 임베딩과 유사한 캡션을 가진 이미지를 찾을 수도 있어.

cat_results = client.query(embedding_input=cat_embedding)

2.5. 이미지 디렉토리로 질의하기

  • 유사한 텍스트/이미지 쌍으로 기존 데이터셋을 향상시키고 싶다면, 이미지 디렉토리를 질의하고 결과를 결합할 수 있어.
  • 이 과정은 네 컴퓨터에 있는 특정 폴더(여기서는 "my-images")에 저장된 이미지들을 하나씩 가져와서, 각 이미지에 대해 클립 모델을 사용하여 유사한 텍스트/이미지 쌍을 찾는 질의를 수행하는 거야.
  • 이렇게 해서 얻은 결과들을 모아서 "search-results.json"이라는 파일에 저장하고 있어.
all_results = [result for result in [client.query(image=image) for image in os.listdir("my-images")]]
with open("search-results.json", "w") as f:
    json.dump(all_results, f)

2.6. 데이터셋 만들기

  • 저장된 json 결과와 img2dataset 도구를 사용해서 데이터셋을 만들 수 있어.
  • 이 과정은 앞서 언급한 'search-results.json' 파일에 저장된 검색 결과를 사용하여, 새로운 데이터셋을 만드는 방법에 대해 설명하고 있어.
  • 여기서 사용되는 도구인 img2dataset은 특정 형식의 데이터(이 경우는 JSON 파일)에서 이미지와 관련 메타데이터(예: 캡션)를 추출하여,
    • 물리적인 이미지 파일과 메타데이터 파일로 구성된 데이터셋을 생성하는 데 사용돼.
  • 구체적으로, 이 명령어는 다음 단계를 수행해:
  1. "search-results.json" 파일을 읽어들임:
  • 이 JSON 파일에는 이미지의 URL, 이미지에 대한 설명(캡션), 이미지의 ID, 그리고 이미지와 질의 사이의 유사도 점수와 같은 정보가 들어 있어.
  • 이 파일은 앞서 이미지 디렉토리를 질의하여 얻은 결과를 저장한 것이야.
  1. --input_format="json" 옵션을 사용:
  • 이 옵션은 입력 파일이 JSON 형식임을 명시해.
  1. --output_folder="knn_search_dataset" 옵션을 사용:
  • 이 옵션은 생성될 데이터셋의 저장 위치를 지정해.
  • 여기서는 "knn_search_dataset"이라는 이름의 폴더에 데이터셋이 저장될 거야.
  1. --caption_col="caption" 옵션을 사용:
  • 이 옵션은 JSON 파일 내에서 이미지 설명(캡션)을 포함하고 있는 컬럼의 이름을 지정해.
  • 이 경우, 'caption'이라는 이름의 컬럼에서 캡션 데이터를 추출해 사용하게 돼.
  • 결과적으로, img2dataset 도구는 이 정보를 바탕으로 각 이미지를 다운로드하고, 각 이미지에 해당하는 캡션과 함께 데이터셋을 구성해.
img2dataset "search-results.json" \
    --input_format="json" \
    --output_folder="knn_search_dataset" \
    --caption_col="caption"

3. clip end2end

  • 이미지 URL과 캡션의 데이터셋(예시)을 선택한 후 실행해:
  • GPU VRAM이 충분하지 않다면, GPU 사용을 피하기 위해 export CUDA_VISIBLE_DEVICES=를 실행할 수 있어.
wget https://github.com/rom1504/img2dataset/raw/main/tests/test_files/test_1000.parquet
clip-retrieval end2end test_1000.parquet /tmp/my_output
  • 그 다음 http://localhost:1234 로 가서 사진들 사이에서 검색을 즐겨봐.
  • 백엔드를 실행하지 않으려면 --run_back False를 사용해.

4. clip inference

예를 들어, img2dataset를 설치하고 다음을 실행해서 example_folder에 몇몇 이미지를 가져와봐:

pip install img2dataset
echo 'https://placekitten.com/200/305' >> myimglist.txt
echo 'https://placekitten.com/200/304' >> myimglist.txt
echo 'https://placekitten.com/200/303' >> myimglist.txt
img2dataset --url_list=myimglist.txt --output_folder=image_folder --thread_count=64 --image_size=256

이미지와 동일한 이름의 텍스트 파일을 그 폴더에 두면, 텍스트 임베딩도 얻을 수 있어.

그런 다음 clip-retrieval inference --input_dataset image_folder --output_folder embeddings_folder를 실행해.

출력 폴더에는 다음이 포함될 거야:

  • img_emb/: numpy로 이미지 임베딩이 포함된 img_emb_0.npy
  • text_emb/: numpy로 텍스트 임베딩이 포함된 text_emb_0.npy
  • metadata/: 이미지 경로, 캡션, 메타데이터가 포함된 metadata_0.parquet

이건 백만 단위의 샘플까지 확장될 수 있어. 3080에서 1400 샘플/초로, 10M 샘플을 2시간 안에 처리할 수 있어.

profile
모든 의사 결정 과정을 지나칠 정도로 모두 기록하고, 나중에 스스로 피드백 하는 것
post-custom-banner

0개의 댓글