Qué es Metal Performance Shaders (MPS) y cómo acelera la IA en Mac

Última actualización: diciembre 17, 2025
Autor: Isaac
  • Metal Performance Shaders (MPS) ofrece kernels optimizados de GPU para gráficos, visión e IA sobre la API Metal.
  • MPSGraph construye grafos de cómputo para machine learning aprovechando MPS y permitiendo control fino de memoria y sincronización.
  • El backend MPS de PyTorch y las nuevas APIs de Metal 4 integran redes neuronales en la línea de tiempo de GPU en Apple Silicon.
  • Herramientas como Metal Debugger y MPSGraph Viewer facilitan depurar, optimizar y visualizar modelos complejos ejecutados en la GPU.

Metal Performance Shaders MPS

Si trabajas con inteligencia artificial, gráficos 3D o apps exigentes en Mac, es muy probable que te hayas topado con el término Metal Performance Shaders (MPS), MPSGraph o el backend mps de PyTorch. Y, claro, la duda típica: ¿qué es exactamente todo esto, cómo encaja con Metal y qué futuro tiene en Apple Silicon?

En este artículo vamos a desmenuzar de forma clara qué es Metal Performance Shaders (MPS), qué aporta MPSGraph y cómo se aprovechan en IA, desde el motor gráfico Metal y sus sombreados hasta la aceleración de modelos con PyTorch, Core ML y las nuevas APIs de Metal 4. También veremos cómo Apple está empujando el aprendizaje automático directamente dentro de la GPU y por qué esto es clave en Mac con chips M‑series.

Qué es Metal y dónde encaja Metal Performance Shaders (MPS)

Metal es la API de bajo nivel de Apple para gráficos 3D y cómputo en GPU, disponible en iOS, iPadOS, macOS y tvOS desde 2014. Nació como alternativa moderna y eficiente a OpenGL y OpenCL, ofreciendo un acceso mucho más directo al hardware de la GPU con menos sobrecarga.

Esta API combina en un solo entorno capacidades de renderizado 3D y computación general en GPU (GPGPU), algo similar a lo que hacen Vulkan o DirectX 12 en otras plataformas. Los desarrolladores pueden programar en Swift, Objective‑C o C++17, mientras que el código que corre en la GPU se escribe en Metal Shading Language (MSL), un lenguaje basado en C++ diseñado específicamente para sombreadores y cómputo.

El enfoque de Metal se basa en codificar comandos por adelantado y enviarlos a la GPU de forma asíncrona. La aplicación decide en qué momento esperar resultados, lo que permite superponer trabajo de CPU y GPU, mejorar el rendimiento o ahorrar energía. Además, la codificación de comandos se puede hacer desde varios hilos de CPU, y gran parte del estado de la canalización gráfica se pre‑calcula, reduciendo el trabajo del driver en tiempo de ejecución.

En macOS, Metal ofrece la posibilidad de elegir qué GPU usar para cada carga de trabajo: la integrada de bajo consumo, una GPU discreta (en algunos Mac) o incluso una GPU externa conectada por Thunderbolt. El desarrollador puede orientar qué GPU es más eficiente para cada tipo de comando, por ejemplo: renderizado principal en la discreta y postprocesado en la integrada.

Sobre esta base de Metal se construyen distintos frameworks de más alto nivel. Uno de los más importantes para IA y procesamiento intensivo es precisamente Metal Performance Shaders (MPS), que funciona como una colección de kernels optimizados listos para usar.

Metal Performance Shaders (MPS): la biblioteca de kernels optimizados de Metal

Metal Performance Shaders es una biblioteca de funciones de alto rendimiento creada por Apple sobre Metal. Su objetivo es que no tengas que reescribir a mano, una y otra vez, los mismos kernels complejos de GPU, sino reutilizar implementaciones muy afinadas para cada familia de GPU compatible.

Dentro de MPS se incluyen primitivas pensadas para gráficos, visión por computador y aprendizaje automático. El framework abstrae diferencias entre GPUs y reduce el mantenimiento de código específico de hardware, algo clave si quieres que tu app funcione bien en distintas generaciones de chips.

Entre las capacidades más destacadas de Metal Performance Shaders encontramos cuatro grandes grupos de funciones que se reutilizan continuamente en aplicaciones gráficas y de IA:

  • Filtrado y procesado de imágenes: desenfoques, convoluciones, detección de bordes y otros filtros.
  • Redes neuronales y visión: capas de convolución, pooling, activaciones y operaciones típicas de modelos de deep learning.
  • Operaciones matemáticas avanzadas: multiplicación de matrices, reducciones y otras operaciones numéricas pesadas.
  • Trazado de rayos y efectos avanzados: soporte para técnicas de iluminación y gráficos de nueva generación.

