GPU en WSL: requisitos reales (y errores comunes)

¿Te fue útil?

La promesa es seductora: mantener Windows para todo lo corporativo, usar Linux para todo lo útil y, aun así, aprovechar la GPU como si estuvieras en una estación de trabajo real.
Luego ejecutas nvidia-smi en WSL y dice “command not found”, o peor, “No devices were found”.

Esta es la realidad: el soporte de GPU en WSL2 es sólido ahora, pero es exigente. No “instalas CUDA en WSL” de la misma manera que en hardware nativo.
Montas una cadena de dependencias entre Windows, el kernel de WSL, el espacio de usuario de Linux y, a veces, Docker. Un eslabón débil y obtienes un fallo lento y confuso.

El modelo mental: qué significa realmente “GPU en WSL”

WSL2 no es “Linux sobre Windows” en el sentido simpático. Es una VM ligera. Tus procesos de Linux se ejecutan en un kernel Linux real (proporcionado por Microsoft),
y ven el hardware a través de una frontera de virtualización.

Para cómputo en GPU, WSL2 usa una interfaz de GPU paravirtualizada. En compilaciones modernas de Windows, el controlador de GPU de Windows expone una ruta de cómputo a la VM de WSL.
Los procesos de Linux no hablan con un dispositivo PCI físico; hablan con un nodo de dispositivo virtual que reenvía el trabajo al controlador del host.
El controlador de Windows es la fuente de la verdad. En la práctica, eso significa:

  • No instalas un controlador de kernel NVIDIA completo en Linux dentro de WSL para la GPU. Si lo intentas, normalmente empeorarás las cosas.
  • El libcuda de WSL proviene de una capa de integración especial, no de la pila habitual de módulos del kernel de tu distro.
  • La mayoría de fallos son desajustes entre la versión del controlador de Windows, la capacidad del kernel de WSL y las bibliotecas de usuario (toolkit CUDA / frameworks ML).

Piensa en el soporte de GPU de WSL como “CUDA remoto al controlador de Windows sobre un canal local muy rápido”, no como “Linux posee la GPU”.
Este cambio mental evita el error clásico: perseguir módulos del kernel de Linux que ni siquiera aplican.

Broma #1: Solucionar GPU en WSL es como arrear gatos—excepto que los gatos son controladores, y todos insisten en que ya están instalados.

Los requisitos reales (qué debe cumplirse)

1) Tu compilación de Windows debe soportar cómputo GPU en WSL2

El cómputo GPU en WSL2 depende de la pila del host Windows: controladores WDDM, la plomería de WSL y soporte en el kernel.
Si Windows es demasiado antiguo, obtendrás una instalación de WSL que parece limpia pero con una ruta de GPU completamente muerta.

Orientación práctica: mantén Windows actualizado. Si estás en un anillo empresarial que se queda atrás, verifica el soporte de GPU-en-WSL antes de prometer nada al equipo.
Esto no es opcional; es la base.

2) Tu proveedor de GPU y el controlador deben soportar explícitamente WSL

En el mundo real, la mayoría de la gente que usa CUDA en WSL está en NVIDIA. AMD puede funcionar en ciertos escenarios (y existe DirectML),
pero CUDA-en-WSL es principalmente una historia de NVIDIA.

El requisito clave es la versión del controlador NVIDIA de Windows que incluye soporte para WSL.
Instalar un controlador “Studio” o “Game Ready” al azar está bien siempre que sea lo suficientemente nuevo e incluya los componentes de cómputo para WSL.
Los controladores antiguos renderizarán juegos sin problema mientras se niegan a exponer cómputo a WSL.

3) WSL2, no WSL1

WSL1 traduce llamadas al sistema de Linux. Es ingenioso, pero no es la plataforma para cómputo en GPU. Quieres WSL2 con el kernel real.
Si tu distribución aún está en WSL1, detente. Conviértela. No depures nada más hasta que lo hagas.

4) Un kernel y una versión de WSL soportados

Hay dos piezas en movimiento: la compilación del SO Windows y el propio componente WSL (que ahora se actualiza más como una app).
La ruta de GPU vive en ese espacio. Si estás en una versión obsoleta de WSL, puedes ver desajustes extraños: el controlador de Windows parece correcto, pero WSL carece del pegamento.

5) Las bibliotecas de usuario deben coincidir con lo que espera el framework

Aquí es donde la gente se hace daño: instalan el toolkit CUDA completo en WSL como si estuvieran en Ubuntu nativo,
luego sobrescriben bibliotecas clave y se preguntan por qué nvidia-smi funciona pero PyTorch no.

