Acelerando kernels de GPU un 38 % con un sistema multiagente
Nuestro sistema multiagente optimizó de forma autónoma 235 kernels de CUDA para GPUs NVIDIA Blackwell 200, logrando una aceleración media geométrica del 38 % frente a las referencias en solo 3 semanas.
Durante los últimos meses, hemos estado desarrollando un sistema multiagente capaz de crear, mantener y desplegar software complejo de forma autónoma. Como parte de ese trabajo, hemos estado poniendo a prueba el sistema en distintos ámbitos, entre ellos la creación de un navegador desde cero y la resolución de un problema matemático de nivel de investigación en el benchmark First Proof.
Recientemente, empezamos a colaborar con NVIDIA en un nuevo desafío: aplicar nuestro sistema multiagente a la optimización de kernels de CUDA. Se trata de problemas técnicos difíciles con consecuencias importantes en el mundo real: los kernels de CUDA son el software base que sustenta el entrenamiento y la inferencia de modelos de IA en las GPU de NVIDIA. Kernels más rápidos se traducen en un mejor aprovechamiento de la GPU, menor consumo de energía, menor latencia y menor costo por token, lo que permite a los proveedores ofrecer modelos más grandes y más capaces a más usuarios a la vez.
Nuestro sistema multiagente operó de forma autónoma durante tres semanas en 235 problemas. El sistema logró una aceleración media geométrica del 38 % al crear y optimizar desde cero kernels para GPUs Blackwell, hasta llegar al nivel de ensamblador.
Este nivel de mejora del rendimiento normalmente solo se consigue tras meses o años de trabajo de ingenieros de kernels con muchísima experiencia. El sistema multiagente lo logró en semanas, abordando la larga cola de problemas de kernels que resultaban impracticables con los enfoques existentes.
Optimización de kernel como prueba de las capacidades de un sistema de agentes
Una de las mejores formas de evaluar sistemas multiagente de ejecución prolongada es plantearles problemas de optimización abiertos en los que ni siquiera nosotros sabemos cuál es la respuesta correcta. Los problemas de optimización de kernel cumplen este criterio: ofrecen objetivos medibles que el sistema puede optimizar de forma iterativa, en lugar de limitarse a buscar un diff conocido y sencillo.
Hoy en día, los ingenieros optimizan kernels descomponiendo los modelos en operaciones matemáticas individuales y ajustando cada una por separado. Esto hace que el problema sea manejable, pero deja rendimiento sin explotar, porque la optimización por partes pasa por alto posibles mejoras que surgirían de optimizar todo el sistema a la vez. Hasta ahora, el rendimiento de la GPU ha estado limitado por nuestra incapacidad para explorar todo el espacio de soluciones más allá de estas simplificaciones manuales.
Con este experimento, queríamos ver si nuestro sistema multiagente podía salir de estas limitaciones y explorar un espacio de soluciones más amplio para generar kernels más rápidos.
SOL-ExecBench para la generación de problemas y el benchmarking
NVIDIA usó SOL-ExecBench para generar 235 problemas de optimización a partir de más de 124 modelos de código abierto en producción, como Deepseek, Qwen, Gemma, Kimi y Stable Diffusion. A diferencia de los datos sintéticos o los kernels de prueba, cada problema representa una limitación real en cargas de trabajo de entrenamiento o inferencia para una variedad de arquitecturas de modelos: LLM, difusión, visión, audio, video e híbridos multimodales.


También usamos SOL-ExecBench para evaluar el rendimiento de soluciones de kernel multiagente en 27 GPU NVIDIA Blackwell 200. SOL-ExecBench es un evaluador eficaz que compara el rendimiento de los kernels con implementaciones de software existentes de referencia y con los límites teóricos de rendimiento del hardware. Si los agentes usan tácticas engañosas, como el almacenamiento en caché, y ofrecen un rendimiento superior al que una B200 puede admitir, el pipeline invalida el resultado.
Cómo ejecutamos el experimento
El sistema multiagente resolvió los 235 problemas de optimización de kernel de GPU en una sola ejecución, mediante el despliegue de un agente planificador que distribuía y reequilibraba el trabajo entre workers autónomos en función de métricas de rendimiento.
Todo el protocolo de coordinación estaba contenido en un único archivo markdown que especificaba el formato de salida, las reglas y las pruebas. El sistema multiagente aprendió por sí solo a llamar al pipeline de benchmarking durante sus ejecuciones, creando un bucle en el que probaba, depuraba y optimizaba continuamente los kernels sin ninguna intervención de los desarrolladores.


Para evaluar mejor las capacidades del sistema multiagente, le pedimos que escribiera sus soluciones en dos lenguajes, en dos ejecuciones separadas, en extremos opuestos del espectro de abstracción de GPU:
- CUDA C with inline PTX, que proporciona a los agentes acceso directo a registros e instrucciones a nivel de ISA, poniendo a prueba si el sistema puede razonar sobre el hardware en su nivel más bajo.
- CuTe DSL, que ofrece abstracciones componibles de alto nivel con una presencia mínima en los datos públicos de entrenamiento, poniendo a prueba si el sistema puede aprender APIs nuevas únicamente a partir de la documentación proporcionada.
Aceleración del 38 %, con un 19 % de las optimizaciones que logran mejoras superiores a 2x
Reportamos el rendimiento del sistema multiagente de dos maneras:
- Aceleración media geométrica frente al código de PyTorch optimizado por un solo agente como referencia.
- Puntuaciones Speed-of-Light (SOL) que representan lo buena que es una solución en comparación con los límites teóricos del hardware en una curva logarítmica. Una puntuación de 0.5 representa la referencia optimizada de PyTorch, y 1.0 es el límite de rendimiento.


