mirror of
https://github.com/MacRimi/ProxMenux.git
synced 2026-06-01 21:14:49 +00:00
complete i18n migration to /[locale]/ with EN+ES content
Full rewrite of the docs site under app/[locale]/ with next-intl in localePrefix:"always" mode. Every page now exists at both /en/<path> and /es/<path>; the root / shows a meta-refresh + JS redirect to /<defaultLocale>/ so GitHub Pages serves something on the apex URL. Highlights: - 107 doc pages migrated to file-per-page JSON namespaces under messages/en/ and messages/es/. Spanish content is fully translated (no copy-of-English placeholders). - New documentation for the Active Suppressions section in the Settings tab and the per-event Dismiss dropdown in the Health Monitor modal. - New screenshots: dismiss-duration-dropdown.png and an updated health-suppression-settings.png. - Pagefind integrated for client-side search; index is built on every CI deploy (not committed). - RSS feeds: per-locale at /<locale>/rss.xml plus root /rss.xml for backward compat. - Removed the dead app/[locale]/guides/[slug]/ route — every guide now has its own static page and no markdown source remains. - Fixed orphan link /guides/nvidia -> /guides/nvidia-manual in docs/hardware/nvidia-host. - Removed obsolete components (footer2, calendar, drawer). Verified locally with `npm ci && npm run build`: 2804 files in out/, 231 pages indexed by pagefind, root redirect intact, both locale roots and the new Active Suppressions docs render OK.
This commit is contained in:
@@ -0,0 +1,120 @@
|
||||
{
|
||||
"meta": {
|
||||
"title": "Añadir Coral TPU a LXC | ProxMenux Documentation",
|
||||
"description": "Pasa una Google Coral TPU (USB o M.2 / PCIe) a un contenedor LXC de Proxmox. ProxMenux escribe las entradas correctas de dev / cgroup / mount para cada variante, arranca el contenedor e instala el runtime de Edge TPU dentro para que apps como Frigate puedan usar el acelerador."
|
||||
},
|
||||
"header": {
|
||||
"title": "Añadir Coral TPU a LXC",
|
||||
"description": "Comparte una Google Coral TPU (USB Accelerator o M.2 / Mini-PCIe) con un contenedor LXC de Proxmox. ProxMenux se encarga de la config del LXC y de la instalación del runtime Edge TPU dentro del contenedor. Coral es solo TPU: para compartir GPU / iGPU (Quick Sync, VA-API, NVENC) en el mismo contenedor, ejecuta Añadir GPU a LXC por separado.",
|
||||
"section": "Hardware: GPUs y Coral-TPU"
|
||||
},
|
||||
"intro": {
|
||||
"title": "Qué hace esto",
|
||||
"body": "Escribe la config de passthrough en <code>/etc/pve/lxc/<ctid>.conf</code> — entradas distintas dependiendo de si el host tiene un <strong>USB Accelerator</strong>, una <strong>Coral M.2 / PCIe</strong>, o ambos. Luego arranca el contenedor e instala el último runtime <code>libedgetpu</code> de Google dentro de él. El passthrough de iGPU / GPU lo gestiona un script aparte (<lxcGpuLink>Añadir GPU a LXC</lxcGpuLink>) — este se centra en la TPU."
|
||||
},
|
||||
"whenUse": {
|
||||
"heading": "Cuándo usar esto",
|
||||
"body": "Caso de uso típico: ejecutar <frigateLink>Frigate</frigateLink>, Agent DVR, Blue Iris + CodeProject.AI o cualquier otra app de detección de objetos dentro de un LXC y querer que la Coral TPU haga la inferencia ML en lugar de la CPU. Con Coral, la latencia de inferencia baja de ~100 ms a ~5 ms por frame y la carga de CPU se mantiene cerca de cero."
|
||||
},
|
||||
"prereqs": {
|
||||
"title": "Antes de empezar",
|
||||
"drivers": "<strong>Drivers de Coral ya instalados en el host</strong>. Este script no los instala; solo configura el passthrough al contenedor. Ejecuta <hostLink>Install Coral TPU on the Host</hostLink> primero si no lo has hecho.",
|
||||
"driversCheck": "ls /dev/apex_* 2>/dev/null ; lsusb | grep -E '1a6e:089a|18d1:9302'",
|
||||
"container": "<strong>Un contenedor LXC existente</strong>, idealmente con una distro basada en <strong>Debian / Ubuntu</strong>. La instalación dentro del contenedor usa <code>apt-get</code>; los contenedores Alpine / Arch no están soportados por este script actualmente.",
|
||||
"downtime": "<strong>Asume una breve interrupción</strong> del contenedor. El script lo para para aplicar los cambios de config y lo arranca de nuevo para instalar los drivers dentro. No hace falta reiniciar el host."
|
||||
},
|
||||
"hostPrep": {
|
||||
"title": "El host debe estar preparado primero",
|
||||
"body": "Si ejecutas este script antes de instalar los drivers de Coral en el host (el módulo de kernel <code>gasket</code>/<code>apex</code> para M.2, el runtime <code>libedgetpu</code> para USB), la config del LXC se escribe igualmente pero el contenedor no encontrará el dispositivo en tiempo de ejecución. El orden importa: <strong>instalación en el host → passthrough al LXC → app dentro del contenedor</strong>."
|
||||
},
|
||||
"running": {
|
||||
"heading": "Ejecutar el script",
|
||||
"body": "Abre ProxMenux en el host, ve a <strong>Hardware: GPUs and Coral-TPU → Add Coral TPU to LXC</strong>.",
|
||||
"imageAlt": "Entrada del menú 'Add Coral TPU to LXC' dentro de Hardware: GPUs and Coral-TPU"
|
||||
},
|
||||
"howRuns": {
|
||||
"heading": "Cómo se ejecuta el script",
|
||||
"body": "Una decisión por adelantado (¿qué contenedor?), luego el script gestiona los caminos USB y PCIe de forma independiente según lo que encuentre en el host. Si ambos están presentes, ambos se pasan."
|
||||
},
|
||||
"walkthrough": {
|
||||
"heading": "Recorriendo el flujo",
|
||||
"pick": {
|
||||
"title": "Elige el contenedor LXC",
|
||||
"body": "Un diálogo muestra cada LXC del host (desde <code>pct list</code>). Elige el que debería recibir la Coral. En ejecución o parado, da igual — el script gestiona ambos casos (lo para brevemente para escribir la config y luego lo arranca de nuevo para instalar los drivers)."
|
||||
},
|
||||
"gpuHint": {
|
||||
"title": "Sugerencia de passthrough de GPU (opcional)",
|
||||
"body": "Si el host tiene una GPU (Intel iGPU, AMD, NVIDIA) y el contenedor elegido NO tiene passthrough de GPU configurado, el script muestra un diálogo único sugiriendo que ejecutes <lxcGpuLink>Añadir GPU a LXC</lxcGpuLink> primero. La Coral suele combinarse con decodificación de vídeo por hardware (Quick Sync, VA-API, NVENC) para apps como Frigate. Puedes decir sí (sale, ejecutas el script de GPU y vuelves) o no (continúa con el setup solo de TPU)."
|
||||
},
|
||||
"usb": {
|
||||
"title": "Escribir la config del LXC — ruta USB",
|
||||
"body": "Si hay un USB Accelerator presente, el script hace dos cosas: (1) escribe una regla udev en el host para que el dispositivo tenga un nombre estable <code>/dev/coral</code> independientemente del puerto USB en el que esté, y (2) hace bind-mount del árbol <strong>completo</strong> <code>/dev/bus/usb</code> dentro del contenedor.",
|
||||
"whyTitle": "¿Por qué montar /dev/bus/usb en lugar de /dev/coral?",
|
||||
"whyBody": "La ruta del nodo del dispositivo USB (p. ej. <code>/dev/bus/usb/001/005</code>) cambia cuando reconectas el acelerador a otro puerto. Versiones anteriores del script hacían bind-mount del symlink <code>/dev/coral</code>, que apuntaba a una ruta vieja y se rompía. Montar el árbol USB completo significa que el contenedor ve la ruta actual sea cual sea, así que reconectar simplemente funciona."
|
||||
},
|
||||
"pcie": {
|
||||
"title": "Escribir la config del LXC — ruta M.2 / PCIe",
|
||||
"body1": "Si hay una Coral M.2 / PCIe presente en el host y <code>/dev/apex_0</code> existe (el módulo de kernel apex está cargado), el script usa la API moderna <code>dev</code> de Proxmox que gestiona los permisos de cgroup2 automáticamente tanto para contenedores privilegiados como unprivileged:",
|
||||
"body2": "Si el host aún no ha arrancado con el módulo apex cargado (acabas de ejecutar <hostLink>Install Coral on Host</hostLink> y no has reiniciado), <code>/dev/apex_0</code> aún no existe. El script recurre al cgroup2 + bind mount clásico con <code>create=file</code> para que las entradas sean válidas incluso cuando el dispositivo no se ha materializado:",
|
||||
"rebootTitle": "Reinicia el host primero si acabas de instalar los drivers de Coral",
|
||||
"rebootBody": "El fallback de cgroup2 + mount se escribirá, pero el dispositivo solo existe realmente después de un reinicio del host que cargue el módulo <code>apex</code>. Si no has reiniciado, reinicia ahora antes de arrancar el contenedor."
|
||||
},
|
||||
"drivers": {
|
||||
"title": "Arrancar el contenedor + instalar el runtime de Coral dentro",
|
||||
"body": "Los cambios de config en LXC de Proxmox surten efecto en el siguiente arranque — así que el script arranca el contenedor, espera hasta 15 segundos a que <code>pct exec</code> responda y luego deja un bash script dentro que:",
|
||||
"items": [
|
||||
"Ejecuta <code>apt-get update</code>.",
|
||||
"Instala los prerequisitos del repositorio Coral: <code>gnupg</code>, <code>curl</code>, <code>ca-certificates</code>.",
|
||||
"Importa la clave GPG de Coral de Google en <code>/etc/apt/keyrings/coral-edgetpu.gpg</code> (ruta moderna, la misma que usa el instalador del host) y añade el repositorio APT <code>coral-edgetpu-stable</code> con <code>signed-by=</code>.",
|
||||
"Instala el último <code>libedgetpu1-std</code> (por defecto). Si tienes una Coral M.2, se te preguntará entre <code>libedgetpu1-std</code> (estándar) y <code>libedgetpu1-max</code> (máximo rendimiento, calienta más)."
|
||||
],
|
||||
"noIgpuTitle": "¿Por qué no hay drivers de iGPU aquí?",
|
||||
"noIgpuBody": "Versiones anteriores de este script también instalaban Intel <code>va-driver-all</code>, <code>intel-opencl-icd</code> y compañía para que el mismo contenedor pudiera hacer decode de vídeo Quick Sync junto a la inferencia de Coral. Esa doble responsabilidad causaba fallos confusos cuando el usuario solo quería Coral. El lado iGPU es ahora trabajo exclusivo de <lxcGpuLink>Añadir GPU a LXC</lxcGpuLink> — ejecútalo primero si también quieres decode de vídeo por hardware en el contenedor.",
|
||||
"debianTitle": "Solo contenedores Debian / Ubuntu",
|
||||
"debianBody": "La instalación dentro del contenedor usa <code>apt-get</code> directamente. Los contenedores Alpine, Arch o basados en RHEL no están soportados actualmente — el paso de instalación fallará y dejará el LXC con la config de passthrough pero sin drivers dentro. Para esas distros, instala el runtime de Coral manualmente siguiendo la <coralLink>guía oficial</coralLink> de Google después del paso de config del LXC."
|
||||
},
|
||||
"summary": {
|
||||
"title": "Resumen",
|
||||
"body": "El script imprime una checklist al final resumiendo qué se habilitó (Coral USB, Coral M.2) con marcas ✓ o ⚠ según si el hardware se detectó realmente. El contenedor sigue en ejecución — puedes saltar directamente a la config de Frigate / CodeProject.AI / tu app."
|
||||
}
|
||||
},
|
||||
"manual": {
|
||||
"heading": "Equivalente manual",
|
||||
"body": "Si quieres ver exactamente qué va en la config del LXC, o aplicarlo a mano:",
|
||||
"usbHeading": "Coral USB",
|
||||
"pcieHeading": "Coral M.2 / PCIe",
|
||||
"runtimeHeading": "Dentro del contenedor — runtime de Coral"
|
||||
},
|
||||
"verification": {
|
||||
"heading": "Verificación",
|
||||
"body": "Entra en el contenedor y comprueba que la Coral es visible:"
|
||||
},
|
||||
"troubleshoot": {
|
||||
"heading": "Solución de problemas",
|
||||
"apexTitle": "El contenedor arrancó pero /dev/apex_0 no está dentro",
|
||||
"apexBody": "El módulo apex del host no está cargado. En el host: <code>lsmod | grep apex</code> — si está vacío, ejecuta <code>modprobe apex</code>, o reinicia si acabas de instalar los drivers de Coral. Una vez el host tenga <code>/dev/apex_0</code>, reinicia el contenedor: <code>pct stop <ctid> && pct start <ctid></code>.",
|
||||
"replugTitle": "La Coral USB desaparece al reconectarla en otro puerto",
|
||||
"replugBody": "Justo por eso el script monta <code>/dev/bus/usb</code> en lugar del symlink <code>/dev/coral</code>. Si te pasa esto, comprueba que tu config del LXC tiene <code>lxc.mount.entry: /dev/bus/usb dev/bus/usb ...</code> y no una referencia directa a <code>/dev/coral</code>. Las configs viejas de versiones anteriores del script pueden necesitar actualizarse — vuelve a ejecutar el script sobre el mismo contenedor y la config se refresca.",
|
||||
"alpineTitle": "La instalación dentro del contenedor falla en un contenedor Alpine",
|
||||
"alpineBody": "El script usa <code>apt-get</code>, que Alpine no tiene. La config de passthrough del LXC sigue siendo válida — solo instala el runtime de Coral manualmente con <code>apk add</code> siguiendo la guía de Google para Alpine, o usa un contenedor basado en Debian si no necesitas la huella más pequeña.",
|
||||
"frigateTitle": "Frigate dice 'Coral EdgeTPU detected but not available'",
|
||||
"frigateBody": "Casi siempre es un problema de permisos dentro del contenedor. Frigate corre como root por defecto; comprueba que el usuario root está en el grupo <code>plugdev</code> dentro del contenedor (para USB), y que el proceso puede leer <code>/dev/apex_0</code> (para M.2). <code>ls -l /dev/apex_0</code> desde dentro del contenedor debería mostrar el grupo <code>apex</code> — si no, añade el alineamiento de GID a <code>/etc/group</code> o cambia el contenedor a modo privilegiado.",
|
||||
"logsTitle": "Revisa los logs del host y del contenedor",
|
||||
"logsBody": "En el host: <code>journalctl -u pvedaemon | grep -i coral</code>. Dentro del contenedor: revisa los logs de la app (Frigate: <code>/config/logs/</code>, CodeProject.AI: su propio directorio de logs). El patrón clásico de error es \"Coral detected, runtime loaded, but inference engine can't claim it\" — eso son permisos 9 de cada 10 veces."
|
||||
},
|
||||
"related": {
|
||||
"heading": "Relacionado",
|
||||
"items": [
|
||||
{
|
||||
"label": "Instalar Coral TPU (Host)",
|
||||
"href": "/docs/hardware/install-coral-tpu-host",
|
||||
"tail": " — prerequisito necesario para tarjetas Coral M.2 / PCIe antes de pasarlas a un CT."
|
||||
},
|
||||
{
|
||||
"label": "Añadir GPU a LXC",
|
||||
"href": "/docs/hardware/igpu-acceleration-lxc",
|
||||
"tail": " — el mismo patrón para GPUs (a menudo emparejado con una Coral TPU en setups de Frigate)."
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,178 @@
|
||||
{
|
||||
"meta": {
|
||||
"title": "Añadir GPU a VM (Passthrough) | ProxMenux Documentation",
|
||||
"description": "Pasa una GPU Intel, AMD o NVIDIA a una VM Proxmox con rendimiento cercano al nativo. ProxMenux gestiona la preparación del host (módulos VFIO, blacklist de drivers, cmdline del kernel), la configuración de la VM (hostpci, función de audio, hermanos del grupo IOMMU), workarounds específicos del fabricante (Code 43 de NVIDIA, reset bug de AMD, dump de ROM) y conflictos de switch-mode con LXCs."
|
||||
},
|
||||
"header": {
|
||||
"title": "Añadir GPU a VM (Passthrough)",
|
||||
"description": "Dale una de tus GPUs a una máquina virtual con rendimiento cercano al nativo. ProxMenux detecta Intel / AMD / NVIDIA, valida IOMMU, analiza el grupo IOMMU de la GPU para pasar cada dispositivo hermano junto, configura VFIO en el host, escribe las líneas hostpci correctas en la config de la VM y aplica fixes específicos del fabricante cuando hace falta.",
|
||||
"section": "Hardware: GPUs y Coral-TPU"
|
||||
},
|
||||
"intro": {
|
||||
"title": "Qué hace esto",
|
||||
"body": "Todo lo que la <pveLink>wiki oficial de Proxmox de PCI passthrough</pveLink> te explica paso a paso manualmente — habilitar IOMMU, módulos VFIO, blacklisting de drivers, descubrimiento de vendor ID, setup de <code>hostpci</code>, dump de ROM en AMD, ocultación de KVM en NVIDIA — hecho en una sola ejecución con comprobaciones de cordura en cada paso. El script también es consciente de las <em>otras</em> cosas en tu host: si la misma GPU ya está asignada a un LXC u otra VM, te ofrece migrar limpiamente en lugar de romper silenciosamente el setup existente."
|
||||
},
|
||||
"who": {
|
||||
"heading": "¿Para quién es esto?",
|
||||
"body": "Tienes una GPU física en tu host Proxmox y quieres que una <strong>máquina virtual</strong> (Windows gaming, macOS, un nodo headless de cómputo en GPU, un media server en VM) la use directamente. Pasar una GPU a una VM no es lo mismo que pasarla a un LXC — las VMs necesitan que el kernel trate la GPU como dispositivo VFIO (en esencia \"el host no la tocará\"), lo que significa que el host no puede usar esa GPU para nada más mientras la VM esté en ejecución. Para transcoding / cómputo en <em>LXC</em>, usa <lxcLink>Añadir GPU a LXC</lxcLink> — comparte la GPU y no necesita VFIO."
|
||||
},
|
||||
"prereqs": {
|
||||
"title": "Antes de empezar",
|
||||
"gpu": "<strong>Una GPU soportada</strong> instalada físicamente. El script detecta Intel, AMD y NVIDIA vía <code>lspci</code>.",
|
||||
"gpuCheck": "lspci | grep -iE 'VGA|3D|Display'",
|
||||
"iommu": "<strong>Virtualización IOMMU</strong> disponible en BIOS/UEFI (Intel VT-d o AMD-Vi). Si está apagada a nivel de firmware, ninguna config de Linux lo arregla — tienes que habilitarla primero en la BIOS. El script detecta esto y se ofrece a habilitarlo en el lado del SO.",
|
||||
"q35": "La VM destino usa machine type <strong>q35</strong>. El antiguo <code>i440fx</code> no soporta de forma fiable el passthrough PCIe y el script se negará a continuar.",
|
||||
"q35Check": "qm config '<'vmid'>' | grep machine",
|
||||
"moreGpus": "Preferiblemente <strong>más de una GPU</strong> en el host, o acceso por consola en otra salida (IPMI, KVM-over-IP, serie). Una vez pases la única GPU a una VM, la consola del host se queda a oscuras. Con dos GPUs NVIDIA puedes pasar una a una VM y mantener la otra en el host — el script gestiona esto por BDF (ver <em>NVIDIA</em> en las notas del fabricante más abajo).",
|
||||
"nvidiaInstalled": "Si estás en un Proxmox que ya instaló el driver de NVIDIA vía <nvidiaLink>NVIDIA Drivers en el host</nvidiaLink>: la GPU que pases a la VM se desvincula del driver <code>nvidia</code> del host y se vincula a <code>vfio-pci</code>. El módulo <code>nvidia</code> sigue cargado, así que cualquier <strong>otra</strong> GPU NVIDIA que tengas en el host sigue funcionando con <code>nvidia-smi</code>."
|
||||
},
|
||||
"pickOne": {
|
||||
"title": "Passthrough a VM vs compartición con LXC — elige uno por GPU",
|
||||
"body": "Una GPU vinculada a <code>vfio-pci</code> para passthrough a VM no puede usarla simultáneamente el host ni un LXC. Si tienes dos GPUs, puedes dedicar una a cada ruta. Si solo tienes una, elige:",
|
||||
"vmItem": "<strong>Ruta VM (esta página):</strong> acceso completo al hardware, pero exclusivo para la VM dueña de la GPU mientras esté en ejecución.",
|
||||
"lxcItem": "<strong>Ruta LXC (<lxcLink>Añadir GPU a LXC</lxcLink>):</strong> compartida con el host y otros contenedores, ideal para transcoding, sin magia VFIO."
|
||||
},
|
||||
"running": {
|
||||
"heading": "Ejecutar el instalador",
|
||||
"body": "Abre ProxMenux en el host, ve a <strong>Hardware: GPUs and Coral-TPU → Add GPU to VM</strong>.",
|
||||
"imageAlt": "Entrada del menú 'Add GPU to VM' dentro de Hardware: GPUs and Coral-TPU"
|
||||
},
|
||||
"howRuns": {
|
||||
"heading": "Cómo se ejecuta el script",
|
||||
"body": "El flujo tiene tres fases con separación clara entre \"recopilar información y decisiones\" y \"aplicar cambios realmente\". Hasta la confirmación final, no se ha tocado nada en tu host ni en la VM."
|
||||
},
|
||||
"walkthrough": {
|
||||
"heading": "Recorriendo el flujo",
|
||||
"detect": {
|
||||
"title": "Detectar GPUs y comprobar IOMMU",
|
||||
"body": "El script lista cada GPU que encuentra. Si IOMMU no está ya habilitado en la cmdline del kernel en ejecución, recibirás un prompt sí/no para añadir <code>intel_iommu=on</code> (o <code>amd_iommu=on</code>) + <code>iommu=pt</code> al archivo de arranque correcto — <code>/etc/kernel/cmdline</code> en ZFS (systemd-boot) o <code>/etc/default/grub</code> en LVM/ext4. Si aceptas y la cmdline del kernel cambia, el script marca que el prompt de reinicio al final será obligatorio.",
|
||||
"tipTitle": "¿Ya ejecutaste post-instalación?",
|
||||
"tipBody": "Si habilitaste anteriormente <postLink>soporte VFIO IOMMU</postLink> desde los scripts post-instalación, IOMMU ya está activo y este paso pasa silenciosamente. Bien.",
|
||||
"imageAlt": "Lista de GPUs detectadas con fabricante y dirección PCI"
|
||||
},
|
||||
"preflight": {
|
||||
"title": "Elegir una GPU y ejecutar las comprobaciones previas",
|
||||
"intro": "Una vez eliges la GPU, el script ejecuta una serie de comprobaciones que pueden bloquear el progreso:",
|
||||
"items": [
|
||||
"<strong>No en SR-IOV.</strong> Si el dispositivo es una Virtual Function o una Physical Function con VFs activas, el passthrough chocaría con el uso de SR-IOV. Bloqueado.",
|
||||
"<strong>Aviso de GPU única.</strong> Si esta es la única GPU del host, recibirás un diálogo de aviso recordándote que después del reinicio la consola se queda a oscuras — asegúrate de tener acceso SSH o por la UI web desde otra máquina.",
|
||||
"<strong>Método de reset AMD.</strong> Las GPUs AMD tienen un largo historial de no resetear limpiamente entre paradas y arranques de VM. El script comprueba <code>/sys/bus/pci/devices/<pci>/reset_method</code>: si la tarjeta es una APU sin FLR <em>bloquea</em> (prácticamente inutilizable); una tarjeta AMD dedicada sin FLR también se bloquea; cualquier cosa con un modo de reset desconocido avisa pero te deja continuar con override explícito.",
|
||||
"<strong>No en D3cold.</strong> Algunas tarjetas AMD reportan estado de energía <code>D3cold</code> en reposo, lo que las hace invisibles durante el arranque de la VM. Bloqueado hasta que despiertes la GPU.",
|
||||
"<strong>Análisis del grupo IOMMU.</strong> Lee <code>/sys/kernel/iommu_groups/</code> para encontrar cada dispositivo no-bridge del grupo de la GPU. <em>Todos ellos</em> se pasarán a la VM juntos — si tu placa base agrupa la GPU con una tarjeta de red, la tarjeta de red va también."
|
||||
],
|
||||
"audioIntro": "<strong>Audio compañero.</strong> Dos rutas, según dónde viva el audio:",
|
||||
"audioDgpu": "<strong>GPU discreta (NVIDIA / AMD):</strong> el audio HDMI está en la misma tarjeta como función <code>.1</code> del slot PCI de la GPU. Incluido automáticamente. Este dispositivo de audio nunca lo usó el host, así que nadie pierde nada.",
|
||||
"audioIgpu": "<strong>iGPU Intel (o cualquier GPU sin hermano <code>.1</code>):</strong> el audio HDMI / analógico vive en el chipset en un slot distinto (<code>00:1f.3</code> normalmente). El script escanea el host, lista cada controlador de audio PCI con su driver actual (<code>snd_hda_intel</code>, etc.) y te pregunta cuál(es) pasar. Por defecto <strong>ninguno</strong> — tienes que aceptarlo explícitamente."
|
||||
},
|
||||
"pickVm": {
|
||||
"title": "Elegir la VM destino",
|
||||
"body": "Se te muestra la lista de VMs del host y eliges una. El script comprueba que la VM es q35 — los machine types BIOS/i440fx se rechazan porque el passthrough PCIe en ellos no es fiable. Si tienes una VM q35 con la GPU ya asignada (parcial o completamente), la entrada existente se reutiliza en lugar de duplicarse.",
|
||||
"imageAlt": "Lista de VMs con nombre, ID y estado mostrada como selector"
|
||||
},
|
||||
"switchMode": {
|
||||
"title": "Switch mode — gestionar que la GPU ya esté en otro sitio",
|
||||
"intro": "El script escanea cada config de VM y cada config de LXC en el host buscando la GPU que elegiste. Tres resultados posibles:",
|
||||
"items": [
|
||||
"<strong>La GPU está libre.</strong> Nada que hacer, continúa.",
|
||||
"<strong>La GPU está en otra VM.</strong> Se te ofrece quitarla de esa otra VM antes de asignarla aquí. Si rechazas, el script aborta — dos VMs no pueden compartir una asignación VFIO exclusiva.",
|
||||
"<strong>La GPU está en un LXC (modo compartido).</strong> Se te ofrece quitar la configuración de passthrough del LXC (líneas <code>lxc.cgroup2.devices.allow</code> + <code>lxc.mount.entry</code>). El LXC dejará de ver la GPU, pero la VM la verá — esta es la mecánica de \"switch mode\" que le da a esta entrada de menú su etiqueta secundaria."
|
||||
],
|
||||
"imageAlt": "Diálogo que ofrece quitar la GPU de un LXC antes de asignarla a la VM",
|
||||
"smartTitle": "Los hermanos de audio también se limpian con inteligencia",
|
||||
"smartBody": "Si la VM origen tenía dispositivos de audio extra adjuntos junto a la GPU, el script quita <strong>solo los que ahora son huérfanos</strong> — es decir, entradas de audio cuyo hermano de display también se está quitando. El audio vinculado a otra GPU que se queda en la VM se deja intacto. Esto importa cuando desadjuntas una iGPU Intel (que comparte el audio del chipset) de una VM que también tiene una tarjeta dedicada NVIDIA / AMD aún pasada: el audio HDMI de la dGPU (<code>02:00.1</code>) se queda, el audio del chipset (<code>00:1f.3</code>) se va."
|
||||
},
|
||||
"audioPick": {
|
||||
"title": "(Si no hay hermano .1) Elegir qué controladores de audio incluir",
|
||||
"body": "Solo ocurre para iGPUs Intel y setups similares con audio separado. Una checklist muestra cada controlador de audio PCI del host (excluyendo cualquiera ya en el grupo IOMMU de la GPU), etiquetado con su driver actual. Selecciona los que quieras — o ninguno, si la VM no necesita audio del hardware del host.",
|
||||
"imageAlt": "Diálogo checklist con cada controlador de audio PCI del host (BDF + driver) cuando la GPU no tiene audio hermano .1",
|
||||
"warnTitle": "No marques audio del que depende el host",
|
||||
"warnBody": "Si el host usa actualmente un controlador de audio para algo — por ejemplo, el beep del shell de Proxmox o una VM a la que ya lo has pasado — marcarlo aquí significa que el host (y cualquier otra VM que lo comparta) pierde acceso después del reinicio. Ante la duda, déjalo vacío y siempre puedes volver a ejecutar el script más tarde para añadir audio si hace falta."
|
||||
},
|
||||
"summary": {
|
||||
"title": "Revisar el resumen de confirmación",
|
||||
"body": "Un diálogo final muestra exactamente qué está a punto de cambiar en el host y en la VM. Esta es la última salida — si algo se ve mal (un dispositivo extra en el grupo IOMMU que no esperabas, la GPU equivocada, la VM equivocada), cancela aquí y aún no se ha tocado nada.",
|
||||
"imageAlt": "Diálogo de resumen listando los cambios del host (archivos VFIO/blacklist) y los cambios de config de la VM (líneas hostpci) antes de aplicar"
|
||||
},
|
||||
"hostApply": {
|
||||
"title": "Se aplican los cambios del host",
|
||||
"intro": "La Fase 2 se ejecuta de forma no interactiva. En el lado del host el script puede tocar:",
|
||||
"items": [
|
||||
"<code>/etc/modules</code> — añade <code>vfio</code>, <code>vfio_iommu_type1</code>, <code>vfio_pci</code> (más <code>vfio_virqfd</code> en kernels < 6.2).",
|
||||
"<code>/etc/modprobe.d/vfio.conf</code> — para AMD / Intel, define <code>options vfio-pci ids=<vendor:device,...> disable_vga=1</code> para que VFIO reclame la GPU pronto en el arranque. Para NVIDIA el archivo solo añade <code>softdep nvidia pre: vfio-pci</code> (más <code>_drm</code>/<code>_modeset</code>/<code>_uvm</code>) — el binding real es por BDF vía la regla udev de abajo. En AMD, también añade líneas <code>softdep</code> forzando que <code>vfio-pci</code> cargue antes de <code>radeon</code> / <code>amdgpu</code>.",
|
||||
"<code>/etc/modprobe.d/iommu_unsafe_interrupts.conf</code> y <code>kvm.conf</code> — workarounds sensatos que la mayoría de VMs Windows / macOS necesitan (<code>allow_unsafe_interrupts=1</code>, <code>ignore_msrs=1</code>).",
|
||||
"<code>/etc/modprobe.d/blacklist.conf</code> — pone en blacklist los drivers open-source compañeros (<code>nouveau</code>, <code>amdgpu</code>, <code>radeon</code>, <code>i915</code>) que si no agarrarían la GPU antes que VFIO. El módulo propietario <code>nvidia</code> <strong>nunca se pone en blacklist</strong> — sigue disponible para cualquier OTRA GPU NVIDIA que mantengas en el host.",
|
||||
"<code>/etc/udev/rules.d/10-proxmenux-vfio-bind.rules</code> + <code>/etc/proxmenux/vfio-bind.bdfs</code> — <strong>solo NVIDIA</strong>. Estado de binding por BDF. La regla udev aplica <code>ATTR'{'driver_override'}'=\"vfio-pci\"</code> en el evento PCI ADD para cada Bus:Device.Function rastreado, así que solo las GPUs que has pasado explícitamente van a VFIO. Esto es lo que hace que NVIDIA multi-GPU funcione — tus otras tarjetas NVIDIA mantienen su driver <code>nvidia</code> y siguen siendo usables en el host.",
|
||||
"<strong>Solo AMD.</strong> Vuelca la ROM de la GPU desde sysfs (<code>/sys/bus/pci/.../rom</code>) o la tabla ACPI VFCT a <code>/usr/share/kvm/vbios_<card>.bin</code>. La VM la referencia vía <code>romfile=</code> para que las tarjetas que mal-reportan su propia VBIOS aún inicialicen correctamente.",
|
||||
"<strong>Solo NVIDIA.</strong> Para y deshabilita los servicios NVIDIA del host que podrían sondear / bloquear la GPU en el arranque (<code>nvidia-persistenced</code>, <code>nvidia-powerd</code>, <code>nvidia-fabricmanager</code>). El propio módulo <code>nvidia</code> se deja cargado para que otras GPUs NVIDIA del host sigan funcionando con <code>nvidia-smi</code>.",
|
||||
"<code>update-initramfs -u -k all</code> — solo se ejecuta si algo de lo de arriba ha cambiado realmente."
|
||||
]
|
||||
},
|
||||
"vmApply": {
|
||||
"title": "La config de la VM se aplica vía qm set",
|
||||
"body": "La config de la VM en <code>/etc/pve/qemu-server/<vmid>.conf</code> se actualiza vía <code>qm set</code> (nunca por <code>sed</code> directo):",
|
||||
"after1": "Se añade un flag <code>x-vga=1</code> para cada fabricante <strong>excepto</strong> iGPU Intel — las GPUs integradas Intel no tienen VRAM dedicada para una consola pre-arranque, así que ese flag causa hangs.",
|
||||
"after2": "Se añaden líneas <code>hostpciN</code> adicionales si el grupo IOMMU de la GPU contiene otros dispositivos que necesitas pasar juntos."
|
||||
},
|
||||
"reboot": {
|
||||
"title": "Reiniciar si se tocó la config del host",
|
||||
"body": "Si la Fase 2 cambió algo a nivel de módulo de kernel / cmdline / blacklist, se te pedirá reiniciar. El reinicio es obligatorio antes de arrancar la VM — si no la GPU sigue retenida por el driver del host y VFIO no puede reclamarla.",
|
||||
"imageAlt": "Pantalla de resumen mostrando qué se cambió, seguida de un prompt de reinicio"
|
||||
}
|
||||
},
|
||||
"vendors": {
|
||||
"heading": "Notas específicas del fabricante",
|
||||
"nvidiaHeading": "NVIDIA",
|
||||
"nvidiaBody": "Los drivers de consumo de NVIDIA detectan que están corriendo en una VM y se niegan a inicializar con el infame error <em>\"Code 43\"</em>. El workaround de ProxMenux: ocultar KVM al guest (<code>hidden=1</code>), poner un hypervisor vendor ID falseado <code>NV43FIX</code> en la línea <code>args</code> y pasar <code>kvm=off</code>. Esto ha funcionado de forma fiable en drivers GeForce durante años. En tarjetas datacenter / Tesla / Quadro esto no hace falta — esos drivers están licenciados para virtualización.",
|
||||
"nvidiaMultiHeading": "Soporte NVIDIA multi-GPU",
|
||||
"nvidiaMultiBody": "Los hosts con dos o más GPUs NVIDIA son de primera clase. Puedes pasar una tarjeta a una VM y mantener la(s) otra(s) en el host para <code>nvidia-smi</code>, compartición de GPU con LXC o cualquier carga del lado del host. ProxMenux vincula VFIO <strong>por BDF</strong> (Bus:Device.Function) vía una regla udev en lugar de poner en blacklist globalmente el módulo <code>nvidia</code> — así el destino de cada tarjeta es independiente de las otras, incluso cuando ambas GPUs son del mismo modelo y comparten el mismo ID <code>vendor:device</code>. El driver nvidia del host sigue cargado; solo los BDFs específicos que selecciones se redirigen a <code>vfio-pci</code>.",
|
||||
"amdHeading": "AMD",
|
||||
"amdBody": "El \"AMD reset bug\" significa que algunas tarjetas crashean cuando la VM para y no pueden re-inicializarse sin un reinicio del host. ProxMenux pre-criba para esto leyendo el método de reset PCI, pero no puede arreglarlo después. Si lo encuentras, el fix de la comunidad es el módulo de kernel <vendorResetLink>vendor-reset</vendorResetLink>. El script no lo instala automáticamente — el módulo es una build DKMS que añades tú si ves fallos de reset. También en guests Windows, el servicio <em>RadeonResetBugFix</em> es el workaround común a nivel userspace.",
|
||||
"intelHeading": "iGPU Intel",
|
||||
"intelBody": "El passthrough de iGPU Intel es inestable pero posible en generaciones UHD 630+ con <sriovLink>i915-sriov-dkms</sriovLink> para SR-IOV. Para un caso simple de \"darle la iGPU a una VM\", el script la vincula exactamente como una GPU dedicada, pero se salta <code>x-vga=1</code> (las iGPUs no llevan una VBIOS pre-arranque). Perderás la salida de consola del host — planifícalo en consecuencia."
|
||||
},
|
||||
"verification": {
|
||||
"heading": "Verificación"
|
||||
},
|
||||
"troubleshoot": {
|
||||
"heading": "Solución de problemas",
|
||||
"code43Title": "Code 43 en Windows (NVIDIA)",
|
||||
"code43Body": "Los args de ocultación de KVM no se aplicaron. Comprueba <code>qm config <vmid> | grep -E \"cpu|args\"</code> — deberías ver <code>hidden=1</code> y <code>hv_vendor_id=NV43FIX</code>. Si faltan, vuelve a ejecutar el script y reselecciona la misma VM.",
|
||||
"amdResetTitle": "La GPU AMD funciona una vez, falla al reiniciar la VM",
|
||||
"amdResetBody": "El AMD reset bug. Soluciones (en orden): (1) reiniciar el host — la GPU será usable de nuevo para un ciclo más de VM; (2) instalar el módulo DKMS <code>vendor-reset</code> y añadir <code>softdep amdgpu pre: vendor-reset</code>; (3) dentro de Windows, instalar el servicio <em>RadeonResetBugFix</em>.",
|
||||
"stuckBootTitle": "VM colgada arrancando / GPU no detectada",
|
||||
"stuckBootBody": "Confirma que VFIO realmente retiene la GPU al arrancar: <code>lspci -nnk -d vendor:device</code> debe mostrar <code>Kernel driver in use: vfio-pci</code>. Si aún muestra el driver del fabricante, el blacklist no surtió efecto — revisa <code>/etc/modprobe.d/blacklist.conf</code> y <code>dmesg | grep vfio</code>, y regenera initramfs: <code>update-initramfs -u -k all</code> y luego reinicia.",
|
||||
"darkTitle": "La consola del host se queda a oscuras tras reiniciar y no puedo entrar por SSH",
|
||||
"darkBody": "Pasaste la GPU primaria sin tener acceso alternativo. Arranca en un recovery shell (ISO de rescate, IPMI), quita las líneas de la config de la VM (<code>/etc/pve/qemu-server/<vmid>.conf</code>) y quita las opciones vfio:",
|
||||
"logTitle": "Revisa el log de instalación",
|
||||
"logBody": "Cada ejecución escribe en <code>/tmp/add_gpu_vm.log</code>. Adjúntalo cuando pidas ayuda en GitHub."
|
||||
},
|
||||
"revert": {
|
||||
"heading": "Revertir manualmente",
|
||||
"intro": "Hoy no hay un atajo dedicado de \"quitar GPU de la VM\" en ProxMenux. Para desadjuntar limpiamente:"
|
||||
},
|
||||
"related": {
|
||||
"heading": "Relacionado",
|
||||
"items": [
|
||||
{
|
||||
"label": "Instalar drivers NVIDIA (Host)",
|
||||
"href": "/docs/hardware/nvidia-host",
|
||||
"tail": " — instala los drivers en el host primero si también quieres la GPU usable desde ahí."
|
||||
},
|
||||
{
|
||||
"label": "Añadir GPU a LXC",
|
||||
"href": "/docs/hardware/igpu-acceleration-lxc",
|
||||
"tail": " — modelo alternativo: comparte la GPU con varios contenedores en lugar de dedicarla a una VM."
|
||||
},
|
||||
{
|
||||
"label": "Switch GPU Mode (VM ↔ LXC)",
|
||||
"href": "/docs/hardware/switch-gpu-mode",
|
||||
"tail": " — cambia la misma GPU entre modos sin rehacer todo el cableado."
|
||||
},
|
||||
{
|
||||
"label": "Comandos de GPU Passthrough",
|
||||
"href": "/docs/help-info/gpu-commands",
|
||||
"tail": " — referencia de lspci, verificación de IOMMU, qm set hostpci."
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,185 @@
|
||||
{
|
||||
"meta": {
|
||||
"title": "Añadir GPU a LXC | ProxMenux Documentation",
|
||||
"description": "Comparte una GPU Intel, AMD o NVIDIA con un contenedor LXC para transcoding acelerado por hardware (Plex / Jellyfin / Frigate), cargas OpenCL / CUDA y aceleración de vídeo Mesa. ProxMenux gestiona los nodos de dispositivo, la alineación de GIDs y la instalación de drivers específica por distro dentro del contenedor."
|
||||
},
|
||||
"header": {
|
||||
"title": "Añadir GPU a LXC",
|
||||
"description": "Comparte una o varias GPUs con un contenedor LXC de Proxmox. El host sigue usando la GPU con normalidad — el contenedor solo recibe acceso a través de los nodos de dispositivo. Funciona con iGPUs Intel (Quick Sync / VA-API), tarjetas AMD (Mesa / ROCm) y NVIDIA (CUDA / NVENC).",
|
||||
"section": "Hardware: GPUs y Coral-TPU"
|
||||
},
|
||||
"intro": {
|
||||
"title": "Qué hace esto",
|
||||
"body": "Añade entradas <code>dev<N></code> a la config del LXC (<code>/etc/pve/lxc/<ctid>.conf</code>) para que el contenedor vea <code>/dev/dri/*</code>, <code>/dev/kfd</code> o <code>/dev/nvidia*</code> — lo que aplique a tu GPU. Luego arranca el contenedor, detecta la distro de dentro e instala los drivers de userspace correspondientes (Mesa, intel-media-driver, runtime NVIDIA…) para que apps como Plex, Jellyfin o Frigate usen realmente la GPU para transcoding. Los GIDs (<code>video</code>, <code>render</code>) se alinean entre host y contenedor para que los permisos coincidan."
|
||||
},
|
||||
"compare": {
|
||||
"heading": "Compartición LXC vs passthrough a VM",
|
||||
"intro": "Los contenedores LXC comparten el kernel del host, así que pueden <em>compartir</em> la GPU del host sin apropiársela. Esa es una gran diferencia con las VMs: con <vmLink>passthrough a VM</vmLink> la GPU es exclusiva de una VM y el host no puede usarla. Con LXC, varios contenedores más el host pueden usar a la vez la misma GPU.",
|
||||
"headerFeature": "Característica",
|
||||
"headerLxc": "LXC (esta página)",
|
||||
"headerVm": "VM",
|
||||
"rows": [
|
||||
{
|
||||
"feature": "¿El host sigue usando la GPU?",
|
||||
"lxc": "Sí",
|
||||
"vm": "No — exclusiva de la VM"
|
||||
},
|
||||
{
|
||||
"feature": "¿Varios contenedores compartiendo una GPU?",
|
||||
"lxc": "Sí",
|
||||
"vm": "No"
|
||||
},
|
||||
{
|
||||
"feature": "¿Requiere IOMMU / VFIO en el host?",
|
||||
"lxc": "No",
|
||||
"vm": "Sí"
|
||||
},
|
||||
{
|
||||
"feature": "¿Hace falta reiniciar?",
|
||||
"lxc": "Normalmente no (solo reiniciar el CT)",
|
||||
"vm": "Sí, siempre"
|
||||
},
|
||||
{
|
||||
"feature": "¿Soporta correr cualquier SO?",
|
||||
"lxc": "Solo Linux (LXC es solo Linux)",
|
||||
"vm": "Windows, macOS, cualquier Linux"
|
||||
}
|
||||
]
|
||||
},
|
||||
"prereqs": {
|
||||
"title": "Antes de empezar",
|
||||
"gpu": "<strong>Una GPU en el host</strong> — iGPU Intel, dGPU o APU AMD, o una tarjeta NVIDIA. El script autodetecta los tres vía <code>lspci</code>.",
|
||||
"gpuCheck": "lspci | grep -iE 'VGA|3D|Display'",
|
||||
"vfio": "<strong>La GPU NO está vinculada a vfio-pci.</strong> Si la GPU está actualmente asignada a una VM vía passthrough, es invisible para el driver del kernel del host y el LXC no puede usarla. El script detecta esto y se ofrece a ejecutar <switchLink>Switch GPU Mode</switchLink> por ti.",
|
||||
"nvidia": "<strong>Solo para NVIDIA:</strong> el driver NVIDIA del host debe estar ya instalado — ProxMenux necesita hacer coincidir las libs userspace del contenedor con la versión del host. Si aún no lo has hecho, ejecuta <nvidiaLink>Instalar drivers NVIDIA en el host</nvidiaLink> primero.",
|
||||
"nvidiaCheck": "nvidia-smi",
|
||||
"container": "<strong>Un contenedor LXC existente.</strong> El script opera sobre un contenedor que ya creaste — no crea uno. El contenedor debería idealmente ser <strong>privilegiado</strong> (unprivileged funciona pero necesita mapeo UID/GID que el script no configura)."
|
||||
},
|
||||
"unpriv": {
|
||||
"title": "Funciona en contenedores privilegiados y unprivileged",
|
||||
"body": "El script escribe entradas <code>dev<N></code> en la config del LXC y, en contenedores unprivileged, alinea los GIDs de <code>video</code> y <code>render</code> entre host y contenedor para que los nodos de la GPU sean accesibles desde dentro sin tener que tocar manualmente <code>lxc.idmap</code>."
|
||||
},
|
||||
"running": {
|
||||
"heading": "Ejecutar el instalador",
|
||||
"body": "Abre ProxMenux en el host, ve a <strong>Hardware: GPUs and Coral-TPU → Add GPU to LXC</strong>.",
|
||||
"imageAlt": "Entrada del menú 'Add GPU to LXC' dentro de Hardware: GPUs and Coral-TPU"
|
||||
},
|
||||
"howRuns": {
|
||||
"heading": "Cómo se ejecuta el script",
|
||||
"body": "Dos fases: todas las decisiones por adelantado, luego todos los cambios de una vez. No se toca nada en tu contenedor hasta que confirmas."
|
||||
},
|
||||
"walkthrough": {
|
||||
"heading": "Recorriendo el flujo",
|
||||
"detect": {
|
||||
"title": "Detectar GPUs del host",
|
||||
"body": "El script escanea <code>lspci</code> buscando controladoras VGA / 3D / Display que coincidan con Intel, AMD o NVIDIA. Para NVIDIA también verifica que el módulo de kernel <code>nvidia</code> esté cargado y que <code>nvidia-smi</code> funcione — la versión del driver del host que reporta se usará para elegir el instalador <code>.run</code> correcto para el contenedor.",
|
||||
"tipTitle": "¿NVIDIA no está listo?",
|
||||
"tipBody": "Si NVIDIA se detecta pero el módulo no está cargado, el script no ofrecerá la ruta NVIDIA. Ejecuta <nvidiaLink>Instalar drivers NVIDIA en el host</nvidiaLink> primero (y reinicia), luego vuelve."
|
||||
},
|
||||
"pickCt": {
|
||||
"title": "Elige un contenedor LXC",
|
||||
"body": "Verás una lista de cada LXC del host con su ID y nombre. Elige el que debería recibir la GPU. El contenedor puede estar en ejecución o parado — el script gestiona ambos casos (lo para brevemente durante la config, lo reinicia y lo deja en su estado original al final).",
|
||||
"imageAlt": "Diálogo listando los contenedores LXC existentes para elegir"
|
||||
},
|
||||
"selectGpu": {
|
||||
"title": "Selecciona la(s) GPU(s) a añadir",
|
||||
"body": "Si hay más de una GPU presente, recibes una checklist. Puedes añadir varias al mismo contenedor (p. ej., una iGPU Intel para Quick Sync + una dGPU AMD para ROCm). Si solo se detecta una GPU, se autoselecciona.",
|
||||
"imageAlt": "Checklist mostrando las GPUs detectadas (Intel / AMD / NVIDIA) con fabricante y dirección PCI"
|
||||
},
|
||||
"preflight": {
|
||||
"title": "Comprobaciones previas",
|
||||
"imageAlt": "Diálogo que ofrece ejecutar Switch GPU Mode cuando la GPU seleccionada sigue vinculada a vfio-pci para passthrough a VM",
|
||||
"intro": "Tres comprobaciones, cualquiera de las cuales puede bloquearte o redirigirte:",
|
||||
"items": [
|
||||
"<strong>SR-IOV.</strong> Si la GPU seleccionada es una Virtual Function (VF) o una Physical Function con VFs activas, el passthrough a LXC no aplica — el dispositivo lo gestiona el driver SR-IOV. Bloqueado.",
|
||||
"<strong>Vinculada a vfio-pci.</strong> Si la GPU está actualmente retenida por VFIO para passthrough a VM, el kernel del host no puede crear nodos <code>/dev/dri/*</code> o <code>/dev/nvidia*</code> para ella. El script se ofrece a ejecutar <switchLink>Switch GPU Mode</switchLink> que deshace el binding VFIO; probablemente necesitarás un reinicio antes de volver a ejecutar Añadir GPU a LXC.",
|
||||
"<strong>Ya configurada.</strong> Si el contenedor ya tiene todos los nodos de dispositivo para la GPU seleccionada, el script lo dice y sale limpiamente. Si está parcialmente configurada, continúa solo con las piezas que faltan."
|
||||
]
|
||||
},
|
||||
"applyConfig": {
|
||||
"title": "Aplica los cambios de config del LXC",
|
||||
"body1": "El script para el contenedor, edita <code>/etc/pve/lxc/<ctid>.conf</code> y añade entradas <code>dev<N></code> con los GIDs correctos para las GPUs seleccionadas. Usar entradas <code>dev:</code> (en lugar de las viejas líneas <code>lxc.mount.entry</code>) es la forma moderna de Proxmox — los permisos de grupo se aplican en tiempo de parseo de la config en lugar de en tiempo de mount.",
|
||||
"body2": "Ejemplo después de Intel + NVIDIA en el mismo contenedor:"
|
||||
},
|
||||
"installDrivers": {
|
||||
"title": "Arranca el contenedor e instala los drivers dentro",
|
||||
"body": "Una vez escrita la config, el script arranca el contenedor, espera hasta ~30 segundos a que <code>pct exec</code> responda y luego detecta la distro del contenedor desde <code>/etc/os-release</code>. En base a eso, instala los paquetes userspace correctos.",
|
||||
"headerDistro": "Distro",
|
||||
"headerInt": "Intel / AMD",
|
||||
"headerNvidia": "NVIDIA",
|
||||
"rows": [
|
||||
{
|
||||
"distro": "Alpine",
|
||||
"intel": "apk add mesa-va-gallium intel-media-driver libva-utils",
|
||||
"nvidia": "apk add nvidia-utils"
|
||||
},
|
||||
{
|
||||
"distro": "Arch / Manjaro",
|
||||
"intel": "pacman -Sy intel-media-driver mesa libva-utils",
|
||||
"nvidia": "pacman -Sy nvidia-utils"
|
||||
}
|
||||
],
|
||||
"debianDistro": "Debian / Ubuntu / otras",
|
||||
"debianIntel": "apt-get install va-driver-all intel-opencl-icd vainfo",
|
||||
"debianNvidia": "extraer el <code>.run</code> del host → <code>pct push</code> → ejecutar con <code>--no-kernel-modules --no-dkms</code>",
|
||||
"whyTitle": "Por qué el baile del .run de NVIDIA en Debian",
|
||||
"whyBody": "Debian / Ubuntu no traen paquetes NVIDIA con una versión lo bastante granular como para coincidir con el driver del host byte por byte. Las libs userspace dentro del contenedor <strong>deben coincidir con la versión del módulo de kernel</strong> cargado en el host, o <code>nvidia-smi</code> falla con un version mismatch. ProxMenux lo resuelve usando exactamente el mismo instalador <code>.run</code> que se usó para el host — extraído, tarred, enviado al contenedor con <code>pct push</code> y ejecutado con <code>--no-kernel-modules --no-dkms</code> para que solo se toque el userspace."
|
||||
},
|
||||
"alignGids": {
|
||||
"title": "Alinear GIDs y restaurar el estado",
|
||||
"body1": "Los archivos de dispositivo en el host pertenecen al grupo <code>video</code> (GID 44) o <code>render</code> (GID 104). La distro del contenedor puede traer números de GID distintos para esos grupos, lo que haría que los nodos de la GPU fueran inalcanzables desde dentro. El script reescribe <code>/etc/group</code> en el contenedor para que <code>video:44</code> y <code>render:104</code> coincidan exactamente.",
|
||||
"body2": "Finalmente, restaura el contenedor a su estado original — si estaba parado cuando empezaste, se vuelve a parar. Si estaba en ejecución, se queda en ejecución."
|
||||
}
|
||||
},
|
||||
"vendors": {
|
||||
"heading": "Notas específicas del fabricante",
|
||||
"intelHeading": "iGPU Intel",
|
||||
"intelBody": "La ruta más común — ideal para transcoding por hardware de Plex / Jellyfin / Frigate vía <em>Quick Sync</em>. El contenedor recibe <code>/dev/dri/card0</code> (legacy) y <code>/dev/dri/renderD128</code> (nodo render-only moderno — lo que las apps usan realmente). No hace falta cambios del lado del host; el driver <code>i915</code> del host ya creó los nodos.",
|
||||
"amdHeading": "AMD",
|
||||
"amdBody": "Los mismos nodos DRI que Intel para gráficos / VA-API. Si <code>/dev/kfd</code> existe en el host (soporte de cómputo AMD / kernel ROCm), el script también lo añade para que los contenedores puedan hacer cargas OpenCL / ROCm. Los drivers VA de Mesa cubren el lado de decodificación de vídeo.",
|
||||
"nvidiaHeading": "NVIDIA",
|
||||
"nvidiaBody": "Añade cada nodo <code>/dev/nvidia*</code> que el host expone. La pieza crítica es <strong>el matching de versión de driver</strong>: la versión del módulo del host y la versión de la lib userspace del contenedor deben ser idénticas, si no <code>nvidia-smi</code> dentro del contenedor falla. ProxMenux captura la versión del host en tiempo de detección y usa el mismo archivo <code>.run</code> para instalar el userspace del contenedor. Para contenedores Debian, la instalación sube la memoria del contenedor a 2 GB temporalmente (el instalador necesita ~1.5 GB libres para extraer) y la restaura después.",
|
||||
"updateTitle": "Después de actualizar el driver NVIDIA del host, vuelve a ejecutar este script",
|
||||
"updateBody": "Cuando actualizas el driver NVIDIA en el host, las libs userspace del contenedor se quedan en la versión vieja y <code>nvidia-smi</code> dentro del contenedor se rompe. El <nvidiaLink>instalador NVIDIA host</nvidiaLink> de ProxMenux detecta los contenedores con passthrough NVIDIA y se ofrece a actualizarlos automáticamente — pero si te saltaste ese prompt, simplemente ejecuta Añadir GPU a LXC otra vez sobre el mismo contenedor y refrescará el userspace."
|
||||
},
|
||||
"verification": {
|
||||
"heading": "Verificación",
|
||||
"body": "Después de que el script termine, entra en el contenedor y comprueba que la GPU es visible:"
|
||||
},
|
||||
"troubleshoot": {
|
||||
"heading": "Solución de problemas",
|
||||
"mismatchTitle": "nvidia-smi: Failed to initialize NVML: Driver/library version mismatch",
|
||||
"mismatchBody": "La versión userspace del contenedor ≠ la versión del módulo del host. Ejecuta Añadir GPU a LXC otra vez sobre ese contenedor — el script extrae el <code>.run</code> actual del host y reinstala el userspace haciéndolo coincidir.",
|
||||
"denyTitle": "Permission denied en /dev/dri/renderD128 dentro del contenedor",
|
||||
"denyBody": "Normalmente uno de: (1) el contenedor es unprivileged sin mapeo UID/GID al grupo <code>render</code> del host; (2) el usuario dentro del contenedor no está en el grupo <code>render</code>. Fix: añade el usuario a <code>render</code> dentro del contenedor (<code>usermod -aG render <user></code>), o pasa a modo privilegiado si la carga es de confianza.",
|
||||
"vainfoTitle": "vainfo dice: VA-API version 1.xx; failed to initialize",
|
||||
"vainfoBody": "El runtime de VA-API está, pero no se instaló ningún driver adecuado. En Intel, instala <code>intel-media-driver</code> (gens nuevas) o <code>i965-va-driver</code> (gens viejas). En AMD, <code>mesa-va-drivers</code>. Vuelve a ejecutar el script en caso de duda.",
|
||||
"logTitle": "Log de instalación",
|
||||
"logBody": "Cada ejecución escribe en <code>/tmp/add_gpu_lxc.log</code> en el host. Inclúyelo cuando pidas ayuda en GitHub."
|
||||
},
|
||||
"related": {
|
||||
"heading": "Relacionado",
|
||||
"items": [
|
||||
{
|
||||
"label": "Instalar drivers NVIDIA (Host)",
|
||||
"href": "/docs/hardware/nvidia-host",
|
||||
"tail": " — prerequisito necesario para GPUs NVIDIA antes de pasarlas a un contenedor."
|
||||
},
|
||||
{
|
||||
"label": "Añadir GPU a VM (Passthrough)",
|
||||
"href": "/docs/hardware/gpu-vm-passthrough",
|
||||
"tail": " — modelo alternativo cuando necesitas la GPU dedicada a una sola VM."
|
||||
},
|
||||
{
|
||||
"label": "Switch GPU Mode (VM ↔ LXC)",
|
||||
"href": "/docs/hardware/switch-gpu-mode",
|
||||
"tail": " — alterna la misma GPU entre compartición LXC y passthrough a VM."
|
||||
},
|
||||
{
|
||||
"label": "Comandos de GPU Passthrough",
|
||||
"href": "/docs/help-info/gpu-commands",
|
||||
"tail": " — referencia rápida para comandos shell relacionados."
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,191 @@
|
||||
{
|
||||
"meta": {
|
||||
"title": "Instalar Coral TPU en el host | ProxMenux Documentation",
|
||||
"description": "Instala los drivers de Google Coral TPU en un host Proxmox VE. ProxMenux autodetecta si tienes M.2 / Mini-PCIe o el USB Accelerator (o ambos) y ejecuta solo la ruta de instalación que aplica — módulos de kernel gasket/apex vía DKMS para PCIe, runtime libedgetpu1-std para USB."
|
||||
},
|
||||
"header": {
|
||||
"title": "Instalar Coral TPU en el host",
|
||||
"description": "Prepara el host Proxmox para que más adelante se pueda pasar una Coral TPU a un contenedor LXC. ProxMenux autodetecta si tienes una tarjeta M.2 / Mini-PCIe, un USB Accelerator, o ambos, y ejecuta solo la ruta de instalación que aplica — build del módulo de kernel vía DKMS para PCIe, runtime Edge TPU de Google para USB.",
|
||||
"section": "Hardware: GPUs y Coral-TPU"
|
||||
},
|
||||
"intro": {
|
||||
"title": "Qué hace esto",
|
||||
"body": "El instalador de Coral es <strong>unificado y consciente del hardware</strong>: ejecutas una opción del menú y averigua qué tienes realmente. Las tarjetas M.2 / Mini-PCIe necesitan módulos de kernel (<code>gasket</code> + <code>apex</code>) construidos con DKMS para que sobrevivan a las actualizaciones de kernel. Los USB Accelerators solo necesitan el runtime Edge TPU de Google (<code>libedgetpu1-std</code>) desde el propio repositorio APT de Google. ¿Ambos tipos enchufados? Ambas rutas se ejecutan en secuencia."
|
||||
},
|
||||
"which": {
|
||||
"heading": "¿Qué Coral tengo?",
|
||||
"body": "Los dos tipos de dispositivos Coral que puedes enchufar en un host Proxmox se ven muy diferentes y la instalación del lado del host también es muy diferente. El script gestiona ambos, pero conviene saber qué tienes antes de ejecutar nada:",
|
||||
"headerForm": "Factor de forma",
|
||||
"headerDetect": "Detección",
|
||||
"headerInstall": "Tipo de instalación",
|
||||
"headerReboot": "¿Reiniciar?",
|
||||
"pcieForm": "M.2 / Mini-PCIe",
|
||||
"pcieFormSub": "(TPU dual-edge en una tarjeta M.2)",
|
||||
"pcieDetect": "PCI vendor <code>1ac1</code>",
|
||||
"pcieInstall": "Módulo de kernel (gasket + apex) vía DKMS",
|
||||
"pcieReboot": "Sí",
|
||||
"usbForm": "USB Accelerator",
|
||||
"usbFormSub": "(pequeño dongle de plástico)",
|
||||
"usbDetect": "USB <code>1a6e:089a</code> (sin programar) / <code>18d1:9302</code> (programado)",
|
||||
"usbInstall": "Runtime userspace (<code>libedgetpu1-std</code>) desde el repo APT de Google",
|
||||
"usbReboot": "No"
|
||||
},
|
||||
"prereqs": {
|
||||
"title": "Antes de empezar",
|
||||
"coral": "<strong>Una Coral TPU enchufada en el host</strong> (M.2, Mini-PCIe o USB). Sin Coral no hay instalación — el script simplemente te dice que no se detectó nada y sale.",
|
||||
"coralCheck": "lspci -d 1ac1: ; lsusb | grep -E '1a6e:089a|18d1:9302'",
|
||||
"internet": "<strong>Acceso a internet</strong> en el host — para PCIe la ruta DKMS clona un repo de GitHub, para USB añade un repo APT de Google y descarga el paquete <code>libedgetpu1-std</code>.",
|
||||
"headers": "<strong>Headers del kernel disponibles vía APT</strong>. En Proxmox esto significa que <code>proxmox-headers-$(uname -r)</code> debe ser instalable — solo necesario para la ruta PCIe/M.2, pero el script lo trae automáticamente para que tú no tengas que hacerlo.",
|
||||
"reboot": "<strong>Asume un reinicio</strong> si tienes hardware PCIe. El módulo de kernel se construye y se carga al final, pero un arranque limpio es la forma limpia de confirmar que sale por sí solo."
|
||||
},
|
||||
"hostPrepTip": {
|
||||
"title": "Esto solo prepara el host",
|
||||
"body": "Instalar Coral aquí deja el host <em>listo</em> — la TPU es visible para el kernel del host y se puede entregar a un LXC. Para <em>usarla</em> realmente desde un contenedor (Frigate, DeepStack, etc.), el siguiente paso es <lxcLink>Añadir Coral TPU a un LXC</lxcLink>."
|
||||
},
|
||||
"running": {
|
||||
"heading": "Ejecutar el instalador",
|
||||
"body": "Abre ProxMenux en el host, ve a <strong>Hardware: GPUs and Coral-TPU → Install/Update Coral TPU on Host</strong>.",
|
||||
"imageAlt": "Entrada del menú 'Install/Update Coral TPU on Host' dentro de Hardware: GPUs and Coral-TPU"
|
||||
},
|
||||
"howRuns": {
|
||||
"heading": "Cómo se ejecuta el script",
|
||||
"body": "El hardware se detecta primero, así que el plan de instalación se adapta a tu setup real. No se instala nada hasta que confirmas."
|
||||
},
|
||||
"walkthrough": {
|
||||
"heading": "Recorriendo el flujo",
|
||||
"detect": {
|
||||
"title": "Detección de hardware",
|
||||
"body": "El script lee <code>/sys/bus/pci/devices/*/vendor</code> buscando <code>0x1ac1</code> (Global Unichip Corp., el fabricante del silicio de los chips Coral TPU) y ejecuta <code>lsusb</code> buscando los IDs del USB Accelerator. El dispositivo USB tiene <strong>dos</strong> IDs según si su firmware ya se ha cargado:",
|
||||
"items": [
|
||||
"<code>1a6e:089a</code> — Global Unichip, estado <em>sin programar</em> (antes de que el runtime Edge TPU le hable por primera vez).",
|
||||
"<code>18d1:9302</code> — Google, estado <em>programado</em> (después de que el runtime le cargue firmware)."
|
||||
],
|
||||
"outro": "Si no se encuentra ninguno, recibes un diálogo informativo y el script sale limpiamente — sin cambios parciales en el host."
|
||||
},
|
||||
"prompt": {
|
||||
"title": "Prompt previo a la instalación",
|
||||
"body": "Antes de tocar nada, un único diálogo resume lo que se detectó y lo que se instalará. Puedes cancelar aquí sin ningún efecto secundario.",
|
||||
"imageAlt": "Diálogo previo a la instalación mostrando el hardware Coral detectado (cuenta de M.2/PCIe + cuenta de USB) y la lista de pasos que ejecutará el instalador"
|
||||
},
|
||||
"pcie": {
|
||||
"title": "Ruta PCIe — módulos de kernel gasket + apex vía DKMS",
|
||||
"body": "Solo se ejecuta si el script encontró una Coral PCIe / M.2. Es la más pesada de las dos rutas porque está compilando un módulo de kernel para tu kernel en ejecución exacto.",
|
||||
"items": [
|
||||
"<strong>Limpieza.</strong> Si una instalación anterior de <code>gasket-dkms</code> dejó dpkg en un estado roto (típico tras una actualización de kernel PVE 9 donde el autoinstall de DKMS falló silenciosamente), force-purge.",
|
||||
"<strong>Instalar dependencias de build:</strong> <code>git</code>, <code>dkms</code>, <code>build-essential</code>, <code>proxmox-headers-$(uname -r)</code>."
|
||||
],
|
||||
"cloneIntro": "<strong>Clonar el código del driver.</strong> Prefiere el fork de la comunidad <feranickLink>feranick/gasket-driver</feranickLink> (mantenimiento activo, listo para kernel 6.12+). Recurre a <googleLink>google/gasket-driver</googleLink> si feranick no es accesible, aplicando parches específicos del kernel:",
|
||||
"kernelPatches": [
|
||||
"Kernel 6.5+ : <code>no_llseek</code> eliminado en upstream → sustitución por <code>noop_llseek</code>",
|
||||
"Kernel 6.13+ : <code>MODULE_IMPORT_NS(DMA_BUF)</code> requiere literal de string"
|
||||
],
|
||||
"afterItems": [
|
||||
"<strong>Stage del código en <code>/usr/src/gasket-1.0/</code>,</strong> generar <code>dkms.conf</code>, registrar con <code>dkms add</code>.",
|
||||
"<strong>Build + install:</strong> <code>dkms build</code> y luego <code>dkms install</code>. Si algo falla, las últimas 50 líneas de <code>make.log</code> se imprimen en el terminal para que veas el error real — sin tener que cazar en archivos de log.",
|
||||
"<strong>Crear el grupo <code>apex</code> + reglas udev</strong> (<code>/etc/udev/rules.d/99-coral-apex.rules</code>) para que los nodos <code>/dev/apex_*</code> tengan el grupo correcto en el siguiente arranque.",
|
||||
"<strong>Cargar los módulos:</strong> <code>modprobe gasket</code> + <code>modprobe apex</code>."
|
||||
],
|
||||
"imageAlt": "Progreso de build DKMS + salida de carga de módulo para los módulos de kernel gasket/apex"
|
||||
},
|
||||
"usb": {
|
||||
"title": "Ruta USB — runtime Edge TPU de Google",
|
||||
"body": "Solo se ejecuta si se detectó un USB Accelerator. Mucho más simple:",
|
||||
"items": [
|
||||
"<strong>Añadir la clave GPG de Google</strong> a <code>/etc/apt/keyrings/coral-edgetpu.gpg</code>.",
|
||||
"<strong>Añadir el repositorio APT</strong> a <code>/etc/apt/sources.list.d/coral-edgetpu.list</code> con <code>signed-by=</code> apuntando al keyring (formato moderno, no deprecado).",
|
||||
"<strong>Instalar <code>libedgetpu1-std</code></strong> — el runtime Edge TPU de rendimiento estándar.",
|
||||
"<strong>Recargar udev</strong> para que las reglas que vienen con el paquete apliquen al dispositivo USB sin tener que desenchufar/reenchufar."
|
||||
],
|
||||
"stdTitle": "¿Por qué libedgetpu1-std y no libedgetpu1-max?",
|
||||
"stdBody": "La variante <code>max</code> overclockea la Coral y calienta más. Está bien para uso de desktop con ventilación; no recomendado en builds NUC / Mini-PC pequeños o hosts Proxmox refrigerados pasivamente. Si realmente la quieres, instálala a mano después: <code>apt install libedgetpu1-max</code>."
|
||||
},
|
||||
"reboot": {
|
||||
"title": "Prompt de reinicio (solo si se ejecutó PCIe)",
|
||||
"body": "Si la ruta PCIe se ejecutó, el script ofrece un reinicio. Los módulos ya se <code>modprobe</code>'aron así que en teoría puedes saltarte el reinicio — pero un arranque limpio es la forma correcta de verificar que el módulo sale por sí solo y que <code>/dev/apex_0</code> aparece con grupo <code>apex</code>. Para instalaciones solo USB, no se sugiere reinicio (el runtime y las reglas udev están activos inmediatamente).",
|
||||
"imageAlt": "Resumen final + prompt de reinicio después de una instalación PCIe"
|
||||
}
|
||||
},
|
||||
"reinstallUninstall": {
|
||||
"heading": "Reinstalar o desinstalar",
|
||||
"intro": "Ejecutar el instalador en un host donde Coral ya está instalada (PCIe vía <code>gasket-dkms</code>, USB vía <code>libedgetpu1-std</code>/<code>libedgetpu1-max</code>, o ambos) ya no cae directamente en otra instalación fresca. En su lugar, ProxMenux detecta el setup existente y muestra un menú de acciones para que decidas qué hacer.",
|
||||
"imageAlt": "Menú de acciones de Coral con dos opciones — Reinstalar / actualizar drivers Coral, o Desinstalar drivers y configuración Coral — mostrado cuando el instalador detecta una instalación previa de Coral en el host",
|
||||
"imageCaption": "El menú de acciones solo aparece cuando al menos un componente de Coral está ya instalado (entrada DKMS de gasket, paquete <code>libedgetpu1-*</code> o nodos de dispositivo <code>/dev/apex_*</code> en vivo).",
|
||||
"reinstallHeading": "Reinstalar / actualizar",
|
||||
"reinstallBody": "Continúa con el flujo normal de instalación — útil después de una actualización de kernel si la rebuild DKMS no ocurrió automáticamente, o para elevar el runtime a un <code>libedgetpu1-*</code> más nuevo del repo apt de Google Coral. Primero se limpia el estado DKMS anterior para que un paquete medio instalado de un intento previo fallido no bloquee el nuevo build.",
|
||||
"uninstallHeading": "Desinstalar — qué se elimina",
|
||||
"uninstallIntro": "Confirma con un diálogo sí/no antes de hacer nada (los contenedores LXC con passthrough de apex perderán acceso a <code>/dev/apex_*</code> después del siguiente reinicio — el aviso lo deja claro). Luego ejecuta un rollback completo e idempotente:",
|
||||
"uninstallItems": [
|
||||
"Descarga los módulos de kernel <code>apex</code> y <code>gasket</code>.",
|
||||
"Quita cada entrada <code>gasket/<version></code> registrada en DKMS para que los módulos no vuelvan en la siguiente instalación de kernel.",
|
||||
"Purga los paquetes apt <code>gasket-dkms</code>, <code>libedgetpu1-std</code> y <code>libedgetpu1-max</code>, luego ejecuta <code>apt-get autoremove --purge</code>.",
|
||||
"Borra la regla udev <code>/etc/udev/rules.d/99-coral-apex.rules</code> que escribió ProxMenux; restaura el grupo de la regla upstream <code>60-gasket-dkms.rules</code> a su default si sigue presente.",
|
||||
"Elimina el grupo de sistema <code>apex</code> <strong>solo si ya no hay usuarios en él</strong> — si mapeaste un usuario custom a <code>apex</code> para un passthrough a LXC, el grupo se deja en su sitio y un aviso imprime los miembros actuales.",
|
||||
"Limpia la entrada del repositorio apt de Google Coral y el keyring (<code>/etc/apt/sources.list.d/coral-edgetpu.list</code> + <code>coral-edgetpu-archive-keyring.gpg</code>).",
|
||||
"Pide reiniciar al final <strong>solo si se instaló la ruta PCIe</strong> — la forma más limpia de descargar los módulos del kernel. Las desinstalaciones solo USB no lo necesitan."
|
||||
],
|
||||
"lxcWarnTitle": "Contenedores LXC con passthrough de apex",
|
||||
"lxcWarnBody": "Desinstalar en el host invalida la ruta de dispositivo mapeada a cualquier contenedor LXC configurado para passthrough de apex. Planifica la operación en una ventana de mantenimiento si Frigate / DeepStack / cargas similares dependen de ello."
|
||||
},
|
||||
"updates": {
|
||||
"heading": "Notificaciones de actualización",
|
||||
"intro": "ProxMenux ahora rastrea los componentes Coral instalados en su registro de instalaciones gestionadas. Ambas variantes se siguen de forma independiente — un host con dispositivos Coral M.2 y USB recibe dos streams de actualización, cada uno con su propia fuente upstream:",
|
||||
"headerVariant": "Variante",
|
||||
"headerTracked": "Versión rastreada",
|
||||
"headerUpstream": "Fuente upstream",
|
||||
"pcieVariant": "PCIe / M.2",
|
||||
"pcieTracked": "Versión Debian de <code>gasket-dkms</code> (o la versión registrada en DKMS si el paquete se quitó a la fuerza)",
|
||||
"pcieUpstream": "Último tag de <code>feranick/gasket-driver</code> en GitHub (caché de 7 días, comparación por número de build)",
|
||||
"usbVariant": "USB",
|
||||
"usbTracked": "Versión apt de <code>libedgetpu1-std</code> o <code>libedgetpu1-max</code>",
|
||||
"usbUpstream": "Candidato local de <code>apt-cache policy</code> (repo apt de Google Coral)",
|
||||
"outro": "Cuando se detecta una versión más nueva el Monitor dispara una notificación <code>coral_driver_update_available</code> en cada canal habilitado (Telegram, Discord, Gotify, ntfy, email, webhook). La notificación apunta de vuelta a la misma entrada del instalador — elige <strong>Reinstall / update</strong> del menú de acciones de arriba para aplicarla.",
|
||||
"antiTitle": "Anti-cascada por diseño",
|
||||
"antiBody": "Una notificación por variante, solo cuando la versión upstream cambia realmente — nunca en cada escaneo de 24h. Si ignoras una actualización no te vuelve a pingar hasta que llegue una release más nueva.",
|
||||
"rebootTitle": "El reinicio solo hace falta para la ruta PCIe",
|
||||
"rebootBody": "La rebuild DKMS de gasket carga nuevos módulos de kernel — eso necesita un reinicio para estar activo. La actualización del runtime USB es un swap de librería userspace, sin reinicio."
|
||||
},
|
||||
"manual": {
|
||||
"heading": "Equivalente manual",
|
||||
"intro": "Si quieres saber qué pasa bajo el capó, o rehacer un paso individual a mano, los comandos crudos por ruta se ven así.",
|
||||
"pcieHeading": "PCIe / M.2 (gasket + apex vía DKMS)",
|
||||
"usbHeading": "USB (runtime libedgetpu)"
|
||||
},
|
||||
"verification": {
|
||||
"heading": "Verificación",
|
||||
"pcieHeading": "PCIe / M.2",
|
||||
"usbHeading": "USB"
|
||||
},
|
||||
"troubleshoot": {
|
||||
"heading": "Solución de problemas",
|
||||
"dkmsFailTitle": "La build DKMS falla después de una actualización de kernel",
|
||||
"dkmsFailBody": "Causa más común en PVE 9: el kernel en ejecución subió pero <code>proxmox-headers-$(uname -r)</code> aún no está instalado para él. Comprueba con <code>dpkg -l proxmox-headers-$(uname -r)</code>. Instala los headers que faltan y vuelve a ejecutar el script — el paso <code>cleanup_broken_gasket_dkms</code> de ProxMenux gestiona cualquier estado residual de paquete medio configurado.",
|
||||
"apexMissTitle": "/dev/apex_0 no está después del reinicio",
|
||||
"apexMissBody": "El módulo no está cargado. Prueba <code>modprobe apex</code> a mano. Si eso da error, comprueba <code>dmesg | grep -iE \"apex|gasket\"</code> para el fallo real — culpables comunes son version mismatch del kernel (DKMS se construyó para un kernel distinto del que arrancaste) o una actualización de firmware que deshabilitó el slot PCIe en el que está la Coral.",
|
||||
"lxcMissTitle": "Puedo ver /dev/apex_0 pero el LXC no",
|
||||
"lxcMissBody": "El host está bien. El problema es la config de passthrough — consulta <lxcLink>Añadir Coral TPU a un LXC</lxcLink>.",
|
||||
"usbUnreachTitle": "USB Accelerator detectado pero Frigate / TFLite no llega a él",
|
||||
"usbUnreachBody": "Comprueba que las reglas udev que vienen con <code>libedgetpu1-std</code> surtieron efecto: <code>ls -l /dev/bus/usb/*/*</code>. El dispositivo NO debería ser propiedad de root:root con modo 0600 — si lo es, ejecuta <code>udevadm control --reload-rules && udevadm trigger</code> en el host, desenchufa la Coral USB, espera 3 segundos y vuelve a enchufarla.",
|
||||
"logTitle": "Log de instalación",
|
||||
"logBody": "Cada ejecución escribe en <code>/tmp/coral_install.log</code> en el host. Si la build DKMS muere, el script también añade las últimas 50 líneas de <code>/var/lib/dkms/gasket/1.0/build/make.log</code> a ese log — adjúntalo cuando pidas ayuda en GitHub."
|
||||
},
|
||||
"related": {
|
||||
"heading": "Relacionado",
|
||||
"items": [
|
||||
{
|
||||
"label": "Añadir Coral TPU a LXC",
|
||||
"href": "/docs/hardware/coral-tpu-lxc",
|
||||
"tail": " — pasar el dispositivo Coral del host a un contenedor (Frigate, CodeProject.AI…)."
|
||||
},
|
||||
{
|
||||
"label": "Instalar drivers NVIDIA (Host)",
|
||||
"href": "/docs/hardware/nvidia-host",
|
||||
"tail": " — la misma idea para GPUs NVIDIA."
|
||||
},
|
||||
{
|
||||
"label": "ProxMenux Monitor — pestaña Hardware",
|
||||
"href": "/docs/monitor/dashboard/hardware",
|
||||
"tail": " — el modal de Coral que muestra driver, módulos, nodos de dispositivo, estado del runtime y temperatura en vivo una vez hecha la instalación en el host."
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,204 @@
|
||||
{
|
||||
"meta": {
|
||||
"title": "Instalar drivers NVIDIA en el host | ProxMenux Documentation",
|
||||
"description": "Instala y configura los drivers propietarios NVIDIA en un host Proxmox VE usando ProxMenux. Cubre compatibilidad de kernel, setup VFIO, servicio de persistencia, parche NVENC opcional y propagación automática a LXCs."
|
||||
},
|
||||
"header": {
|
||||
"title": "Instalar drivers NVIDIA en el host",
|
||||
"description": "Instala el driver propietario NVIDIA en un host Proxmox VE usando ProxMenux. El instalador gestiona la compatibilidad de kernel, el blacklisting de nouveau, la configuración VFIO, el servicio de persistencia y puede propagar el driver a cualquier contenedor LXC que ya tenga passthrough NVIDIA configurado.",
|
||||
"section": "Hardware: GPUs y Coral-TPU"
|
||||
},
|
||||
"intro": {
|
||||
"title": "Qué hace esto",
|
||||
"body": "ProxMenux automatiza todo el ciclo de vida del driver NVIDIA en el host: detecta tu GPU, elige una versión de driver compatible con tu kernel en ejecución, pone <code>nouveau</code> en blacklist, descarga y ejecuta el instalador oficial <code>.run</code> de NVIDIA con DKMS, instala el servicio <code>nvidia-persistenced</code> y las reglas udev, y se ofrece a aplicar el parche NVENC opcional. Si ya tienes contenedores LXC con passthrough NVIDIA, puede actualizar las librerías userspace dentro de ellos para que su versión coincida con la del host."
|
||||
},
|
||||
"who": {
|
||||
"heading": "¿Para quién es esto?",
|
||||
"body": "Si tienes una GPU NVIDIA y quieres usarla para transcoding acelerado por hardware en Plex, Jellyfin, Frigate, Immich, Stable Diffusion o cualquier otra app corriendo <strong>dentro de un contenedor LXC</strong>, necesitas instalar el driver en el <em>host</em> Proxmox primero. Esta página cubre esa instalación en el lado del host. Pasar la GPU a una <strong>máquina virtual (VM)</strong> usa un flujo distinto (passthrough VFIO) y se documenta aparte."
|
||||
},
|
||||
"prereqs": {
|
||||
"title": "Antes de empezar",
|
||||
"gpu": "<strong>Una GPU NVIDIA</strong> instalada físicamente en el host. El script la autodetecta; las GPUs AMD e Intel no se gestionan aquí.",
|
||||
"gpuCheck": "lspci | grep -i nvidia",
|
||||
"notVm": "La GPU <strong>no está asignada actualmente a una VM vía passthrough VFIO</strong>. Si lo está, el script se negará a instalar el driver del host para evitar romper la config de passthrough.",
|
||||
"internet": "Acceso a internet en el host. El instalador descarga el driver desde <code>download.nvidia.com</code> y, opcionalmente, clona <code>nvidia-persistenced</code> y <code>nvidia-patch</code> desde GitHub.",
|
||||
"space": "Unos <strong>2 GB de espacio libre</strong> en <code>/opt/nvidia</code> (workdir) más la RAM usada durante la instalación. Se necesita reiniciar al final."
|
||||
},
|
||||
"vmWarn": {
|
||||
"title": "¿GPU asignada a una VM? Para aquí",
|
||||
"body": "Si la GPU está actualmente vinculada a <code>vfio-pci</code> (es decir, se está pasando a una VM), instalar el driver del host puede romper el passthrough y desestabilizar el sistema. ProxMenux detecta esto y aborta. Quita la GPU de la configuración de passthrough de la VM y reinicia antes de ejecutar este script."
|
||||
},
|
||||
"running": {
|
||||
"heading": "Ejecutar el instalador",
|
||||
"body": "Abre ProxMenux en el host, ve a <strong>Hardware Graphics → NVIDIA GPU Driver Installer</strong>. Lo que verás depende de si ya hay un driver presente.",
|
||||
"imageAlt": "Menú Hardware Graphics con la entrada NVIDIA GPU Driver Installer resaltada"
|
||||
},
|
||||
"howRuns": {
|
||||
"heading": "Cómo se ejecuta el script",
|
||||
"body": "El instalador pasa por tres fases con separación clara entre \"recopilar información y validar\" y \"tocar realmente el host\". Hasta la confirmación final, no se ha cambiado nada."
|
||||
},
|
||||
"walkthrough": {
|
||||
"detect": {
|
||||
"title": "Detección de GPU y resumen",
|
||||
"body1": "El script escanea el bus PCI y muestra cada controladora de vídeo NVIDIA que encuentra, el estado actual del driver (o <em>\"No NVIDIA driver installed\"</em>) y cualquier contenedor LXC que ya tenga passthrough NVIDIA configurado (versión del driver dentro de cada uno).",
|
||||
"body2": "Revisa el resumen cuidadosamente. Si la GPU detectada no es la que esperas, o si la versión de un contenedor ya coincide con la del host, puedes cancelar aquí sin efectos secundarios.",
|
||||
"imageAlt": "Resumen previo a la instalación mostrando las GPUs detectadas, el estado actual del driver y los contenedores LXC con passthrough NVIDIA"
|
||||
},
|
||||
"version": {
|
||||
"title": "Elegir la versión del driver",
|
||||
"body1": "ProxMenux obtiene la lista de drivers disponibles de NVIDIA y <strong>filtra las versiones que no son compatibles con tu kernel en ejecución</strong>. La opción <em>Latest available</em> es casi siempre la elección correcta.",
|
||||
"body2": "La matriz de compatibilidad que usa el script:",
|
||||
"headerKernel": "Kernel",
|
||||
"headerPve": "Versión típica de PVE",
|
||||
"headerMin": "Driver NVIDIA mínimo",
|
||||
"rows": [
|
||||
{
|
||||
"kernel": "6.17+",
|
||||
"pve": "Proxmox VE 9.x",
|
||||
"minCode": "580.82.07",
|
||||
"minTail": " o más nuevo"
|
||||
},
|
||||
{
|
||||
"kernel": "6.8 – 6.16",
|
||||
"pve": "Proxmox VE 8.2+",
|
||||
"minCode": "550.x",
|
||||
"minTail": " o más nuevo"
|
||||
},
|
||||
{
|
||||
"kernel": "6.2 – 6.7",
|
||||
"pve": "Proxmox VE 8.0 – 8.1",
|
||||
"minCode": "535.x",
|
||||
"minTail": " o más nuevo"
|
||||
},
|
||||
{
|
||||
"kernel": "5.15+",
|
||||
"pve": "Proxmox VE 7.x (legacy)",
|
||||
"minCode": "470.x",
|
||||
"minTail": " o más nuevo"
|
||||
}
|
||||
],
|
||||
"whyTitle": "Por qué importa el kernel",
|
||||
"whyBody": "El kernel 6.17 introdujo cambios en la API interna que rompen los drivers NVIDIA más viejos. Si instalas un driver por debajo del mínimo de tu kernel, DKMS no podrá construir el módulo y la GPU no estará disponible después de reiniciar. ProxMenux filtra la lista para que no puedas elegir una versión incompatible por accidente.",
|
||||
"imageAlt": "Selector de versión del driver con las versiones compatibles con el kernel, Latest available arriba"
|
||||
},
|
||||
"uninstall": {
|
||||
"title": "Desinstalación limpia (solo si reinstalas)",
|
||||
"body": "Si ya hay un driver presente y elegiste una versión distinta, ProxMenux para los servicios NVIDIA, descarga los módulos de kernel, quita las entradas DKMS y purga los paquetes <code>nvidia-*</code> / <code>libnvidia-*</code> / <code>cuda-*</code> antes de tocar el nuevo instalador. Esto evita el clásico desastre de versiones mezcladas."
|
||||
},
|
||||
"prepare": {
|
||||
"title": "Preparar el sistema",
|
||||
"body": "Tras una única confirmación, el script:",
|
||||
"items": [
|
||||
"Instala <code>pve-headers-$(uname -r)</code> (o <code>proxmox-headers-$(uname -r)</code>), <code>build-essential</code> y <code>dkms</code>.",
|
||||
"Crea <code>/etc/modprobe.d/nouveau-blacklist.conf</code> poniendo <code>nouveau</code> en blacklist e intenta descargarlo inmediatamente.",
|
||||
"Escribe <code>/etc/modules-load.d/nvidia-vfio.conf</code> con <code>vfio</code>, <code>vfio_pci</code>, <code>nvidia</code>, <code>nvidia_uvm</code> y módulos relacionados."
|
||||
]
|
||||
},
|
||||
"download": {
|
||||
"title": "Descargar y ejecutar el instalador NVIDIA",
|
||||
"body": "El instalador descarga el archivo <code>NVIDIA-Linux-x86_64-<version>.run</code> en <code>/opt/nvidia</code>, lo valida (tamaño + firma de ejecutable, no solo HTTP 200), y luego lo ejecuta con DKMS para que el módulo de kernel se reconstruya automáticamente con las actualizaciones de kernel.",
|
||||
"imageAlt": "Progreso de descarga seguido del instalador NVIDIA ejecutando su build DKMS"
|
||||
},
|
||||
"persist": {
|
||||
"title": "Servicio de persistencia y reglas udev",
|
||||
"body": "ProxMenux luego instala <persistLink>nvidia-persistenced</persistLink> y escribe reglas udev en <code>/etc/udev/rules.d/70-nvidia.rules</code> para que los nodos de dispositivo <code>/dev/nvidia*</code> aparezcan de forma fiable en el arranque. Sin esto, el passthrough LXC puede tener carreras al arranque del contenedor y acabar con un contenedor que no ve la GPU."
|
||||
},
|
||||
"nvenc": {
|
||||
"title": "Opcional: aplicar el parche NVENC",
|
||||
"body": "Las GPUs NVIDIA de consumo (línea GeForce) limitan el número de sesiones simultáneas de codificación NVENC. El <patchLink>keylase/nvidia-patch</patchLink> de la comunidad elimina esa restricción. Si planeas usar la GPU para Plex / Jellyfin / Frigate con muchos streams concurrentes, responde <strong>Sí</strong> cuando se pregunte.",
|
||||
"supportTitle": "Comprueba el soporte del parche para tu driver",
|
||||
"supportBody": "El parche no cubre todas las versiones de driver. Antes de depender de él en producción, verifica que tu versión esté listada en la <patchTableLink>tabla de parches</patchTableLink>. Si aún no está soportada, elige un driver cercano más antiguo que sí lo esté."
|
||||
},
|
||||
"propagate": {
|
||||
"title": "Opcional: propagar el driver a los contenedores LXC",
|
||||
"body1": "Si la pantalla de resumen listó contenedores con passthrough NVIDIA, ProxMenux ahora se ofrece a actualizar las librerías userspace dentro de cada uno para que coincidan con el host. El módulo de kernel del host y el userspace del contenedor <strong>deben ser exactamente la misma versión</strong> — si no <code>nvidia-smi</code> dentro del contenedor fallará con un error \"version mismatch\".",
|
||||
"body2": "La actualización es consciente de la distro: <code>apk</code> para Alpine, <code>pacman</code> para Arch y el mismo instalador <code>.run</code> (con <code>--no-kernel-modules --no-dkms --no-install-compat32-libs</code>) para Debian/Ubuntu y otras distros. Eleva temporalmente la RAM del contenedor a 2 GB si es menor, ejecuta la instalación y luego restaura la RAM original.",
|
||||
"imageAlt": "Prompt listando los LXCs con passthrough NVIDIA y la versión actual del driver, con Sí/No para actualizarlos todos"
|
||||
},
|
||||
"reboot": {
|
||||
"title": "Reiniciar",
|
||||
"body": "Finalmente, el script reconstruye <code>initramfs</code> para todos los kernels y ofrece reiniciar. Reiniciar <strong>es obligatorio</strong>: el blacklist de nouveau y el nuevo módulo de kernel solo surten efecto tras el reinicio."
|
||||
}
|
||||
},
|
||||
"reinstallUninstall": {
|
||||
"heading": "Reinstalar o desinstalar",
|
||||
"intro": "Cuando el instalador detecta que ya hay un driver NVIDIA cargado (<code>nvidia-smi</code> devuelve una versión), no reinstala silenciosamente encima. En lugar de eso muestra un menú de acciones para que elijas qué hacer.",
|
||||
"imageAlt": "Menú de acciones NVIDIA ofrecido cuando ya hay un driver instalado — dos opciones: Reinstalar / actualizar driver, o Desinstalar el driver NVIDIA completamente",
|
||||
"imageCaption": "El menú de acciones solo aparece cuando hay un driver NVIDIA activo actualmente en el host.",
|
||||
"reinstallHeading": "Reinstalar / actualizar",
|
||||
"reinstallBody": "Continúa con el flujo normal de instalación pero, antes de descargar nada, ejecuta una eliminación limpia del driver actual (apt purge + entradas DKMS quitadas + módulos residuales descargados). Esta es la ruta segura para aplicar una versión más nueva del driver, cambiar de rama cuando el kernel lo exige o recuperarte de un estado medio roto. Los prompts de propagación LXC y parche NVENC se vuelven a ejecutar al final.",
|
||||
"uninstallHeading": "Desinstalar — qué se elimina",
|
||||
"uninstallIntro": "Confirma primero con un diálogo sí/no. Luego ejecuta un rollback completo e idempotente:",
|
||||
"uninstallItems": [
|
||||
"Para y deshabilita <code>nvidia-persistenced</code>, descarga los módulos de kernel (<code>nvidia_uvm</code>, <code>nvidia_drm</code>, <code>nvidia_modeset</code>, <code>nvidia</code>) — cualquier contenedor LXC con passthrough NVIDIA será cortado limpiamente.",
|
||||
"Ejecuta <code>apt purge</code> sobre cada paquete NVIDIA, quita el árbol fuente DKMS y la caché del instalador .run de <code>/opt/nvidia</code>.",
|
||||
"Revierte el blacklist de nouveau (<code>/etc/modprobe.d/nouveau-blacklist.conf</code>) y la config de modules-load (<code>/etc/modules-load.d/nvidia-vfio.conf</code>) para que nouveau pueda volver si quieres gráficos genéricos otra vez.",
|
||||
"Quita las reglas udev (<code>/etc/udev/rules.d/70-nvidia.rules</code>) y el archivo de estado del parche NVENC (si el parche keylase se aplicó antes).",
|
||||
"Reconstruye <code>initramfs</code> para todos los kernels y pide reiniciar para finalizar (el desblacklisting de nouveau solo surte efecto tras reiniciar)."
|
||||
],
|
||||
"lxcWarnTitle": "Contenedores LXC con passthrough NVIDIA",
|
||||
"lxcWarnBody": "Quitar el driver del host invalida las rutas de dispositivo y las librerías CUDA mapeadas a cualquier LXC con passthrough NVIDIA. Planifica la operación en una ventana de mantenimiento si Frigate / Plex / Jellyfin / Ollama (o cualquier otra cosa) depende de ello."
|
||||
},
|
||||
"updates": {
|
||||
"heading": "Notificaciones de actualización",
|
||||
"body": "El driver NVIDIA instalado se rastrea en el registro de instalaciones gestionadas de ProxMenux. En el arranque y cada 24h el Monitor comprueba el listado upstream en <code>download.nvidia.com/XFree86/Linux-x86_64/</code> contra la versión que reporta <code>nvidia-smi</code>, y dispara una notificación cuando hay una nueva versión compatible disponible.",
|
||||
"kindsHeading": "Dos tipos de mensaje de actualización",
|
||||
"kindsItems": [
|
||||
"<strong>Parche de la misma rama.</strong> Una release de mantenimiento más nueva en tu rama actual de driver (p. ej. instalado 580.65.06 → disponible 580.105.08). Bug fixes y parches de seguridad sin cambiar de rama.",
|
||||
"<strong>Subida de rama requerida por el kernel.</strong> Si el host está en un kernel que ya no soporta tu rama actual (p. ej. subiste el kernel del host a 6.17 mientras seguías en el driver 570.x), el mensaje lo dice explícitamente y recomienda la rama mínima compatible con el kernel — la misma matriz que usa el instalador para filtrar el menú de versión."
|
||||
],
|
||||
"antiTitle": "Anti-cascada por diseño",
|
||||
"antiBody": "Una notificación por versión upstream distinta, nunca en cada escaneo de 24h. El mensaje de subida de rama en particular solo se dispara cuando realmente necesitas cambiar — hasta entonces el tracker de la misma rama se queda silenciado.",
|
||||
"applyTitle": "Aplicar la actualización",
|
||||
"applyBody": "El Monitor no autoaplica actualizaciones de driver — reinstalar el driver NVIDIA siempre necesita un reinicio. Abre la misma entrada del instalador descrita arriba, elige <strong>Reinstall / update</strong> y la nueva versión se descarga, el módulo DKMS se reconstruye contra el kernel en ejecución y se pide el reinicio al final."
|
||||
},
|
||||
"verify": {
|
||||
"heading": "Verificar la instalación",
|
||||
"intro": "Una vez el host esté arriba de nuevo, entra por SSH o por la shell de Proxmox y ejecuta:",
|
||||
"after": "Deberías ver tu GPU listada, la versión del driver en el borde superior y ningún proceso aún (nada está usando la GPU en este punto). Luego comprueba el servicio de persistencia:",
|
||||
"imageAlt": "Salida de nvidia-smi en el host mostrando la GPU detectada y la versión del driver instalada"
|
||||
},
|
||||
"troubleshoot": {
|
||||
"heading": "Solución de problemas",
|
||||
"smiFailTitle": "`nvidia-smi` dice 'NVIDIA-SMI has failed'",
|
||||
"smiFailBody": "Casi siempre es <strong>nouveau</strong> aún cargado o un <strong>mismatch de headers del kernel</strong>. Tras reiniciar, ejecuta <code>lsmod | grep nouveau</code> — si devuelve algo, el blacklist no surtió efecto (comprueba que <code>/etc/modprobe.d/nouveau-blacklist.conf</code> existe y reconstruye initramfs con <code>update-initramfs -u -k all</code>, luego reinicia). Si nouveau no está, comprueba <code>dmesg | grep -i nvidia</code> — los errores de build DKMS suelen significar que tus headers de kernel no coinciden con el kernel en ejecución; reinstálalos con <code>apt install --reinstall pve-headers-$(uname -r)</code>.",
|
||||
"lxcMissTitle": "El contenedor LXC no ve la GPU tras actualizar el host",
|
||||
"lxcMissBody": "Las librerías userspace del contenedor están atascadas en la versión anterior del driver. O vuelves a ejecutar el instalador NVIDIA y aceptas el prompt de propagación LXC, o instalas la misma versión del driver manualmente dentro del contenedor con <code>--no-kernel-modules</code>.",
|
||||
"logTitle": "Revisa el log de instalación",
|
||||
"logBody": "Cada instalación escribe en <code>/tmp/nvidia_install.log</code>. Si algo falla silenciosamente, ese archivo tiene la salida completa (descargas, build DKMS, instalaciones de servicio). Adjúntalo cuando reportes issues en GitHub."
|
||||
},
|
||||
"manualSteps": {
|
||||
"heading": "¿Buscas los pasos manuales?",
|
||||
"body": "La guía original de la comunidad — instalar todo a mano con <code>wget</code> y <code>./NVIDIA-Linux-...run</code> — sigue disponible como referencia en <guideLink>Guides → NVIDIA</guideLink>. Es útil si quieres entender cada comando que ejecuta el instalador de ProxMenux, o si estás depurando un setup inusual. Para instalaciones del día a día, usa ProxMenux — es la ruta que sigue recibiendo fixes (compatibilidad de kernel, propagación a LXC, comprobaciones de seguridad VFIO)."
|
||||
},
|
||||
"related": {
|
||||
"heading": "Relacionado",
|
||||
"items": [
|
||||
{
|
||||
"label": "Añadir GPU a VM (Passthrough)",
|
||||
"href": "/docs/hardware/gpu-vm-passthrough",
|
||||
"tail": " — pasar la GPU NVIDIA a una VM (modelo de binding distinto al de LXC)."
|
||||
},
|
||||
{
|
||||
"label": "Añadir GPU a LXC",
|
||||
"href": "/docs/hardware/igpu-acceleration-lxc",
|
||||
"tail": " — compartir la GPU NVIDIA con uno o más contenedores."
|
||||
},
|
||||
{
|
||||
"label": "Switch GPU Mode (VM ↔ LXC)",
|
||||
"href": "/docs/hardware/switch-gpu-mode",
|
||||
"tail": " — alternar la misma GPU entre modos passthrough (VM) y compartido (LXC)."
|
||||
},
|
||||
{
|
||||
"label": "ProxMenux Monitor — pestaña Hardware",
|
||||
"href": "/docs/monitor/dashboard/hardware",
|
||||
"tail": " — el modal de GPU que dispara este instalador en un click, más monitorización en vivo una vez hecho."
|
||||
},
|
||||
{
|
||||
"label": "Comandos de GPU Passthrough",
|
||||
"href": "/docs/help-info/gpu-commands",
|
||||
"tail": " — referencia de lspci / dmesg / IOMMU / nvidia-smi."
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,172 @@
|
||||
{
|
||||
"meta": {
|
||||
"title": "Switch GPU Mode (VM ↔ LXC) | ProxMenux Documentation",
|
||||
"description": "Mueve una GPU ya asignada entre modo VM (vfio-pci) y modo LXC (driver nativo) en un host Proxmox. ProxMenux detecta el binding actual, pide políticas de conflicto por workload, gestiona la limpieza de audio huérfano y reconstruye initramfs solo cuando hace falta."
|
||||
},
|
||||
"header": {
|
||||
"title": "Switch GPU Mode (VM ↔ LXC)",
|
||||
"description": "Reasigna una GPU que ya está en uso — cambia de passthrough a VM a compartición con LXC o al revés. ProxMenux gestiona todos los cambios de binding del lado del host (vfio.conf, blacklist de drivers, módulos, initramfs) y ofrece una política limpia para cada VM o LXC que use la GPU actualmente, para que el cambio no deje config rota detrás.",
|
||||
"section": "Hardware: GPUs y Coral-TPU"
|
||||
},
|
||||
"intro": {
|
||||
"title": "Qué hace esto",
|
||||
"body": "Una GPU en un host Proxmox vive en uno de dos modos: vinculada a <code>vfio-pci</code> (reservada para una VM) o vinculada a su driver nativo <em>(i915 / amdgpu / nvidia)</em> para que el host + los LXCs puedan compartirla. <strong>Switch GPU Mode</strong> alterna entre esos dos sin que tengas que editar <code>vfio.conf</code> a mano, gestionar blacklists o recordar qué líneas de VM / LXC apuntan a la tarjeta. También te avisa limpiamente si un workload aún referencia la GPU para que no acabes con una VM rota en el arranque."
|
||||
},
|
||||
"graphics": {
|
||||
"lxcTitle": "Listo para contenedores LXC",
|
||||
"lxcDesc": "Driver nativo activo",
|
||||
"vmTitle": "Listo para passthrough a VM",
|
||||
"vmDesc": "Driver VFIO-PCI activo"
|
||||
},
|
||||
"when": {
|
||||
"heading": "¿Cuándo debería usar esto?",
|
||||
"intro": "Usa este script cuando una GPU está <strong>ya asignada</strong> y quieres moverla:",
|
||||
"headerSituation": "Situación",
|
||||
"headerUse": "¿Usar esta página?",
|
||||
"rows": [
|
||||
{
|
||||
"situation": "La GPU está libre — nunca asignada. Quieres dársela a una VM.",
|
||||
"useRich": "No — usa <vmLink>Añadir GPU a VM</vmLink>"
|
||||
},
|
||||
{
|
||||
"situation": "La GPU está libre — nunca asignada. Quieres dársela a un LXC.",
|
||||
"useRich": "No — usa <lxcLink>Añadir GPU a LXC</lxcLink>"
|
||||
},
|
||||
{
|
||||
"situationRich": "La GPU está en una VM vía <code>vfio-pci</code>, quiero usarla desde un LXC en su lugar.",
|
||||
"useRich": "<strong>Sí — esta página.</strong>"
|
||||
},
|
||||
{
|
||||
"situation": "La GPU está compartida con un LXC, quiero dedicarla a una VM.",
|
||||
"useRich": "<strong>Sí — esta página.</strong>"
|
||||
},
|
||||
{
|
||||
"situation": "Solo quiero desvincular completamente una GPU de todo.",
|
||||
"use": "Sí — elige el destino LXC y luego desadjunta manualmente."
|
||||
}
|
||||
]
|
||||
},
|
||||
"prereqs": {
|
||||
"title": "Antes de empezar",
|
||||
"assigned": "<strong>Una GPU ya asignada</strong> — o bien en una VM vía VFIO o adjuntada al menos a un LXC. Si aún no la has asignado, empieza desde Añadir GPU a VM / LXC en su lugar.",
|
||||
"iommu": "<strong>IOMMU habilitado en el host</strong> — solo estrictamente necesario al cambiar <em>a</em> modo VM, pero vale la pena tenerlo en cualquier caso. El script avisa si falta el parámetro del kernel.",
|
||||
"iommuCheck": "dmesg | grep -i 'IOMMU enabled' | head -1",
|
||||
"reboot": "<strong>Asume un reinicio.</strong> Cambiar bindings de GPU a nivel de kernel significa que el host regenera initramfs y reinicias para aplicar. El script lo pide al final.",
|
||||
"knowList": "<strong>Saber qué VMs / LXCs están usando la GPU.</strong> El script las encontrará y preguntará qué hacer con cada una, pero es más rápido si ya conoces la lista."
|
||||
},
|
||||
"blocklist": {
|
||||
"title": "No todas las GPUs son seguras para pasar a una VM",
|
||||
"body": "Una pequeña blocklist de IDs de GPU se rechaza para modo VM por inestabilidad conocida de passthrough (p. ej. Intel Arc A770 <code>8086:5a84</code> / <code>8086:5a85</code>). Si la GPU seleccionada coincide, el script explica por qué y sale. Cambiar <em>a</em> modo LXC siempre se permite."
|
||||
},
|
||||
"running": {
|
||||
"heading": "Ejecutar el script",
|
||||
"body": "Abre ProxMenux en el host, ve a <strong>Hardware: GPUs and Coral-TPU → Switch GPU Mode (VM ↔ LXC)</strong>.",
|
||||
"imageAlt": "Entrada del menú 'Switch GPU Mode (VM ↔ LXC)' dentro de Hardware: GPUs and Coral-TPU"
|
||||
},
|
||||
"howRuns": {
|
||||
"heading": "Cómo se ejecuta el script",
|
||||
"body": "Dos fases como siempre: todo se recopila y valida primero, no se aplica nada hasta que confirmas al final."
|
||||
},
|
||||
"walkthrough": {
|
||||
"heading": "Recorriendo el flujo",
|
||||
"detect": {
|
||||
"title": "Detectar las GPUs y su binding actual",
|
||||
"body": "El script escanea cada controladora VGA / 3D / Display del host e inspecciona <code>/sys/bus/pci/devices/*/driver</code> para encontrar el driver de kernel actual. Verás cada GPU etiquetada con su nombre, slot PCI y binding de driver actual — así puedes ver de un vistazo en qué modo está.",
|
||||
"imageAlt": "Checklist de GPU mostrando cada GPU detectada con su driver actual (vfio-pci / nvidia / amdgpu / i915) y slot PCI"
|
||||
},
|
||||
"pickGpu": {
|
||||
"title": "Elegir la(s) GPU(s) a cambiar",
|
||||
"body": "Una GPU → autoseleccionada. Varias GPUs → checklist. Puedes marcar varias, pero todas deben estar en el <em>mismo</em> modo actual — si no el script no puede elegir un modo destino para el batch y recibes un aviso de \"modo mixto\" pidiéndote que reduzcas la selección.",
|
||||
"tipTitle": "Cambios en batch",
|
||||
"tipBody": "Útil cuando estás reconstruyendo un host: \"Las tres NVIDIA van a modo VM, luego la iGPU vuelve a LXC.\" Dos ejecuciones, cada una con destino uniforme, mucha menos fricción que una a una."
|
||||
},
|
||||
"direction": {
|
||||
"title": "Revisar la dirección propuesta",
|
||||
"intro": "Según el modo actual, el script propone el opuesto como destino:",
|
||||
"items": [
|
||||
"<strong>VM → LXC:</strong> desvincular de <code>vfio-pci</code>, dejar que el driver nativo (<code>nvidia</code>, <code>amdgpu</code>, <code>i915</code>) reclame la tarjeta para que los LXCs puedan compartirla. En NVIDIA, la entrada por BDF se quita de <code>/etc/udev/rules.d/10-proxmenux-vfio-bind.rules</code> para que el módulo nvidia reclame la GPU tras reiniciar.",
|
||||
"<strong>LXC → VM:</strong> vincular a <code>vfio-pci</code> para que la tarjeta esté libre para passthrough VFIO a una sola VM. En AMD / Intel esto significa poner el driver nativo en blacklist y definir <code>options vfio-pci ids=…</code>. En NVIDIA el módulo <code>nvidia</code> <strong>no</strong> se pone en blacklist — en su lugar una regla udev por BDF aplica <code>driver_override=vfio-pci</code> solo a las GPUs que selecciones, para que otras GPUs NVIDIA del host mantengan su driver <code>nvidia</code>."
|
||||
],
|
||||
"outro": "Confirma la dirección o cancela."
|
||||
},
|
||||
"conflict": {
|
||||
"title": "Política de conflicto por workload afectado",
|
||||
"body": "El script escanea cada <code>/etc/pve/lxc/*.conf</code> y <code>/etc/pve/qemu-server/*.conf</code> buscando referencias al slot PCI de la GPU. Por cada workload afectado eliges una política:",
|
||||
"headerPolicy": "Política",
|
||||
"headerEffect": "Efecto",
|
||||
"headerWhen": "Cuándo elegirla",
|
||||
"keepPolicy": "Mantener config, deshabilitar onboot",
|
||||
"keepEffect": "<code>pct set -onboot 0</code> (o <code>qm set</code>). Las líneas de GPU se quedan en la config.",
|
||||
"keepWhen": "Planeas volver a esta VM/LXC una vez la GPU esté de vuelta en su modo original. Default seguro.",
|
||||
"removePolicy": "Quitar GPU de la config",
|
||||
"removeEffect": "Las líneas <code>hostpci</code> / <code>dev</code> del slot de esta GPU se quitan con sed.",
|
||||
"removeWhen": "La VM/LXC seguirá funcionando sin la GPU (transcoding solo por CPU, etc.). Workflow limpio.",
|
||||
"imageAlt": "Diálogo preguntando la política de conflicto por VM / por LXC al cambiar una GPU que está actualmente asignada"
|
||||
},
|
||||
"audio": {
|
||||
"title": "Limpieza de audio huérfano (solo al salir del modo VM)",
|
||||
"body1": "Las dGPUs (NVIDIA / AMD) traen una función de audio HDMI en <code>.1</code> del mismo slot, y a veces se adjuntan controladores de audio extra junto a la GPU. Cuando la GPU deja la VM, esas líneas de audio quedan huérfanas — la VM tiene entradas <code>hostpci</code> apuntando a dispositivos de audio que no van con la GPU.",
|
||||
"body2": "El script las descubre (match BDF preciso, sin falsos positivos por substring) y muestra una checklist para que puedas quitarlas limpiamente. También limpia sus IDs vendor:device de <code>/etc/modprobe.d/vfio.conf</code> — pero solo si ninguna otra VM sigue usando esos IDs de audio."
|
||||
},
|
||||
"apply": {
|
||||
"title": "Aplicar cambios del host + workloads",
|
||||
"body": "Una vez confirmas, el script escribe los cambios del lado del host — <code>vfio.conf</code>, blacklist, módulos y (para NVIDIA) la regla udev por BDF en <code>/etc/udev/rules.d/10-proxmenux-vfio-bind.rules</code> más el estado BDF en <code>/etc/proxmenux/vfio-bind.bdfs</code>. También aplica la política de conflicto elegida a cada VM/LXC afectada. Si la config del host realmente cambió, ejecuta <code>update-initramfs -u -k all</code> — si no, salta ese paso."
|
||||
},
|
||||
"reboot": {
|
||||
"title": "Reiniciar",
|
||||
"body": "El nuevo binding de GPU solo surte efecto tras reiniciar. El script te lo pide; puedes reiniciar ahora o luego, pero no arranques la VM/LXC destino hasta que el host haya reiniciado — si no la GPU sigue retenida por el driver anterior.",
|
||||
"imageAlt": "Diálogo de resumen listando qué cambió, seguido del prompt de reinicio"
|
||||
}
|
||||
},
|
||||
"manual": {
|
||||
"heading": "Equivalente manual",
|
||||
"intro": "Si quieres entender exactamente qué hace el script (o depurar uno de los pasos a mano), estas son las operaciones crudas para <strong>VM → LXC</strong> en una tarjeta NVIDIA con vendor:device <code>10de:2204</code>:",
|
||||
"lxcToVm": "Y para <strong>LXC → VM</strong>:",
|
||||
"oneVmTitle": "Solo una VM puede usar una GPU vfio-pci dada a la vez",
|
||||
"oneVmBody": "Poner varias entradas <code>hostpci</code> con el mismo slot PCI en dos VMs es config válida pero solo una de las VMs puede arrancar con la GPU — la segunda fallará. El paso de política de conflicto de ProxMenux trata exactamente de evitar esta trampa."
|
||||
},
|
||||
"verification": {
|
||||
"heading": "Verificación tras el reinicio"
|
||||
},
|
||||
"troubleshoot": {
|
||||
"heading": "Solución de problemas",
|
||||
"stillVfioTitle": "La GPU sigue mostrando vfio-pci tras cambiar a modo LXC",
|
||||
"stillVfioBody": "<code>update-initramfs</code> no se ejecutó (o el reinicio no llegó a pasar realmente). Comprueba <code>lsmod | grep vfio</code> — si vfio-pci está cargado, vuelve a ejecutar <code>update-initramfs -u -k all</code> y reinicia. Para AMD/Intel: verifica que <code>vfio.conf</code> ya no contiene el ID vendor:device de la GPU. Para NVIDIA: verifica que el BDF ya no está en <code>/etc/proxmenux/vfio-bind.bdfs</code> y que <code>/etc/udev/rules.d/10-proxmenux-vfio-bind.rules</code> no lo lista.",
|
||||
"vmFailTitle": "Una VM no arranca tras cambiar una GPU a modo LXC",
|
||||
"vmFailBody": "La VM aún tiene entradas <code>hostpci</code> apuntando a una GPU que no puede reclamar. Vuelve a ejecutar el script y elige la política <em>Quitar GPU de la config</em>, o limpia la config a mano:",
|
||||
"smiFailTitle": "nvidia-smi falla con 'Driver/library version mismatch' tras volver a LXC",
|
||||
"smiFailBody": "Los módulos NVIDIA del host no se recargaron limpiamente. <code>modprobe -r nvidia</code> y luego <code>modprobe nvidia</code>. Si eso falla, reinicia — un reinicio completo siempre limpia el estado residual del binding vfio.",
|
||||
"logTitle": "Log de instalación",
|
||||
"logBody": "Cada ejecución escribe en <code>/tmp/proxmenux_gpu_switch_mode.log</code> en el host. Adjúntalo cuando pidas ayuda en GitHub."
|
||||
},
|
||||
"related": {
|
||||
"heading": "Relacionado",
|
||||
"items": [
|
||||
{
|
||||
"label": "Añadir GPU a VM (Passthrough)",
|
||||
"href": "/docs/hardware/gpu-vm-passthrough",
|
||||
"tail": " — setup inicial del modo VM."
|
||||
},
|
||||
{
|
||||
"label": "Añadir GPU a LXC",
|
||||
"href": "/docs/hardware/igpu-acceleration-lxc",
|
||||
"tail": " — setup inicial del modo LXC."
|
||||
},
|
||||
{
|
||||
"label": "Instalar drivers NVIDIA (Host)",
|
||||
"href": "/docs/hardware/nvidia-host",
|
||||
"tail": " — necesario para el modo LXC en GPUs NVIDIA."
|
||||
},
|
||||
{
|
||||
"label": "ProxMenux Monitor — pestaña Hardware",
|
||||
"href": "/docs/monitor/dashboard/hardware",
|
||||
"tail": " — la sección Graphics Cards donde cada GPU muestra su modo actual y expone el control inline para cambiarlo."
|
||||
},
|
||||
{
|
||||
"label": "Comandos de GPU Passthrough",
|
||||
"href": "/docs/help-info/gpu-commands",
|
||||
"tail": " — referencia rápida de comandos."
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user