# Asistente offline Jan.ai

## Resumen

[Jan.ai](https://github.com/janhq/jan) es una alternativa de ChatGPT de código abierto y centrada en la privacidad con más de 40.000 estrellas en GitHub. Aunque Jan es más conocido como una aplicación de escritorio, su componente de servidor — **Jan Server** — expone una API REST totalmente compatible con OpenAI que puede desplegarse en infraestructura GPU en la nube como Clore.ai.

Jan Server está construido sobre el [Cortex.cpp](https://github.com/janhq/cortex.cpp) motor de inferencia, un runtime de alto rendimiento que admite `llama.cpp`, `TensorRT-LLM`, y backends ONNX. En Clore.ai puedes alquilar un servidor GPU por tan solo **$0.20/hr**, ejecutar Jan Server con Docker Compose, cargar cualquier modelo GGUF o GPTQ y servirlo a través de una API compatible con OpenAI — todo sin que tus datos salgan de la máquina.

**Características clave:**

* 🔒 100% sin conexión — los datos nunca abandonan tu servidor
* 🤖 API compatible con OpenAI (`/v1/chat/completions`, `/v1/models`, etc.)
* 📦 Hub de modelos con descargas de modelos con un solo comando
* 🚀 Aceleración por GPU mediante CUDA (backends llama.cpp + TensorRT-LLM)
* 💬 Gestión de conversaciones integrada e historial de hilos
* 🔌 Reemplazo directo para OpenAI en aplicaciones existentes

***

## Requisitos

### Requisitos de hardware

| Nivel               | GPU           | VRAM  | RAM    | Almacenamiento | Precio de Clore.ai |
| ------------------- | ------------- | ----- | ------ | -------------- | ------------------ |
| **Mínimo**          | RTX 3060 12GB | 12 GB | 16 GB  | 50 GB SSD      | \~$0.10/h          |
| **Recomendado**     | RTX 3090      | 24 GB | 32 GB  | 100 GB SSD     | \~$0.20/h          |
| **Gama alta**       | RTX 4090      | 24 GB | 64 GB  | 200 GB SSD     | \~$0.35/h          |
| **Modelos grandes** | A100 80GB     | 80 GB | 128 GB | 500 GB SSD     | \~$1.10/h          |

### Referencia de VRAM del modelo

| Modelo              | VRAM requerida | GPU recomendada |
| ------------------- | -------------- | --------------- |
| Llama 3.1 8B (Q4)   | \~5 GB         | RTX 3060        |
| Llama 3.1 8B (FP16) | \~16 GB        | RTX 3090        |
| Llama 3.3 70B (Q4)  | \~40 GB        | A100 40GB       |
| Llama 3.1 405B (Q4) | \~220 GB       | 4× A100 80GB    |
| Mistral 7B (Q4)     | \~4 GB         | RTX 3060        |
| Qwen2.5 72B (Q4)    | \~45 GB        | A100 80GB       |

### Requisitos de software

* Cuenta de Clore.ai con cartera financiada
* Conocimientos básicos de Docker
* (Opcional) Cliente OpenSSH para reenvío de puertos

***

## Inicio rápido

### Paso 1 — Alquila un servidor GPU en Clore.ai

1. Navega a [clore.ai](https://clore.ai) y accede
2. Filtrar servidores: **Tipo de GPU** → RTX 3090 o superior, **Docker** → habilitado
3. Selecciona un servidor y elige la **Docker** opción de despliegue
4. Usa la `nvidia/cuda:12.1.0-devel-ubuntu22.04` imagen base oficial o cualquier imagen CUDA
5. Puertos abiertos: **1337** (API de Jan Server), **39281** (API de Cortex), **22** (SSH)

### Paso 2 — Conéctate a tu servidor

```bash
# Conéctate por SSH a tu servidor de Clore.ai
ssh -p <CLORE_SSH_PORT> root@<CLORE_SERVER_IP>

# Verificar que la GPU esté disponible
nvidia-smi
```

### Paso 3 — Instala Docker Compose (si no está presente)

```bash
# Comprueba si Docker Compose está disponible
docker compose version

# Instala si falta (Ubuntu/Debian)
apt-get update && apt-get install -y docker-compose-plugin

# Verificar
docker compose version
```

### Paso 4 — Despliega Jan Server con Docker Compose

```bash
# Crea el directorio de trabajo
mkdir -p /workspace/jan-server && cd /workspace/jan-server

# Descarga el docker-compose.yml oficial de Jan Server
curl -fsSL https://raw.githubusercontent.com/janhq/jan-server/main/docker-compose.yml \
  -o docker-compose.yml

# Revisa y edita la configuración
cat docker-compose.yml
```

Si el archivo compose upstream no está disponible o quieres control total, créalo manualmente:

```yaml
# /workspace/jan-server/docker-compose.yml
versión: '3.8'

services:
  jan-server:
    image: ghcr.io/janhq/cortex:latest
    container_name: jan-server
    restart: unless-stopped
    ports:
      - "1337:1337"
      - "39281:39281"
    volumes:
      - jan-data:/root/jan
      - jan-models:/root/cortex/models
    environment:
      - CUDA_VISIBLE_DEVICES=0
      - JAN_API_HOST=0.0.0.0
      - JAN_API_PORT=1337
      - CORTEX_API_PORT=39281
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: all
              capabilities: [gpu]
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:1337/health"]
      intervalo: 30s
      tiempo de espera: 10s
      retries: 5
      start_period: 60s

volumes:
  jan-data:
    driver: local
  jan-models:
    driver: local
```

```bash
# Inicia Jan Server
docker compose up -d

# Sigue los logs de arranque (espera el mensaje "Server started")
docker compose logs -f jan-server
```

### Paso 5 — Verifica que el servidor está en ejecución

```bash
# Comprueba la salud del servidor
curl http://localhost:1337/health

# Lista los modelos disponibles (inicialmente vacío)
curl http://localhost:1337/v1/models

# Respuesta esperada:
# {"object":"list","data":[]}
```

### Paso 6 — Descarga tu primer modelo

```bash
# Descarga Llama 3.2 3B (buen inicio, ~2GB)
curl -X POST http://localhost:1337/v1/models/pull \
  -H "Content-Type: application/json" \
  -d '{"model": "llama3.2:3b-gguf-q4-km"}'

# O descarga Mistral 7B Instruct Q4
curl -X POST http://localhost:1337/v1/models/pull \
  -H "Content-Type: application/json" \
  -d '{"model": "mistral:7b-instruct-v0.3-gguf-q4-km"}'

# Monitorea el progreso de la descarga
curl http://localhost:1337/v1/models
```

### Paso 7 — Inicia el modelo y chatea

```bash
# Inicia el modelo (lo carga en la VRAM de la GPU)
curl -X POST http://localhost:1337/v1/models/start \
  -H "Content-Type: application/json" \
  -d '{"model": "llama3.2:3b-gguf-q4-km"}'

# Envía tu primera solicitud de chat
curl http://localhost:1337/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "llama3.2:3b-gguf-q4-km",
    "messages": [
      {"role": "system", "content": "Eres un asistente útil."},
      {"role": "user", "content": "¡Hola! ¿En qué puedes ayudarme?"}
    ],
    "temperature": 0.7,
    "max_tokens": 512,
    "stream": false
  }'
```

***

## Configuración

### Variables de entorno

| Variable               | Valor por defecto     | Descripción                                    |
| ---------------------- | --------------------- | ---------------------------------------------- |
| `JAN_API_HOST`         | `0.0.0.0`             | Host al que enlazar el servidor API            |
| `JAN_API_PORT`         | `1337`                | Puerto de la API de Jan Server                 |
| `CORTEX_API_PORT`      | `39281`               | Puerto interno del motor Cortex                |
| `CUDA_VISIBLE_DEVICES` | `all`                 | Qué GPUs exponer (índices separados por comas) |
| `JAN_DATA_FOLDER`      | `/root/jan`           | Ruta a la carpeta de datos de Jan              |
| `CORTEX_MODELS_PATH`   | `/root/cortex/models` | Ruta de almacenamiento de modelos              |

### Configuración multi-GPU

Para servidores con múltiples GPUs (p. ej., 2× RTX 3090 en Clore.ai):

```yaml
environment:
  - CUDA_VISIBLE_DEVICES=0,1  # Usar ambas GPUs
```

O para dedicar GPUs específicas:

```bash
# Ejecutar Jan Server solo en la GPU 0
docker run -d \
  --name jan-server \
  --gpus '"device=0"' \
  -p 1337:1337 \
  -v jan-data:/root/jan \
  -v jan-models:/root/cortex/models \
  ghcr.io/janhq/cortex:latest
```

### Configuración personalizada del modelo

```bash
# Lista todos los modelos descargados
curl http://localhost:1337/v1/models | jq '.data[].id'

# Obtén detalles del modelo
curl http://localhost:1337/v1/models/llama3.2:3b-gguf-q4-km

# Detener un modelo en ejecución (libera VRAM)
curl -X POST http://localhost:1337/v1/models/stop \
  -H "Content-Type: application/json" \
  -d '{"model": "llama3.2:3b-gguf-q4-km"}'

# Eliminar un modelo (libera espacio en disco)
curl -X DELETE http://localhost:1337/v1/models/llama3.2:3b-gguf-q4-km
```

### Asegurar la API con un token

Jan Server no incluye autenticación por defecto. Usa Nginx como proxy inverso:

```bash
apt-get install -y nginx apache2-utils

# Crea el archivo de contraseñas
htpasswd -c /etc/nginx/.htpasswd admin

# Configura Nginx
cat > /etc/nginx/sites-available/jan-server << 'EOF'
server {
    listen 80;
    server_name _;

    location / {
        auth_basic "Jan Server";
        auth_basic_user_file /etc/nginx/.htpasswd;
        proxy_pass http://127.0.0.1:1337;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_read_timeout 300s;
    }
}
EOF

ln -s /etc/nginx/sites-available/jan-server /etc/nginx/sites-enabled/
nginx -t && systemctl restart nginx
```

***

## Aceleración por GPU

### Verificando la aceleración CUDA

El motor Cortex de Jan Server detecta CUDA automáticamente. Verifica que esté usando la GPU:

```bash
# Comprueba el uso de memoria GPU después de cargar un modelo
nvidia-smi

# Debería mostrar el proceso cortex consumiendo VRAM
# Ejemplo de salida:
# | Processes:                                                            |
# |  GPU   GI   CI        PID   Type   Process name            GPU Memory |
# |    0    N/A  N/A    12345    C   /usr/local/bin/cortex    8192MiB |
```

### Cambio de backends de inferencia

Cortex admite múltiples backends:

```bash
# Comprueba qué backends están disponibles dentro del contenedor
docker exec jan-server cortex engines list

# Usa el backend TensorRT-LLM para GPUs NVIDIA (más rápido, requiere más configuración)
docker exec jan-server cortex engines install tensorrt-llm

# Usa el backend llama.cpp (por defecto, el más compatible)
docker exec jan-server cortex engines install llama-cpp
```

### Ajuste de la ventana de contexto y el tamaño de lote

```bash
# Personaliza los parámetros del modelo para el rendimiento en GPU
curl -X POST http://localhost:1337/v1/models/start \
  -H "Content-Type: application/json" \
  -d '{
    "model": "llama3.2:3b-gguf-q4-km",
    "ctx_len": 8192,
    "ngl": 99,
    "n_batch": 512,
    "n_parallel": 4,
    "cpu_threads": 8
  }'
```

| Parámetro    | Descripción                                     | Recomendación                                 |
| ------------ | ----------------------------------------------- | --------------------------------------------- |
| `ngl`        | Capas de GPU (más alto = más uso de GPU)        | Establecer en `99` para maximizar la GPU      |
| `ctx_len`    | Tamaño de la ventana de contexto                | 4096–32768 dependiendo de la VRAM             |
| `n_batch`    | Tamaño de lote para el procesamiento de prompts | 512 para RTX 3090, 256 para GPUs más pequeñas |
| `n_parallel` | Slots de solicitudes concurrentes               | 4–8 para uso del servidor API                 |

***

## Consejos y mejores prácticas

### 🎯 Selección de modelos para presupuestos en Clore.ai

```bash
# Nivel económico (~$0.10/hr, RTX 3060 12GB):
# Usa cuantizaciones Q4_K_M de modelos de 7B
curl -X POST http://localhost:1337/v1/models/pull \
  -d '{"model": "mistral:7b-instruct-v0.3-gguf-q4-km"}'

# Nivel estándar (~$0.20/hr, RTX 3090 24GB):
# Usa cuantizaciones Q5_K_M de modelos de 13B o Q4 de 30B
curl -X POST http://localhost:1337/v1/models/pull \
  -d '{"model": "llama3.1:8b-instruct-gguf-q5-km"}'

# Nivel alto (~$1.10/hr, A100 80GB):
# Ejecuta modelos completos de 70B en alta precisión
curl -X POST http://localhost:1337/v1/models/pull \
  -d '{"model": "llama3.3:70b-instruct-gguf-q4-km"}'
```

### 💾 Almacenamiento persistente de modelos

Dado que las instancias de Clore.ai son efímeras, considera montar almacenamiento externo:

```bash
# Usa un volumen con nombre (persiste con Docker)
docker compose down
# Los modelos sobreviven en el volumen con nombre 'jan-models'

# Para almacenamiento verdaderamente persistente entre instancias,
# sube los modelos a un almacenamiento de objetos y descárgalos al inicio:
cat > /workspace/startup.sh << 'EOF'
#!/bin/bash
docker compose up -d
sleep 30
# Pre-descarga tus modelos de uso frecuente
curl -X POST http://localhost:1337/v1/models/pull \
  -H "Content-Type: application/json" \
  -d '{"model": "mistral:7b-instruct-v0.3-gguf-q4-km"}'
EOF
chmod +x /workspace/startup.sh
```

### 🔗 Usando Jan Server como reemplazo de OpenAI

```python
# Python — usa las bibliotecas cliente de OpenAI existentes
from openai import OpenAI

client = OpenAI(
    base_url="http://<CLORE_IP>:1337/v1",
    api_key="not-required"  # Jan Server no tiene autenticación por defecto
)

response = client.chat.completions.create(
    model="llama3.2:3b-gguf-q4-km",
    messages=[{"role": "user", "content": "Explica la computación cuántica"}],
    temperature=0.7
)
print(response.choices[0].message.content)
```

```bash
# Soporte de streaming
curl http://localhost:1337/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "llama3.2:3b-gguf-q4-km",
    "messages": [{"role": "user", "content": "Escribe un haiku sobre GPUs"}],
    "stream": true
  }'
```

### 📊 Monitorización del uso de recursos

```bash
# Observa la utilización de la GPU en tiempo real
watch -n 1 nvidia-smi

# Comprueba el uso de recursos del contenedor
docker stats jan-server

# Ver logs detallados
docker compose logs --tail=100 jan-server

# Comprobar tiempos de carga del modelo
docker compose logs jan-server | grep -E "(loaded|started|error)"
```

***

## Solución de problemas

### El contenedor no arranca — GPU no encontrada

```bash
# Verifica que el runtime NVIDIA Docker esté configurado
docker info | grep -i nvidia

# Prueba el acceso a la GPU directamente
docker run --rm --gpus all nvidia/cuda:12.1.0-base-ubuntu22.04 nvidia-smi

# Si esto falla, revisa la configuración del daemon de Docker
cat /etc/docker/daemon.json
# Debería contener: {"runtimes": {"nvidia": {...}}}
```

### Descarga del modelo atascada o fallida

```bash
# Comprobar espacio en disco
df -h /root

# Comprueba los logs del contenedor para ver el error
docker compose logs jan-server | tail -50

# Reintenta la descarga
curl -X POST http://localhost:1337/v1/models/pull \
  -H "Content-Type: application/json" \
  -d '{"model": "mistral:7b-instruct-v0.3-gguf-q4-km"}'
```

### Sin VRAM (CUDA out of memory)

```bash
# Comprueba el uso actual de VRAM
nvidia-smi --query-gpu=memory.used,memory.free --format=csv

# Detén primero todos los modelos en ejecución
curl http://localhost:1337/v1/models | jq -r '.data[].id' | while read model; do
  curl -X POST http://localhost:1337/v1/models/stop \
    -H "Content-Type: application/json" \
    -d "{\"model\": \"$model\"}"
done

# Usa un modelo más cuantizado (Q3 o Q4 en lugar de Q8)
# Q4_K_M típicamente usa ~50% del requerimiento de VRAM de Q8
```

### No se puede conectar a la API desde fuera del contenedor

```bash
# Asegura que el puerto 1337 esté enlazado en todas las interfaces
docker ps --format "table {{.Names}}\t{{.Ports}}"
# Debería mostrar: 0.0.0.0:1337->1337/tcp

# Revisa las reglas del firewall de Clore.ai — abre el puerto 1337 en la configuración del servidor
# Prueba localmente primero:
curl http://127.0.0.1:1337/health

# Luego prueba desde fuera:
curl http://<CLORE_SERVER_IP>:<MAPPED_PORT>/health
```

### Inferencia lenta (caída a CPU)

```bash
# Confirma que se está usando CUDA (no la CPU)
docker exec jan-server cortex ps
# Debería mostrar memoria GPU asignada

# Forzar capas de GPU al iniciar el modelo
curl -X POST http://localhost:1337/v1/models/start \
  -H "Content-Type: application/json" \
  -d '{"model": "mistral:7b-instruct-v0.3-gguf-q4-km", "ngl": 99}'
```

***

## Lecturas adicionales

* [Documentación oficial de Jan.ai](https://jan.ai/docs) — Documentación completa de la plataforma
* [Repositorio de Jan en GitHub](https://github.com/janhq/jan) — Código fuente e incidencias
* [Jan Server / Jan API](https://github.com/janhq/jan-server) — Documentación específica del servidor
* [Motor Cortex.cpp](https://github.com/janhq/cortex.cpp) — El motor de inferencia subyacente
* [Empezando con Clore.ai](/guides/guides_v2-es/primeros-pasos/getting-started.md) — Conceptos básicos de la plataforma
* [Guía de comparación de GPU](/guides/guides_v2-es/primeros-pasos/gpu-comparison.md) — Elige la GPU adecuada
* [Ejecutando Ollama en Clore.ai](/guides/guides_v2-es/modelos-de-lenguaje/ollama.md) — Servidor LLM alternativo
* [Ejecutando vLLM en Clore.ai](/guides/guides_v2-es/modelos-de-lenguaje/vllm.md) — Servidor de inferencia de alto rendimiento
* [Hugging Face Model Hub](https://huggingface.co/models?library=gguf) — Encuentra modelos GGUF

> 💡 **Consejo de coste:** Una RTX 3090 en Clore.ai (\~$0.20/hr) puede ejecutar Llama 3.1 8B a **\~50 tokens/segundo** — suficiente para uso personal o APIs de bajo tráfico. Para cargas de producción, considera vLLM (ver [guía de vLLM](/guides/guides_v2-es/modelos-de-lenguaje/vllm.md)) en una A100.


---

# 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/plataformas-y-agentes-de-ia/jan.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.