Decide qué necesitas realmente:

  • Si solo ejecutas PyTorch o TensorFlow: a menudo no necesitas el toolkit CUDA completo; necesitas la versión correcta del framework y bibliotecas de usuario compatibles.
  • Si compilas código CUDA personalizado: necesitas el toolkit dentro de WSL, pero aún así no debes instalar un controlador de kernel de Linux.

6) Docker añade otra capa de dependencias

Docker en WSL es común—y un amplificador frecuente de fallos. Ahora tienes:
Windows driver → interfaz GPU de WSL → espacio de usuario WSL → motor Docker → runtime de contenedores NVIDIA → tu imagen de contenedor.
Un desajuste y pierdes la GPU, o tienes un contenedor que ve la GPU pero no puede ejecutar kernels.

Hechos y contexto histórico (por qué es raro)

Esto no es trivia por trivia. Explica el diseño actual y los modos de fallo que realmente verás.

  1. WSL1 (2016) no era una VM. Tradujo syscalls. Genial para herramientas de línea de comandos; no un ajuste natural para GPUs y controladores en modo kernel.
  2. WSL2 (2019) cambió a un kernel Linux real. Eso hizo que las cargas de contenedores y las herramientas dependientes del kernel fueran prácticas.
  3. El cómputo GPU en WSL2 llegó vía paravirtualización, no passthrough PCI. Tu invitado Linux no “posee” el dispositivo GPU como en un passthrough típico de hipervisor.
  4. El modelo de controlador de pantalla de Windows (WDDM) está en la ruta crítica. Si los componentes WDDM están desactualizados, el cómputo puede fallar aunque los gráficos funcionen bien.
  5. El soporte de NVIDIA para WSL incluyó una ruta CUDA en espacio de usuario dedicada. Por eso la versión del controlador de Windows importa más que la idea de “última” del gestor de paquetes Linux.
  6. nvidia-smi en WSL es una señal de compatibilidad, no toda la verdad. Puede tener éxito mientras tu framework ML falla por desajustes en cuDNN/cublas.
  7. El soporte temprano de GPU en WSL estuvo limitado a compilaciones de Windows Insider. Mucho del lore de “funciona en mi máquina” viene de esa era.
  8. DirectML se convirtió en una alternativa pragmática para algunas cargas de trabajo centradas en Windows. Pero si quieres el ecosistema CUDA principal, sigues en terreno NVIDIA.

Tareas prácticas: comandos, salidas, decisiones

Estas son las comprobaciones de grado producción. No los rituales de “reinstala todo”.
Cada tarea incluye un comando, qué significa una salida típica y qué decisión tomar a continuación.

Task 1: Confirmar la versión de WSL y salud básica (lado Windows)

cr0x@server:~$ wsl.exe --version
WSL version: 2.1.5.0
Kernel version: 5.15.146.1-2
WSLg version: 1.0.61
MSRDC version: 1.2.5326
Direct3D version: 1.611.1-81528511
DXCore version: 10.0.26052.1000-240405-2035.ge-release
Windows version: 10.0.22631.3007

Interpretación: Quieres una versión moderna de WSL y un kernel 5.15+ en la mayoría de entornos. Los números exactos varían, pero lo “antiguo” es obvio.

Decisión: Si wsl.exe --version falla o muestra componentes muy antiguos, actualiza WSL antes de tocar CUDA o frameworks.

Task 2: Confirmar que tu distro corre como WSL2 (no WSL1)

cr0x@server:~$ wsl.exe -l -v
  NAME            STATE           VERSION
* Ubuntu-22.04    Running         2
  Debian          Stopped         2

Interpretación: VERSION debe ser 2.

Decisión: Si es 1, conviértela: wsl.exe --set-version <distro> 2. No depures GPU en WSL1.

Task 3: Verificar que Windows vea el controlador NVIDIA (sanidad en el host)

cr0x@server:~$ nvidia-smi.exe
Tue Feb  6 09:14:22 2026
+---------------------------------------------------------------------------------------+
| NVIDIA-SMI 551.23                 Driver Version: 551.23         CUDA Version: 12.4   |
|-----------------------------------------+------------------------+----------------------+
| GPU  Name                 Persistence-M | Bus-Id          Disp.A | Volatile Uncorr. ECC |
| Fan  Temp   Perf          Pwr:Usage/Cap |           Memory-Usage | GPU-Util  Compute M. |
|                                         |                        |               MIG M. |
|=========================================+========================+======================|
|   0  NVIDIA RTX 4090               On   |   00000000:01:00.0  On |                  N/A |
|  0%   44C    P8             21W / 450W  |     987MiB / 24564MiB   |      2%      Default |
+-----------------------------------------+------------------------+----------------------+

