全部产品
Search
文档中心

Tair (Redis® OSS-Compatible):Implementasikan pengambilan embedding multimodal citra-teks menggunakan TairVector

更新时间:Dec 20, 2025

Topik ini menjelaskan solusi untuk pencarian multimodal citra-teks berkinerja tinggi secara real-time menggunakan TairVector dan CLIP.

Informasi latar belakang

Internet berisi sejumlah besar data tidak terstruktur, seperti citra dan teks. Model open source Contrastive Language-Image Pre-training (CLIP) dari Akademi DAMO mencakup model bawaan, seperti Text Transformer dan ResNet, yang mengekstraksi fitur dari data tidak terstruktur—seperti citra dan teks—serta menguraikannya menjadi data terstruktur.

Anda dapat mempraproses data, seperti citra dan dokumen, menggunakan model CLIP dan menyimpan hasilnya di Tair. Selanjutnya, Anda dapat memanfaatkan fitur pencarian tetangga terdekat (nearest neighbor search) dari TairVector untuk mengimplementasikan pencarian multimodal citra-teks yang efisien. Untuk informasi selengkapnya tentang TairVector, lihat Vector.

Ikhtisar solusi

  1. Unduh data citra.

    Contoh ini menggunakan data uji berikut:

  2. Hubungkan ke instans Tair. Untuk detail implementasinya, lihat fungsi get_tair dalam kode contoh.

  3. Buat indeks vektor untuk citra dan teks di Tair. Untuk detail implementasinya, lihat fungsi create_index dalam kode contoh.

  4. Tulis data citra dan teks.

    Praproses data citra dan teks menggunakan model CLIP, lalu simpan nama dan fiturnya di Tair dengan perintah TVS.HSET dari TairVector. Untuk detail implementasinya, lihat fungsi insert_images untuk citra dan fungsi upsert_text untuk teks.多模检索..jpeg

  5. Lakukan kueri multimodal.

    • Pencarian teks-ke-gambar (text-to-image search)

      Praproses teks kueri menggunakan model CLIP, lalu gunakan perintah TVS.KNNSEARCH dari TairVector untuk mengkueri database Tair guna mencari citra yang paling mirip dengan deskripsi teks tersebut. Untuk detail implementasinya, lihat fungsi query_images_by_text dalam kode contoh.

    • Pencarian gambar-ke-teks (image-to-text search)

      Praproses citra kueri menggunakan model CLIP, lalu gunakan perintah TVS.KNNSEARCH dari TairVector untuk mengkueri database Tair guna mencari teks yang paling sesuai dengan citra tersebut. Untuk detail implementasinya, lihat fungsi query_texts_by_image dalam kode contoh.

    Catatan
    • Teks atau citra kueri tidak perlu disimpan di TairVector.

    • Perintah TVS.KNNSEARCH memungkinkan Anda menentukan jumlah hasil yang dikembalikan (topK). Jarak kemiripan yang lebih kecil (distance) menunjukkan tingkat kemiripan yang lebih tinggi.

Contoh kode

Contoh ini menggunakan Python 3.8 dan memerlukan dependensi Tair-py, torch, Image, pylab, plt, dan CLIP. Untuk menginstal Tair-py, jalankan perintah berikut: pip3 install tair.

# -*- coding: utf-8 -*-
# !/usr/bin/env python
from tair import Tair
from tair.tairvector import DistanceMetric
from tair import ResponseError

from typing import List
import torch
from PIL import Image
import pylab
from matplotlib import pyplot as plt
import os
import cn_clip.clip as clip
from cn_clip.clip import available_models


def get_tair() -> Tair:
    """
    Metode ini menghubungkan ke instans Tair.
    * host: Titik akhir (endpoint) instans Tair.
    * port: Nomor port instans Tair. Nilai default adalah 6379.
    * password: Kata sandi akun default instans Tair. Jika Anda terhubung dengan akun kustom, formatnya adalah 'username:password'.
    """
    tair: Tair = Tair(
        host="r-8vbehg90y9rlk9****pd.redis.rds.aliyuncs.com",
        port=6379,
        db=0,
        password="D******3",
        decode_responses=True
    )
    return tair