La gran ventaja práctica es que MPS ofrece kernels ya ajustados a cada familia de GPU Metal, de forma que frameworks como Core ML o PyTorch pueden mapear sus operaciones de alto nivel a estos kernels de bajo nivel, obteniendo un gran rendimiento sin que el desarrollador tenga que optimizar manualmente cada paso.

MPSGraph: construir y ejecutar grafos de cómputo para machine learning

Sobre Metal Performance Shaders se apoya otro componente clave para IA: Metal Performance Shaders Graph (MPSGraph), un framework pensado para construir y ejecutar grafos de cómputo generales usando Metal como backend.

MPSGraph está diseñado para dar control de bajo nivel sobre memoria, sincronización y planificación en GPU, pero manteniendo un modelo de programación basado en tensores y operaciones de grafos típico del machine learning moderno. Esto permite tanto que lo usen directamente apps avanzadas como que se apoyen en él frameworks de más alto nivel.

De hecho, hoy en día Core ML, PyTorch, TensorFlow o JAX sobre Apple Silicon aprovechan MPSGraph bajo el capó para acelerar sus modelos en la GPU. Si tu aplicación ya usa Metal para gráficos, puedes integrar MPSGraph para secuenciar tareas de IA en la misma línea de tiempo de GPU, compartiendo recursos de bajo nivel como MTLBuffers o texturas con el resto del pipeline.

  El servidor dns no responde en windows 10

Trabajar directamente con MPSGraph resulta interesante cuando necesitas sincronizar con precisión trabajo de ML y otras etapas de GPU, o cuando quieres un control fino sobre cómo se ejecutan las operaciones del modelo, incluida la posibilidad de optimizar memoria, fusionar kernels o combinar cómputo clásico y aprendizaje automático.

Aceleración de PyTorch con el backend MPS en macOS

nuevo MacBook de 12.9 pulgadas para 2026

En el ecosistema de Python, Apple y la comunidad han colaborado para ofrecer un backend específico para Mac llamado MPS backend de PyTorch, asociado al dispositivo mps dentro del framework.

Cuando activas este backend, PyTorch mapea los grafos de cómputo y sus primitivas sobre MPSGraph y los kernels de MPS. El objetivo es que tus modelos en PyTorch puedan entrenarse y ejecutarse de forma acelerada en GPU en equipos con Apple Silicon o GPUs AMD compatibles con Metal.

Para usar este backend se requieren varias condiciones técnicas: macOS 12.3 o posterior, un Mac con Apple Silicon o GPU AMD compatible, Python 3.7 o superior y las herramientas de línea de comandos de Xcode. El backend llegó de forma oficial en PyTorch 1.12, y las versiones nocturnas (Preview/Nightly) suelen incorporar las últimas mejoras y correcciones relacionadas con mps.

La instalación puede hacerse mediante Anaconda o pip, teniendo en cuenta que el procedimiento cambia ligeramente entre Macs con procesador Intel x86 y Macs con chips M‑series. También es posible compilar PyTorch desde cero con soporte para MPS, usando Xcode 13.3.1 o superior y habilitando la variable de entorno USE_MPS durante la compilación.

Una vez instalado, basta con ejecutar un pequeño script en Python para comprobar que el dispositivo mps está disponible. Si todo está bien configurado, PyTorch indicará que puede usar la GPU vía Metal para tus modelos. Aunque este backend se ha marcado en ocasiones como mantenimiento limitado en la documentación, sigue siendo una pieza clave para aprovechar Apple Silicon con frameworks populares de IA.

Metal 4 y el salto del aprendizaje automático integrado en el pipeline de GPU

Con las últimas versiones de los sistemas de Apple, el framework ha evolucionado hacia Metal 4, que integra el aprendizaje automático como un ciudadano de primera clase dentro del pipeline de GPU, junto al cómputo general y al renderizado clásico.

En aplicaciones como videojuegos o herramientas 3D, el ML se está usando cada vez más para mejorar los gráficos, comprimir recursos y simular fenómenos complejos. Ejemplos prácticos son el antialiasing basado en redes neuronales, la compresión neuronal de materiales o el sombreado asistido por ML que reemplaza algoritmos tradicionales costosos.