Interpretación: El controlador de Windows está instalado y la GPU es visible. La versión de CUDA mostrada aquí es la capacidad del controlador, no tu toolkit en WSL.

Decisión: Si esto falla en Windows, detente y arregla el controlador en Windows primero. WSL no lo arreglará mágicamente.

Task 4: Verificar que exista el nodo de dispositivo GPU dentro de WSL

cr0x@server:~$ ls -l /dev/dxg
crw-rw-rw- 1 root root 509, 0 Feb  6 09:10 /dev/dxg

Interpretación: /dev/dxg es el dispositivo puente GPU de WSL. Sin /dev/dxg, no hay ruta de cómputo GPU.

Decisión: Si falta, sospecha WSL/kernel desactualizado, compilación de Windows incorrecta o controlador GPU sin soporte WSL.

Task 5: Confirmar que WSL puede llamar a la pila de gestión NVIDIA

cr0x@server:~$ nvidia-smi
Tue Feb  6 09:16:05 2026
+---------------------------------------------------------------------------------------+
| NVIDIA-SMI 551.23                 Driver Version: 551.23         CUDA Version: 12.4   |
|-----------------------------------------+------------------------+----------------------+
| GPU  Name                 Persistence-M | Bus-Id          Disp.A | Volatile Uncorr. ECC |
| Fan  Temp   Perf          Pwr:Usage/Cap |           Memory-Usage | GPU-Util  Compute M. |
|                                         |                        |               MIG M. |
|=========================================+========================+======================|
|   0  NVIDIA RTX 4090               On   |   00000000:01:00.0  On |                  N/A |
|  0%   45C    P8             23W / 450W  |     992MiB / 24564MiB   |      1%      Default |
+-----------------------------------------+------------------------+----------------------+

Interpretación: Esta es una comprobación necesaria pero no suficiente. Prueba que la pila de gestión funciona a través de WSL.

Decisión: Si esto falla, no pierdas tiempo reinstalando PyTorch todavía. Arregla primero la integración driver/WSL.

Task 6: Comprobar si instalaste accidentalmente un controlador NVIDIA de kernel en Linux (normalmente malo en WSL)

cr0x@server:~$ lsmod | grep -E '^nvidia|^nouveau' || true
nouveau              2539520  0
drm_ttm_helper         16384  1 nouveau
ttm                  106496  2 drm_ttm_helper,nouveau
drm_kms_helper        315392  1 nouveau

Interpretación: Ver módulos de kernel nouveau o nvidia cargados en WSL es una señal de alarma.
En configuraciones típicas de GPU en WSL, no deberías usar esos módulos de kernel para la ruta paravirtual.

Decisión: Si están cargados, quítalos/ponlos en blacklist y vuelve al modelo de integración soportado por WSL. Este es un apagón auto infligido común.

Task 7: Verificar la resolución de libcuda.so dentro de WSL

cr0x@server:~$ ldconfig -p | grep -E 'libcuda\.so|libnvidia-ml\.so' | head
	libcuda.so.1 (libc6,x86-64) => /usr/lib/wsl/lib/libcuda.so.1
	libnvidia-ml.so.1 (libc6,x86-64) => /usr/lib/wsl/lib/libnvidia-ml.so.1

Interpretación: En WSL, normalmente quieres stubs CUDA y bibliotecas de integración bajo /usr/lib/wsl/lib.
Si libcuda.so.1 se resuelve en otro sitio (como /usr/lib/x86_64-linux-gnu desde un paquete de la distro), puedes tener conflictos de bibliotecas.

Decisión: Si la resolución es incorrecta, arregla el ruteo de bibliotecas y elimina paquetes conflictivos antes de depurar frameworks.

Task 8: Confirmar que el entorno no sabotea las rutas de carga de bibliotecas

cr0x@server:~$ env | grep -E 'LD_LIBRARY_PATH|CUDA_HOME|CUDA_PATH' || true
LD_LIBRARY_PATH=/usr/local/cuda/lib64:/usr/local/cuda/extras/CUPTI/lib64
CUDA_HOME=/usr/local/cuda

Interpretación: Esto puede estar bien si instalaste intencionalmente un toolkit coincidente.
También puede forzar a tus apps a elegir bibliotecas incorrectas e ignorar /usr/lib/wsl/lib.