def create_index():
    """
    Membuat indeks Vector untuk menyimpan embedding citra dan teks:
    * Nama kunci untuk citra adalah 'index_images', dan nama kunci untuk teks adalah 'index_texts'.
    * Dimensi vektor adalah 1024.
    * Fungsi jarak vektor adalah IP.
    * Algoritma indeks adalah HNSW.
    """
    ret = tair.tvs_get_index("index_images")
    if ret is None:
        tair.tvs_create_index("index_images", 1024, distance_type="IP",
                              index_type="HNSW")
    ret = tair.tvs_get_index("index_texts")
    if ret is None:
        tair.tvs_create_index("index_texts", 1024, distance_type="IP",
                              index_type="HNSW")


def insert_images(image_dir):
    """
    Masukkan path ke citra. Metode ini secara otomatis melakukan traversal file citra di path tersebut.
    Metode ini juga memanggil metode `extract_image_features` untuk mempraproses file citra menggunakan model CLIP dan mengembalikan informasi fitur citra tersebut. Informasi fitur yang dikembalikan kemudian disimpan di Tair Vector.
    Format penyimpanan di Tair adalah:
    * Nama indeks vektor: 'index_images' (tetap).
    * Kunci: Path citra beserta nama filenya, misalnya 'test/images/boxer_18.jpg'.
    * Informasi fitur: Vektor berdimensi 1024.
    """
    file_names = [f for f in os.listdir(image_dir) if (f.endswith('.jpg') or f.endswith('.jpeg'))]
    for file_name in file_names:
        image_feature = extract_image_features(image_dir + "/" + file_name)
        tair.tvs_hset("index_images", image_dir + "/" + file_name, image_feature)


def extract_image_features(img_name):
    """
    Metode ini mempraproses file citra menggunakan model CLIP dan mengembalikan informasi fitur citra tersebut (vektor berdimensi 1024).
    """
    image_data = Image.open(img_name).convert("RGB")
    infer_data = preprocess(image_data)
    infer_data = infer_data.unsqueeze(0).to("cuda")
    with torch.no_grad():
        image_features = model.encode_image(infer_data)
    image_features /= image_features.norm(dim=-1, keepdim=True)
    return image_features.cpu().numpy()[0]  # [1, 1024]


def upsert_text(text):
    """
    Masukkan teks yang akan disimpan. Metode ini memanggil metode `extract_text_features` untuk mempraproses teks menggunakan model CLIP dan mengembalikan informasi fitur teks tersebut. Informasi fitur yang dikembalikan kemudian disimpan di Tair Vector.
    Format penyimpanan di Tair adalah:
    * Nama indeks vektor: 'index_texts' (tetap).
    * Kunci: Konten teks, misalnya 'a running dog'.
    * Informasi fitur: Vektor berdimensi 1024.
    """
    text_features = extract_text_features(text)
    tair.tvs_hset("index_texts", text, text_features)


def extract_text_features(text):
    """
    Metode ini mempraproses teks menggunakan model CLIP dan mengembalikan informasi fitur teks tersebut (vektor berdimensi 1024).
    """
    text_data = clip.tokenize([text]).to("cuda")
    with torch.no_grad():
        text_features = model.encode_text(text_data)
    text_features /= text_features.norm(dim=-1, keepdim=True)
    return text_features.cpu().numpy()[0]  # [1, 1024]


