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

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

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

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

Другая хорошая аналогия — сама карта. Подумайте о карте и двух городах, о которых вы ничего не знаете. Допустим, вы не очень хороши в географии и не знаете, где на карте находятся Токио и Нью-Йорк. Если я скажу вам, что нам следует позавтракать в Нью-Йорке и пообедать в Токио, вы можете сказать: "Давайте это сделаем".

Однако, как только я дам вам координаты для проверки городов на карте, вы увидите, что они находятся очень далеко друг от друга. Это то же самое, что дать модели встраивания: они координаты!

Построение карты

Ещё до того, как вы когда-либо задали вопрос, модель встраивания была обучена. Она прочитала миллионы предложений и заметила закономерности. Например, она видит, что "кот" и "котёнок" часто появляются в одинаковых типах предложений, в то время как "кот" и "холодильник" редко встречаются вместе.

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

  • Похожие концепции (как "кот" и "котёнок") размещаются рядом друг с другом на карте.
  • Несколько связанные концепции (как "кот" и "собака") размещаются рядом, но не прямо друг на друге.
  • Совершенно не связанные концепции (как "кот" и "квантовая физика") размещаются в совершенно разных уголках карты, как Нью-Йорк и Токио.

Цифровой отпечаток

Хорошо. Теперь мы знаем, как была создана карта. Что дальше?

Теперь мы будем работать с этой обученной моделью встраивания. Когда мы даём модели предложение типа "Пушистый котёнок спит":

  1. Она не смотрит на буквы. Вместо этого она посещает эти координаты на своей карте для каждого слова.
  2. Она вычисляет центральную точку (среднее значение) всех этих местоположений. Эта единственная центральная точка становится "отпечатком" для всего предложения.
  3. Она ставит булавку на карту туда, где находится отпечаток вашего вопроса.
  4. Смотрит вокруг в круге, чтобы увидеть, какие другие отпечатки находятся поблизости.

Любые документы, которые "живут" рядом с вашим вопросом на этой карте, считаются совпадением, потому что они имеют одинаковую "вибрацию" или тему, даже если они не содержат точно такие же слова.

Встраивания: невидимая карта

Это похоже на поиск книги не по определённому ключевому слову, а указав на точку на карте, которая говорит "все эти книги о котятах", и позволив модели найти всё в этом районе.

Этапы работы модели встраивания

Давайте посмотрим, как модель встраивания работает пошагово после получения запроса.

  1. Компьютер принимает текст.
  2. Разбивает его на токены — наименьший кусок фразы со смыслом. Обычно это слово или часть слова.
  3. Разбиение на части: входной текст разделяется на управляемые части (обычно около 512 токенов), чтобы модель не была перегружена слишком большим объёмом информации одновременно.
  4. Встраивание: оно преобразует каждый фрагмент в длинный список чисел (вектор), который действует как уникальный отпечаток представляющий значение этого текста.
  5. Поиск по векторам: когда вы задаёте вопрос, модель превращает ваш вопрос в "отпечаток" и быстро вычисляет, какие сохранённые фрагменты имеют наиболее математически похожие числа.
  6. Модель возвращает наиболее похожие векторы, связанные с текстовыми фрагментами.
  7. Генерация: если вы выполняете поиск с увеличенной генерацией (RAG), модель передаёт эти несколько "выигрышных" фрагментов ИИ (например, LLM), который их читает и пишет естественно звучащий ответ только на основе этой конкретной информации.

Кодирование

Отлично. Мы много говорили. Теперь давайте попробуем написать немного кода и сделаем эти концепции более практичными.

Мы начнём с простого встраивания BERT (двунаправленные кодировки представлений из трансформеров). Он был создан Google и использует архитектуру Трансформер и его механизм внимания. Вектор для слова меняется в зависимости от окружающих его слов.

# Импорты
from transformers import BertTokenizer

