# Compilación de llama.cpp con HIP para GPUs AMD (ROCm)

---

### Introducción

Este artículo documenta el proceso de **compilación de `llama.cpp` con backend HIP** para utilizar **aceleración por GPU en hardware AMD**, dentro del stack de inferencia local de modelos LLM.
La integración se realiza sobre **ROCm**, interactuando directamente con la GPU mediante HIP y, opcionalmente, **rocWMMA** para optimizar Flash Attention en arquitecturas modernas.

El caso documentado corresponde a un sistema **Fedora 43**, con **Ryzen 9 5900X** y una **GPU RDNA3 (gfx1100)**. El enfoque es extrapolable a otras GPUs AMD compatibles, pero las decisiones y validaciones están hechas específicamente sobre este entorno.

---

### Enfoque general / Arquitectura

El flujo seguido es intencionadamente directo:

* `llama.cpp` se compila **desde código fuente**.
* Se habilita el backend **GGML_HIP** mediante CMake.
* La compilación se ajusta explícitamente a la **arquitectura de la GPU** (`GPU_TARGETS`).
* El binario resultante (`llama-cli` o `llama-server`) ejecuta inferencia usando GPU vía HIP.

No se emplean contenedores ni capas intermedias. Se prioriza **control total del toolchain**, visibilidad de errores y reproducibilidad en el sistema base Fedora.

---

### Requisitos previos

* Fedora 43.
* GPU AMD compatible con **ROCm / HIP** (RDNA2+, RDNA3 o CDNA).
* ROCm instalado y operativo.
* `clang` proporcionado por ROCm accesible vía `hipconfig`.
* CMake moderno.
* Espacio suficiente para la compilación.

---

### Desarrollo

**Clonado del repositorio**

Se parte siempre del repositorio oficial de `llama.cpp`, evitando forks o parches externos que puedan introducir comportamientos no controlados.

**Compilación con HIP habilitado**

La compilación se realiza indicando explícitamente:

* El compilador HIP (`HIPCXX`).
* La ruta base de ROCm (`HIP_PATH`).
* Activación del backend HIP en GGML.
* Arquitectura concreta de la GPU (`gfx1100`).
* Build en modo `Release`.
* Paralelización elevada, acorde al Ryzen 9 5900X.

```bash
HIPCXX="$(hipconfig -l)/clang" HIP_PATH="$(hipconfig -R)" \
cmake -S . -B build \
  -DGGML_HIP=ON \
  -DGGML_HIP_ROCWMMA_FATTN=ON \
  -DGPU_TARGETS=gfx1100 \
  -DCMAKE_BUILD_TYPE=Release \
&& cmake --build build --config Release -- -j 24
```

**Decisiones técnicas relevantes**

* `GPU_TARGETS=gfx1100`
  Se fuerza la arquitectura RDNA3 para evitar builds genéricos innecesarios y reducir tanto tiempos de compilación como tamaño del binario.

* `GGML_HIP_ROCWMMA_FATTN=ON`
  Activa Flash Attention optimizado mediante `rocWMMA`, especialmente relevante en RDNA3.

* No se omite `GPU_TARGETS`: aunque es opcional, dejarlo implícito suele derivar en builds más lentas y menos predecibles.

---

#### Uso del binario resultante

Tras la compilación, los binarios quedan disponibles en:

```
build/bin/
```

La ayuda completa puede consultarse con:

```bash
./build/bin/llama-cli -h
```

Ejemplo mínimo de ejecución con `llama-cli`:

```bash
./build/bin/llama-cli \
  -m /ruta/a/tu/modelo.gguf \
  -p "Building a website can be done in 10 steps:"
```

La ruta del modelo depende del layout local de almacenamiento y no forma parte de esta documentación.

---

#### Ejecución como servicio con llama-server

Además del modo CLI, `llama.cpp` incluye **`llama-server`**, pensado para ejecutar inferencia persistente mediante una API HTTP (compatible con clientes tipo OpenAI).

Este modo es el habitual cuando se quiere:

* Mantener el modelo cargado en GPU.
* Evitar tiempos de arranque por inferencia.
* Consumir el modelo desde aplicaciones externas.

