El Transformer (Vaswani et al., 2017) supuso una ruptura absoluta con las redes secuenciales anteriores (como RNN y LSTM) al tratar el procesamiento del lenguaje como un problema relacional global en lugar de una cadena temporal paso a paso.
En lugar de procesar palabra por palabra, el modelo proyecta cada token en tres vectores distintos mediante matrices de pesos entrenables: Query ($Q$), Key ($K$) y Value ($V$).
La operación matemática fundamental que ocurre en cada capa es:
$$\text{Attention}(Q, K, V) = \text{softmax}\left(\frac{Q K^T}{\sqrt{d_k}}\right) V$$
Donde $d_k$ es la dimensión de los vectores de clave. Esto genera una matriz de atención donde cada token recibe un peso de importancia respecto a todos los demás tokens del contexto, resolviendo de forma nativa la dependencia a larga distancia.
Las redes antiguas mantenían un “estado oculto” (hidden state) que se pasaba linealmente del paso $t-1$ al paso $t$, impidiendo la paralelización. El Transformer elimina esta dependencia temporal. Al introducir toda la secuencia de tokens simultáneamente en la GPU, las operaciones de multiplicación de matrices se ejecutan de golpe en los miles de núcleos CUDA de la tarjeta gráfica.
[Image comparing RNN sequential processing vs Transformer parallel processing]
Como el procesamiento es paralelo, la red no sabe inherentemente qué palabra va antes y cuál después. Los LLM modernos sustituyen las funciones trigonométricas fijas del Transformer original por RoPE (Rotary Position Embedding). RoPE aplica una matriz de rotación interna a los vectores $Q$ y $K$. La propiedad matemática clave de RoPE es que el producto escalar entre dos tokens codificados conserva la información de la distancia relativa entre ellos, lo que permite al modelo extrapolar su comprensión a contextos masivos (de 32k a más de un millón de tokens) sin que la geometría espacial del modelo se rompa.
Un modelo no nace sabiendo chatear o seguir órdenes; se le esculpe a lo largo de tres fases críticas.
El texto plano es indigerible para una red neuronal. Un algoritmo (como Byte-Pair Encoding) fragmenta el texto en tokens (raíces de palabras, prefijos o signos de puntuación). Cada token se asocia a un ID entero dentro de un vocabulario fijo (por ejemplo, 128,000 tokens en la familia Llama 3). Ese ID recupera un vector continuo de alta dimensión (ej. 4096 dimensiones) de la matriz de embeddings. En este espacio geométrico se codifica la semántica inicial de cada fragmento de texto.
Es un aprendizaje autosupervisado a escala masiva que requiere meses de computación en clústeres de miles de GPUs. El objetivo es el Modelado de Lenguaje Causal: maximizar la probabilidad de predecir el token correcto dada una ventana de tokens anteriores.
$$\mathcal{L} = \sum_{i} \log P(x_i \mid x_{<i}; \Theta)$$
Donde $\Theta$ representa los parámetros (pesos) del modelo. Al repetir esta operación matemática miles de millones de veces sobre terabytes de texto de internet, el modelo absorbe de forma colateral la estructura del mundo, la gramática, la lógica y la sintaxis de programación. El resultado es un Modelo Base (incapaz de chatear, solo autocompleta).
El modelo base se refina para convertirlo en un asistente mediante dos pasos:
<|user|>¿Cómo se calcula una derivada?<|assistant|>Para calcular una derivada...
Tener acceso a los pesos libres del modelo permite alterar su estructura interna o su comportamiento directamente mediante código de Python.
La penúltima capa de un LLM genera un vector denso que condensa toda la información semántica del contexto (el hidden state). Normalmente, la última capa (LM Head) es una capa lineal simple que mapea este vector contra los 128,000 tokens del vocabulario para calcular las probabilidades de la siguiente palabra.
Si eliminamos esa capa con el comando model.lm_head = torch.nn.Identity(), podemos conectar una capa lineal propia con, por ejemplo, solo 2 neuronas de salida. Esto permite reutilizar toda la inteligencia analítica profunda del modelo para tareas de clasificación de texto (Spam / No Spam) o regresión a un coste computacional infinitamente menor.
Modificar todos los pesos de un modelo durante un entrenamiento tradicional requiere actualizar matrices gigantescas de dimensiones $d \times k$, algo inviable en hardware doméstico. LoRA (Low-Rank Adaptation) asume que la matriz de actualización de pesos ($\Delta W$) tiene un “rango intrínseco” muy bajo.
En lugar de modificar la matriz original $W_0$ (que se congela), LoRA añade dos matrices auxiliares paralelas y delgadas, $A$ y $B$, de rango $r$ (donde $r \ll d$).
$$W = W_0 + \Delta W = W_0 + B \cdot A$$
Si el peso original es una matriz de $4096 \times 4096$ (16 millones de parámetros), con LoRA ($r=8$) se entrenan dos matrices de $4096 \times 8$ y $8 \times 4096$, reduciendo los parámetros activos a entrenar en más de un 99%.
QLoRA lleva esta técnica al límite: mantiene la matriz base $W_0$ comprimida en un formato ultra-reducido de 4 bits (NF4) y calcula los gradientes exclusivamente sobre los adaptadores LoRA en precisión FP16, permitiendo entrenar modelos en GPUs de consumo.
La cuantización consiste en mapear un espacio continuo de alta precisión (como los números en punto flotante de 16 bits, FP16, donde cada peso ocupa 2 bytes) a un espacio discreto de baja precisión (como enteros de 4 bits, INT4, donde cada peso ocupa 0,5 bytes).
La fórmula básica de cuantización lineal es:
$$Q(X) = \text{round}\left(\frac{X}{S}\right) + Z$$
Donde $S$ es el factor de escala (scale) y $Z$ es el punto cero (zero-point). Esto permite reducir el tamaño de un modelo en un 75% con una pérdida de precisión matemática casi imperceptible.
| Formato | Entorno de Ejecución | Características Clave |
|---|---|---|
| GGUF | CPU / GPU (Local) | Formato contenedor binario unificado (pesos + tokenizador). Permite offloading (repartir capas de forma dinámica entre la VRAM de la gráfica y la RAM del sistema mediante la CPU). Es el motor nativo de Ollama. |
| AWQ | 100% GPU (Servidores) | Analiza las activaciones del modelo con datos reales para identificar el 1% de pesos críticos que dictan la lógica. Aplica un factor de escala para proteger estos pesos antes de comprimir el resto a 4 bits rígidos. Optimizado para Tensor Cores. |
| EXL2 | 100% GPU (Consumo) | Diseñado exclusivamente para exprimir tarjetas NVIDIA en local. Permite cuantizaciones con precisión fraccionaria (ej. 4.25 o 4.65 bits) para ajustar el tamaño del modelo exactamente al límite físico de la VRAM disponible. |
Durante el proceso de inferencia (generación de texto en tiempo real), el consumo de memoria de video (VRAM) de la tarjeta gráfica se divide estrictamente en tres bloques:
[ Memoria del Modelo (Fija) ] + [ Overheads del Sistema / CUDA (~1GB) ] + [ KV Cache (Dinámica) ]
En la atención tradicional (MHA), cada cabeza de consulta ($Q$) tiene su propia cabeza de clave ($K$) y valor ($V$). En textos largos, almacenar todas estas matrices $K$ y $V$ para no recalcularlas satura la VRAM.
Los modelos modernos optimizan este espacio usando GQA (Grouped-Query Attention), donde múltiples cabezas de consulta comparten una única cabeza de clave y valor. Esto reduce drásticamente el tamaño del KV Cache en memoria en un factor de 4 u 8, permitiendo ventanas de contexto mucho más amplias en tarjetas de consumo.
Para estimar la memoria exacta del KV Cache en bytes para una longitud de contexto $L$, la fórmula de ingeniería es:
$$\text{Memoria}_{KVCache} = 2 \times 2 \times L \times N_{\text{capas}} \times H_{kv} \times D_{\text{cabeza}}$$
Donde $L$ es la longitud del contexto, $N_{\text{capas}}$ es el número de bloques del modelo, $H_{kv}$ es el número de cabezas de clave/valor (reducido por GQA) y $D_{\text{cabeza}}$ es la dimensión interna de la cabeza.
Importante: El Contexto es la suma geométrica de todo lo que tiene el modelo en memoria en ese instante: System Prompt + Historial de chat + Pregunta actual + Respuesta generándose. Todo ello reside indexado dentro del KV Cache.
Cuando la conversación se alarga tanto que el KV Cache alcanza el límite configurado en el motor de inferencia (num_ctx), el sistema activa estrategias de mitigación:
En un entorno de desarrollo o producción local, las herramientas interactúan mediante una arquitectura de capas bien definida:
[Open WebUI] ---(Petición HTTP/JSON API)---> [Ollama Engine] ---> [Drivers CUDA] -----------> [RTX 3060 VRAM]
(UI/Chat) (Carga de GGUF / (Cálculo de Tensores (Pesos + KVCache)
Gestión de Capas) con PyTorch de bajo nivel)
temperature, top_p, repeat_penalty) sobre las probabilidades de salida de la red.Nota: Generado con Gemini Flash con nivel de pensamiento avanzado a partir de conversación mantenida. Junio 2026.