8 de septiembre de 2026

Ollama con GPU AMD: los cinco fallos que te dejan en CPU sin avisar

Foto de Marco Orta Marco Orta | 15 min de lectura
Compartir
Portada tipográfica sobre fondo de terminal: la palabra Ollama y debajo un diff de dos líneas, «- library=cpu 15.89 tok/s» en rojo y «+ library=Vulkan 132.48 tok/s» en verde
Tabla de Contenidos

    El peor fallo de Ollama con una GPU AMD no es el que te tira el servidor. Es el que no te tira nada: Ollama arranca, responde, contesta bien — y lo hace en CPU, a 15,89 tokens por segundo en vez de 132,48. Un 8,3x de penalización que no aparece en ningún log salvo que lo busques, porque para Ollama eso no es un error: es un fallback.

    Este artículo es el resumen de tres semanas midiendo una Radeon RX 7900 XTX de 24 GB sobre un Ryzen 9 7950X3D, en Windows, en Linux nativo y dentro de WSL2. No es una guía de instalación —de esas hay muchas— sino el inventario de las cinco formas en que este montaje se rompe sin decírtelo, con los números de cada una y con lo que probé que no las arregla, que suele ser más útil.

    Los tok/s de aquí son de una tarjeta concreta con un entorno concreto. Lo que sí se traslada tal cual son los modos de fallo y el método para cazarlos.

    Antes de nada: la comprobación de treinta segundos

    Si te llevas una sola cosa del artículo, que sea esta. Ollama sondea la GPU una única vez, al arrancar, y no vuelve a mirar. Así que hay dos preguntas que responder siempre, y ninguna se contesta mirando si el chat va «rápido»:

    1. ¿Qué backend declaró el servidor al arrancar? Está en el log de arranque (%LOCALAPPDATA%\Ollama\server.log en Windows, journalctl -u ollama en Linux):

    library=Vulkan compute=0.0 name=Vulkan0 description="AMD Radeon RX 7900 XTX"
    libdirs=ollama,vulkan  total="24.0 GiB" available="23.2 GiB"
    

    Lo que buscas es library=. Si dice cpu, ya está: no hay GPU, y no te lo va a decir de otra forma.

    2. ¿El modelo entró entero? ollama ps te da el reparto:

    ollama ps
    # NAME              SIZE     PROCESSOR
    # gpt-oss:20b       16 GB    100% GPU
    

    Cualquier cosa que no sea 100 % GPU es un modelo partido entre GPU y CPU, y eso no da error tampoco.

    Un detalle que me costó un verificador entero: no exijas compute=gfx1100 ni un pci_id. El backend Vulkan reporta compute=0.0 y pci_id="" donde ROCm daba los valores reales, así que un script que compruebe esos campos suspende un sistema perfectamente sano. Lee library= y libdirs=, y nada más.


    Fallo 1: la GPU integrada del procesador se lleva el trabajo

    Este es el más traicionero porque el hardware culpable no es el que estás mirando.

    Si tienes un Ryzen de escritorio con gráficos integrados —los 7000 en adelante los llevan casi todos— tu máquina tiene dos GPU AMD, no una. Y la enumeración de ROCm las ordena como le da la gana:

    ROCm0: AMD Radeon(TM) Graphics (36694 MiB)   <- la integrada
    ROCm1: AMD Radeon RX 7900 XTX (24560 MiB)
    

    La integrada sale primera y reporta 36 GB de VRAM (que no tiene: es RAM del sistema). Los binarios de llama.cpp la eligen, cargan kernels compilados para gfx1100 y revientan:

    ggml-cuda.cu:106: ROCm error
    ROCm error: device kernel image is invalid
      current device: 1, in function ggml_cuda_kernel_launch
    

    Lo que no lo arregla —y lo probé todo antes de rendirme:

    IntentoResultado
    --device ROCm1 (elegirla por nombre)⛔ mismo error
    HIP_VISIBLE_DEVICES=0 y =1⛔ mismo error o «no usable GPU found»
    ROCR_VISIBLE_DEVICES=1 + --device ROCm0⛔ igual
    ROCBLAS_TENSILE_LIBPATH al directorio de kernels⛔ igual (los de gfx1100 sí estaban)

    Lo que sí lo arregla: desactivar la integrada en la BIOS. Con un solo dispositivo no hay nada que elegir mal y arranca a la primera, sin banderas:

    antesdespués
    --list-devicesintegrada + dedicadasolo la RX 7900 XTX
    llama-server sueltokernel image is invalid136 tok/s
    Ollama118 tok/s132,5 tok/s

    El miedo razonable era perder VRAM al mover el monitor a la dedicada. Medido: cuesta 0,2 GiB. Con la pantalla a 3440×1440 y 165 Hz colgando de la tarjeta grande, Ollama sigue reportando total 24.0 GiB / available 23.8 GiB. El intercambio sale gratis.

    Y una nota para no volverse loco: bajo Ollama esto no pasa, porque Ollama enmascara la integrada por su cuenta y para él la dedicada es ROCm0. Por eso puedes tener a Ollama funcionando y a llama-server fallando en la misma máquina con los mismos pesos. No estás loco: son dos enumeraciones distintas.


    Fallo 2: actualizar cualquier cosa devuelve el backend al principio

    Ya lo he dicho arriba, pero merece su propia sección porque es el que más caro sale: Ollama sondea la GPU al arrancar y punto.

    Tras una reinstalación de drivers de AMD, el servicio se quedó sirviendo así:

    inference compute  id=cpu  library=cpu
    

    Sin un error. Sin un aviso. 15,89 tok/s contra 132,48. Reiniciar Ollama lo devolvió a library=ROCm compute=gfx1100 y a los 132.

    Hay una segunda versión de este mismo fallo, y es peor porque no la disparas tú: cada actualización de Ollama reinstala el bundle de ROCm. Si habías cambiado a Vulkan a propósito, el update te devuelve a ROCm en silencio. Nadie te avisa; simplemente el número que llevabas semanas midiendo deja de ser el mismo.

    La regla operativa que salió de esto: pasa el comprobador después de tocar drivers, BIOS o versión de Ollama. No después de que algo vaya mal — después de tocar, siempre, aunque no vaya mal.


    Fallo 3: dentro de WSL2 no hay GPU para Ollama, y no la va a haber

    Esta es la que más tiempo me comió, así que va con detalle para que no se lo comas tú.

    La pregunta era razonable: si el Linux nativo le saca a Windows entre un 6,7 y un 19,5 % en tok/s, ¿me lo llevo dentro de WSL y me ahorro reiniciar? La respuesta es que Ollama en WSL no usa la GPU en absoluto. Y no es un problema de drivers.

    Lo medido, en orden:

    ComprobaciónResultado
    /dev/kfd y /sys/class/kfdno existen
    /dev/dxg✅ existe (la vía de WSL)
    ¿HIP computa en WSL? — sonda con hipcc: hipGetDeviceCount rc=0 n=1, gfx1100
    Ollama detecta GPUlibrary=cpu
    HSA_ENABLE_DXG_DETECTION=1⛔ no cambia nada
    llama-server --list-devices con ROCmAvailable devices: (none)
    llama-server --list-devices con VulkanAvailable devices: (none)

    La paradoja que lo explica: HIP funciona en WSL, a través de la runtime HSA que habla con /dev/dxg. Pero Ollama enumera GPUs leyendo la topología KFD de sysfs, que WSL no expone. No falta el driver — Ollama busca por una puerta que en WSL no existe.

    Con OLLAMA_DEBUG=1 aparece la causa real, que de otro modo queda enterrada:

    failure during llama-server GPU discovery
    error="llama-server --list-devices failed: signal: segmentation fault (core dumped)"
    

    Circula por ahí una receta —el issue 16551 de Ollama, que es el caso idéntico: misma tarjeta, mismo WSL2, misma ROCm 7.2— cuyo autor reporta library=ROCm compute=gfx1100 al 100 % de GPU colocando el bundle de ROCm y poniendo HSA_ENABLE_DXG_DETECTION=1. Probado aquí, no reproduce.

    ¿Y el backend Vulkan? En WSL exigiría el ICD dzn (Vulkan sobre D3D12), que Ubuntu no empaqueta. Se podría compilar Mesa con -Dvulkan-drivers=microsoft-experimental y ver qué pasa, pero es trabajo grande con pago incierto.

    Conclusión práctica: para Ollama, WSL está descartado. Las dos salidas son el Ollama de Windows (que sí usa la GPU y es lo que hay hoy) o arrancar en Linux nativo. Y si desarrollas dentro de WSL como yo, la buena noticia es que no hace falta mover Ollama: con WSL2 en networkingMode=mirrored, localhost:11434 desde WSL alcanza el Ollama de Windows sin configurar nada.


    Fallo 4: el modelo no cabe, se parte, y sigue contestando

    Cuando pides más contexto del que entra en la VRAM, Ollama no te dice que no. Reparte el modelo entre GPU y CPU y sigue. El síntoma es size_vram < size en /api/ps, y nada más.

    Medido con qwen3.8 (27,3B) en la 7900 XTX, con OLLAMA_FLASH_ATTENTION=1 y la caché KV en q8_0:

    num_ctx pedidoEn GPU
    262.14463,4 % — un tercio en CPU
    131.072⛔ 92,4 %
    122.880✅ 100 % (con 0,6 GiB de margen)

    Con 0,6 GiB libres, cualquier cosa que abras en el escritorio lo tira. Ese techo es de esa tarde y de esa pantalla, no una constante del modelo.

    Y aquí va el aviso que casi me cuesta una decisión mal tomada: ollama ps subestima la VRAM real entre 4,3 y 6,8 GiB. Cruzado contra el contador del sistema, con cuatro modelos:

    Modeloollama psVRAM real
    gpt-oss:20b12,33 GiB16,59 GiB
    muse-glimmer (27,9B)15,49 GiB20,77 GiB
    gemma4 (25,8B)17,24 GiB22,37 GiB
    qwen3.8 (27,3B)16,61 GiB23,36 GiB

    Para decidir sobre memoria, la columna de ps no sirve. Solo sirve para saber si Ollama repartió a CPU. Si estás calculando si un modelo te cabe, mide la VRAM del sistema, no la que Ollama declara.

    Fallo 5: te recorta el contexto y te deja creer que lo tienes

    Variante fina del anterior. Si a muse-glimmer o a gpt-oss les pides num_ctx: 262144, cargan tan felices — y el context_length que devuelve /api/ps dice 131072. Lo que pediste no es lo que tienes.

    La causa de fondo es que estos modelos tienen un techo de arquitectura por debajo del de la tarjeta. Y explica algo contraintuitivo que sale al medir: el tamaño en disco no predice el contexto máximo. Lo que decide es si el modelo usa ventana deslizante (SWA) o KV denso:

    ModeloSWACrecimiento de KV de 16K a 128K
    muse-glimmer2048~0
    gpt-oss128+0,36 GiB
    gemma41024+0,40 GiB
    qwen3.8— (KV denso)+1,35 GiB

    Tres de los cuatro tocan su techo de arquitectura y ni se enteran de la VRAM. El único que paga contexto de verdad es el único que se sale.

    Lee siempre el context_length real de /api/ps, no el que mandaste.


    ROCm o Vulkan en 2026: qué gana cada uno

    Este es el cambio de fondo del año y por eso el artículo llega ahora. Ollama incorporó soporte Vulkan experimental en la 0.12.6 y a lo largo de 2026 ha ido llegando a los binarios, con el argumento de abrir la puerta a las GPU de AMD e Intel que ROCm nunca soportó — que son la mayoría de las de consumo.

    En mi máquina, forzando cada backend con el mismo Ollama y los mismos pesos, Vulkan gana:

    ModeloGanancia de Vulkan sobre ROCm
    gpt-oss:20b+17,8 %
    gemma4+30,1 %
    muse-glimmer+30,3 %

    Rangos disjuntos en dos rondas independientes, así que la señal es real. Y encaja con lo que reportan otros: en una RX 9070 XT, Llama 2 7B Q4_0 decodifica a 137 tok/s con Vulkan contra 101 con ROCm.

    Con dos advertencias que casi nadie pone.

    La primera: el delta compara dos cosas a la vez. En Windows es ROCm 7.1 contra AMDVLK; en Linux es ROCm 7.2.4 contra RADV. Un ROCm peor infla exactamente el mismo número que un Vulkan mejor, y no están separados.

    La segunda es un coste que no vi venir. Vulkan deja 0,6 GiB menos de VRAM disponible: 23,2 GiB declarados contra 23,8 con ROCm. Para tres de mis cuatro modelos da igual porque no apuraban la tarjeta. Para qwen3.8, que iba justo de 0,6 GiB, se lo come entero:

    num_ctxCon Vulkan
    122.880 (el techo con ROCm)93,8 % en GPU
    98.304✅ 100 %

    El intercambio real de esta palanca no es velocidad contra estabilidad: es velocidad contra contexto. Si tu modelo apura la tarjeta, Vulkan te cuesta ventana. Si no la apura, es gratis.

    Lo que sigue sin medir —ni yo ni casi nadie— es la estabilidad de Vulkan en sesiones de horas. Para un chat de diez minutos da igual; para un agente que lleva toda la tarde en bucle, no.


    El checklist, entero

    Lo que hago ahora cada vez que toco esta máquina:

    1. Desactiva la GPU integrada en la BIOS si tienes un Ryzen con gráficos. Cuesta 0,2 GiB y quita un eje entero de ambigüedad.
    2. Reinicia Ollama después de tocar drivers, BIOS o versión. No es opcional: sondea una vez.
    3. Comprueba library= en el log de arranque. No compute=, no pci_id.
    4. Comprueba que ollama ps dice 100 % GPU antes de dar por buena cualquier medida.
    5. Lee el context_length real de /api/ps, no el que enviaste.
    6. Para decidir sobre memoria, mide la VRAM del sistema, no la columna de ollama ps.
    7. En WSL, no lo intentes. Apunta a localhost:11434 contra el Ollama de Windows.
    8. Cierra Chrome, Spotify y Slack antes de medir. No tanto por los tok/s como por el rango: una diferencia real del 2 % se pierde si el ruido lo ensancha.

    Y la que resume todas: un vacío no es un cero. Cuando un instrumento no devuelve nada, la lectura no es «no hay»; es «no pude mirar». En esta máquina, Get-Process | Modules devolvió 0 módulos y estuve a punto de leerlo como «no hay capas cargadas». Eran 0 porque el proceso corría elevado y yo no podía verlo. Lo salvó tener un caso de control al lado —explorer, mismo usuario, 389 módulos—. Sin ese contraste, el cero se lee como un dato.


    Si te estás planteando el hardware

    La conclusión honesta después de todo esto: una Radeon de consumo corre modelos locales perfectamente bien en 2026, y las cifras están al nivel de lo que se publica para NVIDIA en el mismo rango. ROCm 7.2 es la primera versión donde Ollama, LM Studio, llama.cpp y vLLM funcionan sobre Radeon sin parchear a mano.

    Lo que sigue costando más que en NVIDIA no son los tok/s: es el diagnóstico. Todo lo de este artículo es tiempo que en una 4090 no habrías gastado, no porque el hardware sea peor, sino porque el camino está menos pisado y los fallos son silenciosos en vez de ruidosos.

    Si eso te cuadra —y a mí me cuadra, porque 24 GB de VRAM a este precio no existen en el otro lado— este artículo es el atajo por los cinco agujeros.

    Para seguir:

    Preguntas frecuentes

    ¿Cómo sé si Ollama está usando mi GPU AMD?

    Con dos comprobaciones, no con una. Primero, el log de arranque del servidor (%LOCALAPPDATA%\Ollama\server.log en Windows, journalctl -u ollama en Linux) tiene que declarar library=ROCm o library=Vulkan; si dice library=cpu, no hay GPU. Segundo, ollama ps tiene que decir 100% GPU: cualquier otro valor significa que el modelo está partido entre GPU y CPU. Ollama no da error en ninguno de los dos casos, solo va más lento.

    ¿Por qué Ollama corre en CPU después de actualizar los drivers?

    Porque Ollama sondea la GPU una sola vez, al arrancar, y no vuelve a mirar. Si actualizas drivers, cambias la BIOS o instalas una versión nueva mientras el servicio está en marcha, se queda con la detección vieja y pasa a CPU sin dar ningún error. Medido en una RX 7900 XTX: 15,89 tok/s en CPU contra 132,48 en GPU, un 8,3x. La solución es reiniciar Ollama y volver a comprobar la línea library= del log.

    ¿Se puede usar la GPU AMD con Ollama dentro de WSL2?

    No. Comprobado en agosto de 2026 con una RX 7900 XTX y ROCm 7.2: Ollama enumera las GPU leyendo la topología KFD de sysfs, y WSL no expone /dev/kfd ni /sys/class/kfd. HIP sí computa en WSL a través de /dev/dxg, pero Ollama no busca por ahí, y HSA_ENABLE_DXG_DETECTION=1 no lo cambia. Tanto ROCm como Vulkan devuelven «Available devices: (none)». La salida práctica es apuntar a localhost:11434 contra el Ollama de Windows: con WSL2 en networkingMode=mirrored funciona sin configurar nada.

    ¿Es mejor ROCm o Vulkan para Ollama en una GPU AMD?

    Depende de si tu modelo apura la VRAM. En una RX 7900 XTX, Vulkan gana entre un 17,8 % y un 30,3 % en tokens por segundo según el modelo, con rangos disjuntos en dos rondas. Pero Vulkan deja 0,6 GiB menos de VRAM disponible (23,2 frente a 23,8 GiB), así que un modelo que iba justo de contexto deja de caber. El intercambio no es velocidad contra estabilidad: es velocidad contra ventana de contexto.

    ¿Por qué falla llama.cpp con «device kernel image is invalid» en un Ryzen?

    Porque la máquina tiene dos GPU AMD: la dedicada y la integrada del procesador. ROCm enumera la integrada primero, el binario la elige, y los kernels compilados para gfx1100 no valen para ese chip. Ni --device por nombre ni HIP_VISIBLE_DEVICES ni ROCR_VISIBLE_DEVICES lo arreglan. Lo único que funciona es desactivar la integrada en la BIOS, y cuesta solo 0,2 GiB de VRAM. Ollama no sufre esto porque enmascara la integrada por su cuenta.

    ¿Cuánta VRAM necesita de verdad un modelo en Ollama?

    Más de la que dice ollama ps, que subestima entre 4,3 y 6,8 GiB. Medido con cuatro modelos en una tarjeta de 24 GB: gpt-oss:20b declara 12,33 GiB y ocupa 16,59; qwen3.8 declara 16,61 y ocupa 23,36. Para decidir si un modelo cabe hay que mirar el contador de VRAM del sistema; la columna de ollama ps solo sirve para saber si el modelo se repartió a CPU.

    Compartir

    Buscar

    Etiquetas

    IA PHP JavaScript Migración Laravel Tutorial Desarrollo Web Buenas Prácticas Seguridad Upgrade Laravel 13 OpenAI Backend SEO Claude