# Servir modelos en Jobs

Con [puertos expuestos](./jobs-configuration#expose-ports), un Job puede actuar como un servidor de inferencia temporal: inicia vLLM en un sabor de GPU, apunta cualquier cliente compatible con OpenAI a la URL del job y cancela el job cuando termines. Pagas por minuto mientras el job se ejecuta y el punto de acceso desaparece con el job.

Es una buena opción cuando el punto de acceso es un medio y no el producto en sí: una ejecución de evaluación, una sesión de etiquetado de datos, iterar sobre prompts contra un modelo caliente, o una demostración que solo necesita estar activa durante una tarde.

> [!TIP]
> Si deseas un punto de acceso más permanente que no desaparezca, lo que necesitas son los [Inference Endpoints](https://huggingface.co/docs/inference-endpoints), que proporcionan infraestructura administrada con escalado automático, monitoreo y URLs estables.

## Iniciar un servidor de vLLM

La imagen `vllm/vllm-openai` tiene todo preinstalado. Un solo comando inicia un servidor compatible con OpenAI:

```bash
>>> hf jobs run --detach --expose 8000 --flavor a10g-small -s HF_TOKEN \
...   vllm/vllm-openai \
...   vllm serve LiquidAI/LFM2.5-8B-A1B --max-model-len 8192
✓ Job started
  id: 6a2b137a59bbdade52d4a58c
  url: https://huggingface.co/jobs/davanstrien/6a2b137a59bbdade52d4a58c
Hint: Exposed ports are reachable at (requires an HF token with read access to the job):
  https://6a2b137a59bbdade52d4a58c--8000.hf.jobs
```

`-s HF_TOKEN` transfiere tu token de Hugging Face al trabajo como un secreto, de modo que la descarga del modelo esté autenticada: es obligatorio para modelos con acceso restringido o privados, y te otorga límites de tasa más altos y descargas más rápidas para todo lo demás.

> [!NOTE]
> Jobs ejecuta directamente el comando que proporcionas; no pasa argumentos al entrypoint de la imagen como lo hace `docker run`. Escribe siempre el comando completo (`vllm serve ...`, no solo `--model ...`).

El servidor tarda unos minutos en estar listo (descarga de la imagen, descarga del modelo, carga del modelo). Siga el progreso con `hf jobs logs -f <job_id>`; el servidor estará listo cuando los registros muestren `Application startup complete`.

## Conectar un cliente

Los puertos expuestos requieren un token de HF con acceso `read` al espacio de nombres del trabajo, pasado como token Bearer. Para un servidor compatible con OpenAI, esto se inserta directamente como clave de API del cliente: la URL base es la URL del puerto expuesto más `/v1`:

```python
import os
from openai import OpenAI

client = OpenAI(
    base_url="https://6a2b137a59bbdade52d4a58c--8000.hf.jobs/v1",
    api_key=os.environ["HF_TOKEN"],  # any token with read access to the job's namespace
)

response = client.chat.completions.create(
    model="LiquidAI/LFM2.5-8B-A1B",
    messages=[{"role": "user", "content": "Write a haiku about ephemeral compute."}],
)
print(response.choices[0].message.content)
```

LFM2.5 es un modelo de razonamiento, por lo que la respuesta incluye su razonamiento dentro de las etiquetas `<think>` antes de la respuesta final.

O con `curl`:

```bash
>>> curl https://6a2b137a59bbdade52d4a58c--8000.hf.jobs/v1/chat/completions \
...   -H "Authorization: Bearer $HF_TOKEN" \
...   -H "Content-Type: application/json" \
...   -d '{"model": "LiquidAI/LFM2.5-8B-A1B", "messages": [{"role": "user", "content": "Hello!"}]}'
```

Dado que el token viaja en la cabecera `Authorization`, estas URLs funcionan desde scripts, notebooks y agentes, es decir, en cualquier lugar donde se utilice una API compatible con OpenAI. No se pueden abrir directamente en un navegador. Para servir un puerto sin un token de HF, usa `--expose-public`; consulta [Expose Ports](./jobs-configuration#expose-ports).

## Sirve modelos GGUF con llama.cpp

El mismo patrón funciona con cualquier servidor que hable HTTP. `llama serve` de llama.cpp obtiene los archivos GGUF directamente del Hub con la bandera `-hf` y sirve la misma API compatible con OpenAI. Por ejemplo, para servir [Gemma 4 E4B](https://huggingface.co/ggml-org/gemma-4-E4B-it-GGUF) con los ajustes de muestreo recomendados por Gemma:

```bash
>>> hf jobs run --detach --expose 8080 --flavor a10g-small -s HF_TOKEN \
...   ghcr.io/ggml-org/llama.cpp:server-cuda -- \
...   /app/llama serve -hf ggml-org/gemma-4-E4B-it-GGUF \
...   --host 0.0.0.0 --port 8080 -ngl 99 \
...   --temp 1.0 --top-p 0.95 --top-k 64
```

El `--` separa el comando del trabajo de las propias opciones de `hf jobs run`; es necesario aquí porque, de lo contrario, las banderas de `llama serve` serían analizadas por la propia CLI.

> [!TIP]
> Puede omitir por completo la descarga del modelo montando el repositorio del modelo como un volumen de solo lectura y apuntando el servidor directamente al archivo:
>
> ```bash
> >>> hf jobs run --detach --expose 8080 --flavor a10g-small -s HF_TOKEN \
> ...   -v hf://ggml-org/gemma-4-E4B-it-GGUF:/model:ro \
> ...   ghcr.io/ggml-org/llama.cpp:server-cuda -- \
> ...   /app/llama serve --model /model/gemma-4-E4B-it-Q4_K_M.gguf \
> ...   --host 0.0.0.0 --port 8080 -ngl 99
> ```
>
> El servidor se inicia mucho más rápido porque no hay nada que descargar: el modelo se transmite desde el repositorio montado a medida que se carga.

> [!WARNING]
> Tu servidor debe escuchar en `0.0.0.0`. `llama serve` se une a `127.0.0.1` de forma predeterminada, lo que el proxy de trabajos no puede alcanzar; pasa `--host 0.0.0.0` explícitamente.

Lo mismo aplica a cualquier otro servidor compatible con OpenAI (SGLang, ...): inicia el servidor en un puerto expuesto, escucha en `0.0.0.0` y conéctate con tu token de HF como clave de API.

## Detener el servidor

El trabajo —y su facturación— se detiene cuando lo cancelas o cuando se alcanza su tiempo de espera (30 minutos por defecto; establece `--timeout` explícitamente para sesiones más largas):

```bash
>>> hf jobs cancel <job_id>
```

> [!NOTE]
> Los puertos expuestos requieren `huggingface_hub` >= 1.19.0 y se facturan además del precio del hardware del trabajo; consulte [Jobs pricing](./jobs-pricing).