Decisión: Si solo ejecutas ruedas/paquetes conda de frameworks, considera desactivar estas variables y dejar que el framework gestione dependencias.

Task 9: Validar acceso a la GPU desde un framework (ejemplo PyTorch)

cr0x@server:~$ python3 -c "import torch; print(torch.__version__); print('cuda:', torch.version.cuda); print('is_available:', torch.cuda.is_available()); print('device:', torch.cuda.get_device_name(0) if torch.cuda.is_available() else 'none')"
2.2.1
cuda: 12.1
is_available: True
device: NVIDIA RTX 4090

Interpretación: Esta es la prueba decisiva. Si nvidia-smi funciona pero torch.cuda.is_available() es falso, probablemente tienes desajustes en las bibliotecas de usuario.

Decisión: Si es falso, inspecciona ldd en las libs CUDA relevantes y verifica que instalaste una compilación de framework con soporte CUDA.

Task 10: Inspeccionar el enlazado dinámico de una biblioteca CUDA (captura “libcuda incorrecta” rápido)

cr0x@server:~$ python3 -c "import ctypes; import os; print(ctypes.CDLL('libcuda.so.1'))"
<CDLL 'libcuda.so.1', handle 55b7f6d8f900 at 0x7f2df0b7f2d0>

Interpretación: Si esto lanza “cannot open shared object file”, tu ruta de bibliotecas está rota.

Decisión: Si falla, vuelve a las Tareas 7 y 8. No reinstales todo; arregla el enlace.

Task 11: Comprobar la configuración de memoria y swap de WSL (asesino silencioso de rendimiento)

cr0x@server:~$ free -h
               total        used        free      shared  buff/cache   available
Mem:           31Gi       4.2Gi       21Gi       136Mi       5.8Gi        26Gi
Swap:          16Gi          0B       16Gi

Interpretación: WSL usa memoria dinámica, pero aún puede intercambiar o sufrir presión de memoria en cargas de entrenamiento.
Si tu pipeline de datos usa mucha memoria, la utilización de la GPU puede caer mientras la CPU trabaja en paginación.

Decisión: Si el swap está activo durante el entrenamiento, corrige límites de memoria y el buffering del pipeline de datos. No culpes a CUDA primero.

Task 12: Medir la utilización de GPU mientras ejecutas una carga

cr0x@server:~$ nvidia-smi dmon -s pucm -d 1
# gpu   pwr gtemp   sm   mem   enc   dec  mclk  pclk
# Idx     W     C    %     %     %     %   MHz   MHz
    0    85    62   97    71     0     0  10501  2520
    0    92    63   98    73     0     0  10501  2520

Interpretación: Si sm es bajo y tu trabajo es “entrenamiento”, no estás limitado por GPU. Estás limitado río arriba (CPU, I/O, cargador de datos).

Decisión: La baja utilización indica que debes perfilar el pipeline de entrada, almacenamiento y los hilos de CPU antes de tocar ajustes de GPU.

Task 13: Revisar disco y tipo de sistema de archivos (auditoría de I/O)

cr0x@server:~$ df -Th / /mnt/c
Filesystem     Type   Size  Used Avail Use% Mounted on
/dev/sdd       ext4   250G   42G  196G  18% /
C:\           drvfs  953G  611G  342G  65% /mnt/c

Interpretación: El sistema de archivos nativo de WSL ext4 (/) se comporta como Linux. /mnt/c es DrvFS y tiene características de rendimiento diferentes.
Muchas cargas ML quedan destrozadas al leer datasets desde /mnt/c.

Decisión: Mantén datasets y I/O pesado dentro del sistema ext4 de WSL. Usa /mnt/c por conveniencia, no por rendimiento.

Task 14: Benchmark I/O rápido y sucio donde está tu dataset

cr0x@server:~$ dd if=/dev/zero of=./io-test.bin bs=1M count=2048 oflag=direct status=progress
2147483648 bytes (2.1 GB, 2.0 GiB) copied, 1.92 s, 1.1 GB/s
2048+0 records in
2048+0 records out
2147483648 bytes (2.1 GB, 2.0 GiB) copied, 1.92 s, 1.1 GB/s

Interpretación: Esto prueba el throughput de escritura secuencial. Si ejecutas lo mismo en /mnt/c y obtienes números dramáticamente peores, encontraste un cuello de botella.

Decisión: Mueve datos o rediseña el pipeline (shards tar, caché, menos operaciones de archivos pequeños) si debes permanecer en DrvFS.

