Многоязыковый и мультимодальный поиск с помощью LlamaIndex#

Обзор#

Информацию зачастую передается более эффективно при сочетании различных типов данных. Например, вкус комфортной еды может вызвать воспоминания из детства. Можно описать песню просто звуками «пам пам хлоп». Вместо написания абзацев. Иногда используются эмодзи и стикеры для выражения чувств или передачи сложных идей.

Различные комбинации модальностей данных, таких как текст, изображения, видео и аудио, представляют собой ценные случаи использования приложений семантического поиска.

Векторные базы данных, будучи модально-независимыми, идеально подходят для создания этих приложений.

В этом простом руководстве осуществляется работа с двумя простыми модальностями: изображение и текстовые данные. Однако можно создать приложение для семантического поиска с любой комбинацией модальностей, если выбрать подходящую модель встраивания для преодоления семантической пропасти.

Термин «семантическая пропасть» обозначает разницу между низкоуровневыми признаками (например, яркостью) и высокоуровневыми концепциями.

Например, модель vdr-2b-multi-v1 от LlamaIndex предназначена для многоязычного встраивания и особенно эффективна для визуального извлечения документов по нескольким языкам и областям. Она позволяет выполнять поиск и запросы визуально богатых многоязычных документов без необходимости использовать технологии оптического распознавания символов (OCR) или другие конвейеры обработки данных.

Настройка#

Сначала установите необходимые библиотеки qdrant-client и llama-index-embeddings-huggingface:

pip install qdrant-client llama-index-embeddings-huggingface

Набор данных#

Чтобы сделать демонстрацию простой, используется предварительно созданный набор изображений и их подписей.

Изображения можно скачать здесь. Важно разместить их в той же папке, где находится код, в папке под названием images.

Векторизация данных#

Модель LlamaIndexvdr-2b-multi-v1 поддерживает кросс-лингвистический поиск, обеспечивая эффективный поиск по различным языкам и доменам. Она преобразует снимки страниц документа в плотные векторные представления, устраняя необходимость в использовании технологий оптического распознавания символов (OCR) и других сложных процессов извлечения данных.

Встройте изображения и их подписи в общее пространство вложений:

from llama_index.embeddings.huggingface import HuggingFaceEmbedding

model = HuggingFaceEmbedding(
    model_name="llamaindex/vdr-2b-multi-v1",
    device="cpu",  # "mps" for mac, "cuda" for nvidia GPUs
    trust_remote_code=True,
)

documents = [
    {"caption": "An image about plane emergency safety.", "image": "images/image-1.png"},
    {"caption": "An image about airplane components.", "image": "images/image-2.png"},
    {"caption": "An image about COVID safety restrictions.", "image": "images/image-3.png"},
    {"caption": "An confidential image about UFO sightings.", "image": "images/image-4.png"},
    {"caption": "An image about unusual footprints on Aralar 2011.", "image": "images/image-5.png"},
]

text_embeddings = model.get_text_embedding_batch([doc["caption"] for doc in documents])
image_embeddings = model.get_image_embedding_batch([doc["image"] for doc in documents])

Загрузка данных в Vector DB#

  1. Создайте объект клиента для Platform V Vector DB (далее - Vector DB):

    from qdrant_client import QdrantClient, models
    
    # docker run -p 6333:6333 qdrant/qdrant
    client = QdrantClient(url="http://localhost:6333/")
    
  2. Создайте новую коллекцию для изображений с подписями:

    COLLECTION_NAME = "llama-multi"
    
    if not client.collection_exists(COLLECTION_NAME):
        client.create_collection(
            collection_name=COLLECTION_NAME,
            vectors_config={
                "image": models.VectorParams(size=len(image_embeddings[0]), distance=models.Distance.COSINE),
                "text": models.VectorParams(size=len(text_embeddings[0]), distance=models.Distance.COSINE),
            }
        )
    
  3. Загрузите изображения с подписями в Коллекцию:

    client.upload_points(
        collection_name=COLLECTION_NAME,
        points=[
            models.PointStruct(
                id=idx,
                vector={
                    "text": text_embeddings[idx],
                    "image": image_embeddings[idx],
                },
                payload=doc
            )
            for idx, doc in enumerate(documents)
        ]
    )
    

Поиск#

Текст к изображению#

Посмотрим, какое изображение будет получено по запросу «Приключения на снежных холмах»:

from PIL import Image

find_image = model.get_query_embedding("Adventures on snow hills")

Image.open(client.query_points(
    collection_name=COLLECTION_NAME,
    query=find_image,
    using="image",
    with_payload=["image"],
    limit=1
).points[0].payload['image'])

Выполните тот же запрос на итальянском языке и сравните результаты.

Многоязычный поиск#

Теперь проведите многоязыковый поиск с использованием итальянского запроса:

Image.open(client.query_points(
    collection_name=COLLECTION_NAME,
    query=model.get_query_embedding("Avventure sulle colline innevate"),
    using="image",
    with_payload=["image"],
    limit=1
).points[0].payload['image'])

Ответ:

Следы на снегу

Изображение к тексту#

Выполните обратный поиск по следующему изображению:

Самолет

client.query_points(
    collection_name=COLLECTION_NAME,
    query=model.get_image_embedding("images/image-2.png"),  
    # Now we are searching only among text vectors with our image query
    using="text",
    with_payload=["caption"],
    limit=1
).points[0].payload['caption']

Ответ:

'An image about plane emergency safety.'

Заключение#

Случаи применения даже простого мультимодального поиска по изображениям и тексту бесчисленны: электронная коммерция, управление медиа, рекомендации контента, системы распознавания эмоций, биомедицинский поиск изображений, транскрипция разговорного языка жестов и так далее.

Представьте себе сценарий: пользователь хочет найти продукт, похожий на имеющуюся у него фотографию, но также имеет конкретные текстовые требования, например, «в бежевом цвете». Можно искать только по текстовым данным или изображениям и комбинировать их вложения способом поздней слияния (позднее объединение — суммирование и взвешивание могут работать удивительно хорошо).