1 puntos por GN⁺ 2 시간 전 | 1 comentarios | Compartir por WhatsApp
  • Para complementar un entorno local de LLM donde solo una RTX 4080 16GB no bastaba, se agregó una Tesla V100 SXM2 16GB usada con un adaptador por unas £200, logrando un total de 32GB de VRAM
  • La V100 SXM2 es una GPU para servidores sin ranura PCIe, salida de video ni conector de energía convencional, pero pudo instalarse en una PC gamer mediante un adaptador SXM2-to-PCIe
  • El ventilador de servidor venía con un nivel base de 82dB, demasiado ruidoso para uso en interiores, pero al conectarlo al header de ventilador de la motherboard con un cable jumper PH2.0-2.54mm se logró control PWM y operación silenciosa
  • Con tensor splitting de llama.cpp se distribuyó Qwen3.6-27B-MTP Q5_K_M entre la RTX 4080 y la V100, obteniendo un contexto de 128k y una velocidad de inferencia de unos 32 tok/s
  • No es tan limpio como usar una sola GPU de 32GB y siguen existiendo problemas de drivers, CUDA y warm reboot, pero las GPU de servidor usadas pueden ser una alternativa barata para ampliar VRAM en LLM locales

Un entorno local de LLM de 32GB armado por £200

  • Con solo RTX 4080 16GB VRAM no alcanzaba para ejecutar los modelos locales deseados, así que se añadió una GPU usada de centro de datos a una PC gamer mediante un adaptador
  • Se compró una Tesla V100 SXM2 16GB junto con un adaptador SXM2-to-PCIe por unas £200 en total, formando un entorno con 32GB de VRAM entre ambas GPU
  • Se cargó un modelo de 27B parámetros repartido entre las dos GPU y corrió a unos 32 tokens/s, con el modelo completo y el contexto dentro de la VRAM
  • No ofrece la misma experiencia que una sola GPU de consumo de 32GB, pero consigue esa capacidad de VRAM por mucho menos dinero que una RTX 5090 32GB

Tesla V100 SXM2 y el adaptador

  • La Tesla V100 SXM2 16GB es una GPU pensada para servidores NVIDIA DGX y racks de hyperscalers
    • No tiene ranura PCIe convencional, salida de video ni conector de energía estándar
    • Está diseñada para montarse en una placa propietaria dentro del servidor y comunicarse por NVLink
    • Para conectarla directo a una motherboard hace falta un adaptador aparte
  • La V100 es una GPU Volta con 16GB de memoria HBM2 y 5120 núcleos CUDA
    • El precio de compra en eBay fue de unas £150
    • Aunque es una GPU de 2017, su rendimiento de cómputo y su VRAM siguen siendo útiles para LLM locales
  • El ancho de banda de memoria HBM2 es una de sus principales ventajas
    • La V100 ofrece 900GB/s con un bus de memoria de 4096-bit
    • Eso es 22% más que los 736GB/s de GDDR6X de una RTX 4080
    • También supera a Apple M3 Max con 400GB/s, M4 Max con 546GB/s y M5 Max con 614GB/s
  • La AMD RX 7900 XTX tiene 24GB de GDDR6 y 960GB/s de ancho de banda, ligeramente más que la V100, pero cuesta más de £700
    • Se considera que el soporte de inferencia LLM en ROCm todavía es más áspero que en CUDA
    • La V100 ofrece el 94% del ancho de banda de la RX 7900 XTX por menos de una cuarta parte del precio y funciona con llama.cpp
  • La RTX 5090, con 1,792GB/s de ancho de banda, supera claramente a la V100, pero cuesta más de £2,000
    • En inferencia de LLM, el ancho de banda de memoria suele ser el cuello de botella que determina los tokens/s, por eso importa tanto
  • El adaptador SXM2-to-PCIe no es un producto oficial de NVIDIA ni cuenta con soporte oficial
    • Es una PCB desnuda con un socket SXM2 en un lado y un conector PCIe edge en el otro
    • Costó unas £50, dejando el armado completo en unas £200
    • Gracias al adaptador se pudo conectar la V100 16GB a la motherboard junto con la RTX 4080

