top of page

llama.cpp CUDA Fusion se integra con un procesamiento de prompts hasta un 10,7% más rápido

hace 2 horas
14 min de lectura

llama.cpp integró una optimización de CUDA el 25 de octubre, y los benchmarks del colaborador informan mejoras en el procesamiento de prompts de hasta el 10,7% en DGX Spark. El cambio de fusión CUDA de llama.cpp combina operaciones dentro de la red feed-forward de un modelo, el componente que transforma las representaciones de tokens entre etapas de atención. Su beneficio se refiere a la lectura de prompts, no a la generación de cada token posterior de la respuesta.

Las mediciones del colaborador anujj también muestran mejoras en la RTX 5090 de NVIDIA, aunque las ganancias porcentuales reportadas son menores. Se trata de comparaciones informadas por el autor, no de resultados reproducidos de forma independiente. El cambio subyacente puede verificarse en el código integrado, mientras que su valor práctico sigue dependiendo del formato del modelo, el hardware y la carga de trabajo.

La comparación central enfrenta la ejecución fusionada, que combina operaciones relacionadas, con una ruta de ejecución existente que programa esas operaciones por separado. Una propuesta anterior abordó la misma oportunidad de otra manera. El enfoque integrado reorganiza cómo llegan los valores a los hilos de la GPU, reduciendo el trabajo intermedio sin modificar los pesos almacenados del modelo. Para los desarrolladores que ejecutan prompts largos localmente, esto constituye una mejora de software específica que vale la pena medir frente a un despliegue existente.

Qué cambia con la integración de la fusión CUDA de llama.cpp

El cambio integrado amplía una optimización existente a cargas de trabajo mayores de procesamiento de prompts en hardware NVIDIA compatible.

CUDA, la plataforma de computación GPU de NVIDIA, proporciona el entorno de ejecución para esta implementación. MMQ, la ruta de multiplicación de matrices cuantizadas de llama.cpp, gestiona cálculos con pesos de modelos comprimidos. La cuantización representa esos pesos con una precisión numérica reducida para disminuir los requisitos de almacenamiento y memoria.

El cambio de fusión integrado se dirige a una secuencia recurrente dentro de capas feed-forward densas compatibles. Las proyecciones separadas gate y up transforman la misma entrada. Después, una unidad lineal con compuerta, o GLU, combina sus resultados mediante una activación y una multiplicación elemento a elemento.

Anteriormente, las cargas de trabajo mayores en esta ruta gestionaban las proyecciones y su combinación como operaciones separadas. Según anujj, la nueva implementación ejecuta esa secuencia mediante un único kernel de multiplicación de matrices. Un kernel es una función lanzada a través de los hilos de la GPU.

Esa consolidación importa porque el trabajo circundante también consume recursos. Preparar entradas, lanzar operaciones, escribir resultados intermedios y volver a leerlos puede añadir sobrecarga. Combinar operaciones crea la oportunidad de eliminar parte de ese tráfico mientras se mantiene la transformación matemática prevista.

El cambio no introduce esta idea en todas las rutas de ejecución de forma simultánea. El colaborador afirma que la fusión para lotes pequeños ya existía mediante otras implementaciones de matriz-vector. Los cálculos matriz-vector suelen atender cargas de trabajo más pequeñas que los cálculos matriz-matriz destacados aquí.

Esta distinción explica por qué el anuncio se centra en el procesamiento de prompts. El prefill, la fase que procesa un prompt de entrada antes de generar una respuesta, puede exponer lotes de trabajo mayores. La ruta de ejecución recién compatible se ocupa de esa parte de la inferencia.

La cronología también importa. La descripción inicial del pull request data del 4 de octubre, mientras que el proyecto lo integró el 25 de octubre. La integración lleva la implementación a la rama master del proyecto. No establece que todas las aplicaciones empaquetadas ya incluyan el cambio.

