¿Podría facilitarse un modelo para generar embeddings en español?
Repito la pregunta que hice en PlanTL-GOB-ES/roberta-base-biomedical-clinical-es porque no sé qué repositorio será antendido antes:
Dado el trabajo de recolección y limpieza del corpus, me pregunto si es accesible un modelo de generación de embeddings basado en transformers especializado en biomedicina en español. Un modelo como este sería muy beneficioso para la investigación de usos de PLN en hospitales, biomedicina y ámbitos clínicos.
Quizás es posible obtener un modelo así a partir de este mismo, eliminando la parte de decoder para obtener la representación del input en las capas intermedias, pero quería saber si algo así ya está o estará disponible.
Hola David,
No tenemos previsto generar nada por el estilo de momento, pero lo tendremos en cuenta.
Un saludo.
¡Resulta que es muy sencillo transformar este modelo en un modelo de generación de embeddings!
Es posible ignorar las últimas capas y utilizar las representaciones intermedias de 768 elementos, o combinar varias de estas para obtener embeddings más grandes. No garantizo que el código sea óptimo, pero como punto de partida es suficiente. Con esto se pueden obtener representaciones semánticamente ricas para bloques de texto.
import torch
from transformers import AutoTokenizer, AutoModelForMaskedLM
if __name__ == "__main__":
device = "cuda" if torch.cuda.is_available() else "cpu"
# Load the model and tokenizer
tokenizer = AutoTokenizer.from_pretrained("BSC-TeMU/roberta-base-biomedical-es")
model = AutoModelForMaskedLM.from_pretrained("BSC-TeMU/roberta-base-biomedical-es", output_hidden_states=True)
# "Ignore" model last layers
model.lm_head.layer_norm = torch.nn.Identity()
model.lm_head.decoder = torch.nn.Identity()
# Get sentence embedding
sentence = "No conozco el nombre de mi enfermedad, pero me duele la cabeza."
sentence_ids = torch.LongTensor(tokenizer.encode(sentence)).unsqueeze(0)
model = model.to(device)
sentence_ids = sentence_ids.to(device)
with torch.no_grad():
out = model(input_ids=sentence_ids)
# Mean of the last layer
#sentence_embedding = torch.mean(out.hidden_states[-1], dim=1).squeeze()
#print(sentence_embedding.size())
# Mean of the last four layers concatenated
last_four_layers = [out.hidden_states[i] for i in (-1, -2, -3, -4)]
# cast layers to a tuple and concatenate over the last dimension
cat_hidden_states = torch.cat(tuple(last_four_layers), dim=-1)
# take the mean of the concatenated vector over the token dimension
cat_sentence_embedding = torch.mean(cat_hidden_states, dim=1).squeeze()
print(cat_sentence_embedding.size())