El problema del ventilador de servidor y cómo se resolvió

  • La V100 SXM2 está diseñada para funcionar en el entorno de refrigeración industrial de un servidor 2U
    • El ventilador del adaptador hacía demasiado ruido para una habitación normal
    • El ruido medido con un Apple Watch fue de 82dB, descrito como algo entre un triturador de basura y una podadora
  • En el estado original no había forma de controlar el ventilador
    • Fallaron los intentos con nvidia-smi, exploración de dispositivos en Linux y Windows Afterburner
    • Todo indicaba que el ventilador del adaptador estaba pensado para girar al 100% de forma permanente dentro de un rack de servidor
  • Se verificó el pinout del ventilador con una prueba usando batería de 9V
    • Al conectar cables jumper a VCC y ground y aplicar la batería de 9V, el ventilador giró
    • Quedó claro que a menor voltaje era mucho más silencioso, así que sí había margen para controlarlo
  • El ventilador terminó comportándose como un ventilador estándar de gabinete para PC
    • Se conectaron cables jumper al conector del ventilador y el otro extremo a un header libre de ventilador en la motherboard
    • La motherboard pudo leer las RPM y también aplicar control PWM
    • Incluso al 10% de velocidad la GPU no pasó de 50°C bajo carga total, y quedó casi inaudible
  • El cable final fue un jumper cable 2.54mm male to PH2.0 female
    • El conector del ventilador del adaptador es un plug JST PH2.0 de 4 pines
    • El header de ventilador de la motherboard usa el estándar 0.1 inch, es decir, paso de 2.54mm
    • El lado PH2.0 hembra se conectó a los pines de tacómetro y PWM del ventilador, y el lado 2.54mm macho al header de la motherboard
    • Con un cable jumper de unas £2 y verificando el conector se resolvió el problema de los 82dB

Ampliar VRAM con dos GPU

  • La configuración final de GPU fue la siguiente
    • RTX 4080: 16GB VRAM, arquitectura Ada
    • Tesla V100: 16GB VRAM, arquitectura Volta
    • Total: 32GB VRAM repartidos entre las dos GPU
  • llama.cpp puede repartir el modelo entre dos GPU usando tensor splitting
    • Hace pipeline de capas a través del bus PCIe
    • La RTX 4080 procesa parte de las capas y la V100 procesa el resto
    • No es más rápido que una sola GPU de 32GB, pero funciona, y el costo equivale a cerca del 10% de una GPU de 32GB
  • El consumo de energía de la V100 se observó en alrededor de 150W como máximo
    • No es una GPU pequeña para inferencia local de LLM, pero tampoco algo fuera de lo normal
  • La V100 de 32GB sigue siendo una opción posible
    • Cuesta más del doble de lo pagado aquí, pero permitiría tener 32GB de HBM2 en una sola tarjeta por unos pocos cientos de libras
    • Con dos V100 de 32GB se podrían lograr 64GB de VRAM, descrito como alrededor del 20% del precio actual de una RTX 5090
  • El formato SXM2 incluye soporte para NVLink por diseño
    • En una configuración multi-GPU bien armada, las GPU podrían comunicarse con alto ancho de banda
    • Incluso a través del adaptador PCIe, el rendimiento de tensor split fue suficientemente sólido

Hacer coincidir drivers y CUDA en NixOS

  • La configuración de software resultó relativamente fluida gracias a NixOS
  • La V100 usa un chip Volta, y NVIDIA dejó de dar soporte a Volta a partir de la rama 560 de drivers
    • El último driver que soporta al mismo tiempo la RTX 4080 Ada y la V100 Volta es la rama 550.x
    • En NixOS eso corresponde a nvidiaPackages.legacy_535
  • Ese driver solo soporta hasta CUDA 12.2
    • El nixpkgs actual ofrece CUDA 12.6 o superior
    • Hubo que traer CUDA 12.2 desde nixpkgs 24.05
  • El driver requiere Linux kernel 6.6
    • El driver legacy no soporta kernels más nuevos
  • Aun siendo un servidor headless de inferencia, hizo falta services.xserver.enable = true
    • Sin esa configuración, el módulo de kernel de NVIDIA no cargaba
  • La configuración clave de NixOS quedó compuesta por kernel, driver legacy de NVIDIA y selección del driver NVIDIA para X server
boot.kernelPackages = pkgs.linuxPackages_6_6;
hardware.nvidia.package = config.boot.kernelPackages.nvidiaPackages.legacy_535;
services.xserver.enable = true;
services.xserver.videoDrivers = [ "nvidia" ];
  • CUDA 12.2 se importó desde una versión anterior de nixpkgs mediante un overlay
