4 puntos por GN⁺ 2024-10-04 | 1 comentarios | Compartir por WhatsApp
  • Motor de inferencia basado en Docker para ejecutar modelos de lenguaje grandes en GPU de AMD, orientado a modelos de Hugging Face y con foco en la familia LLaMA
  • El entorno de ejecución requiere una GPU de AMD compatible con ROCm, Docker y el driver ROCm 5.4.2 o una versión compatible instalado en el host
  • run-docker-amd.sh construye automáticamente la imagen de Docker y ejecuta el contenedor con /dev/kfd, /dev/dri, el grupo video, SYS_PTRACE y la configuración seccomp=unconfined necesarios para acceder a la GPU de AMD
  • El usuario puede cambiar el modelo pasando como argumentos el nombre del repositorio de Hugging Face y el prompt; se muestran como ejemplos meta-llama/Llama-2-7b-chat-hf y facebook/opt-1.3b
  • Para cambiar el comportamiento de la inferencia hay que modificar run_inference.py y volver a construir la imagen de Docker; si falta memoria, se debe usar un modelo más pequeño o entradas y salidas más cortas

Objetivo del proyecto y modelos objetivo

  • Este proyecto es un motor de inferencia basado en Docker para ejecutar LLM en GPU de AMD
  • Está diseñado para usar modelos de Hugging Face, con especial enfoque en la familia de modelos LLaMA
  • Usa la biblioteca Hugging Face Transformers

Requisitos del entorno

  • Antes de ejecutar, se necesitan las siguientes condiciones
    • Una GPU de AMD compatible con ROCm
    • Docker instalado en el sistema
    • Driver ROCm instalado en el sistema host
      • Se requiere la versión 5.4.2 o una versión compatible

Estructura del proyecto

  • La estructura del repositorio está compuesta por el directorio src/ y archivos de ejecución y compilación
    • src/engine.py
    • src/model.py
    • src/utils.py
    • src/amd_setup.py
    • Dockerfile
    • requirements.txt
    • run_inference.py
    • run-docker-amd.sh
    • README.md

Flujo de ejecución rápida

  • Clona el repositorio y luego entra al directorio del proyecto
git clone https://github.com/slashml/amd-gpu-inference.git
cd amd-gpu-inference
  • Da permisos de ejecución al script de arranque
chmod +x run-docker-amd.sh
  • Ejecuta el motor de inferencia pasando el nombre del modelo y el prompt
./run-docker-amd.sh "meta-llama/Llama-2-7b-chat-hf" "Translate the following English text to French: 'Hello, how are you?'"
  • "meta-llama/Llama-2-7b-chat-hf" puede reemplazarse por el modelo de Hugging Face que quieras usar, y el prompt también puede definirse directamente

Cómo funciona la ejecución con Docker y ROCm

  • Aptfile enumera los paquetes de ROCm que se instalarán dentro del contenedor de Docker
    • Es una configuración para poder usar dentro del contenedor los drivers y bibliotecas ROCm necesarios
  • run-docker-amd.sh construye automáticamente la imagen de Docker
  • La compilación manual puede hacerse con el siguiente comando
docker build -t amd-gpu-inference .
  • Al ejecutar el contenedor manualmente, hay que indicar los dispositivos y opciones de permisos para acceder a la GPU de AMD
docker run --rm -it \
    --device=/dev/kfd \
    --device=/dev/dri \
    --group-add=video \
    --cap-add=SYS_PTRACE \
    --security-opt seccomp=unconfined \
    amd-gpu-inference "model_name" "your prompt here"
  • En "model_name" va el nombre del modelo de Hugging Face, y en "your prompt here" va el texto de entrada

Personalización y solución de problemas

  • El cambio de modelo se maneja indicando el nombre del repositorio de Hugging Face al momento de ejecutar
./run-docker-amd.sh "facebook/opt-1.3b" "Your prompt here"
  • Para cambiar la lógica de inferencia, modifica el archivo run_inference.py
    • Después de los cambios, hay que volver a construir la imagen de Docker
  • Los puntos de solución de problemas son los siguientes
    • Hay que verificar que el driver de la GPU de AMD y ROCm estén correctamente instalados y configurados en el sistema host
    • Si aparece el error "out of memory", hay que usar un modelo más pequeño o reducir la longitud de entrada y salida
    • Para problemas específicos de cada modelo, hay que consultar la documentación del modelo correspondiente en Hugging Face

Licencia y referencia

  • El proyecto acepta contribuciones mediante Pull Request
  • ROCm fue desarrollado por AMD y se ofrece bajo la MIT License
  • Las preguntas o problemas pueden abrirse como issues en el repositorio de GitHub