Una aplicación de escritorio, un contenedor o un proyecto posterior puede incorporar llama.cpp según su propio calendario. Por tanto, los usuarios deben identificar la versión real del runtime detrás de una interfaz. Una actualización de aplicación y una integración de código fuente upstream son eventos separados.

Para los archivos de modelos existentes, la historia de compatibilidad es relativamente directa. El colaborador afirma que el diseño de los pesos almacenados permanece sin cambios. Los usuarios no deberían interpretar la referencia del título a filas intercaladas como un requisito para descargar archivos de modelos reorganizados de forma especial.

Por tanto, la noticia inmediata es acotada y concreta. Una secuencia de ejecución compatible ahora cuenta con una optimización adicional disponible upstream. Que una solicitud concreta la utilice depende de las comprobaciones de elegibilidad del runtime.

Las ganancias de los benchmarks favorecen a Spark, con una mejora menor en RTX 5090

Los resultados reportados muestran una dirección coherente en las configuraciones enumeradas, pero su magnitud varía según el hardware y la cuantización.

El autor probó DGX Spark con su procesador GB10 y, por separado, una RTX 5090. Ambas tablas de benchmarks comparan una referencia etiquetada como master con el pull request. Todas las filas enumeradas informan un mayor rendimiento de procesamiento de prompts para la implementación modificada.

En DGX Spark, la mayor mejora porcentual enumerada corresponde a Llama-3.1-8B con IQ4_XS, un formato de pesos comprimidos. El rendimiento aumenta de 2.933,9 a 3.249,0 tokens por segundo. El autor informa una ganancia del 10,7% para esa configuración.

Otros resultados de Llama-3.1-8B en Spark quedan por debajo de ese máximo, aunque conservan mejoras reportadas sustanciales. La configuración Q4_K_M pasa de 2.749,3 a 3.000,6 tokens por segundo. La configuración Q5_K_M aumenta de 2.699,4 a 2.960,3 tokens por segundo.

Estas etiquetas identifican distintas configuraciones cuantizadas de modelos, en lugar de mediciones intercambiables de un binario idéntico. Sus resultados muestran por qué los usuarios deberían igualar el formato exacto del archivo al evaluar una optimización. El nombre de una familia de modelos por sí solo omite una variable relevante.

La tabla de Spark también enumera modelos etiquetados como Qwen3.8-27B y Qwen3.6-27B. Estos nombres se reproducen aquí como etiquetas de benchmark del informe del colaborador. La propia tabla de rendimiento no establece de forma independiente sus detalles de entrenamiento, capacidades o disponibilidad más amplia.

Para la entrada etiquetada Qwen3.8-27B, las mejoras en Spark van del 4,6% al 7,4%. La fila Q4_K_M sube de 840,1 a 899,9 tokens por segundo. La fila IQ4_XS aumenta de 882,4 a 948,0 tokens por segundo.

Los resultados de RTX 5090 presentan una escala de mejora diferente. En sus configuraciones enumeradas, el autor informa ganancias de entre el 1,9% y el 4,7%. Ese rango porcentual menor hace esencial una interpretación específica para cada hardware.

Para Llama-3.1-8B en IQ4_XS, el resultado de RTX 5090 aumenta de 12.997,6 a 13.603,3 tokens por segundo. La mejora reportada es del 4,7%. Para la entrada Qwen3.8-27B Q6_K, el rendimiento sube de 3.220,5 a 3.281,0 tokens por segundo, o un 1,9%.

Por tanto, los benchmarks de fusión de llama.cpp respaldan una conclusión acotada. En las pruebas de prompts largos seleccionadas por el autor, la optimización mejora el rendimiento de entrada medido en toda la matriz reportada. No establecen una mejora idéntica para todas las GPU compatibles.

La comparación porcentual tampoco revela por qué Spark se beneficia más. Diferencias en el comportamiento de la memoria, las características de ejecución y los cuellos de botella existentes pueden afectar los resultados de una optimización. Establecer su contribución relativa requeriría un perfilado adicional, que estas mediciones principales por sí solas no proporcionan.

