Модель Mistral генерирует одни и те же вложения для разных входных текстов

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

Коды:

from transformers import pipeline, AutoTokenizer, AutoModel
import numpy as np
PRETRAIN_MODEL = 'mistralai/Mistral-7B-Instruct-v0.2'
tokenizer = AutoTokenizer.from_pretrained(PRETRAIN_MODEL)
model = AutoModel.from_pretrained(PRETRAIN_MODEL)

def generate_embedding(document):
    inputs = tokenizer(document, return_tensors='pt')
    print("Tokenized inputs:", inputs)
    with torch.no_grad():
        outputs = model(**inputs)
    embedding = outputs.last_hidden_state[0, 0, :].numpy()
    print("Generated embedding:", embedding)
    return embedding

text1 = "this is a test"
text2 = "this is another test"
text3 = "there are other tests"

embedding1 = generate_embedding(text1)
embedding2 = generate_embedding(text2)
embedding3 = generate_embedding(text3)

are_equal = np.array_equal(embedding1, embedding2) and np.array_equal(embedding2, embedding3)

if are_equal:
    print("The embeddings are the same.")
else:
    print("The embeddings are not the same.")

Напечатанные токены разные, но напечатанные вложения одинаковы. Выходы:

Tokenized inputs: {'input_ids': tensor([[   1,  456,  349,  264, 1369]]), 'attention_mask': tensor([[1, 1, 1, 1, 1]])}
Generated embedding: [-1.7762679  1.9293272 -2.2413437 ...  2.6379988 -3.104867   4.806004 ]
Tokenized inputs: {'input_ids': tensor([[   1,  456,  349, 1698, 1369]]), 'attention_mask': tensor([[1, 1, 1, 1, 1]])}
Generated embedding: [-1.7762679  1.9293272 -2.2413437 ...  2.6379988 -3.104867   4.806004 ]
Tokenized inputs: {'input_ids': tensor([[   1,  736,  460,  799, 8079]]), 'attention_mask': tensor([[1, 1, 1, 1, 1]])}
Generated embedding: [-1.7762679  1.9293272 -2.2413437 ...  2.6379988 -3.104867   4.806004 ]
The embeddings are the same.

Кто-нибудь знает, где проблема? Большое спасибо!

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
3
0
523
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы не разрезаете его по размерам прямо на

outputs.last_hidden_state[0, 0, :].numpy()

Вопрос: Что такое 0-й токен во всех входах?

A: Токен начала предложения (BOS).

Вопрос: Итак, «встраивания», которые я нарезаю, — это токен BOS?

А: Попробуйте это:

from transformers import pipeline, AutoTokenizer, AutoModel
import numpy as np

PRETRAIN_MODEL = 'mistralai/Mistral-7B-Instruct-v0.2'
tokenizer = AutoTokenizer.from_pretrained(PRETRAIN_MODEL)
model = AutoModel.from_pretrained(PRETRAIN_MODEL)

model(**tokenizer("", return_tensors='pt')).last_hidden_state

[вне]:

tensor([[[-1.7763,  1.9293, -2.2413,  ...,  2.6380, -3.1049,  4.8060]]],
       grad_fn=<MulBackward0>)

Вопрос: Тогда как мне получить встраивания из модели, предназначенной только для декодера?

Ответ: Действительно ли вы можете получить «встраивание» из модели, состоящей только из декодера? Модель выводит скрытое состояние для каждого токена, через который она «регрессирует», поэтому разные тексты получают разный выходной размер тензора.

Вопрос: Как тогда превратить его в один вектор фиксированного размера?

А: Скорее всего,

  • какая-то функция объединения?
  • открытый вопрос исследования (по состоянию на апрель 2024 г.), но ведется работа над такими инструментами, как https://arxiv.org/abs/2404.05961

Огромное спасибо за подробный ответ @alvas. Я подумал, что могу использовать встраивание специального токена в начале для представления всей последовательности, точно так же, как встраивание токена CLS для представления последовательности для классификации текста. Теперь оказывается, что встраивание токена BOS в эту модель практически одинаково для разных входных текстов. Тогда мне нужно хотя бы выполнить объединение токенов в последовательность. Спасибо!

Howie 12.04.2024 11:12

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

cronoik 25.04.2024 23:53

Другие вопросы по теме