15 puntos por GN⁺ 2026-02-23 | 1 comentarios | Compartir por WhatsApp
  • Motor de inferencia LLM basado en C++/CUDA que puede ejecutar el modelo Llama 70B en una RTX 3090 (24 GB de VRAM) mediante streaming de memoria de GPU y E/S directa desde NVMe
  • Usa una estructura de caché adaptativa de 3 niveles para dividir automáticamente entre VRAM, RAM fijada y NVMe/mmap, logrando una mejora de velocidad de hasta 83 veces frente a mmap
  • El backend gpu-nvme-direct omite por completo la CPU y transfiere datos directamente de NVMe a la GPU, aprovechando al máximo el ancho de banda de PCIe
  • Las funciones Layer skip y self-speculative decoding reducen cálculos innecesarios y aumentan la velocidad de procesamiento sin pérdida de calidad
  • Permite ejecutar de forma eficiente modelos enormes en hardware de consumo, mostrando el potencial de ampliar el acceso a la inferencia LLM de alto rendimiento

Descripción general de NTransformer

  • Motor de inferencia LLM C++/CUDA de alta eficiencia que ejecuta el modelo Llama 70B en una RTX 3090 (24 GB de VRAM)
    • Hace streaming de las capas del modelo a través de la memoria de GPU y, opcionalmente, usa E/S directa desde NVMe para omitir por completo la CPU
  • Sin dependencias externas aparte de CUDA Toolkit; no requiere PyTorch ni cuBLAS
  • Compatible con el formato de modelos GGUF y con las cuantizaciones Q4_0, Q8_0, Q4_K_M, Q5_K, Q6_K, F16 y F32

Rendimiento y estructura de caché

  • Caché adaptativa de 3 niveles (3-Tier Adaptive Caching)
    • Capas residentes en VRAM (0 E/S)
    • RAM fijada (solo para transferencia H2D)
    • Respaldo en NVMe/mmap
  • En un entorno con RTX 3090 + 48 GB de RAM, logra una mejora de velocidad de 83 veces frente a mmap
  • El ancho de banda de PCIe Gen3 x8 (aprox. 6.5 GB/s) actúa como cuello de botella
  • La cuantización Q4_K_M carga 10 capas más en VRAM (36 vs 26), reduciendo el volumen de transferencia
  • Con Layer skip (basado en similitud coseno), omite 20 de 80 capas con una pérdida mínima de calidad

Funciones principales

  • Streaming SLEP: superpone lecturas NVMe, DMA por PCIe y cómputo en GPU con doble búfer
  • Backend gpu-nvme-direct: lee datos de NVMe directamente a memoria fijada accesible para la GPU
  • Self-speculative decoding: usa las capas residentes en VRAM como modelo borrador, sin necesidad de un modelo adicional
  • Selección automática de ruta de datos: residente en VRAM > RAM fijada H2D > mmap fijado > memcpy de CPU
  • Compatibilidad con la arquitectura Llama: incluye RoPE, GQA, SwiGLU, RMSNorm y caché KV

Requisitos del sistema

  • Linux (Ubuntu, kernel 6.17+), CUDA Toolkit 13.1, gcc/g++ 14, CMake 3.24+
  • GPU con Compute Capability 8.0+ (probado en RTX 3090)
  • Para usar E/S directa desde NVMe, se requiere un SSD NVMe en una ranura PCIe separada y la biblioteca gpu-nvme-direct

Streaming directo desde NVMe

  • Si el modelo no cabe en VRAM, utiliza una ruta directa NVMe → GPU que excluye por completo a la CPU
    • Flujo de datos: SSD NVMe → DMA → memoria de staging fijada → PCIe H2D → búfer de GPU → cómputo
  • Vincula el NVMe a VFIO para acceso directo desde espacio de usuario
  • Cada capa (aprox. 670 MB en 70B Q6_K) se lee en unos 202 ms mediante 670 comandos NVMe
  • La lectura NVMe, el DMA H2D y el cómputo en GPU se procesan en paralelo en una tubería de doble búfer

Configuración del sistema y advertencias de riesgo

  • El script de configuración automática (setup_system.sh) configura en secuencia GRUB, NVIDIA DKMS, encabezados de CUDA, VFIO y el binding de NVMe
  • Incluye tareas de alto riesgo como desactivar IOMMU, parchear módulos del kernel y vincular NVMe a VFIO
  • Una configuración incorrecta puede causar fallos de arranque, pérdida de datos en NVMe e inestabilidad del sistema
  • Nunca usar la unidad de arranque; se requiere un dispositivo NVMe dedicado aparte
  • Se proporcionan scripts de respaldo y restauración para todos los cambios