Para los compradores, la implicación útil se refiere a la disciplina de evaluación. Estos resultados no justifican elegir hardware basándose únicamente en las ganancias porcentuales. El rendimiento absoluto, el ajuste del modelo, la capacidad de memoria y la latencia real de la aplicación siguen siendo consideraciones separadas.

Las filas intercaladas eliminan trabajo entre cálculos

El movimiento central de la implementación consiste en organizar resultados relacionados juntos antes de aplicar la operación gate.

Anujj describe la carga de filas gate y up en fragmentos alternos de ocho. Esta disposición coloca los valores correspondientes dentro de los resultados de trabajo del mismo hilo. El hilo puede entonces combinar esos valores al escribir la salida final.

Los registros, las pequeñas ubicaciones de almacenamiento de la GPU asignadas a los hilos en ejecución, contienen esos resultados intermedios. Aplicar allí la combinación evita un viaje adicional de ida y vuelta a través de búferes de salida intermedios para esa parte del cálculo. El ahorro previsto proviene de la organización de la ejecución.

La implementación mantiene una disposición de acumulador en lugar de introducir una segunda tesela acumuladora para la proyección gate. Un acumulador conserva sumas parciales durante la multiplicación. Una tesela es un bloque de elementos de matriz procesados conjuntamente.

Esta elección de diseño distingue esta implementación de la propuesta de fusión anterior. Según la descripción del colaborador, el enfoque más reciente sigue una sugerencia de am17an. Ambas propuestas se dirigen a operaciones relacionadas, pero organizan el cálculo de manera diferente.

La distinción es práctica más que cosmética. Mantener más estado intermedio puede aumentar la presión sobre los recursos de ejecución limitados de una GPU. Combinar operaciones solo ayuda cuando los ahorros superan cualquier coste adicional de programación o almacenamiento.

Por eso, “menos kernels” no significa automáticamente “inferencia más rápida”. Una operación combinada mayor puede utilizar el hardware con menor eficiencia en algunas condiciones. Una optimización debe preservar suficiente trabajo paralelo mientras evita nuevas restricciones que anulen sus beneficios.

El código integrado refleja esa preocupación mediante comprobaciones de elegibilidad. Evalúa si la carga de trabajo es adecuada para esta ruta de fusión. Las operaciones matemáticas compatibles por sí solas no garantizan que deba ejecutarse la fusión.

La implementación también compite con stream-k, un método de programación que divide el trabajo de multiplicación de matrices a lo largo de su dimensión de reducción. La ruta fusionada no puede utilizar esa descomposición. Por tanto, necesita otra forma de decidir si su disposición de teselas proporciona suficiente eficiencia.

Johannes Gaessler planteó esa cuestión durante la revisión y solicitó una comparación anticipada entre la eficiencia esperada de teselado y stream-k. El código integrado incluye una decisión de eficiencia antes de seleccionar la ruta fusionada. Eso convierte la ejecución condicional en parte del diseño.

La revisión de programación de la fusión ofrece la perspectiva escéptica más útil sobre la optimización. Se centra en circunstancias en las que una simplificación atractiva podría perder rendimiento. Se trata de una limitación técnica, más que de un desacuerdo sobre la existencia del benchmark.

En consecuencia, la competencia principal aquí sigue estando dentro del runtime. La ejecución fusionada debe superar el enfoque de programación existente para la forma de operación elegible. No hay evidencia en estos resultados de una victoria más amplia sobre otro framework de inferencia.

Este mecanismo también aclara qué deberían esperar los usuarios de la fusión CUDA de llama.cpp. Reorganiza el trabajo para un cálculo existente. No incrementa la capacidad de razonamiento de un modelo, amplía su conocimiento entrenado ni elimina límites de memoria no relacionados.

El mismo modelo sigue realizando la misma tarea general. La oportunidad de ingeniería reside en dedicar menos tiempo a alcanzar la salida de una secuencia concreta.

