Я использую предварительно обученный 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.
Кто-нибудь знает, где проблема? Большое спасибо!
Вы не разрезаете его по размерам прямо на
outputs.last_hidden_state[0, 0, :].numpy()
A: Токен начала предложения (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>)
Ответ: Действительно ли вы можете получить «встраивание» из модели, состоящей только из декодера? Модель выводит скрытое состояние для каждого токена, через который она «регрессирует», поэтому разные тексты получают разный выходной размер тензора.
Вопрос: Как тогда превратить его в один вектор фиксированного размера?
А: Скорее всего,
@Хауи: возможно, вам захочется посмотреть этот ответ для извлечения вложений предложений из моделей декодера.
Огромное спасибо за подробный ответ @alvas. Я подумал, что могу использовать встраивание специального токена в начале для представления всей последовательности, точно так же, как встраивание токена CLS для представления последовательности для классификации текста. Теперь оказывается, что встраивание токена BOS в эту модель практически одинаково для разных входных текстов. Тогда мне нужно хотя бы выполнить объединение токенов в последовательность. Спасибо!