# Servidor Llama.cpp

Ejecute LLMs de manera eficiente con el servidor llama.cpp en GPU.

{% hint style="success" %}
Todos los ejemplos se pueden ejecutar en servidores GPU alquilados a través de [CLORE.AI Marketplace](https://clore.ai/marketplace).
{% endhint %}

## Requisitos del servidor

| Parámetro        | Mínimo        | Recomendado |
| ---------------- | ------------- | ----------- |
| RAM              | 8GB           | 16GB+       |
| VRAM             | 6GB           | 8GB+        |
| Red              | 200Mbps       | 500Mbps+    |
| Tiempo de inicio | \~2-5 minutos | -           |

{% hint style="info" %}
Llama.cpp es eficiente en memoria debido a la cuantización GGUF. Los modelos 7B pueden ejecutarse en 6-8 GB de VRAM.
{% endhint %}

## Alquilar en CLORE.AI

1. Visita [CLORE.AI Marketplace](https://clore.ai/marketplace)
2. Filtrar por tipo de GPU, VRAM y precio
3. Elegir **Bajo demanda** (tarifa fija) o **Spot** (precio de puja)
4. Configura tu pedido:
   * Selecciona imagen Docker
   * Establece puertos (TCP para SSH, HTTP para interfaces web)
   * Agrega variables de entorno si es necesario
   * Introduce el comando de inicio
5. Selecciona pago: **CLORE**, **BTC**, o **USDT/USDC**
6. Crea el pedido y espera el despliegue

### Accede a tu servidor

* Encuentra los detalles de conexión en **Mis Pedidos**
* Interfaces web: Usa la URL del puerto HTTP
* SSH: `ssh -p <port> root@<proxy-address>`

## ¿Qué es Llama.cpp?

Llama.cpp es el motor de inferencia más rápido para LLMs en CPU/GPU:

* Soporta modelos cuantizados GGUF
* Bajo uso de memoria
* API compatible con OpenAI
* Soporte multiusuario

## Niveles de cuantización

| Formato  | Tamaño (7B) | Velocidad     | Calidad   |
| -------- | ----------- | ------------- | --------- |
| Q2\_K    | 2.8GB       | El más rápido | Baja      |
| Q4\_K\_M | 4.1GB       | Rápido        | Bueno     |
| Q5\_K\_M | 4.8GB       | Medio         | Genial    |
| Q6\_K    | 5.5GB       | Más lento     | Excelente |
| Q8\_0    | 7.2GB       | El más lento  | Mejor     |

## Despliegue rápido

**Imagen Docker:**

```
ghcr.io/ggerganov/llama.cpp:server-cuda
```

**Puertos:**

```
22/tcp
8080/http
```

**Comando:**

```bash

# Descargar modelo
wget https://huggingface.co/bartowski/Meta-Llama-3.1-8B-Instruct-GGUF/resolve/main/Meta-Llama-3.1-8B-Instruct-Q4_K_M.gguf

# Ejecutar servidor
./llama-server \
    -m Meta-Llama-3.1-8B-Instruct-Q4_K_M.gguf \
    --host 0.0.0.0 \
    --port 8080 \
    -ngl 35 \
    -c 4096
```

## Accediendo a tu servicio

Después del despliegue, encuentra tu `http_pub` URL en **Mis Pedidos**:

1. Ir a **Mis Pedidos** página
2. Haz clic en tu pedido
3. Encuentra la `http_pub` URL (por ejemplo, `abc123.clorecloud.net`)

Usa `https://TU_HTTP_PUB_URL` en lugar de `localhost` en los ejemplos abajo.

### Verificar que funciona

```bash
# Comprobar salud
curl https://your-http-pub.clorecloud.net/health

# Obtener información del servidor
curl https://your-http-pub.clorecloud.net/props
```

{% hint style="warning" %}
Si obtiene HTTP 502, el servicio puede estar aún iniciándose o descargando el modelo. Espere 2-5 minutos y vuelva a intentarlo.
{% endhint %}

## Referencia completa de la API

### Puntos finales estándar

| Endpoint               | Método | Descripción                                 |
| ---------------------- | ------ | ------------------------------------------- |
| `/health`              | GET    | Comprobación de salud                       |
| `/v1/models`           | GET    | Listar modelos                              |
| `/v1/chat/completions` | POST   | Chat (compatible con OpenAI)                |
| `/v1/completions`      | POST   | Completado de texto (compatible con OpenAI) |
| `/v1/embeddings`       | POST   | Generar embeddings                          |
| `/completion`          | POST   | Punto final de completado nativo            |
| `/tokenize`            | POST   | Tokenizar texto                             |
| `/detokenize`          | POST   | Detokenizar tokens                          |
| `/props`               | GET    | Propiedades del servidor                    |
| `/metrics`             | GET    | Métricas de Prometheus                      |

#### Tokenizar texto

```bash
curl https://your-http-pub.clorecloud.net/tokenize \
    -H "Content-Type: application/json" \
    -d '{"content": "Hello world"}'
```

Respuesta:

```json
{"tokens": [15496, 1917]}
```

#### Propiedades del servidor

```bash
curl https://your-http-pub.clorecloud.net/props
```

Respuesta:

```json
{
  "total_slots": 1,
  "chat_template": "...",
  "default_generation_settings": {...}
}
```

## Construir desde la fuente

```bash

# Clonar el repositorio
git clone https://github.com/ggerganov/llama.cpp
cd llama.cpp

# Compilar con CUDA
make LLAMA_CUDA=1

# O con CMake
mkdir build && cd build
cmake .. -DLLAMA_CUDA=ON
cmake --build . --config Release
```

## Descargar modelos

```bash

# Llama 3.1 8B
wget https://huggingface.co/bartowski/Meta-Llama-3.1-8B-Instruct-GGUF/resolve/main/Meta-Llama-3.1-8B-Instruct-Q4_K_M.gguf

# Mistral 7B
wget https://huggingface.co/bartowski/Mistral-7B-Instruct-v0.3-GGUF/resolve/main/Mistral-7B-Instruct-v0.3-Q4_K_M.gguf

# Mixtral 8x7B
wget https://huggingface.co/bartowski/Mixtral-8x7B-Instruct-v0.1-GGUF/resolve/main/Mixtral-8x7B-Instruct-v0.1-Q4_K_M.gguf

# Phi-2
wget https://huggingface.co/bartowski/Phi-4-GGUF/resolve/main/Phi-4-Q4_K_M.gguf

# CodeLlama 7B
wget https://huggingface.co/bartowski/CodeLlama-7B-Instruct-GGUF/resolve/main/CodeLlama-7B-Instruct-Q4_K_M.gguf
```

## Opciones del servidor

### Servidor básico

```bash
./llama-server \
    -m model.gguf \
    --host 0.0.0.0 \
    --port 8080
```

### Descarga completa a GPU

```bash
./llama-server \
    -m model.gguf \
    --host 0.0.0.0 \
    --port 8080 \
    -ngl 99 \           # Capas GPU (99 = todas)
    -c 4096 \           # Tamaño del contexto
    -t 8 \              # Hilos de CPU
    --parallel 4        # Solicitudes concurrentes
```

### Todas las opciones

```bash
./llama-server \
    -m model.gguf \           # Archivo del modelo
    --host 0.0.0.0 \          # Dirección de enlace
    --port 8080 \             # Puerto
    -ngl 35 \                 # Capas GPU
    -c 4096 \                 # Tamaño del contexto
    -t 8 \                    # Hilos
    -b 512 \                  # Tamaño de lote
    --parallel 4 \            # Solicitudes paralelas
    --mlock \                 # Bloquear memoria
    --no-mmap \               # Deshabilitar mmap
    --cont-batching \         # Agrupamiento continuo
    --flash-attn \            # Flash attention
    --metrics                 # Habilitar endpoint de métricas
```

## Uso de la API

### Chat Completions (compatible con OpenAI)

```python
import openai

client = openai.OpenAI(
    base_url="http://localhost:8080/v1",
    api_key="no-necesaria"
)

response = client.chat.completions.create(
    model="llama-3.1-8b",
    messages=[
        {"role": "system", "content": "Eres un asistente útil."},
        {"role": "user", "content": "What is machine learning?"}
    ],
    temperature=0.7,
    max_tokens=500
)

print(response.choices[0].message.content)
```

### Streaming

```python
stream = client.chat.completions.create(
    model="llama-3.1-8b",
    messages=[{"role": "user", "content": "Write a story"}],
    stream=True
)

for chunk in stream:
    if chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end="", flush=True)
```

### Completado de texto

```python
response = client.completions.create(
    model="llama-3.1-8b",
    prompt="The future of AI is",
    max_tokens=100,
    temperature=0.8
)

print(response.choices[0].text)
```

### Embeddings

```python
response = client.embeddings.create(
    model="llama-3.1-8b",
    input="Hello, world!"
)

print(f"Embedding: {response.data[0].embedding[:5]}...")
```

## Ejemplos con cURL

### Chat

```bash
curl http://localhost:8080/v1/chat/completions \
    -H "Content-Type: application/json" \
    -d '{
        "model": "llama-3.1-8b",
        "messages": [
            {"role": "user", "content": "Hello!"}
        ]
    }'
```

### Completado

```bash
curl http://localhost:8080/completion \
    -H "Content-Type: application/json" \
    -d '{
        "prompt": "Building a website requires",
        "n_predict": 128,
        "temperature": 0.7
    }'
```

### Chequeo de salud

```bash
curl http://localhost:8080/health
```

### Métricas

```bash
curl http://localhost:8080/metrics
```

## Multi-GPU

```bash

# Dividir entre GPUs
./llama-server \
    -m model.gguf \
    -ngl 99 \
    --tensor-split 0.5,0.5 \  # Dividir entre 2 GPUs
    --main-gpu 0              # GPU primaria
```

## Optimización de memoria

### Para VRAM limitada

```bash

# Descarga parcial
./llama-server -m model.gguf -ngl 20 -c 2048

# Usar cuantización más pequeña

# Descargar Q2_K o Q3_K en lugar de Q4_K
```

### Para máxima velocidad

```bash
./llama-server \
    -m model.gguf \
    -ngl 99 \
    --flash-attn \
    --cont-batching \
    --parallel 8 \
    -b 1024
```

## Plantillas específicas del modelo

### Llama 2 Chat

```bash
./llama-server -m Meta-Llama-3.1-8B-Instruct-Q4_K_M.gguf \
    --chat-template llama2
```

### Mistral Instruct

```bash
./llama-server -m mistral-7b-instruct.gguf \
    --chat-template mistral
```

### ChatML (muchos modelos)

```bash
./llama-server -m model.gguf \
    --chat-template chatml
```

## Wrapper de servidor en Python

```python
import subprocess
import requests
import time

class LlamaCppServer:
    def __init__(self, model_path, port=8080, gpu_layers=35):
        self.port = port
        self.process = subprocess.Popen([
            "./llama-server",
            "-m", model_path,
            "--host", "0.0.0.0",
            "--port", str(port),
            "-ngl", str(gpu_layers),
            "-c", "4096"
        ])
        self._wait_for_ready()

    def _wait_for_ready(self, timeout=60):
        start = time.time()
        while time.time() - start < timeout:
            try:
                r = requests.get(f"http://localhost:{self.port}/health")
                if r.status_code == 200:
                    return
            except:
                pass
            time.sleep(1)
        raise TimeoutError("Server didn't start")

    def chat(self, messages, **kwargs):
        response = requests.post(
            f"http://localhost:{self.port}/v1/chat/completions",
            json={"messages": messages, **kwargs}
        )
        return response.json()

    def stop(self):
        self.process.terminate()

# Uso
server = LlamaCppServer("llama-3.1-8b.gguf")
result = server.chat([{"role": "user", "content": "Hello!"}])
print(result["choices"][0]["message"]["content"])
server.stop()
```

## Benchmarking

```bash

# Benchmark incorporado
./llama-bench -m model.gguf -ngl 99

# La salida incluye:

# - Tokens por segundo

# - Uso de memoria

# - Tiempo de carga
```

## Comparación de rendimiento

| Modelo       | GPU      | Cuantización | Tokens/seg |
| ------------ | -------- | ------------ | ---------- |
| Llama 3.1 8B | RTX 3090 | Q4\_K\_M     | \~100      |
| Llama 3.1 8B | RTX 4090 | Q4\_K\_M     | \~150      |
| Llama 3.1 8B | RTX 3090 | Q4\_K\_M     | \~60       |
| Mistral 7B   | RTX 3090 | Q4\_K\_M     | \~110      |
| Mixtral 8x7B | A100     | Q4\_K\_M     | \~50       |

## Solución de problemas

### CUDA no detectado

```bash

# Reconstruir con CUDA
make clean
make LLAMA_CUDA=1

# Verificar CUDA
nvidia-smi
```

### Memoria insuficiente

```bash

# Reducir capas GPU
-ngl 20  # En lugar de 99

# Reducir el contexto
-c 2048  # En lugar de 4096

# Usar cuantización más pequeña

# Q4_K_S en lugar de Q4_K_M
```

### Generación lenta

```bash

# Aumentar el tamaño del lote
-b 1024

# Habilitar flash attention
--flash-attn

# Habilitar agrupamiento continuo
--cont-batching
```

## Configuración de producción

### Servicio Systemd

```ini

# /etc/systemd/system/llama.service
[Unit]
Description=Llama.cpp Server
After=network.target

[Service]
Type=simple
ExecStart=/opt/llama.cpp/llama-server -m /models/model.gguf -ngl 99 --host 0.0.0.0 --port 8080
Restart=always

[Install]
WantedBy=multi-user.target
```

### Con nginx

```nginx
upstream llama {
    server localhost:8080;
}

server {
    listen 80;

    location / {
        proxy_pass http://llama;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
    }
}
```

## Estimación de costos

Tarifas típicas del marketplace de CLORE.AI (a fecha de 2024):

| GPU       | Tarifa por hora | Tarifa diaria | Sesión de 4 horas |
| --------- | --------------- | ------------- | ----------------- |
| RTX 3060  | \~$0.03         | \~$0.70       | \~$0.12           |
| RTX 3090  | \~$0.06         | \~$1.50       | \~$0.25           |
| RTX 4090  | \~$0.10         | \~$2.30       | \~$0.40           |
| A100 40GB | \~$0.17         | \~$4.00       | \~$0.70           |
| A100 80GB | \~$0.25         | \~$6.00       | \~$1.00           |

*Los precios varían según el proveedor y la demanda. Consulta* [*CLORE.AI Marketplace*](https://clore.ai/marketplace) *para las tarifas actuales.*

**Ahorra dinero:**

* Usa **Spot** market para cargas de trabajo flexibles (a menudo 30-50% más barato)
* Paga con **CLORE** tokens
* Compara precios entre diferentes proveedores

## Próximos pasos

* Inferencia vLLM - Mayor rendimiento
* [ExLlamaV2](/guides/guides_v2-es/modelos-de-lenguaje/exllamav2-fast.md) - Inferencia más rápida
* [Text Generation WebUI](/guides/guides_v2-es/modelos-de-lenguaje/text-generation-webui.md) - Interfaz web


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.clore.ai/guides/guides_v2-es/modelos-de-lenguaje/llamacpp-server.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