Arquitectura y estructura del código

  • Componentes principales dentro del directorio src/
    • core/: tensores, asignación de memoria y gestión de dispositivos GPU
    • cuda/: kernels de GEMV, RMSNorm, RoPE, SwiGLU y softmax
    • memory/: motor de streaming SLEP basado en NVMe y mmap
    • model/: configuración del Transformer, cargador GGUF, attention, FFN y normalization
    • inference/: tokenizador, sampler y motor
  • scripts/: incluye scripts de configuración del sistema, binding de NVMe y restauración

Hoja de ruta de desarrollo

  • Fase 1: Llama 8B Q8_0, kernels CUDA personalizados, 48.9 tok/s (completado)
  • Fase 2: streaming SLEP, ejecución de 70B en una sola GPU, mejora de velocidad de 33 veces (completado)
  • Fase 3: compatibilidad con Q4_K_M/Q5_K, Layer skip, self-speculative decoding, caché KV en F16 (completado)
  • Fase 4: backend NVMe Direct, lectura NVMe dirigida por GPU a 3.35 GB/s (completado)
  • Fase 5: optimización de inferencia y API C pública (pendiente)

Licencia

  • Licencia BSD-2-Clause

1 comentarios

 
GN⁺ 2026-02-23
Comentarios en Hacker News
  • Me parece muy ingeniosa la forma de transferir directamente de NVMe al GPU evitando la CPU
    Al ejecutar modelos grandes en local, el cuello de botella siempre ha sido la jerarquía de memoria, y esto equivale a tratar el NVMe como si fuera VRAM extendida mediante DMA directo
    Me pregunto cómo se compararía con el enfoque de memoria unificada (unified memory) de los Apple M series. El M4 Max puede cargar por completo un modelo de 70B en memoria, pero su rendimiento es menor que el de una 3090
    Sería interesante ver benchmarks comparando el rendimiento nativo de una 3090 usando este enfoque con NVMe frente a un M4 Max, tomando como base la inferencia por lotes (batch inference)

    • Tengo una M3, así que planeo probarlo en Metal
  • Con GPUdirect es posible hacer transferencia DMA directa hacia dispositivos de almacenamiento
    Me hizo pensar: ¿y si el almacenamiento m.2 fuera realmente DRAM? Como al hacer spill del modelo desde el GPU no hace falta persistencia, se podría dejar la RAM del sistema para la CPU

    • Con un RAM disk probablemente sería mucho mejor. Es una lástima que Intel Optane no se haya vuelto estándar. Era una tecnología ideal para este tipo de flujo de trabajo
    • Pensé exactamente lo mismo. Hace tiempo di una charla en Dask Summit sobre dask-cudf, donde acelerábamos análisis de logs con una arquitectura de arreglos SSD en paralelo → GPUDirect Storage → PCIe → GPU A100. Ahora sería interesante aplicar una arquitectura así a LLM o modelos MoE
    • En realidad, el almacenamiento m.2 basado en DRAM ya existe en forma de CXL (Compute Express Link). El problema es que la RAM es demasiado cara, así que resulta difícil aprovechar los 31 GB/s de ancho de banda por conector NVMe
  • Una velocidad de 0.2 tokens por segundo es lenta para chat, pero suficiente para trabajos por lotes/asíncronos
    Yo ejecuto pipelines automáticos de generación de contenido, con varias llamadas a LLM en paralelo. La generación de imágenes es el cuello de botella, así que de todos modos el trabajo completo tarda como 20 minutos
    Si pudiera ejecutar un modelo de 70B en local, me ahorraría el costo de los tokens de API, así que sería un gran ahorro de costos

    • En términos de costo no es eficiente. A 0.5 tok/s son 3600 tokens por hora, y un sistema con 3090 consume entre 200 y 300 W. Para la misma cantidad de tokens, usar llama 3.1 en OpenRouter sale mucho más barato que la electricidad. Aun así, sí tiene sentido por el lado de la inferencia privada
    • También hay que considerar el costo eléctrico de tener una 3090 corriendo a 350 W durante mucho tiempo
  • 0.2 tok/s está bien para experimentar, pero no alcanza para un uso interactivo
    En la mayoría de los casos, un modelo 8B o 13B bien cuantizado ofrece un mejor equilibrio entre latencia y calidad

    • Yo solo quería probar si era posible. Antes saqué 3000 tokens por segundo en una PS2 con un transformer clásico, gracias a una arquitectura que envía instrucciones directamente de la memoria al GPU. Una PC normal tiene que pasar por la CPU y por eso es más lenta. Los GPU profesionales resuelven este problema, pero son demasiado caros
    • Aun así, en ciertas situaciones la calidad de un modelo grande importa más
    • Ejecutarlo con una combinación CPU+GPU es más rápido. Yo obtengo alrededor de 1.5 tok/s con un 7950X+3090
    • Solo al ver la tabla de rendimiento entendí que el elemento superior era un modelo 8B. 5 segundos por token es demasiado lento. Con mi sistema 5950X+128GB RAM, probablemente una combinación de CPU y GPU 3060 sería más rápida. Tampoco me convence mucho la afirmación de que 2 segundos por token sea el límite de cómputo en una 3090
  • Es un experimento realmente interesante. Yo también debí haber intentado algo así antes
    Me da curiosidad el valor real de throughput frente al ancho de banda teórico de PCIe. Quisiera saber si es un problema de latencia o de ancho de banda

    • En la práctica es un cuello de botella de ancho de banda. Mi placa madre B450 solo soporta PCIe3 x8, así que eso limita al GPU. Si actualizo a X570, la velocidad probablemente suba entre 2 y 3 veces
  • Es un hack genial, pero 0.5 tok/s con un modelo 70B es lento comparado con los 30+ tok/s que da un modelo 7B en la misma tarjeta
    Según investigaciones de NVIDIA, incluso los modelos de 10B o menos pueden encargarse de 40 a 70% de las tareas de agentes, y la brecha de calidad también se está reduciendo rápidamente

  • Este campo vale mucho la pena para seguir experimentando
    A largo plazo, parece que lo clave será la optimización de modelos, es decir, investigar qué partes del modelo pueden omitirse sin afectar el rendimiento. Después de todo, un modelo también es una especie de estructura de compresión con pérdida (lossy compression). Ir en esa dirección también ayudaría a la democratización de la IA

    • La analogía con compresión es interesante. El fine-tuning también se puede ver así. Por ejemplo, si ajustas un modelo 3B para una tarea específica, deja de hacer falta la generalidad de un modelo 70B
  • Es un proyecto realmente genial. Me pregunto qué tipo de conocimientos de sistemas/hardware se necesitan para concebir una idea así
    Yo trabajo en entornos donde el hardware está muy abstraído, así que me cuesta imaginar este tipo de enfoque. Parece que no solo hace falta creatividad, sino también comprensión a nivel de sistema

    • Ese es precisamente el experimento: proyecto ps2-llm
      Intenté ejecutar un LLM en una PS2, pero choqué con los límites de 32 MB de RAM y 4 MB de VRAM, así que ideé un método de streaming de capas. La PS2 podía manejar direcciones de 32 bits directamente en la VRAM, así que era muy rápida, y quise intentar reproducir eso en PC
    • Yo pienso algo parecido. En las consolas antiguas, como la CPU era lenta, la transferencia DMA era fundamental. Probablemente esa experiencia llevó a este tipo de idea. La smart memory card de PS2 también tenía una funcionalidad DMA bastante compleja
  • Yo también estoy intentando algo parecido. Estoy experimentando con ejecutar un modelo 1T usando menos de la mitad de la VRAM
    Creo que, modificando la capa de enrutamiento de SGLang, se podría implementar expert swap basado en predicción JIT desde Gen5 NVMe hacia la memoria del GPU. Usaría primitivas de NVIDIA Dynamo y NIXL
    Me pregunto si alguien ya intentó algo así

    • Yo también quisiera verlo. Estoy pensando en comprar otra 3090 y actualizar la placa madre para resolver el cuello de botella de PCIe3. Quizá se podría ejecutar glm 4.7~5 en q4_k_m
  • Gran proyecto. Me gustaría saber un poco más sobre el proceso de parcheo DKMS en GPU comunes. Yo también quiero intentarlo

    • Actualicé la documentación para agregar el proceso de parcheo y la información de riesgos
    • También ha habido casos en los que se modificó el driver open source de NVIDIA para desbloquear funciones empresariales como comunicación P2P entre GPU o particionado vGPU
      Enlaces relacionados: RTX4090 P2P Unlock, vGPU Unlock