Ejemplo **básico y genérico**, válido para pruebas iniciales en GPU AMD con HIP:

```bash
./build/bin/llama-server \
  -m /ruta/a/tu/modelo.gguf \
  -ngl 99 \
  -c 4096 \
  --host 127.0.0.1 \
  --port 5000
```

**Notas sobre los parámetros usados:**

* `-m`
  Modelo GGUF a cargar.

* `-ngl 99`
  Intenta offloadear el mayor número posible de capas a la GPU. En sistemas con VRAM suficiente, equivale a "todo a GPU".

* `-c 4096`
  Tamaño de contexto moderado para uso general. Valores altos incrementan consumo de VRAM.

* `--host` / `--port`
  Dirección y puerto de escucha del servidor.

Este ejemplo evita opciones avanzadas (quantización de KV, Flash Attention explícito, buffers personalizados, plantillas de chat, etc.) para mantener un **baseline claro y portable**.

---

### Aceleración adicional con rocWMMA

En arquitecturas **RDNA3+ o CDNA**, `rocWMMA` permite acelerar de forma significativa las operaciones de Flash Attention.

* Se incluye por defecto al instalar ROCm mediante el meta-paquete `rocm`.
* Alternativamente puede instalarse mediante paquetes `rocwmma-dev` / `rocwmma-devel`, según la distribución.

En escenarios no estándar, es posible añadir manualmente el include path:

```bash
-DCMAKE_CXX_FLAGS="-I<ruta>/rocwmma/library/include/"
```

---

### Problemas detectados y resolución

#### Error: ROCm device library no encontrada

Error típico durante la compilación:

```
clang: error: cannot find ROCm device library;
```

Resolución aplicada:

1. Localizar dentro de `HIP_PATH` un directorio que contenga el archivo:

   ```
   oclc_abi_version_400.bc
   ```

2. Definir la variable `HIP_DEVICE_LIB_PATH` apuntando a dicho directorio:

```bash
HIPCXX="$(hipconfig -l)/clang" HIP_PATH="$(hipconfig -p)" \
HIP_DEVICE_LIB_PATH=<directorio_encontrado> \
cmake -S . -B build \
  -DGGML_HIP=ON \
  -DGPU_TARGETS=gfx1030 \
  -DCMAKE_BUILD_TYPE=Release \
&& cmake --build build -- -j 16
```

---

### Arquitecturas GPU y detección

La arquitectura activa puede identificarse con:

```bash
rocminfo | grep gfx | head -1
```

Ejemplos habituales:

* `gfx1030` → RDNA2
* `gfx1100` → RDNA3 (RX 7900 XTX / XT / GRE)

Si la GPU no está oficialmente soportada:

* `HSA_OVERRIDE_GFX_VERSION=10.3.0` para RDNA2.
* `HSA_OVERRIDE_GFX_VERSION=11.0.0` para RDNA3.

---

### Variables de entorno relevantes

* `HIP_VISIBLE_DEVICES`
  Limita qué GPU(s) son visibles para HIP.

* `HSA_OVERRIDE_GFX_VERSION`
  Fuerza compatibilidad con arquitecturas similares cuando el soporte no es oficial.

---

### Resumen breve

* `llama.cpp` puede compilarse con **HIP** para GPUs AMD usando ROCm en Fedora 43.
* Forzar `GPU_TARGETS` mejora tiempos, tamaño y control del binario.
* `rocWMMA` aporta mejoras reales en Flash Attention sobre RDNA3.
* La compilación directa ofrece mayor control que soluciones encapsuladas.

---

### Notas personales

HIP no es inmediato ni indulgente, pero una vez alineado el toolchain en Fedora, el resultado es estable y consistente.
Para inferencia local seria en hardware AMD, ROCm sigue siendo el camino más realista pese a sus fricciones.

---

### Referencias

* [llama.cpp – Build documentation](https://github.com/ggml-org/llama.cpp/blob/master/docs/build.md)
* [Repositorio oficial de llama.cpp](https://github.com/ggml-org/llama.cpp)