Hasta ahora, gran parte de las tareas de IA se realizaban con Core ML de forma más “separada” del pipeline gráfico. Sin embargo, cuando necesitas que el modelo encaje perfectamente en la línea de tiempo de la GPU (por ejemplo, para aplicar una red de super‑resolución dentro de cada frame), Metal 4 añade herramientas específicas para lograrlo.

En un frame típico, un juego puede transformar vértices, rasterizar la escena, ejecutar varios pasos de postprocesado y aplicar técnicas de antialiasing temporal. Cada vez más, algunas de estas tareas se reemplazan por redes neuronales pequeñas que usan MPS, MPSGraph y las nuevas extensiones de Metal, ganando calidad de imagen o reduciendo el coste computacional.

Metal 4 introduce nuevos tipos de recursos y codificadores para que las redes se ejecuten directamente en la GPU junto al resto del trabajo, con sincronización controlada y compartiendo memoria de forma eficiente entre ML, cómputo y renderizado.

MTLTensor: el recurso nativo de Metal para datos de IA

Una de las grandes novedades es el tipo de recurso MTLTensor, pensado para representar datos multidimensionales de aprendizaje automático en Metal. A diferencia de una textura 2D o un simple buffer lineal, un tensor puede tener múltiples dimensiones con información de tamaño y stride integrada.

Las cargas de trabajo de IA usan tensores de manera intensiva, y con MTLTensor es posible describir fácilmente tensores de rango superior a dos dimensiones, como los que aparecen en convoluciones, secuencias o lotes de datos. La información de dimensiones y pasos se almacena en el propio objeto, por lo que la indexación interna se simplifica mucho.

Para crear un tensor se utiliza un MTLTensorDescriptor, donde se definen rango, dimensiones, tipo de dato y usos permitidos (por ejemplo, aprendizaje automático, cómputo o render). El tensor puede crearse directamente desde un MTLDevice, lo que da lugar a un diseño de memoria opaco y optimizado para lectura y escritura en la GPU.

También es posible envolver datos ya almacenados en un MTLBuffer como un tensor, en cuyo caso hay que especificar manualmente los strides porque el layout puede contener relleno. El stride más interno siempre es uno, y los siguientes indican cuánto se avanza al incrementar cada índice de dimensión.

Esta flexibilidad permite que los mismos MTLTensors se usen en contextos de cómputo, gráficos y ML, compartiendo datos entre distintas etapas sin necesidad de copias adicionales o conversiones costosas, algo crítico para la eficiencia de la GPU.

MTL4MachineLearningCommandEncoder: ejecutar redes completas en la GPU

Para integrar de verdad el ML en el flujo de trabajo de Metal, la API introduce MTL4MachineLearningCommandEncoder, un codificador diseñado para ejecutar redes enteras en la línea de tiempo de la GPU junto a cómputo y renderizado.

  ¿Cómo transferir llamadas en EyeBeam?

Este codificador se parece conceptualmente a los ya conocidos MTL4ComputeCommandEncoder y MTL4RenderCommandEncoder, pero enfocado a tareas de aprendizaje automático. Aprovecha las mismas primitivas de sincronización de Metal 4 (barreras, fences, eventos) y permite coordinar el trabajo entre distintas etapas sin quebraderos de cabeza.

El flujo de trabajo se divide en dos partes: una fase offline, que tiene lugar antes de ejecutar la app, y otra en tiempo de ejecución. En la parte offline se crea un MTLPackage a partir de un paquete de Core ML (MLPackage) usando una herramienta de línea de comandos, de manera que la red queda empaquetada en un formato eficiente para cargar en Metal.

Una vez dispones del MTLPackage, en tiempo de ejecución lo abres como una MTLLibrary, seleccionas la función adecuada que representa la red y creas un MTL4MachineLearningPipelineState, que es el equivalente al estado de pipeline para cómputo o gráficos, pero aplicado a la red de ML.

Para lanzar la inferencia, se crea el MTL4MachineLearningCommandEncoder, se establece el pipeline, se enlazan las entradas y salidas (como MTLTensors) y se hace un dispatch de la red usando un heap de intermediarios, de forma que la memoria intermedia se reutiliza entre pases sin crear y destruir buffers constantemente.

Metal 4 también introduce un nuevo identificador de etapa, MTLStageMachineLearning, que permite indicar claramente en las barreras qué trabajo pertenece a ML y qué parte a renderizado o cómputo. Así, solo las tareas que dependen de la salida de la red tienen que esperar; el resto puede ejecutarse en paralelo, aprovechando al máximo la GPU.