Nuestro sistema multiagente superó a las referencias en 149 de 235 problemas (63 %), con una media geométrica de 1,38x (aceleración media geométrica del 38 %).


En 45 de 235 problemas (19 %), el sistema multiagente logró optimizaciones de más de 2x en comparación con las referencias. Puedes consultar las soluciones finales que desarrolló nuestro sistema en este repo público.


Diferentes estrategias de optimización para distintos problemas
Para mostrar la capacidad de adaptación del sistema a distintos tipos de problemas, destacamos tres casos en los que llegó de forma natural a estrategias de optimización diferentes.
Atención de consultas agrupadas BF16 con Paged Prefill
La atención de consultas agrupadas con paged prefill es una operación común en la fase del prompt de los sistemas modernos de inferencia para LLM. Una implementación bien optimizada puede admitir contextos más largos, mayor concurrencia y mejor rendimiento con la misma VRAM de GPU.
El agente usó CUDA C++ para optimizar este problema de atención extraído de la inferencia de SGLang para Llama 3.1 8B. A medida que iteró sobre el kernel, empleó con éxito instrucciones específicas de hardware para la carga de memoria y el cálculo, incorporó una planificación mejorada mediante kernels persistentes y lo optimizó al máximo para el tamaño de entrada.
Comparamos el kernel personalizado del sistema multiagente con una referencia optimizada por humanos en la biblioteca FlashInfer. Descubrimos que el sistema produjo una solución que se acercaba a los límites del hardware, con una puntuación SOL de 0.9722, lo que representa una aceleración media geométrica del 84% con respecto a la referencia.
También reemplazamos el kernel existente en SGLang y observamos una aceleración del 3% en el tiempo hasta el primer token (TTFT) en Llama 3.1 8B. Dado que este problema de atención ocupa entre el 2% y el 5% del proceso de prefill, según la configuración de servicio, consideramos que se trata de una aceleración de extremo a extremo no trivial.


NVFP4 MoE Linear con Gating
Este problema representa un patrón común de dos kernels presente en modelos Mixture-of-Experts como Qwen3, con la particularidad de que el tensor de entrada y el resultado intermedio de la multiplicación están cuantizados a NVFP4 (punto flotante de 4 bits).
El agente identificó correctamente la cuantización como el principal cuello de botella y, en consecuencia, fusionó el cálculo de escala y el redondeo. En lugar de escalar y luego redondear durante la cuantización, usó intervalos de umbral precalculados para asignar directamente valores FP32 a códigos FP4, lo que es posible porque en NVFP4 solo hay 16 valores posibles. A continuación, aplicó estas optimizaciones a casos de prueba más grandes.
El agente finalmente superó la referencia optimizada de PyTorch, con una aceleración media geométrica del 39 % y una puntuación SOL de 0,58.


Multiplicación de matrices BF16
La multiplicación de matrices es un problema notoriamente difícil de optimizar porque requiere un conocimiento profundo de las distintas unidades de hardware y de cómo se programan. Los kernels de multiplicación de matrices (GEMM) de alto rendimiento requieren PTX en línea (similar al lenguaje ensamblador), pipelining y staging dentro de un kernel. Como resultado, históricamente escribir GEMM rápidos ha quedado en manos de expertos en kernels con mucha experiencia.
El sistema multiagente de Cursor generó desde cero un kernel GEMM especializado en CUDA C++, acercándose de forma notable (86%) a una referencia humana meticulosamente ajustada de la biblioteca NVIDIA cuBLAS. El sistema logró este resultado aprendiendo de forma independiente a usar instrucciones específicas de Blackwell, optimizando las lecturas y escrituras de memoria para ese hardware y, después, hiperoptimizando para las dimensiones exactas.
Y en los casos de prueba con M pequeña, que son especialmente importantes para la fase de decode de la inferencia de los LLM, el kernel del sistema multiagente superó a la biblioteca hasta en un 9%. Este resultado apunta a que los sistemas multiagente pronto superarán a los expertos del área incluso en los problemas de kernels más difíciles.


Un sistema multiagente para crear software
Aunque el sistema multiagente logró una aceleración media geométrica del 38% con respecto a las referencias, la puntuación SOL mediana seguía siendo de solo 0,56, lo que dejaba un amplio margen de optimización. Creemos que las soluciones multiagente pueden mejorar enormemente con más capacidad de cómputo, ya que teníamos cientos de problemas y agentes ejecutándose con solo 27 GPU. Esto limitó nuestra capacidad para aprovechar al máximo el sistema multiagente. Con más GPU, el sistema podría explorar soluciones aún más profundas y novedosas.
Las tareas más ambiciosas del desarrollo de software son abiertas y no tienen una solución clara. Los sistemas de agente único tienen dificultades en este terreno porque los modelos funcionan mejor en tareas de alcance reducido que ya han visto durante el entrenamiento. Consideramos que el experimento de optimización de kernel valida aún más que las arquitecturas multiagente se convertirán rápidamente en el enfoque predeterminado para crear software, porque pueden abordar problemas nuevos que quedan muy fuera de la distribución de los datos de entrenamiento.
Las técnicas que estamos investigando aquí pronto influirán en el producto principal de Cursor. Si te interesa trabajar en problemas difíciles de coordinación multiagente, al equipo de Cursor le encantaría saber de ti en hiring@cursor.com.