Task 15: Comprobar visibilidad de GPU en contenedores (si usas Docker)

cr0x@server:~$ docker run --rm --gpus all nvidia/cuda:12.3.2-base-ubuntu22.04 nvidia-smi
Tue Feb  6 09:22:18 2026
+---------------------------------------------------------------------------------------+
| NVIDIA-SMI 551.23                 Driver Version: 551.23         CUDA Version: 12.4   |
|-----------------------------------------+------------------------+----------------------+
| GPU  Name                 Persistence-M | Bus-Id          Disp.A | Volatile Uncorr. ECC |
|=========================================+========================+======================|
|   0  NVIDIA RTX 4090               On   |   00000000:01:00.0  On |                  N/A |
+---------------------------------------------------------------------------------------+

Interpretación: Si esto falla pero nvidia-smi en WSL funciona, tu problema está en la ruta del runtime del contenedor (integración toolkit/runtime).

Decisión: Arregla la configuración del runtime de contenedores NVIDIA y asegura que Docker Desktop/Engine esté conectado a WSL correctamente.

Task 16: Validar cuellos de botella en el lado CPU (porque la GPU a menudo es inocente)

cr0x@server:~$ sudo apt-get update >/dev/null 2>&1; sudo apt-get install -y sysstat >/dev/null 2>&1; mpstat -P ALL 1 3
Linux 5.15.146.1-microsoft-standard-WSL2 (server) 	02/06/2026 	_x86_64_	(24 CPU)

09:23:10 AM  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest  %gnice   %idle
09:23:11 AM  all   320.00    0.00   40.00   55.00    0.00    0.00    0.00    0.00    0.00  585.00
09:23:12 AM  all   330.00    0.00   41.00   60.00    0.00    0.00    0.00    0.00    0.00  570.00

Interpretación: Alto %iowait indica que esperas por almacenamiento, no por cómputo. Ese es el misterio clásico de “GPU al 10%”.

Decisión: Arregla I/O (Tareas 13/14), paralelismo del data loader y disposición de archivos antes de empezar a afinar flags de CUDA.

Guía de diagnóstico rápido (encuentra el cuello de botella)

Cuando alguien te escribe “GPU en WSL está rota”, normalmente significa una de tres cosas:
no hay visibilidad de la GPU, la GPU es visible pero los frameworks fallan, o la GPU funciona pero el rendimiento es pésimo.
Esta guía te lleva al cubo correcto rápido.

Primero: ¿es una falla del controlador de Windows / integración WSL?

  1. Ejecuta nvidia-smi.exe en Windows. Si falla, detente. Arregla la instalación del controlador de Windows.
  2. En WSL, comprueba ls -l /dev/dxg. Si falta, detente. Actualiza WSL y confirma que la compilación de Windows/controlador soporta WSL.
  3. En WSL, ejecuta nvidia-smi. Si falla pero /dev/dxg existe, sospecha conflictos de bibliotecas (libnvidia-ml/libcuda) o integración WSL rota.

Segundo: ¿es un desajuste en el espacio de usuario (confusión framework/toolkit)?

  1. Comprueba ldconfig -p | grep libcuda y asegúrate de que apunte a /usr/lib/wsl/lib.
  2. Prueba el framework directamente (probe mínimo PyTorch/TensorFlow).
  3. Si el framework falla pero nvidia-smi funciona, arregla versiones: compilación del framework vs userland CUDA vs cualquier LD_LIBRARY_PATH fijado.

Tercero: ¿es rendimiento (pipeline de datos / almacenamiento / límites CPU)?

  1. Mientras ejecutas la carga: nvidia-smi dmon -s pucm -d 1. Si sm es bajo, no estás atado a la GPU.
  2. Comprueba dónde están los datos: df -Th. Si el entrenamiento lee desde /mnt/c, muévelos.
  3. Mira %iowait con mpstat. Alto iowait: cuello de botella de almacenamiento. Bajo iowait pero CPU saturada: limitador es el data loader/preprocesado.

Idea parafraseada de Werner Vogels (CTO de Amazon): “Todo falla; la fiabilidad viene de diseñar y operar para esa verdad.”

Tres microhistorias corporativas desde el terreno

Incidente: la suposición equivocada (“WSL es solo Ubuntu, ¿verdad?”)