Shader ML y Metal Performance Primitives: ML dentro de tus propios sombreadores

Además de ejecutar redes completas con su propio codificador, Metal 4 ofrece la posibilidad de incrustar operaciones de ML dentro de sombreadores y kernels existentes mediante Shader ML y una nueva biblioteca de primitivas denominada Metal Performance Primitives.

Esta aproximación es ideal para redes pequeñas que se ejecutan por fragmento o por vértice, como las usadas para compresión de materiales neuronales o para ciertos efectos de iluminación y postprocesado. En lugar de ejecutar la red en varios pasos separados con sincronizaciones intermedias, puedes realizar todo en un único envío de shader.

Con Shader ML puedes declarar MTLTensors directamente en tu sombreador, bien como recursos enlazados mediante slots de buffer o argument buffers, bien como tensores creados “en línea” a partir de datos muestreados en las texturas. El nuevo encabezado metal_tensor expone el tipo MTLTensor parametrizado por tipo de dato y dimensiones.

Los tensores creados en línea se asumen bien empaquetados, por lo que no tienes que indicar strides. De esta forma, es sencillo construir una característica de entrada a partir de varias texturas latentes y pasarla a la red neuronal, encargada de descomprimir o transformar los datos antes de realizar el sombreado final.

Para las operaciones más costosas, Metal introduce Metal Performance Primitives para MTLTensor, una colección de kernels de alto rendimiento que permiten, por ejemplo, multiplicación de matrices y convoluciones directamente en el lenguaje de sombreado, con descriptores específicos como matmul2d_descriptor.

Estas primitivas pueden especializarse según el tamaño del problema, si hay que transponer entradas, requisitos de precisión y número de hilos que participan en la operación. En un sombreador de fragmentos, por ejemplo, es habitual que un solo hilo ejecute toda la multiplicación de matrices asociada al material de ese fragmento.

El resultado es un pipeline mucho más compacto: menos envíos, mejor uso de la caché y menos tráfico de memoria, especialmente cuando se trata de redes de tamaño reducido que se ejecutan por píxel o por vértice dentro de un frame.

Depuración de ML en Metal con Xcode: MTLTensors y MPSGraph Viewer

Con tanta integración de ML en la GPU, la depuración se vuelve crítica. Apple ha reforzado las herramientas de Metal Debugger y GPU Tools en Xcode para cubrir también las cargas de trabajo de aprendizaje automático que usan MTLTensor, MTL4MachineLearningCommandEncoder y MPSGraph.

En primer lugar, el Dependency Viewer de Xcode permite inspeccionar todos los comandos Metal de un frame, incluidos los codificadores de ML, las barreras y eventos. De esta manera es más fácil detectar si un problema de artefactos gráficos procede de una mala sincronización entre pases o de un fallo dentro de la red neuronal.

Además, el depurador ofrece un visor de MTLTensors, tanto de entrada como de salida, de manera similar a como se visualizan texturas o buffers. Esto resulta muy útil para comprobar si los datos intermedios que consume la red tienen el aspecto esperado o si el error se introduce en una capa concreta.

Para modelos construidos con Core ML o convertidos a paquetes Metal, existe un ML Network Debugger que muestra la red como un grafo de operaciones, permite navegar por cada nodo, ver sus atributos y abrir las salidas intermedias en el visor de tensores. Esto facilita aislar errores lógicos o bugs sutiles en la implementación.

Por otro lado, en Xcode 16 llega un nuevo aliado para quienes trabajan con MPSGraph: el MPSGraph Viewer. Esta herramienta permite abrir directamente paquetes de MPSGraph, ver el grafo de operaciones, explorar entradas, salidas, constantes y entender cómo se estructura el modelo.

  ¿Cómo instalar el Kontakt 5?

El visor puede mostrar el grafo “tal cual” fue definido, o bien compilarlo para un dispositivo concreto y enseñar cómo MPSGraph ha fusionado y optimizado operaciones en Metal Stitched Shaders, es decir, kernels combinados que reducen al mínimo la sobrecarga de memoria interna y mejoran claramente el rendimiento en Apple Silicon.

Optimización de transformers con MPS y MPSGraph

Los modelos tipo transformer, muy usados en modelos de lenguaje, traducción y generación de texto, también se benefician de las mejoras constantes de MPS y MPSGraph. Su estructura en bloques de atención, normalización y feed‑forward plantea retos de cómputo y memoria que estas APIs ayudan a resolver.