def query_images_by_text(text, topK):
    """
    Metode ini melakukan pencarian teks-ke-gambar.
    Masukkan konten teks yang ingin dicari (text) dan jumlah hasil yang dikembalikan (topK).
    Metode ini mempraproses teks kueri menggunakan model CLIP. Kemudian menggunakan perintah `TVS.KNNSEARCH` dari Vector untuk mengkueri database Tair guna mencari citra yang paling mirip dengan deskripsi teks tersebut.
    Metode ini mengembalikan nama kunci dan jarak kemiripan (distance) dari citra target. Nilai distance yang lebih kecil menunjukkan tingkat kemiripan yang lebih tinggi.
    """
    text_feature = extract_text_features(text)
    result = tair.tvs_knnsearch("index_images", topK, text_feature)
    for k, s in result:
        print(f'key : {k}, distance : {s}')
        img = Image.open(k.decode('utf-8'))
        plt.imshow(img)
        pylab.show()


def query_texts_by_image(image_path, topK=3):
    """
    Metode ini melakukan pencarian gambar-ke-teks.
    Masukkan path citra kueri dan jumlah hasil yang dikembalikan (topK).
    Metode ini mempraproses citra kueri menggunakan model CLIP. Kemudian menggunakan perintah `TVS.KNNSEARCH` dari Vector untuk mengkueri database Tair guna mencari teks yang paling sesuai dengan citra tersebut.
    Metode ini mengembalikan nama kunci dan jarak kemiripan (distance) dari teks target. Nilai distance yang lebih kecil menunjukkan tingkat kemiripan yang lebih tinggi.
    """
    image_feature = extract_image_features(image_path)
    result = tair.tvs_knnsearch("index_texts", topK, image_feature)
    for k, s in result:
        print(f'text : {k}, distance : {s}')

if __name__ == "__main__":
    # Hubungkan ke database Tair dan buat indeks vektor untuk citra dan teks.
    tair = get_tair()
    create_index()
    # Muat model Chinese-CLIP.
    model, preprocess = clip.load_from_name("RN50", device="cuda", download_root="./")
    model.eval()
    
    # Sebagai contoh, jika path ke set data citra hewan peliharaan adalah '/home/CLIP_Demo', tulis data citra tersebut.
    insert_images("/home/CLIP_Demo")
    # Tulis data teks contoh ('a dog', 'a white dog', 'a running white dog').
    upsert_text("a dog")
    upsert_text("a white dog")
    upsert_text("a running white dog")

    # Lakukan pencarian teks-ke-gambar untuk menemukan tiga citra yang paling sesuai dengan teks 'a running dog'.
    query_images_by_text("a running dog", 3)
    # Lakukan pencarian gambar-ke-teks. Tentukan path citra untuk menemukan teks yang paling menggambarkan citra tersebut.
    query_texts_by_image("/home/CLIP_Demo/boxer_18.jpg",3)

Hasil

  • Pencarian teks-ke-gambar: Tiga citra berikut paling sesuai dengan teks 'a running dog'.

    以文搜图,奔跑的狗..jpeg

  • Pencarian gambar-ke-teks: Citra kueri yang ditentukan ditampilkan di bawah ini.

    奔跑的狗(搜索图)..jpeg

    Hasil kueri adalah sebagai berikut.

    {
      "results":[
        {
          "text":"seekor anjing putih yang sedang berlari",
          "distance": "0,4052203893661499"
        },
        {
          "text":"seekor anjing putih",
          "distance": "0,44666868448257446"
        },
        {
          "text":"seekor anjing",
          "distance": "0,4553511142730713"
        }
      ]
    }

Ringkasan

Tair adalah database dalam memori dengan algoritma indeks bawaan, seperti HNSW, yang mempercepat kecepatan pencarian.

Menggunakan CLIP bersama TairVector untuk pencarian multimodal memungkinkan pencarian teks-ke-gambar dalam skenario seperti rekomendasi produk dan pencarian gambar-ke-teks dalam skenario seperti bantuan penulisan. Anda juga dapat mengganti model CLIP dengan model lain untuk mengimplementasikan fungsionalitas pencarian lintas modalitas lainnya, seperti pencarian teks-ke-video atau teks-ke-audio.