Un equipo de ciencia de datos tenía una imagen estándar de Windows y usaba WSL2 para desarrollo. Contrataron a un ingeniero ML nuevo que había trabajado años con CUDA en Ubuntu nativo.
El ingeniero hizo lo que cualquier persona competente haría: instaló el controlador NVIDIA de Linux y un toolkit CUDA a juego en la distro WSL.

Los síntomas fueron deliciosamente confusos. nvidia-smi funcionaba en Windows, pero dentro de WSL alternaba entre “No devices were found” y un segfault.
A veces funcionaba tras un reinicio. A veces funcionaba hasta que Docker arrancaba. El equipo quemó una semana en arqueología de Slack.

La causa raíz fue simple: habían instalado paquetes que intentaban gestionar un controlador de kernel que WSL no debía usar.
Archivos de bibliotecas se sobrescribieron, la lógica de carga de módulos chocó con la frontera del kernel y el entorno se volvió no determinista según qué se cargara primero.

La solución fue aburrida: quitar los paquetes del controlador NVIDIA de Linux, purgar repos antiguos de CUDA y restaurar la pila provista por WSL en /usr/lib/wsl/lib.
Después de eso, instalaron solo las partes de espacio de usuario que realmente necesitaban para compilar código y fijaron las versiones del framework.

Lo que cambió culturalmente fue más importante que los comandos: dejaron de tratar WSL como un “host Linux real” y empezaron a verlo como un runtime especializado.
El informe del incidente resaltó literalmente una línea: “El controlador de Windows es el controlador.”

Optimización que salió mal: “Guardemos datasets en C: para que OneDrive los respalde”

Un equipo quería una única fuente de verdad para los datasets entre herramientas de Windows y notebooks en WSL.
Guardaron todo bajo C:\Users\...\datasets y accedían desde WSL vía /mnt/c.
Parecía limpio. A los de cumplimiento les gustó. El entrenamiento resultó dolorosamente lento.

Los gráficos de GPU contaron la historia: la utilización oscilaba, el tiempo de entrenamiento se duplicó y aparecieron bloqueos aleatorios.
El equipo asumió sobrecarga de virtualización GPU. Ajustaron tamaño de batch, activaron precisión mixta, cambiaron versiones de CUDA e incluso cambiaron GPUs.
Nada funcionó.

El verdadero villano fue el comportamiento de I/O de archivos bajo DrvFS, amplificado por un layout de dataset con millones de archivos pequeños y patrones de acceso con metadatos pesados.
Añade protección de endpoints corporativos y sincronización en la nube, y obtienes muerte por mil stat() pequeños.

Lo arreglaron moviendo los datasets calientes al sistema ext4 de WSL y exportando solo los artefactos finalizados de vuelta a rutas de Windows.
Para los datasets que debían quedarse en Windows, los empaquetaron en shards archivados para reducir la contención de metadatos.
La “optimización” se revirtió y el rendimiento volvió como si alguien quitara una bota del cuello del data loader.

Práctica aburrida pero correcta: fijar versiones y una prueba smoke salvaron el día

Otra organización tenía un equipo de plataforma adecuado. Nada glamuroso. Principalmente hojas de cálculo y guardrails.
Construyeron una imagen base estándar de WSL: rango de versiones de controlador en Windows, versión mínima de WSL, versión de distro Ubuntu y un conjunto aprobado de frameworks ML.

Cada lunes, un trabajo programado corría una prueba smoke en un puñado de máquinas: comprobar /dev/dxg, ejecutar nvidia-smi, importar PyTorch, ejecutar un pequeño kernel CUDA,
y registrar resultados. No benchmarking profundo—solo “¿sigue funcionando la cadena?”.

Una semana, se desplegaron actualizaciones de Windows y la prueba smoke detectó que un subconjunto de máquinas había reinstalado silenciosamente un controlador OEM más antiguo.
Los usuarios aún no lo habían notado, porque los gráficos estaban bien. El cómputo habría sido lo primero en fallar durante una entrega.

La solución fue una política de aplicación de controladores y un script de remediación automatizado. La victoria clave no fue el script.
Fue la existencia de una prueba rutinaria que trataba GPU-en-WSL como una dependencia operativa, no una superstición de desarrollador.

Broma #2: La configuración de GPU más fiable es la que nadie “mejora” un viernes por la tarde.

Errores comunes: síntoma → causa raíz → solución

1) Síntoma: nvidia-smi en WSL dice “command not found”

  • Causa raíz: Las herramientas de usuario NVIDIA no están instaladas en la distro, o falta PATH.
  • Solución: Instala el conjunto de paquetes de usuario apropiado para tu distro, o usa pruebas a nivel de framework. No instales controladores de kernel. Asegura que /usr/lib/wsl/lib exista.