1 comentarios

 
GN⁺ 2024-10-04
Opiniones en Hacker News
  • Para inferencia, si es una tarjeta compatible o una arquitectura en la que se pueda usar HSA_OVERRIDE_GFX_VERSION en Linux, casi todo se puede correr con PyTorch upstream y transformers
    llama.cpp también compila bastante sin problemas desde hace al menos un año, y en Windows normalmente las releases incluyen binarios win-hip; si no, se puede esquivar con una build Vulkan, aunque con menor rendimiento
    Dicho eso, ROCm 5.4.2 en este artículo es una versión de hace casi 2 años y desde entonces cambió mucho, así que me pregunto por qué se publicó recién en octubre de 2024
    Hace poco actualicé una documentación de compatibilidad enfocada en RDNA3 con base en ROCm 6.2, y aun en unos pocos meses hubo muchos cambios: bitsandbytes upstream, xformers upstream, Flash Attention basado en Triton, etc.: https://llm-tracker.info/howto/AMD-GPUs

  • Es sorprendente la proliferación de librerías de machine learning hechas más o menos con generación automática
    Esta librería es mitad sentencias print, y donde hay ramificaciones en realidad ni siquiera hace falta ramificar
    Básicamente define dos variables de entorno y configura dos flags de torch

    • Tuve que hacer terapia para corregir la idea de confundir a científicos de datos y gente de machine learning con ingenieros de software, y esperarles los mismos entregables, porque eso solo me subía la presión
      En equipos u organizaciones, creo que la gestión de expectativas es una parte realmente importante
    • Pensé que quizá era demasiado duro, pero al ver el repositorio vi que no
      En realidad casi no tiene contenido
    • Entiendo lo que quieres decir, pero comentarios así hacen que la gente se resista a compartir código, hacer contribuciones open source o seguir programando
  • Parece que están usando el viejo ROCm 5.4.2; al ser una versión de hace 2 años, dudo que soporte mi RX 7900 XTX
    Personalmente, lo más fácil fue usar la imagen rocm/pytorch más reciente y ejecutar ahí lo que necesitara

    • La RX 7900 XTX (gfx1100) se habilitó por primera vez en ROCm 5.4 para librerías matemáticas como rocBLAS, pero creo que las librerías de IA como MIOpen no se habilitaron hasta ROCm 5.5
      También creo que el rendimiento mejoró bastante en releases posteriores
  • En Ubuntu 24.04 y Debian Unstable, solo con los paquetes que provee el sistema operativo se puede correr llama.cpp con ROCm en casi cualquier GPU AMD dedicada posterior a Vega
    No hace falta Docker ni HSA_OVERRIDE_GFX_VERSION; basta con instalar hipcc, libhipblas-dev, librocblas-dev, cmake, etc., dar permisos a los grupos video y render, y compilar con GGML_HIPBLAS=ON
    Para usuarios de RDNA 3, MI200 y MI300, por rendimiento convienen más los paquetes ROCm provistos por AMD, y si se necesita PyTorch también conviene usar los paquetes de AMD porque hay dependencias que no están en los paquetes del sistema
    Aun así, en facilidad de instalación y compatibilidad con hardware antiguo, a los paquetes del sistema operativo es difícil ganarles; el enlace de referencia es https://lists.debian.org/debian-ai/2024/07/msg00002.html

    • En Ubuntu 22.04.5 instalé ROCm y Ollama provistos por AMD con una RX 7900 XTX sin mayores problemas, y ejecutar LLM basados en ROCm con Ollama también funciona bien
    • ¿Hay ahora en el mercado alguna tarjeta AMD con más de 24 GB de VRAM a un precio amigable para consumidores?
  • Compré una Ryzen 8700G hace unos 8 meses para hacer inferencia de redes neuronales con la NPU, pero hasta ahora la única aceleración que obtuve fue con Vulkan en la iGPU, no con la NPU.
    Uso solo Linux, y lo bueno es que, gracias a los 64 GB de RAM, pude probar sin problema modelos de más de 32 GB.
    llama.cpp, que soporta el backend Vulkan, merece elogios.

    • Probablemente también puedas obtener soporte ROCm/HIP en la iGPU, y al compilar llama.cpp podrías probar con la bandera LLAMA_HIP_UMA=1.
      Si miras https://github.com/amd/RyzenAI-SW, hay bastante software para jugar con la NPU, pero Phoenix tiene 16 TOPS, así que no me dieron ganas de probarlo directamente.
  • En mi workstation con NixOS bastó con agregar más o menos esto:
    activar hardware.graphics.enable = true; y, en services.ollama, configurar acceleration = "rocm";, ROC_ENABLE_PRE_VEGA = "1";, HSA_OVERRIDE_GFX_VERSION = "11.0.0";.

  • Antes, al ver lo simple que era llamafile, estuve a punto de instalar AMD ROCm.
    Pero el resultado de sudo apt install rocm fue 203 paquetes a instalar, una descarga de unos 2.37 GB y 35.7 GB de espacio requerido.
    No entiendo cómo se justifican 36 GB para algo que, en la práctica, se acerca a un driver de GPU.

    • Es cierto que el software de hoy se ha vuelto absurdamente pesado, pero ROCm no es simplemente un driver de GPU.
      Incluye varias herramientas y bibliotecas.
      El CUDA toolkit, si lo bajas como archivo único, también supera los 4 GB solo de descarga, así que en cualquiera de los dos casos el resultado parece ridículamente grande.
    • En https://github.com/zml/zml están resolviendo este problema.
    • Hoy en día, el driver de CPU que corre en la GPU es casi un sistema operativo completo.
    • AMD está ensuciando por completo el kernel de Linux con sus drivers: https://www.phoronix.com/news/AMD-5-Million-Lines
  • Esto parece un wrapper hecho por IA encima de un wrapper de un wrapper de un wrapper.
    Hay comentarios como # Other AMD-specific optimizations can be added here y # For example, you might want to set specific flags or use AMD-optimized libraries, así que no sé qué se supone que está haciendo esto.

    • En la práctica es un archivo requirements grande y un Dockerfile; el resto son, en su mayoría, scripts auxiliares.
  • ¿Qué GPU de AMD con buena relación precio/rendimiento hay hoy?
    Acabo de comprar dos 3090 usadas reacondicionadas en eBay por unos 750 dólares cada una, y me da curiosidad qué usa la gente para correr LLMs localmente.

    • Hace poco compré una MI100 por 650 dólares.
      Tiene 32 GB de HBM2 y en benchmarks básicos de Flash Attention 2 es entre 0 y 5% más rápida que una 3090, pero el rendimiento en aplicaciones reales es irregular.
      Muchos proyectos no están optimizados para los matrix cores de CDNA, y aunque haya trabajo hecho para RDNA, muchas veces no se traduce directamente a CDNA.
      También es frustrante que llama.cpp haya cerrado el PR de Flash Attention para AMD diciendo que una biblioteca solo de headers agregaba una dependencia innecesaria: https://github.com/ggerganov/llama.cpp/pull/7011
      Con xformers en la configuración por defecto de SDXL da unos 4.5~5 it/s, más o menos entre una 3090 y una 4090; y en exllamav2, Qwen 72B a 3 bpw ronda los 7 t/s, más lento que una 3090, aunque para que entre en una 3090 habría que usar una precisión más baja.
      No tengo claro qué les aporta este proyecto a los usuarios de AMD por encima de opciones existentes como llama.cpp, exllamav2 o mlc-ai; hoy en día la mayoría de los proyectos funcionan relativamente fácil.
    • Personalmente, las iGPU/GPU de AMD se me rompían con cada actualización de PyTorch, ROCm, xformers u Ollama, así que no les vi mucho valor.
      Con Nvidia duermes más tranquilo por la noche.
    • Compré una Radeon Pro VII nueva por 300 euros y fue un trato bastante bueno.
      Tiene HBM2 y un ancho de banda de memoria de 1 TB/s, igual que una 4090.
      Eso sí, solo tiene 16 GB de VRAM.
    • Probablemente la respuesta sea la 7900 XTX.
      Son 24 GB de RAM por 1,000 dólares.
  • La gente suele decir “basado en Docker”, pero lo que realmente significa es que distribuyen $SOFTWARE como una imagen Docker.
    Decir “basado en Docker” suena como si se hiciera inferencia en tarjetas AMD con Docker, y eso me parece una forma de decirlo sin sentido.

    • Puedes hacer inferencia dentro de un contenedor Docker, igual que con Nvidia.
      OpenAI también corre clusters de K8s de esta manera, y AMD tiene documentación al respecto.
      Eso sí, en el lado de IA de AMD necesitas la tarjeta correcta, la versión correcta de ROCm y pura suerte.
      AMD ofrece imágenes Docker con soporte ROCm, así que puedes usarlas como capa base, combinarlas con tu app y pasarle la GPU al contenedor para que funcione.
      Al final reduce en uno los factores de los que tienes que preocuparte durante el despliegue, así que literalmente estás haciendo inferencia en AMD con Docker.
    • Docker se volvió una herramienta estándar en machine learning porque una distribución de Python vinculada a bibliotecas del sistema se vuelve un desastre si no lleva también esa capa consigo.
    • Puedes montar dispositivos específicos en Docker.
      Si miras el script, está montando la GPU: https://github.com/slashml/amd_inference/blob/main/run-docke...
    • En ZML están resolviendo este problema: https://github.com/zml/zml
    • ¿Por qué no tendría sentido? Desde un contenedor Docker también puedes comunicarte con dispositivos; solo tienes que conectarlos.