deep-learning · temario
3.3tema 3 de 4

Embeddings — Vector Representations & Semantic Search

Representaciones vectoriales, similitud coseno y búsqueda semántica

Un embedding es una representación densa de baja dimensión de un objeto de alta dimensión: una palabra, una oración, una imagen o un documento se convierte en un vector de números reales. La clave es que el espacio vectorial conserva relaciones semánticas: cosas similares quedan cerca, cosas distintas quedan lejos.

El poder del embedding está en que permite comparar objetos heterogéneos usando aritmética simple. La distancia o similitud entre vectores reemplaza comparaciones heurísticas complejas. Es como tener un sistema de coordenadas para el significado: dos frases con el mismo sentido caen en la misma región del espacio.

La similitud coseno mide el ángulo entre dos vectores sin importar su magnitud. Es la métrica estándar para comparar embeddings de texto porque los modelos de lenguaje producen vectores cuya dirección es significativa, no su longitud. Valores cercanos a 1 indican alta similitud; cercanos a -1, semántica opuesta.

La búsqueda vectorial (vector search) indexa millones de embeddings para encontrar los K más cercanos a una consulta en milisegundos. Librerías como FAISS (Meta) o frameworks como Qdrant/Chroma/Pinecone implementan índices aproximados (HNSW, IVF) que escalan donde una búsqueda exhaustiva fallaría.

En el contexto RAG (Retrieval-Augmented Generation) los embeddings son el puente entre el usuario y la base de conocimiento. La pregunta del usuario se convierte en un embedding, se buscan los documentos más similares, y esos documentos se inyectan como contexto al LLM. Esto permite que el modelo responda con información actualizada sin re-entrenamiento.

Los modelos de embedding preentrenados (sentence-transformers, OpenAI text-embedding-3, Cohere embed) generan embeddings listos para usar. El embedding no es libre de sesgos: hereda los del corpus de preentrenamiento. Para dominios especializados, el fine-tuning o la normalización de corpus mejoran significativamente la calidad.

structure.txt
GENERATE EMBEDDINGS
  from sentence_transformers import SentenceTransformer
  model = SentenceTransformer('all-MiniLM-L6-v2')
  texts = ['Hello world', 'Hola mundo', 'Bonjour monde']
  embeddings = model.encode(texts)  # shape (3, 384)

COSINE SIMILARITY (numpy)
  import numpy as np
  def cosine_sim(a, b):
      a_norm = a / np.linalg.norm(a)
      b_norm = b / np.linalg.norm(b)
      return np.dot(a_norm, b_norm)

COSINE SIMILARITY (pytorch)
  import torch.nn.functional as F
  sim = F.cosine_similarity(a.unsqueeze(0), b.unsqueeze(0))

VECTOR SEARCH (FAISS)
  import faiss
  index = faiss.IndexFlatIP(dim)   # inner product = cosine if normalized
  index.add(embeddings.astype('float32'))
  D, I = index.search(query_emb.astype('float32'), k=5)

RAG PIPELINE
  query_emb = embed(user_query)
  docs = vector_db.search(query_emb, top_k=5)
  context = '\n'.join(docs)
  answer = llm(f'Context: {context}\nQuestion: {user_query}')

Debugging lab

Detecta y corrige el error en el código.

0/5 tests passing0%
  1. 3.3.5.1

    def cosine_sim(a, b): return np.dot(a, b)

  2. 3.3.5.2

    embeddings = model.encode(texts) # (N, 384) index = faiss.IndexFlatIP(384) index.add(embeddings) D, I = index.search(query_emb, k=5)

  3. 3.3.5.3

    sim = F.cosine_similarity(a, b) # a shape (384,), b shape (384,)

  4. 3.3.5.4

    # encode one by one results = [] for text in texts: results.append(model.encode(text))

  5. 3.3.5.5

    emb_a = model_a.encode('machine learning') # model A emb_b = model_b.encode('deep learning') # model B sim = cosine_sim(emb_a, emb_b)