Fork de llama.cpp (commit eab8ee41f) personalizado y optimizado para correr los modelos GGUF de C:\Users\user\Vahl-models-backup lo más rápido posible en este hardware:
- GPU: NVIDIA RTX 4060 Laptop 8 GB (Vulkan)
- CPU: AMD Ryzen 7 7840HS (8 núcleos / 16 hilos)
- RAM: ~16 GB
El objetivo: ~5x más tokens/segundo (tk/s) sin perder calidad. Se logra vía backend Vulkan + flash-attention + offload de capas ajustado por modelo (ngl/ncmoe) + build nativo (-march=native).
-
Backend Vulkan (en lugar de CPU-only). Compila en Windows sin MSVC ni CUDA Toolkit, usando el toolchain GCC de MSYS2. Soporta la RTX 4060 vía el driver Vulkan de NVIDIA. Habilitado con
GGML_VULKAN=ON. -
Build nativo (
GGML_NATIVE=ON): usa las instrucciones AVX2/AVX512 del Ryzen 7 7840HS (-march=native). -
OpenMP (
GGML_OPENMP=ON): multithreading para la parte que queda en CPU (clave en MoE). -
Flash Attention (
-fa on): reduce uso de VRAM del KV-cache y acelera el prompt processing en GPU. -
Offload ajustado por modelo: para los modelos que caben en 8 GB se offloadean casi todas las capas (
-nglalto). Para los MoE grandes (que no caben) se usa-ncmoepara dejar pocos expertos en CPU y el resto en GPU — el óptimo exacto se midió (no se adivinó).
Se requiere MSYS2 con el toolchain UCRT64 + Vulkan:
pacman -S --needed \
mingw-w64-ucrt-x86_64-gcc \
mingw-w64-ucrt-x86_64-cmake \
mingw-w64-ucrt-x86_64-ninja \
mingw-w64-ucrt-x86_64-vulkan-headers \
mingw-w64-ucrt-x86_64-vulkan-loader \
mingw-w64-ucrt-x86_64-shaderc \
mingw-w64-ucrt-x86_64-spirv-headersLuego, desde la raíz del repo (con C:\msys64\ucrt64\bin en el PATH):
cmake -B build-vulkan -G Ninja \
-DGGML_VULKAN=ON -DGGML_OPENMP=ON -DGGML_NATIVE=ON \
-DCMAKE_BUILD_TYPE=Release
cmake --build build-vulkan --config Release -j 16Los binarios quedan en build-vulkan\bin. Copia las DLLs de runtime de MSYS2 al lado de los exe para que funcionen fuera del entorno MSYS2:
libgcc_s_seh-1.dll, libstdc++-6.dll, libwinpthread-1.dll, libgomp-1.dll, vulkan-1.dll.
vahl-run.ps1 aplica la configuración óptima detectada por modelo:
# single-shot con prompt
.\vahl-run.ps1 -Model "C:\Users\user\Vahl-models-backup\Llama-3.2-1B-Instruct-UD-Q4_K_XL.gguf" -Prompt "Hola"
# modo conversación interactivo
.\vahl-run.ps1 -Model "...\Qwen2.5-Coder-7B-Instruct-Q4_K_M.gguf"# Modelos densos que caben en VRAM -> offload alto + flash-attn
llama-cli -m <modelo> -ngl 24 -fa on -t 8 -dev Vulkan0 -c 4096 -p "..."
# Modelos MoE grandes -> mantener expertos en CPU (ncmoe)
llama-cli -m <modelo-MoE> -ngl 99 -ncmoe 20 -fa on -t 8 -dev Vulkan0 -p "..."Benchmark con llama-bench (pp128 / tg64), comparando CPU (-ngl 0) vs GPU-offload óptimo. Métrica clave = tg (generación, tk/s).
Los resultados de abajo se midieron forzando solo la GPU NVIDIA (
-dev Vulkan0). Esto es crítico: la iGPU AMD Radeon 780M del sistema se detecta como segundo dispositivo Vulkan; si se permite el splitlayerentre ambas, la iGPU (mucho más lenta) hunde el rendimiento. Fijar-dev Vulkan0usa solo la RTX 4060.
| Modelo | Params | CPU tg | GPU tg | Speedup | Config óptima |
|---|---|---|---|---|---|
| Llama-3.2-1B-Instruct-Q4_K_XL | 1.2B | 23.9 | 162.4 | 6.8x | ngl=60, fa |
| Qwen2.5-Coder-7B-Q4_K_M | 7.6B | 8.3 | 51.1 | 6.15x | ngl=60, fa |
| Qwen2.5-VL-7B-Q4_K_M | 7.6B | 8.3 | 51.1 | 6.14x | ngl=40, fa |
| DeepSeek-R1-Distill-Qwen-7B | 7.6B | 8.3 | 51.1 | 6.14x | ngl=40, fa |
| Qwen3-8B-Q4_K_XL | 8.0B | 6.7 | 46.2 | 6.9x | ngl=60, fa |
| Qwen3.5-9B-Q4_K_XL | 9.0B | 5.4 | 39.2 | 7.24x | ngl=40, fa |
| gemma-4-12B-Q4_K_S | 12B | 4.9 | 15.1 | 3.1x | ngl=40, fa |
| gemma-4-26B-A4B-Q3_XXS (MoE) | 26B | 7.2 | 22.2 | 3.1x | ngl=99, ncmoe=20 |
| Qwen3.6-35B-A3B-Q2_K_XL (MoE) | 35B | 4.3 | 15.7 | 3.7x | ngl=99, ncmoe=28 |
| qwen3.8-27b-Q4 (denso) | 27B | 2.2 | 3.7 | 1.7x | ngl=30, fa |
| gpt-oss-20b-MXFP4 | 20B | 9.0 | 12.9 | 1.4x | ngl=16, fa |
Observaciones clave:
- Con solo la NVIDIA (Vulkan0), los modelos densos que caben en VRAM (1B–9B) alcanzan 6.1–7.2x — por encima del objetivo de 5x.
- Los MoE grandes (26B/35B con solo 3–4B activos) → 3.1–3.7x (la GPU procesa solo los expertos activos).
- Los modelos densos que NO caben en 8 GB (20B/27B) están limitados por VRAM → 1.4–1.7x (offload parcial, cuello de botella en transferencia CPU↔GPU).
- La excepción al full-offload es cuando el modelo + KV-cache + buffers no caben en ~7.1 GB; entonces subir
-nglno ayuda y hay que encontrar el pico (lo hacebench/vahl-autotune.ps1).
El objetivo de 5x se cumple para la mayoría de los modelos (los que caben en VRAM). Para los de 20B+/27B, las 8 GB son el límite físico, no el motor.
| Archivo | Qué hace |
|---|---|
vahl-run.ps1 |
Corre un modelo con la config óptima automática (perfil por modelo). |
bench/vahl-bench.ps1 |
Benchmark automático: mide CPU baseline + barre ngl/ncmoe y escribe CSV. |
bench/vahl-autotune.ps1 |
Para UN modelo: encuentra la config (ngl/ncmoe/fa) más rápida. |
bench/results/ |
Resultados de benchmark (CSV/logs). |
En Windows, el backend CUDA de llama.cpp exige cl.exe (MSVC) + el CUDA Toolkit como host compiler, y ambos requieren privilegios de admin para instalarse de forma limpia. El backend Vulkan funciona con GCC (MSYS2/MinGW), sin MSVC ni CUDA, y soporta la RTX 4060 a través del driver Vulkan de NVIDIA. Se obtiene el mismo offload a GPU con menor fricción de instalación.
Para hardware no-NVIDIA (AMD/Intel) o para evitar CUDA por completo, Vulkan es la vía recomendada por el propio proyecto.
- GPU: RTX 4060 Laptop, ~8 GB VRAM (~7.1 GB utilizables con display activo).
- CPU: AMD Ryzen 7 7840HS (Zen 4, AVX2, 8c/16t).
- RAM: 16 GB.
Todos los -ngl / -ncmoe de la tabla están calibrados para este perfil. En otro hardware conviene re-ejecutar bench/vahl-autotune.ps1.