Un punto especialmente costoso es el bloque de multi‑head attention, que realiza grandes multiplicaciones de matrices multidimensionales. MPSGraph ofrece ahora una operación fusionada de Scaled Dot‑Product Attention (SDPA), que agrupa en un solo kernel todo el conjunto de operaciones normalmente separadas, logrando una ejecución mucho más eficiente.

El uso de esta operación se reduce a invocar el método scaledDotProductAttention en un objeto MPSGraph, pasando los tensores de consulta, claves y valores (Q, K, V). El framework genera el kernel óptimo para el dispositivo, evitando trabajo duplicado y reduciendo el coste de memoria intermedia.

Otro cuello de botella importante es el cálculo repetido de proyecciones K y V para secuencias largas. Cuando se generan tokens uno a uno, sería muy ineficiente recalcular todo en cada iteración. Por eso, MPSGraph facilita el uso de un KV‑cache, donde se almacenan las proyecciones ya calculadas y se actualizan in‑place mediante operaciones de slice update.

Para ello se crea un tensor placeholder para el cache, se define una variable que representa su estado actual y, en cada paso, se inserta el nuevo bloque K/V usando sliceUpdateDataTensor. Después se recorta el tensor con slice para extraer solo la parte válida y se reutiliza como entrada en la atención.

Una vez optimizado el cómputo, el siguiente límite suele ser el ancho de banda de memoria. Los pesos de grandes modelos de lenguaje pueden alcanzar decenas de gigabytes si se usan floats de 16 bits, por lo que la reducción de precisión se vuelve imprescindible.

MPS soporta cuantización a 8 bits e incluso a 4 bits, lo que permite comprimir drásticamente los pesos sin perder demasiada calidad. Ofrece varios métodos, como cuantización afín lineal usando un factor de escala y cero, o cuantización basada en tablas de consulta, donde un índice de 4/8 bits referencia a un valor real almacenado en una LUT.

La des‑cuantización se realiza con la operación dequantize de MPSGraph, y en muchos casos el framework es capaz de fusionar esta operación con una posterior multiplicación de matrices, generando un kernel de matmul cuantizado que des‑cuantiza al vuelo sin necesidad de almacenar una copia intermedia en alta precisión.

Para minimizar la pérdida de calidad debida a la cuantización, se puede recurrir a cuantización por bloques con escalas y offsets específicos por grupo de elementos, mejor adaptados a la distribución local de los pesos. El código es muy similar al de cuantización simple, pero en lugar de un único factor de escala y cero se pasa un tensor con las escalas por bloque.

Otra técnica para mejorar resultados en modelos cuantizados es el uso de adapters, pequeñas capas adicionales que se insertan en puntos concretos del modelo y que se re‑entrenan para compensar los errores introducidos. MPSGraph permite implementarlos vía “callables”: subgrafos que se definen por separado y se invocan desde el grafo principal, con sus propios ejecutables compilados y referenciados por nombre.

FFT y procesado de audio con MPSGraph

Más allá del texto, muchos modelos de IA trabajan con audio y señales temporales, donde las transformadas rápidas de Fourier (FFT) son una herramienta fundamental. Apple ha ampliado MPS y MPSGraph con soporte más potente para FFT, permitiendo mover al GPU pipelines completos de procesado de audio.

Un caso típico es la extracción de texto a partir de audio: se aplica una Short‑Time Fourier Transform (STFT) al waveform de entrada para obtener un espectro de frecuencias tiempo‑frecuencia, que después analiza un transformer especializado en audio.

En MPSGraph puedes implementar este flujo dividiendo la señal en ventanas superpuestas mediante vistas estridadas (strided views) sobre el tensor original, de modo que no se copian datos sino que se reinterpreta la memoria con otra forma y strides. Cada ventana se multiplica por una función de ventana (Hann, Gauss, etc.) y se pasa a una operación de FFT batched.

Las vistas estridadas permiten que todas estas operaciones se hagan sin costosas reasignaciones de memoria, simplemente ajustando la visión que el grafo tiene sobre los datos de entrada, algo especialmente ventajoso en aplicaciones de tiempo real.

MPSGraph extiende así su capacidad de acelerar tanto la parte de preprocesado numérico (FFT, operaciones tensoriales) como la parte de modelado (transformers de audio, redes convolucionales, etc.) dentro de un mismo grafo ejecutado íntegramente en la GPU.

Apple M5
Artículo relacionado:
Apple M5: el salto en IA que redefine el Mac y su GPU