2) Síntoma: nvidia-smi en WSL dice “No devices were found”

  • Causa raíz: Falta el puente GPU de WSL (/dev/dxg), controlador de Windows no soportado o WSL/kernel desactualizado.
  • Solución: Actualiza Windows, actualiza WSL, instala un controlador NVIDIA de Windows que soporte cómputo WSL. Valida ls -l /dev/dxg.

3) Síntoma: falta /dev/dxg

  • Causa raíz: No estás en WSL2, el componente WSL es demasiado antiguo o la compilación de Windows no soporta la ruta de cómputo GPU.
  • Solución: Convierte la distro a WSL2, actualiza WSL y asegúrate de que el SO host cumpla los requisitos de GPU-en-WSL.

4) Síntoma: nvidia-smi funciona, pero PyTorch dice CUDA no disponible

  • Causa raíz: Instalaste una compilación de PyTorch solo para CPU, o las bibliotecas CUDA de usuario están desajustadas/sobrescritas por LD_LIBRARY_PATH.
  • Solución: Instala una versión de framework con soporte CUDA; elimina libs CUDA conflictivas; asegura que libcuda.so.1 se resuelva a /usr/lib/wsl/lib.

5) Síntoma: el contenedor Docker no ve la GPU, pero WSL sí

  • Causa raíz: Runtime de contenedores NVIDIA no configurado, Docker no usando el motor WSL correctamente, o falta --gpus all.
  • Solución: Arregla la integración Docker + runtime NVIDIA; vuelve a probar con una imagen base CUDA conocida y nvidia-smi dentro del contenedor.

6) Síntoma: el entrenamiento es lento; la utilización de GPU es baja y espigada

  • Causa raíz: Cuello de botella en pipeline de datos (I/O, preprocesado en CPU, pocos workers), a menudo empeorado por usar /mnt/c.
  • Solución: Mueve datasets al ext4 de WSL; aumenta workers del data loader; shardea archivos; observa %iowait y sm de GPU durante ejecuciones.

7) Síntoma: segfaults aleatorios o “illegal instruction” tras instalar toolkit CUDA

  • Causa raíz: Conflictos de bibliotecas entre paquetes CUDA de la distro y las libs de integración provistas por WSL; mezcla de versiones de repos.
  • Solución: Audita ldconfig -p, elimina paquetes conflictivos, evita sobrescribir libs críticas con LD_LIBRARY_PATH.

8) Síntoma: GPU visible, pero obtienes out-of-memory antes de lo esperado

  • Causa raíz: Interpretación incorrecta del uso de VRAM (caching del framework), o presión de memoria en WSL provocando problemas en CPU que parecen problemas de GPU.
  • Solución: Usa nvidia-smi para inspeccionar VRAM, y free -h para revisar memoria/swap del host; ajusta batch size y pipeline de datos.

Listas de verificación / plan paso a paso

Checklist A: Base limpia para cómputo GPU en WSL (centrado en NVIDIA)

  1. Windows: Instala un controlador NVIDIA actual con soporte de cómputo WSL. Verifica con nvidia-smi.exe.
  2. Windows: Asegura que WSL esté actualizado: wsl.exe --version debe mostrar componentes modernos.
  3. WSL: Asegura que tu distro sea WSL2: wsl.exe -l -v.
  4. WSL: Confirma el dispositivo puente GPU: ls -l /dev/dxg.
  5. WSL: Confirma la pila de gestión: nvidia-smi.
  6. WSL: Confirma la resolución de bibliotecas: ldconfig -p | grep libcuda debe apuntar a /usr/lib/wsl/lib.
  7. WSL: Ejecuta una prueba smoke de framework (PyTorch/TensorFlow).

Checklist B: Sanidad de rendimiento para cargas ML

  1. Mantén datasets en ext4 de WSL, no en /mnt/c. Verifica con df -Th.
  2. Durante el entrenamiento, observa la GPU: nvidia-smi dmon -s pucm -d 1.
  3. Durante el entrenamiento, observa el iowait de la CPU: mpstat -P ALL 1.
  4. Si iowait es alto, haz benchmark del path de disco con dd (o herramientas mejores después) y arregla el layout de datos.
  5. Si la CPU está al 100% pero iowait es bajo, reduce coste de preprocesado, aumenta hilos/trabajadores y cachea datos decodificados.