# Загрузить предварительно обученный токенизатор BERT
tokenizer = BertTokenizer.from_pretrained("bert-base-uncased")

# Пример текста для токенизации
text = "Модели встраивания так крутые!"

# Шаг 1: Токенизируйте текст
tokens = tokenizer(text, return_tensors="pt", padding=True, truncation=True)
# Просмотр
tokens
{'input_ids': tensor([[ 101, 7861, 8270, 4667, 4275, 2024, 2061, 4658,  999,  102]]),
 'token_type_ids': tensor([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]), 
 'attention_mask': tensor([[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]])}

Заметьте, как каждое слово было преобразовано в идентификатор. Поскольку у нас есть только 5 слов, некоторые из них могли быть разбиты на два подслова.

  • ID 101 связан с токеном [CLS]. Вектор этого токена предполагается, чтобы захватить общее значение или информацию всего предложения или последовательности предложений. Это как печать, которая указывает LLM значение этого куска.
  • ID 102 связан с токеном [SEP] для разделения предложений.

Далее, давайте применим модель встраивания к данным.

Встраивание

Вот ещё один простой фрагмент, где мы берём некоторый текст и кодируем его универсальной моделью встраивания all-MiniLM-L6-v2.

from qdrant_client import QdrantClient, models
from sentence_transformers import SentenceTransformer

# 1. Загрузить модель встраивания
model = SentenceTransformer('all-MiniLM-L6-v2', device='cpu')

# 2. Инициализировать клиент Qdrant
client = QdrantClient(":memory:")

# 3. Создать встраивания
docs = ["политика возврата", "детали цены", "отмена учётной записи"]
vectors = model.encode(docs).tolist()

# 4. Сохранить векторы: создать коллекцию (БД)
client.create_collection(
    collection_name="my_collection",
    vectors_config = models.VectorParams(size=384,
                                         distance= models.Distance.COSINE)
)

# Загрузить встроенные документы (векторы)
client.upload_collection(collection_name="my_collection",
                         vectors= vectors,
                         payload= [{"source": docs[i]} for i in range(len(docs))])

# 5. Поиск
query_vector = model.encode("Как отменить мою подписку")

# Результат
result = client.query_points(collection_name= 'my_collection',
                             query= query_vector,
                             limit=2,
                             with_payload=True)

print("\n\n ======= РЕЗУЛЬТАТЫ =========")
result.points

Результаты соответствуют ожиданиям. Это указывает на тему отмены учётной записи!

======= РЕЗУЛЬТАТЫ =========
[ScoredPoint(id='b9f4aa86-4817-4f85-b26f-0149306f24eb', version=0, score=0.6616353073200185, payload={'source': 'отмена учётной записи'}, vector=None, shard_key=None, order_value=None),
 ScoredPoint(id='190eaac1-b890-427b-bb4d-17d46eaffb25', version=0, score=0.2760082702501182, payload={'source': 'политика возврата'}, vector=None, shard_key=None, order_value=None)]

Что только что произошло?

  1. Мы импортировали предварительно обученную модель встраивания.
  2. Инициализировали векторную базу данных по нашему выбору: Qdrant.
  3. Встроили текст и загрузили его в векторную БД в новую коллекцию.
  4. Мы отправили запрос.
  5. Результаты — это те документы с ближайшим математическим "отпечатком" или значением к встраиванию запроса.

Это действительно хорошо.

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

Тонкая настройка модели встраивания

Тонкая настройка модели встраивания отличается от тонкой настройки LLM. Вместо того чтобы учить модель "говорить", вы учите её переорганизовать свою внутреннюю карту так, чтобы определённые концепции в вашей области были отдалены или приближены друг к другу.

Наиболее распространённый и эффективный способ — использование контрастивного обучения с библиотекой типа Sentence-Transformers.

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

  • Якорь: эталонный элемент (например, "Кола бренда A").
  • Позитивное: похожий элемент (например, "Кола бренда B"), который модель должна сблизить с якорем.