nixpkgs.overlays = [
  (final: prev: {
    cudaPackages_12_2 = nixpkgs-cuda.legacyPackages.${prev.system}.cudaPackages_12_2;
  })
];
  • Ambas GPU aparecieron correctamente y CUDA funcionó sin problemas
  • La definición completa de la máquina está incluida en este commit del repo de dotfiles
    • También incluye la definición del servicio de llama.cpp y un build custom fijado a la versión correcta

Modelo ejecutado y rendimiento

  • El modelo ejecutado fue la versión cuantizada Qwen3.6-27B-MTP Q5_K_M
    • El tamaño del modelo es de unos 19GB
    • Usando ambas GPU, el modelo completo entra en VRAM y todavía queda espacio para el contexto
  • La configuración principal de ejecución fue la siguiente
    • Model: Qwen3.6-27B-MTP Q5_K_M, 19GB
    • Context size: 128k tokens
    • GPU layers: 99, todo offloaded
    • Tensor split: -ts 1.0,1.0, reparto uniforme entre ambas GPU
  • El rendimiento fue el siguiente
    • Inference speed: unos 32 tok/s
    • Prompt processing: unos 133~160 tok/s
  • Se considera que 32 tokens/s es suficiente para uso interactivo
    • Se logró incluso con una configuración de tensor split por PCIe entre dos GPU de arquitecturas distintas
    • Considerando también la latencia de red, se describe como más rápido que la mayoría de endpoints de API en la nube

MTP y entrada de imágenes

  • MTP significa Multi-Token Prediction
    • La inferencia normal de un LLM predice un token a la vez, lo acepta y luego predice el siguiente
    • MTP predice varios tokens futuros de una sola vez y luego valida cuáles fueron correctos
    • Los tokens aceptados salen prácticamente gratis, y los errores vuelven a la ruta normal
  • El resultado de MTP es aumentar la velocidad de generación en alrededor de 1.5~2x sin pérdida de precisión
    • En esta configuración, se plantea que desde unos 32 tok/s puede subir a 50~60 tok/s cuando MTP acierta bien
    • Es especialmente efectivo en salidas predecibles como código
  • El soporte de MTP en llama.cpp todavía es una función nueva
    • La versión de llama.cpp en nixpkgs no soporta la arquitectura MTP de Qwen3.6
    • Hubo que compilar llama.cpp desde código fuente en un commit específico donde ya existía ese soporte
    • En NixOS se fijó ese commit en una derivation custom para hacerlo reproducible
    • Cambiar el modelo o la versión de llama.cpp se resuelve modificando una línea de configuración y ejecutando nixos-rebuild switch
  • Qwen3.6-27B también soporta entrada de imágenes mediante un archivo multimodal projector separado llamado mmproj
    • El archivo adicional pesa unos 928MB
    • El vision encoder convierte los píxeles de la imagen al espacio de embeddings de tokens del LLM
    • El modelo no “ve” las imágenes como un humano
    • El LLM procesa esos vectores convertidos como si fueran otra secuencia de tokens
  • Los flags de ejecución de llama.cpp son los siguientes
--mmproj /mnt/nas/llamacpp/mmproj-F16.gguf --mmproj-offload
  • --mmproj-offload sube el vision encoder a la GPU junto con el modelo
    • Así se mantiene una inferencia rápida también con entrada de imágenes

Cómo se usa localmente

  • Esta configuración se usa junto con OpenCode
    • OpenCode es un asistente de programación con IA que puede ejecutarse contra modelos locales
  • El servidor LLM corre en una desktop, pero se usa desde otros dispositivos
    • Se accede por red desde otras máquinas de la casa
    • Desde fuera se entra a través de Tailscale
  • En OpenCode, usar el servidor de llama.cpp se resuelve configurando la URL del API
    • El modelo corre de forma local
    • Las respuestas son rápidas y los datos no salen de la red

Problemas pendientes y limitaciones

  • A veces ocurre que la V100 desaparece después de un warm reboot
    • Tras reiniciar solo el sistema operativo, con la motherboard todavía energizada, puede pasar que la V100 no aparezca en lspci ni en nvidia-smi
    • Parece un problema de enumeración ACPI del slot PCIe
    • Si se apaga físicamente el equipo, se espera unos segundos y luego se hace un cold reboot, siempre vuelve a aparecer
  • Si no está la V100, llama.cpp no puede arrancar
    • Una sola GPU de 16GB no alcanza para cargar el modelo
    • El servicio entra en crash loop hasta que la GPU vuelve a estar disponible
    • Como normalmente se está cerca del equipo al reiniciar, no se considera un gran problema en la práctica
  • Repartir tensores entre dos GPU de arquitecturas distintas no es tan limpio como usar una sola GPU
    • La V100 tampoco es la GPU más rápida para inferencia
    • Aun así, se considera que la relación precio/rendimiento es muy buena