Un procesamiento de prompts más rápido modifica una parte del tiempo de espera

El benchmark mide el procesamiento de entrada, por lo que su valor práctico depende de cuánto contribuya el procesamiento de entrada a una solicitud real.

El comando reportado procesa un prompt de 16.384 tokens y solicita cero tokens generados. Los tokens son las unidades de texto que un modelo consume y produce. Esta configuración aísla el rendimiento del prompt en vez de medir una respuesta conversacional completa.

El comando utiliza tamaños de lote y microlote de 2.048. Un microlote es una unidad de ejecución más pequeña extraída de un lote mayor. También activa Flash Attention, una implementación de atención diseñada para reducir el tráfico de memoria durante los cálculos de atención.

El autor especifica almacenamiento de media precisión para la caché clave-valor, que conserva información de atención de tokens procesados previamente. En el comando aparecen cinco repeticiones. Estos ajustes definen las condiciones evaluadas y deben acompañar cualquier resultado citado.

La metodología de benchmark del proyecto distingue el procesamiento de prompts de la generación de tokens. Esa separación es crucial para interpretar estas cifras. Los tokens de entrada por segundo y los tokens de salida por segundo responden a preguntas de rendimiento diferentes.

Pensemos en un desarrollador que pide a un modelo local que inspeccione un archivo de código fuente grande. El procesamiento de esa entrada puede contribuir de forma significativa al retraso antes de que comience la respuesta. Una ruta de prefill más rápida y elegible aborda esa parte de la interacción.

Un breve intercambio conversacional plantea otra carga de trabajo. Su prompt podría requerir relativamente poco procesamiento en comparación con el tiempo dedicado a generar una respuesta larga. La misma mejora en el rendimiento de entrada afectaría entonces a una parte menor de la espera total.

Los prompts almacenados en caché plantean otra distinción. El almacenamiento en caché de prompts reutiliza cálculos de entradas que el sistema ya ha procesado. Cuando una aplicación reutiliza correctamente ese trabajo, queda menos entrada nueva que esta optimización pueda acelerar.

El análisis de documentos también incluye trabajo más allá de la inferencia. Una aplicación podría recuperar archivos, extraer texto, clasificar pasajes o preparar una instrucción antes de enviar nada al modelo. Un procesamiento de entrada del modelo más rápido no demuestra que esas etapas circundantes terminen antes.

Para los equipos que mantienen una base de conocimiento con búsqueda, esa separación favorece mejores decisiones de rendimiento. La calidad de recuperación y la selección de contexto determinan qué llega al modelo. El rendimiento en tiempo de ejecución determina con qué rapidez los cálculos elegibles lo procesan.

La distinción también presiona a quienes mantienen aplicaciones. Necesitan saber qué runtime distribuye su producto y si sus cargas de trabajo habituales alcanzan la ruta optimizada. Una nota de lanzamiento genérica sobre una IA local más rápida no puede responder a esas preguntas.

La respuesta útil es medir en el límite de la aplicación. El tiempo hasta el primer token mide el retraso antes de que comience la salida. El tiempo total de respuesta mide toda la interacción, mientras que el rendimiento de generación mide el ritmo después de que empieza la salida.

Cada métrica puede cambiar de manera diferente tras una actualización del runtime. Una mejora de prefill puede reducir la espera inicial sin cambiar la velocidad del texto posterior. Informar de esos resultados por separado ofrece a los usuarios una descripción más precisa de la actualización.

Para el procesamiento de prompts de llama.cpp, el caso de uso más sólido sigue siendo una entrada nueva y sustancial en una configuración elegible. El benchmark del autor enfatiza deliberadamente esa carga de trabajo. Extender su resultado a cada sesión de chat iría más allá de la evidencia.

Los formatos compatibles y las comprobaciones de corrección definen los límites

El código fusionado contiene restricciones importantes, y el informe de corrección del autor debe interpretarse dentro de la cobertura de pruebas que declara.