Checklist C: Ruta Docker (solo si la necesitas)

  1. Primero prueba que la GPU funcione en WSL sin contenedores (nvidia-smi y una prueba de framework).
  2. Luego prueba una imagen base CUDA conocida con docker run --gpus all ... nvidia-smi.
  3. Si el contenedor falla: trátalo como un problema de integración del runtime, no como un problema GPU.
  4. Fija la versión CUDA de la imagen base del contenedor a lo que tu framework espera. Evita “latest” a menos que disfrutes la arqueología.

Preguntas frecuentes

1) ¿Necesito instalar el controlador NVIDIA de Linux dentro de WSL?

Normalmente, no. El cómputo GPU en WSL depende del controlador de Windows y de una capa de integración de WSL.
Instalar controladores de kernel Linux en WSL es una forma común de crear conflictos de bibliotecas e inestabilidad extraña.

2) Si nvidia-smi.exe en Windows funciona, ¿por qué no funciona nvidia-smi en WSL?

Porque “controlador instalado” es necesario pero no suficiente. WSL necesita el dispositivo puente GPU (/dev/dxg) y las bibliotecas de usuario correctas.
Si /usr/lib/wsl/lib está siendo ignorado o sobrescrito, las herramientas en WSL pueden fallar.

3) ¿Cuál es la comprobación más rápida para “GPU disponible en WSL”?

Comprueba ls -l /dev/dxg. Si falta, la ruta de cómputo ni siquiera está presente.
Luego ejecuta nvidia-smi como seguimiento.

4) ¿Por qué el entrenamiento con GPU a veces va más lento en WSL que en Linux nativo?

A menudo no es la ruta GPU—es el almacenamiento y el I/O. Entrenar desde /mnt/c puede ser dramáticamente más lento para cargas con metadatos pesados.
Pon los datos en el sistema ext4 de WSL y observa la utilización de GPU.

5) ¿Puedo usar GPUs AMD para cómputo en WSL?

Hay opciones (destaca DirectML para ciertas pilas), pero los ecosistemas CUDA están abrumadoramente centrados en NVIDIA.
Si tu carga depende de bibliotecas CUDA, planea usar hardware y controladores NVIDIA.

6) Docker no ve mi GPU en WSL. ¿Cuál es el culpable habitual?

Integración runtime de GPU para contenedores faltante o mal configurada, o simplemente no usar --gpus all.
Prueba que la GPU funcione fuera de Docker primero, luego depura la capa de contenedores.

7) ¿Necesito el toolkit CUDA completo en WSL para ejecutar PyTorch o TensorFlow?

No siempre. Muchas distribuciones de frameworks incluyen las bibliotecas de usuario CUDA necesarias (o esperan específicas).
Instala el toolkit solo si compilas código CUDA o tienes una dependencia específica que lo requiera.

8) ¿Por qué nvidia-smi muestra una versión CUDA que no coincide con mi toolkit?

La versión CUDA en nvidia-smi refleja la capacidad máxima soportada por el controlador.
Tu toolkit/framework CUDA es un componente de usuario separado. El desajuste no es automáticamente un error; la incompatibilidad sí lo es.

9) ¿El soporte GPU de WSL es lo suficientemente estable para entrenamiento en producción?

Para muchos equipos, sí—especialmente para estaciones de trabajo de desarrollador y pipelines tipo CI repetibles.
Para “este es nuestro único clúster de entrenamiento” todavía querrás el control operativo de servidores Linux nativos, pero WSL puede ser perfectamente creíble para muchas cargas.

Próximos pasos prácticos

  1. Decide tu stack objetivo. Solo framework (más simple) versus compilación CUDA personalizada (requiere toolkit). Deja de mezclar objetivos.
  2. Prueba la cadena en orden. Controlador de Windows → WSL2 → /dev/dxgnvidia-smi → prueba de framework GPU → (opcional) prueba Docker.
  3. Mueve los datos fuera de /mnt/c para entrenamiento. Si no haces nada más por rendimiento, haz esto.
  4. Fija versiones y añade una prueba smoke. Una comprobación automatizada de un minuto ahorra una semana de “pero funcionaba ayer”.

Si tratas la GPU en WSL como un sistema—con dependencias, contratos y una rutina de verificación—se comportará como tal.
Si la tratas como un truco mágico, eventualmente hará el clásico truco: desaparecer justo antes de tu plazo.

← Anterior
Soluciona “Sin Internet, seguro” restableciendo el adaptador de red correcto
Siguiente →
¿Wi‑Fi 6/6E lento en Windows 11? Corrige controlador y gestión de energía

Deja un comentario