Opciones y conclusión

  • Por unas £200, el resultado obtenido fue el siguiente
    • Una GPU de centro de datos de 16GB funcionando junto a una GPU gamer
    • Un total de 32GB de VRAM para inferencia local de LLM
    • 32 tokens/s en un modelo de 27B parámetros
    • Una ventana de contexto de 128k tokens
    • Soporte de visión para entrada de imágenes
    • Un modelo que corre completamente en local, sin nube ni costo por token
  • El costo real estuvo en el ruido del ventilador, y eso se resolvió verificando el conector y usando un cable jumper
  • Para quien quiera correr modelos locales de verdad, el mercado de GPU de servidor usadas puede ser una alternativa interesante
    • Incluso sin una GPU previa, una sola V100 en un servidor barato puede dar 16GB de VRAM y un entorno local de LLM utilizable
    • La V100 SXM2 no es la única opción
    • La P40 ofrece 24GB por un costo similar, pero es más lenta y no tiene Tensor Cores
    • El modelo V100 de 32GB cuesta más, pero sigue siendo más barato que una GPU de consumo con la misma VRAM
  • Eso sí, hay que estar preparado para lidiar con el problema del ventilador

1 comentarios

 
GN⁺ 2 시간 전
Comentarios en Lobste.rs
  • El enfoque está buenísimo, y eso de que la GPU desaparezca del PCIe da todavía más curiosidad porque puede deberse a demasiadas causas
    El ruido fuerte de los ventiladores de la GPU me hizo recordar cuando estaba en el equipo de NVIDIA CUDA. Un colega estaba agregando control de ventiladores a NVML y nvidia-smi, y desde el otro lado del cubículo se escuchaba cómo los ventiladores aceleraban y desaceleraban; luego asomó la cabeza con una gran sonrisa
    Decía que era una de sus funciones favoritas en las que había trabajado, porque podías escuchar con tus propios oídos el momento en que el código funcionaba

  • Si te interesa el LLM autoalojado, las Dell OEM RTX 3090 suelen ser más baratas que los productos de marcas grandes, y se podían conseguir por unos 800 dólares canadienses
    Ahora tengo que leer más sobre cómo funciona vLLM. A veces el modelo empieza a soltar listas largas de nombres y adjetivos relacionados, así que probablemente tengo algo mal configurado

    • Me da curiosidad qué modelo están corriendo en una RTX 3090
      Entendía que la mayoría de los modelos utilizables necesitan al menos 48~64GB de VRAM para correr bien, y por eso pensaba que los chips Apple serie M, con arquitectura de memoria unificada, eran populares en este campo
  • También venden algo así ya empaquetado, pero es de esos casos donde te dan 3 meses de garantía del fabricante y se acabó
    https://ebay.com/itm/297819576914/…

    • Esto sí me tienta bastante. No creo que venga con la modificación del ventilador que mencionan en el post
  • En EE. UU., el modelo usado de 32GB se vende por alrededor de 600 dólares
    El adaptador probablemente lo compraría directo en China, que es su lugar de origen

  • Me pregunto si hay un equivalente del lado de AMD. Ahora mismo uso dos W7900 de 48GB y me gustaría escalar para poder correr modelos más grandes

    • Hasta cierto punto sí. Está la Instinct MI60, de la misma época que la V100; ya tiene sus años, pero trae 32GB de VRAM y además ya existe en versión de tarjeta PCIe
      Sí necesitas agregar refrigeración, pero no hace falta andar jugueteando con adaptadores
      He estado leyendo cada vez que encuentro una configuración local de modelos, y en este momento, en el rango de demanda intermedia de VRAM de 48~128GB, realmente no parece haber un punto óptimo de precio-rendimiento. Las opciones son más o menos tres: varias GPU de centro de datos de hace tres generaciones (Tesla V100, Instinct MI60), varias opciones actuales de gama más baja con mucha VRAM (Arc Pro B70), o cajas integradas de generación actual (DGX Spark, Mac Mini, Strix Halo)
      Cada una tiene sus compromisos, pero también sus ventajas, para alguien que esté actualizando desde una sola GPU de consumo de 32GB o dos de 16GB. Si ya estás usando dos tarjetas de 48GB, no estoy muy seguro de que haya una mejora en hardware usado que realmente se sienta como un avance