La solicitud de extracción describe compatibilidad con los tipos de pesos Q4_K, Q5_K, Q6_K, Q8_0 e IQ4_XS en arquitecturas NVIDIA Turing o posteriores. Esas son familias de pesos compatibles. Los archivos de modelo pueden combinar tipos, por lo que la etiqueta general de un archivo no describe todos los tensores internos.

La implementación también verifica que los pesos relevantes de gate y up cumplan las condiciones necesarias para la fusión. La forma, el tipo y la disposición importan porque la operación combinada espera cálculos correspondientes. Una disposición no compatible debería conservar otra ruta de ejecución.

El código fusionado excluye los casos que requieren su fallback de límite de filas. Un fallback gestiona formas que no llenan limpiamente los mosaicos de procesamiento normales. Esta restricción importa porque la descripción original habla de pruebas que cubrían casos límite durante el desarrollo.

Por tanto, los lectores deben distinguir el resumen inicial de pruebas de las reglas de selección del código final. Probar una implementación de desarrollo más amplia no demuestra que todas las formas evaluadas sigan siendo elegibles en la versión fusionada. Las protecciones finales determinan la ejecución real.

También existen restricciones sobre los parámetros de operación. El código verifica configuraciones de activación concretas antes de seleccionar la fusión. Estas comprobaciones evitan que el runtime trate operaciones superficialmente similares como intercambiables cuando su comportamiento requerido difiere.

El alcance también se centra en operaciones feed-forward densas. Los modelos de mezcla de expertos, que dirigen tokens a través de subredes seleccionadas, introducen requisitos de ejecución diferentes. La revisión identifica explícitamente trabajo adicional de compatibilidad, en lugar de establecer cobertura universal para esos modelos.

Otros backends de hardware no reciben esta optimización simplemente porque sean compatibles con llama.cpp. El colaborador separa explícitamente el cambio de otros backends. Por tanto, los resultados de hardware NVIDIA no pueden demostrar beneficios equivalentes en una GPU de Apple o en una configuración AMD.

La evidencia de corrección es alentadora, pero sigue siendo reportada por el autor. Anujj afirma que la suite completa de pruebas de operaciones del backend supera las pruebas en GB10. El informe también indica que las suites de multiplicación de matrices se superan en una RTX 5090.

El colaborador también informa de resultados de perplejidad idénticos en las pruebas especificadas, con la fusión activada y desactivada. La perplejidad mide qué tan bien un modelo predice un texto de evaluación. Proporciona una comprobación numérica útil, aunque no representa todos los comportamientos posibles de una aplicación.

Ese resultado respalda una afirmación más limitada que una identidad universal de salida. Puntuaciones idénticas en una evaluación declarada no prueban respuestas generadas idénticas en todos los prompts, ajustes o plataformas. Una validación más amplia requiere evidencia más amplia.

Los benchmarks de fusión de llama.cpp tampoco cuentan con una reproducción independiente en las fuentes examinadas para este informe. La revisión y fusión upstream establecen que el proyecto aceptó el código. No convierten las mediciones del colaborador en una auditoría externa de rendimiento.

Ninguno de estos límites elimina la ganancia reportada. Definen dónde la afirmación se vuelve útil. Un lector con hardware y tipos de modelo coincidentes tiene una razón concreta para probar, mientras que otras configuraciones requieren evidencia independiente.

La interpretación más sólida combina ambas partes. El cambio cuenta con un mecanismo claro y mediciones publicadas, junto con condiciones explícitas que determinan cuándo se ejecuta.

Tres señales mostrarán hasta qué punto se extiende la mejora

La próxima evidencia debería conectar el código upstream, las mediciones reproducibles y la latencia que experimentan los usuarios.

La primera señal es la adopción downstream. En los próximos meses, las versiones de aplicaciones y compilaciones empaquetadas deberían establecer qué productos incluyen la implementación fusionada. Esto importa porque los usuarios suelen interactuar con llama.cpp a través de otra aplicación.

Las instrucciones de compilación de CUDA del proyecto describen la ruta de compilación upstream. Las distribuciones empaquetadas pueden seguir calendarios de lanzamiento diferentes. Un identificador de versión vinculado al código fuente incluido resulta más informativo que una afirmación general de usar el backend más reciente.

Si aplicaciones ampliamente utilizadas incorporan el cambio, se refuerza el caso de adopción inmediata. Si permanecen en revisiones antiguas, el alcance práctico de la fusión sigue siendo limitado. Ese resultado se referiría al calendario de distribución, no invalidaría la optimización subyacente.

La segunda señal es una reproducción independiente con ajustes explícitos. Los informes útiles deberían identificar hardware, archivos de modelo, revisiones del runtime y argumentos del benchmark. También deberían separar el procesamiento de prompts nuevos de la entrada en caché y la salida generada.

Las reproducciones con distintas longitudes de prompt aclararían hasta qué punto la ganancia es sensible al tamaño de la carga de trabajo. Los informes en generaciones de GPU compatibles pondrían a prueba si la tendencia se mantiene más allá de las máquinas enumeradas. Los resultados que muestren regresiones ayudarían a identificar limitaciones en la lógica de selección.

La pregunta relevante no es si cada ejecución iguala el máximo del titular. La pregunta es si cargas de trabajo comparables muestran una mejora repetible con una variación aceptable. Una ganancia menor pero constante aún puede ser útil operativamente.

La tercera señal es la latencia de la aplicación. Los equipos deben medir si un runtime actualizado reduce la espera antes de que comience una respuesta en solicitudes representativas. Deben conservar el rendimiento de generación y el tiempo total de respuesta como mediciones independientes.

Esa evidencia conectaría el cambio del kernel con la experiencia del usuario. Una menor demora inicial en prompts largos sin caché respaldaría la promesa práctica de la implementación. Un tiempo total de respuesta sin cambios indicaría que otras etapas dominan el flujo de trabajo medido.

La ampliación de la compatibilidad con formatos o arquitecturas sería desarrollo adicional, no algo establecido por esta fusión. Las afirmaciones futuras deberían identificar su propia implementación y sus propias mediciones. Los resultados actuales proporcionan una línea de base para comparar, no una confirmación anticipada de esas extensiones.

Por ahora, la fusión CUDA de llama.cpp ofrece una razón concreta para revisar el rendimiento de la inferencia local. Se dirige al trabajo repetido dentro de cálculos feed-forward elegibles e informa de ganancias medibles bajo condiciones divulgadas de procesamiento de prompts. Eso basta para justificar una evaluación sin prometer un aumento de velocidad generalizado.

Antes de actualizar una implementación en funcionamiento, conserve su identificador de runtime actual y un conjunto representativo de solicitudes. Compare los mismos archivos de modelo, longitudes de prompt, condiciones de caché y ajustes de salida después de la actualización. Registre por separado el tiempo de espera inicial de la generación de respuestas y conserve los argumentos del benchmark junto con cada resultado. Para flujos de trabajo con documentos largos, incluya entradas nuevas que se parezcan al uso cotidiano en lugar de depender por completo del rendimiento sintético. Para cargas de trabajo conversacionales, compruebe si una menor demora en el procesamiento de entrada cambia la experiencia lo suficiente como para importar. Después, use sus propias mediciones para decidir dónde encaja la mejora upstream en su calendario de lanzamientos. ¿El runtime actualizado acorta la parte de la solicitud que sus usuarios realmente esperan?

 
 

Empieza gratis

Un asistente de IA local-first con gestión del conocimiento personal

Para ofrecer una mejor experiencia con la IA,

actualmente remio solo es compatible con Windows 10+ (x64) y M-Chip Macs.

Tu aliado de IA para el trabajo
Haz más con remio

Planifica. Crea. Entrega.
Todo en un solo lugar.

bottom of page