bolt Valebyte VPS desde $4/mes — NVMe, despliegue en 60s.

Obtener VPS arrow_forward
eco Principiante Tutorial/Cómo hacer

LocalAI en un servidor con CPU: LLM sin tarjeta gráfica

calendar_month Sep 20, 2026 schedule 19 min de lectura visibility 41 vistas
LocalAI на CPU-сервере: LLM без видеокарты
info

¿Necesitas un servidor para esta guía? Ofrecemos servidores dedicados y VPS en más de 50 países con configuración instantánea.

¿Necesitas un VPS para esta guía?

Explore otras opciones de servidores dedicados en

LocalAI en un servidor CPU: LLM sin tarjeta gráfica

TL;DR

LocalAI permite ejecutar un modelo de lenguaje local con una API compatible con OpenAI en un VPS o servidor dedicado sin GPU. En esta guía se configurará un LocalAI protegido en Ubuntu 24.04 LTS con Docker, el backend CPU llama.cpp, un modelo en formato GGUF, HTTPS mediante Caddy, una clave API y copias de seguridad.

  • Para la primera puesta en marcha funcional, bastan 4 vCPU, 8 GB de RAM y 40–60 GB de SSD.
  • Para trabajar cómodamente con modelos 7B–8B en cuantización Q4, es mejor usar 8 vCPU y 16–32 GB de RAM.
  • LocalAI proporciona una interfaz compatible con la API de OpenAI: /v1/chat/completions, /v1/models y otros endpoints.
  • En CPU, la velocidad de un núcleo y la capacidad de RAM son más importantes que el número nominal de vCPU débiles.
  • Los modelos GGUF pueden almacenarse localmente: las solicitudes y los documentos no se envían a servicios externos de IA.
  • Para el acceso público son obligatorios TLS, firewall, una clave API y la restricción de acceso por IP o reverse proxy.

Qué configuramos y por qué

Схема: Что мы настраиваем и зачем
Esquema: Qué configuramos y por qué

LocalAI es un servicio de IA self-hosted que ejecuta modelos de lenguaje, modelos para generar embeddings, speech-to-text y algunas otras tareas en su propio servidor. Para LLM en CPU normalmente se utiliza el backend llama.cpp y modelos en formato GGUF. Están cuantizados: ocupan menos memoria que los pesos originales en FP16 o BF16 y pueden funcionar sin una GPU de NVIDIA.

El resultado práctico de esta guía es un servicio API disponible mediante HTTPS en su propio dominio. Podrán conectarse a él aplicaciones que sean compatibles con la API de OpenAI: un chat interno para el equipo, un bot en Telegram o Mattermost, un asistente de IDE, n8n, Dify, LibreChat, Open WebUI, su propio SaaS o backend en Python, Node.js y Go.

En el servidor funcionarán cuatro capas: Docker Compose administra el contenedor, LocalAI proporciona la API, el modelo GGUF responde a las solicitudes y Caddy recibe el tráfico HTTPS y lo proxifica internamente. LocalAI no se publicará directamente en Internet: el puerto 8080 permanecerá disponible solo en localhost.

Cuándo se justifica LocalAI en CPU

  • Se necesita una API autónoma para un equipo pequeño, un bot o herramientas internas.
  • Los datos no pueden o no conviene enviarlos a proveedores de LLM en la nube.
  • La carga es moderada: desde varias decenas hasta cientos de solicitudes al día.
  • Es aceptable una latencia de respuesta de varios segundos, en lugar de la velocidad de streaming de un servicio GPU.
  • Se necesita un presupuesto mensual predecible sin pago por tokens.
  • Desea experimentar con modelos, prompts de sistema y parámetros de inference.

Lo que un servidor CPU no resuelve

La inferencia en CPU no sustituye a una GPU para alta concurrencia. En un servidor con 8 vCPU modernas, un modelo 8B en Q4 suele generar aproximadamente 4–12 tokens por segundo, pero la cifra real depende de la generación de CPU, la frecuencia, AVX2/AVX-512, el tamaño del contexto y la carga de procesos vecinos. Para un único usuario interactivo, esto suele ser suficiente. Para decenas de diálogos simultáneos, ya no.

No debe esperarse un buen resultado de modelos grandes de 30B, 70B o superiores en un VPS convencional. Incluso si el modelo cabe en memoria, el tiempo hasta el primer token y la latencia total harán que el servicio sea incómodo. Para estos modelos se necesita un servidor con gran cantidad de RAM, CPU potentes o infraestructura GPU.

API en la nube y LocalAI self-hosted

Criterio API managed en la nube LocalAI en su propio servidor
Puesta en marcha Prácticamente instantánea Se necesitan servidor, Docker, modelo y protección de la API
Calidad de los modelos más grandes Normalmente superior Depende del modelo local seleccionado
Confidencialidad Los datos se envían a un proveedor externo Los datos permanecen en su infraestructura
Coste Pago por tokens o suscripción Coste fijo del servidor y almacenamiento
Velocidad con carga elevada Alta; la infraestructura se escala automáticamente Limitada por CPU, RAM y la configuración de la cola
Control sobre el modelo Limitado a los modelos disponibles Control total sobre el modelo, las plantillas y las versiones

Un esquema racional para un producto pequeño es utilizar LocalAI para tareas donde importan la privacidad, el bajo coste y la previsibilidad: clasificación, extracción de datos, resumen de textos internos, RAG sobre documentación y asistencia a desarrolladores. La API externa en la nube puede mantenerse como respaldo para solicitudes complejas o picos de carga.

Qué configuración de VPS se necesita para esta tarea

Схема: Какой VPS-конфиг нужен под эту задачу
Esquema: Qué configuración de VPS se necesita para esta tarea

El principal recurso para LocalAI en CPU es la memoria RAM. La segunda característica más importante es el rendimiento del núcleo del procesador. El disco es importante para almacenar modelos: un modelo GGUF 3B en Q4 suele ocupar 2–3 GB, un modelo 8B en Q4 aproximadamente 4,5–6 GB, y varias variantes de modelos y copias de seguridad llenan rápidamente un SSD pequeño.

Escenario CPU RAM SSD/NVMe Modelos recomendados
Pruebas, un usuario 4 vCPU 8 GB 50 GB 1B–4B, Q4
Chat, bot, RAG para un equipo 8 vCPU 16 GB 100 GB NVMe 7B–8B, Q4_K_M
Varios usuarios y modelos 12–16 vCPU 32–64 GB 200 GB NVMe 8B–14B, embeddings, reranker
Modelos grandes en CPU 16+ núcleos dedicados 64–128 GB 500 GB NVMe 14B–32B con un compromiso de velocidad

Configuración inicial práctica

Para la primera instalación de producción, elija 8 vCPU, 16 GB de RAM, 100 GB NVMe y una conexión desde 1 Gbit/s. Este servidor permitirá ejecutar un modelo principal del nivel de Llama 3.1/3.2 8B, Qwen2.5 7B o Mistral 7B en cuantización GGUF Q4, dejar margen para el sistema operativo y Caddy, y almacenar varios archivos de modelos. Como una de las opciones neutrales, puede elegir un VPS con las características indicadas.

Al elegir un plan, confirme si las vCPU están garantizadas, qué generación de CPU se utiliza y si el procesador cuenta con AVX2. Para llama.cpp, AVX2 influye notablemente en el rendimiento. A veces, 8 núcleos dedicados rápidos dan un resultado más útil que 16 núcleos virtuales sobrecargados.

Estimación de memoria para GGUF

No se debe calcular la RAM solo por el tamaño del archivo GGUF. Además de los pesos del modelo, se necesita memoria para la KV cache, los búferes de inference, el contenedor, el kernel de Linux y la caché de archivos. Una regla práctica segura: para un modelo 8B Q4 de 5 GB, asigne un servidor con al menos 12–16 GB de RAM. Para un 14B Q4 de 9–11 GB se necesitan al menos 24–32 GB de RAM.

El contexto también consume memoria. Si aumenta context_size de 4096 a 16384 tokens, el consumo de RAM puede crecer varios gigabytes. No establezca el contexto máximo «por si acaso»: para un chat habitual y RAG, en la mayoría de los casos bastan 4096–8192 tokens.

Cuándo se necesita un dedicado en lugar de un VPS

Un servidor dedicado es necesario cuando importan una velocidad de generación alta y estable, la garantía de ausencia de noisy neighbors, 32–128 GB de RAM, modelos grandes o solicitudes paralelas constantes. También es la elección correcta si LocalAI atiende un producto comercial donde la latencia influye directamente en la conversión.

Un VPS sigue siendo una buena opción para un prototipo, un servicio interno, un asistente personal y un equipo pequeño. Comience con un VPS, mida la velocidad real mediante la API y pase a un dedicado solo cuando aparezca un cuello de botella confirmado: falta de RAM, saturación de CPU o crecimiento de la cola de solicitudes.

Cómo influye la ubicación del servidor

La ubicación no acelera el cálculo de tokens, pero influye en la latencia de red hasta los usuarios. Para un chat, es recomendable alojar el servidor en una región cercana a la mayoría de los clientes. Una diferencia de 50–100 ms se nota especialmente en las respuestas en streaming, aunque la latencia principal en CPU seguirá estando relacionada con la generación del modelo.

Si LocalAI procesa datos personales, documentos de la empresa o información médica, tenga también en cuenta los requisitos de jurisdicción, almacenamiento de datos y transferencia transfronteriza. Aloje las copias de seguridad separadas del servidor principal, preferiblemente en otro centro de datos.

Preparación del servidor

Схема: Подготовка сервера
Diagrama: Preparación del servidor

A continuación se utiliza Ubuntu Server 24.04 LTS. En el momento de la configuración, es una base LTS estable con un largo período de soporte. Inicie sesión en el servidor como usuario root solo para la preparación inicial; después cree un administrador independiente y desactive el inicio de sesión de root por SSH.

Actualización del sistema y paquetes básicos

El comando instala las actualizaciones de seguridad actuales, herramientas de diagnóstico, firewall y fail2ban.

apt update && apt full-upgrade -y
apt install -y ca-certificates curl gnupg jq nano vim \
  ufw fail2ban unattended-upgrades \
  htop iotop ncdu rsync

Reinicie el servidor si se actualizó el núcleo. Esto aplicará el nuevo kernel y evitará que un núcleo vulnerable siga ejecutándose en memoria.

if [ -f /var/run/reboot-required ]; then reboot; fi

Creación del administrador

Sustituya deploy por su propio nombre de usuario. La cuenta se utilizará para Docker Compose y el mantenimiento posterior de LocalAI.

adduser deploy
usermod -aG sudo deploy

Copie su clave pública SSH al servidor desde el equipo local. Ejecute este comando en su equipo, no en el VPS.

ssh-copy-id deploy@SERVER_IP

Compruebe el inicio de sesión en una terminal independiente. No cierre la sesión actual de root hasta asegurarse de que la autenticación mediante clave funciona.

ssh deploy@SERVER_IP

Protección de SSH

Abra la configuración de SSH y prohíba el inicio de sesión como root y la autenticación por contraseña. Antes de ello, asegúrese de que el usuario deploy dispone de una clave funcional.

sudo nano /etc/ssh/sshd_config.d/99-hardening.conf
PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
X11Forwarding no
MaxAuthTries 3
LoginGraceTime 30

Compruebe la sintaxis y reinicie SSH. Si el comando sshd -t no muestra errores, la configuración es correcta.

sudo sshd -t && sudo systemctl restart ssh

Firewall y fail2ban

Abra únicamente SSH, HTTP y HTTPS. No abra el puerto de LocalAI 8080: después de la configuración, solo escuchará en 127.0.0.1.

sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status verbose

Active fail2ban. Ubuntu proporciona un filtro listo para OpenSSH; el servicio bloqueará temporalmente una IP tras una serie de intentos de inicio de sesión fallidos.

sudo systemctl enable --now fail2ban
sudo fail2ban-client status sshd

Comprobación de recursos antes de la instalación

Antes de descargar el modelo, compruebe la RAM disponible, el tamaño del disco y las características del procesador. Esto ayudará a elegir de antemano la cuantización y el número de hilos adecuados.

free -h
df -h /
lscpu | egrep 'Model name|CPU\(s\)|Thread|AVX|Flags'
nproc

Si la salida de lscpu no incluye AVX2, LocalAI aún puede funcionar, pero el rendimiento en CPU puede ser notablemente inferior. En ese caso, es más razonable utilizar un modelo compacto de 3B–4B y no intentar atender varios chats simultáneos.

Instalación del software — paso a paso

Схема: Установка ПО — пошагово
Diagrama: Instalación del software — paso a paso

Esta configuración utiliza Docker Engine 28+ y Docker Compose v2, Ubuntu 24.04 LTS, Caddy 2.8+ y la rama estable actual de LocalAI 3.x. Para producción, no deje la etiqueta latest de forma permanente: tras realizar pruebas satisfactorias, fije una etiqueta específica o el digest de la imagen en compose.yaml.

Instalación de Docker Engine

Elimine los paquetes antiguos de Docker si están presentes. Esto evita conflictos entre los paquetes de Ubuntu y el Docker Engine oficial.

sudo apt remove -y docker.io docker-compose docker-compose-v2 \
  docker-doc podman-docker containerd runc 2>/dev/null || true

Añada la clave oficial del repositorio de Docker y conecte el repositorio para Ubuntu 24.04.

sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \
  sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
  https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

Instale Docker Engine, containerd y el plugin de Compose. Compose iniciará LocalAI y ejecutará el healthcheck.

sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io \
  docker-buildx-plugin docker-compose-plugin

Permita al usuario deploy administrar Docker sin sudo. Tras ejecutar el comando, cierre la sesión SSH y vuelva a iniciar sesión para que se aplique el grupo.

sudo usermod -aG docker deploy
exit

Tras volver a iniciar sesión, asegúrese de que Docker funciona. El contenedor hello-world debe finalizar sin errores.

docker version
docker compose version
docker run --rm hello-world

Creación de la estructura del proyecto

Todos los archivos de LocalAI estarán en /opt/localai. El directorio models almacena archivos GGUF y configuraciones YAML de modelos, mientras que data conserva los datos de LocalAI entre reinicios.

sudo mkdir -p /opt/localai/{models,data,backups}
sudo chown -R deploy:deploy /opt/localai
cd /opt/localai

Descarga del primer modelo

Para la primera ejecución en CPU, utilice el modelo instructivo Qwen2.5-3B-Instruct con cuantización Q4_K_M. Es más compacto que los modelos 7B–8B, funciona correctamente con 8 GB de RAM y es adecuado para comprobar la API. Antes de usarlo en producción, revise la licencia del modelo concreto y las condiciones de su distribución.

El siguiente comando descarga el GGUF en el directorio de modelos. La URL se indica como ejemplo de repositorio público; antes de descargar, compruebe el nombre actual del archivo y el hash en la página de lanzamiento del modelo.

cd /opt/localai/models

curl -L --fail --retry 3 \
  -o Qwen2.5-3B-Instruct-Q4_K_M.gguf \
  "https://huggingface.co/bartowski/Qwen2.5-3B-Instruct-GGUF/resolve/main/Qwen2.5-3B-Instruct-Q4_K_M.gguf"

Compruebe que el archivo se descargó realmente y no tiene tamaño cero. Para un modelo 3B Q4, espere un tamaño de unos 2–3 GB.

ls -lh /opt/localai/models
sha256sum /opt/localai/models/Qwen2.5-3B-Instruct-Q4_K_M.gguf

Creación de secretos

No almacene la clave API en el archivo compose ni en el código fuente de la aplicación. Genere un valor largo y guárdelo en el archivo .env, accesible solo para el usuario deploy.

cd /opt/localai
umask 077
printf 'LOCALAI_API_KEY=%s\n' "$(openssl rand -hex 32)" > .env
chmod 600 .env
cat .env

Guarde esta clave en un gestor de secretos. Las aplicaciones cliente la necesitarán en la cabecera Authorization: Bearer.

Configuración de LocalAI, modelos y HTTPS

Diagrama: Configuración de LocalAI, modelos y HTTPS
Diagrama: Configuración de LocalAI, modelos y HTTPS

Descripción del modelo

Cree un archivo de configuración YAML. El parámetro threads establece el número de hilos de CPU para inference. En un servidor con 8 vCPU, comience con 6: quedarán recursos para el SO, el reverse proxy y el procesamiento de red. El valor context_size 4096 es un punto de partida seguro para un servidor con CPU.

nano /opt/localai/models/qwen-cpu.yaml
name: qwen2.5-3b-cpu
backend: llama-cpp
parameters:
  model: Qwen2.5-3B-Instruct-Q4_K_M.gguf
  context_size: 4096
  threads: 6
  temperature: 0.7
  top_p: 0.9
  max_tokens: 512
template:
  chat: |
    {{if .System}}<|im_start|>system
    {{.System}}<|im_end|>
    {{end}}{{range .Messages}}<|im_start|>{{.Role}}
    {{.Content}}<|im_end|>
    {{end}}<|im_start|>assistant
    {{.Assistant}}

La plantilla de chat es importante: transforma los mensajes de la API de OpenAI al formato con el que se entrenó el modelo Qwen. Si las respuestas de repente contienen tokens de servicio, repiten el prompt o ignoran los roles, compruebe primero la chat template.

Docker Compose para inferencia con CPU

Cree compose.yaml. La imagen localai/localai:latest-aio-cpu está diseñada para CPU e incluye los componentes necesarios para una ejecución típica. Tras confirmar una versión funcional, reemplace latest-aio-cpu por una version tag específica de las release notes oficiales.

nano /opt/localai/compose.yaml
services:
  localai:
    image: localai/localai:latest-aio-cpu
    container_name: localai
    restart: unless-stopped
    env_file:
      - .env
    environment:
      - DEBUG=false
      - MODELS_PATH=/models
      - THREADS=6
      - CONTEXT_SIZE=4096
    volumes:
      - ./models:/models
      - ./data:/data
    ports:
      - "127.0.0.1:8080:8080"
    healthcheck:
      test: ["CMD-SHELL", "curl -fsS http://localhost:8080/readyz || curl -fsS http://localhost:8080/v1/models"]
      interval: 30s
      timeout: 10s
      retries: 5
      start_period: 120s
    deploy:
      resources:
        limits:
          memory: 12G

Un límite de memoria de 12 GB es adecuado para un servidor con 16 GB de RAM y un modelo 3B. En un VPS con 8 GB de RAM, establezca memory: 6G y utilice un modelo más compacto. En un servidor con 32 GB de RAM, para un modelo 8B puede aumentar el límite a 20–24 GB.

Inicie el contenedor en segundo plano y consulte los registros. La primera carga puede tardar más, ya que LocalAI inicializa el backend y lee el archivo del modelo desde el disco.

cd /opt/localai
docker compose pull
docker compose up -d
docker compose ps
docker compose logs -f --tail=100

No publique el puerto local 8080 a través del firewall. La comprobación siguiente se realiza directamente en el servidor y muestra que la API detecta el modelo configurado.

curl -s http://127.0.0.1:8080/v1/models | jq .

Comprobación local de chat completion

Sustituya el valor de la clave mediante un comando que la lea desde .env. El parámetro stream está desactivado para un diagnóstico sencillo; después de iniciar la aplicación, puede activarlo para entregar tokens gradualmente.

cd /opt/localai
source .env

curl -sS http://127.0.0.1:8080/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer ${LOCALAI_API_KEY}" \
  -d '{
    "model": "qwen2.5-3b-cpu",
    "messages": [
      {
        "role": "system",
        "content": "Ты краткий технический помощник."
      },
      {
        "role": "user",
        "content": "Объясни в одном предложении, что такое reverse proxy."
      }
    ],
    "temperature": 0.2,
    "max_tokens": 100,
    "stream": false
  }' | jq .

Si la API responde con un objeto JSON que contiene choices, la configuración básica está completada. Si LocalAI devuelve 401, compruebe el nombre de la variable y la compatibilidad con la clave API de la versión de imagen utilizada. En algunas compilaciones de LocalAI, la clave se establece mediante una variable de entorno independiente o resulta más conveniente implementar la autenticación a nivel de Caddy.

Configuración de Caddy y TLS

Para HTTPS se necesita un dominio cuyo registro A apunte a la IP del servidor. Antes de iniciar Caddy, compruebe el DNS: el dominio debe devolver la dirección IPv4 pública del VPS. Los puertos 80 y 443 deben ser accesibles desde el exterior.

Instale Caddy desde el repositorio oficial. Obtiene y renueva automáticamente los certificados de Let’s Encrypt si el DNS y el firewall están configurados correctamente.

sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | \
  sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | \
  sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install -y caddy

Cree una contraseña adicional para basic authentication. Es una segunda barrera ante la API: el cliente necesitará tanto Basic Auth como un Bearer token. Inserte en el Caddyfile el hash que devuelva el comando.

caddy hash-password --plaintext 'СЮДА_ДЛИННЫЙ_ОТДЕЛЬНЫЙ_ПАРОЛЬ'

Abra la configuración de Caddy. Sustituya el dominio, el nombre de usuario y el hash. Si es necesario, en lugar de basic auth puede limitar el acceso mediante una red VPN WireGuard o direcciones IP de la oficina.

sudo nano /etc/caddy/Caddyfile
llm.example.com {
    encode zstd gzip

    @not_api not path /v1/ /readyz /healthz
    respond @not_api "Not found" 404

    basicauth {
        apiadmin $2a$14$REPLACE_WITH_CADDY_PASSWORD_HASH
    }

    reverse_proxy 127.0.0.1:8080 {
        header_up Host {host}
        header_up X-Real-IP {remote_host}
        header_up X-Forwarded-For {remote_host}
        transport http {
            read_timeout 300s
            write_timeout 300s
        }
    }

    log {
        output file /var/log/caddy/localai-access.log
        format json
    }
}

Compruebe el archivo antes de aplicarlo. A continuación, recargue Caddy y asegúrese de que el certificado se haya emitido.

sudo caddy validate --config /etc/caddy/Caddyfile
sudo systemctl reload caddy
sudo systemctl status caddy --no-pager
sudo journalctl -u caddy -n 50 --no-pager

Comprobación externa de la API HTTPS

Ejecute el comando desde el equipo de trabajo. Comprueba TLS, basic authentication, el Bearer token y la disponibilidad de la lista de modelos a través del dominio público.

curl -sS https://llm.example.com/v1/models \
  -u 'apiadmin:ВАШ_ОТДЕЛЬНЫЙ_ПАРОЛЬ' \
  -H 'Authorization: Bearer ВАШ_LOCALAI_API_KEY' | jq .

Para el cliente Python, utilice el SDK habitual de OpenAI indicando su propio base_url. Es mejor pasar la contraseña de basic auth mediante un reverse proxy protegido o una VPN; para aplicaciones API resulta más conveniente dejar solo la autenticación Bearer y restringir las direcciones IP en Caddy.

from openai import OpenAI

client = OpenAI(
    base_url="https://llm.example.com/v1",
    api_key="ВАШ_LOCALAI_API_KEY",
)

response = client.chat.completions.create(
    model="qwen2.5-3b-cpu",
    messages=[
        {"role": "user", "content": "Напиши короткое приветствие."}
    ],
    temperature=0.4,
)

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

Control del rendimiento

Durante una solicitud de prueba, ejecute htop en una ventana SSH independiente. Los procesos de inference deben utilizar aproximadamente el número de núcleos establecido por el parámetro threads. Si el servidor empieza a utilizar swap, reduzca el contexto, elija una cuantización menor o aumente la RAM.

htop
free -h
docker stats localai
docker compose -f /opt/localai/compose.yaml logs --tail=100 localai

Copias de seguridad y mantenimiento

Diagrama: Copias de seguridad y mantenimiento
Diagrama: Copias de seguridad y mantenimiento

LocalAI normalmente no contiene una base de datos crítica si se utiliza solo como API de inference. Sin embargo, debe conservar la configuración, los archivos de modelos, las variables de entorno, el Caddyfile, los datos de las aplicaciones cliente y, si aparecen, la base de datos vectorial RAG. No considere la Docker image como una copia de seguridad: la imagen se puede descargar de nuevo, pero las configuraciones y los datos no.

Qué incluir en la copia de seguridad

  • /opt/localai/compose.yaml — versión del servicio y configuración del contenedor.
  • /opt/localai/models/.yaml — parámetros y chat templates de los modelos.
  • /opt/localai/.env — claves API; almacenar solo en un backup cifrado.
  • /opt/localai/data — datos persistentes de LocalAI, si se utilizan.
  • /etc/caddy/Caddyfile — reverse proxy y reglas de acceso.
  • Directorio de modelos GGUF — según el caso: los archivos son grandes, pero volver a descargarlos puede llevar mucho tiempo.
  • Datos de la pila RAG: PostgreSQL, Qdrant, pgvector, Chroma u otro vector store.

Realice una copia diaria de la configuración. Puede hacer backup de los modelos semanalmente o no hacer copia alguna si conserva una lista verificada de URL, versiones y SHA256. Para un servicio de production, es más prudente contar con al menos una copia remota de GGUF: el repositorio público puede cambiar su estructura, eliminar el archivo o restringir el acceso.

Copia de seguridad mediante restic

Restic cifra el archivo antes de enviarlo a un almacenamiento compatible con S3. Instale el paquete y cree un archivo de secretos independiente. No añada este archivo a Git ni lo envíe por mensajería.

sudo apt install -y restic
sudo install -d -m 700 /root/.config/restic
sudo nano /root/.config/restic/localai.env
export RESTIC_REPOSITORY="s3:https://s3.example.net/localai-backups"
export RESTIC_PASSWORD="ДЛИННЫЙ_СЛУЧАЙНЫЙ_ПАРОЛЬ_РЕПОЗИТОРИЯ"
export AWS_ACCESS_KEY_ID="S3_ACCESS_KEY"
export AWS_SECRET_ACCESS_KEY="S3_SECRET_KEY"

Restrinja el acceso al archivo e inicialice el repositorio remoto. Esta operación se realiza una sola vez.

sudo chmod 600 /root/.config/restic/localai.env
sudo bash -c 'source /root/.config/restic/localai.env && restic init'

Cree un script. En el ejemplo, los modelos se excluyen del backup diario; añada el directorio /opt/localai/models si también desea copiar los archivos GGUF. El script también elimina snapshots demasiado antiguos según la política de retención.

sudo nano /usr/local/sbin/backup-localai.sh
#!/usr/bin/env bash
set -euo pipefail

source /root/.config/restic/localai.env

restic backup \
  /opt/localai/compose.yaml \
  /opt/localai/.env \
  /opt/localai/data \
  /opt/localai/models \
  /etc/caddy/Caddyfile \
  --exclude='.gguf' \
  --tag localai

restic forget \
  --keep-daily 7 \
  --keep-weekly 4 \
  --keep-monthly 6 \
  --prune

Haga ejecutable el script, ejecútelo manualmente y compruebe la lista de snapshots. El primer backup confirmará que el acceso a S3, el cifrado y los permisos están configurados correctamente.

sudo chmod 700 /usr/local/sbin/backup-localai.sh
sudo /usr/local/sbin/backup-localai.sh
sudo bash -c 'source /root/.config/restic/localai.env && restic snapshots'

Añada una ejecución diaria mediante cron a las 03:30. Los registros se guardan en un archivo independiente, que conviene revisar al menos una vez por semana.

sudo crontab -e
30 3    /usr/local/sbin/backup-localai.sh >> /var/log/localai-backup.log 2>&1

Comprobación de restauración

Un backup sin una prueba de restauración es solo una suposición. Una vez al mes, restaure un snapshot en un directorio temporal de otro servidor o de una máquina local, compruebe las configuraciones YAML y asegúrese de que .env esté presente.

sudo mkdir -p /tmp/localai-restore
sudo bash -c 'source /root/.config/restic/localai.env && \
  restic restore latest --target /tmp/localai-restore'
sudo find /tmp/localai-restore -maxdepth 4 -type f | sort

Actualizaciones seguras

No actualice LocalAI, Docker, Caddy y el modelo al mismo tiempo. De lo contrario, si ocurre un error será difícil determinar su causa. Para un servicio pequeño, utilice una maintenance window: avise a los usuarios, haga un backup, actualice un componente, realice una smoke test y solo entonces continúe.

La actualización de LocalAI es así: primero guarde el image digest actual, después descargue la nueva imagen, vuelva a crear el contenedor y compruebe la API. Si el modelo o la API dejan de funcionar, restaure la etiqueta de imagen anterior en compose.yaml y vuelva a ejecutar up -d.

cd /opt/localai
docker inspect localai --format='{{.Image}}'
docker compose pull
docker compose up -d
docker compose ps
curl -fsS http://127.0.0.1:8080/v1/models | jq .

Para una actualización rolling sin tiempo de inactividad, necesitará al menos dos instancias de backend, un balanceador y suficiente margen de RAM. En un único VPS con CPU suele ser más seguro programar una breve ventana de mantenimiento: la carga de un solo modelo ya consume una parte considerable de la memoria.

Resolución de problemas y FAQ

¿Por qué LocalAI no ve el modelo en /v1/models?

Primero compruebe la ruta de montaje: el directorio del host /opt/localai/models debe estar conectado en el contenedor como /models. Luego revise los logs: docker compose logs --tail=200 localai. Una causa frecuente es un YAML incorrecto, que el nombre del archivo GGUF no coincida con el parámetro model o permisos incorrectos en el directorio. Asegúrese también de que el archivo de configuración tenga la extensión .yaml y esté junto al modelo.

¿Por qué la respuesta se genera muy lentamente?

Compruebe la carga mediante htop y docker stats localai. En CPU, una velocidad de varios tokens por segundo es normal, especialmente para modelos 7B–8B. Reduzca context_size a 4096, establezca threads aproximadamente en el número de núcleos físicos o virtuales disponibles menos uno o dos, use Q4_K_M en lugar de Q5/Q6 y elija un modelo 3B–4B. Si la CPU está constantemente al 100% y aumenta el número de usuarios, necesitará un servidor más potente o una GPU.

El contenedor se reinicia y los logs muestran out of memory. ¿Qué hacer?

Esto significa que no hubo suficiente RAM para los modelos, la KV cache y los procesos del sistema. Ejecute free -h y compruebe si se utilizó swap. Reduzca el tamaño del contexto, el número de modelos cargados simultáneamente y la cuantización. Por ejemplo, sustituya 8B Q5 por 8B Q4 o 3B Q4. No intente resolver el problema solo con más swap: la inferencia será extremadamente lenta. Para un modelo 8B Q4, el mínimo práctico es 16 GB de RAM.

¿Por qué no se emite el certificado HTTPS de Caddy?

Compruebe el registro A del dominio con el comando dig +short llm.example.com: debe apuntar a la IP del servidor. Asegúrese de que los puertos 80 y 443 estén abiertos en UFW y en el panel del proveedor, si dispone de un firewall independiente. Consulte sudo journalctl -u caddy -n 100. Las causas frecuentes son: DNS aún no se ha actualizado, el dominio se proxifica mediante una CDN externa con un modo TLS inadecuado o el puerto 80 está ocupado por otro servidor web.

La API devuelve 401 Unauthorized. ¿Dónde buscar el error?

Divida la comprobación por niveles. Primero realice una solicitud a 127.0.0.1:8080 sin Caddy. Luego compruebe Basic Auth mediante curl -u y después el Bearer token. Asegúrese de que el valor en .env no contenga espacios adicionales y de que el contenedor se haya reiniciado tras modificar el archivo: docker compose up -d --force-recreate. No pase la clave en la URL ni la guarde en el shell history.

¿Qué configuración mínima de VPS es adecuada?

Para familiarizarse con LocalAI, bastará como mínimo un VPS con 4 vCPU, 8 GB de RAM y 50 GB de SSD. En él debe ejecutar un modelo pequeño 1B–4B con cuantización Q4, un contexto de 2048–4096 y un diálogo activo. Para un modelo 7B–8B, esta configuración ya es límite: el servicio puede funcionar, pero será lento o tendrá falta de memoria. Para un funcionamiento estable con 8B, elija 8 vCPU y 16 GB de RAM.

¿Qué elegir para esta tarea: VPS o dedicated?

Un VPS es adecuado para un asistente personal, un prototipo, RAG sobre documentos internos y un equipo con varios usuarios. Conviene elegir dedicated con carga constante de CPU, requisitos de tiempos de respuesta estables, uso de modelos 14B o mayores, 32–64 GB de RAM o paralelismo considerable. Un enfoque práctico es comenzar con un VPS, recopilar métricas de velocidad, memoria y colas, y después migrar a un servidor dedicado solo cuando exista una necesidad confirmada.

¿Cómo añadir un segundo modelo sin detener el primero?

Copie el segundo archivo GGUF en /opt/localai/models, cree un YAML independiente para él con un name único y reinicie el contenedor. Tenga en cuenta que varios modelos cargados simultáneamente suman su consumo de RAM. En un servidor de 16 GB es razonable mantener un modelo 8B o varios modelos compactos. Si el modelo se necesita rara vez, considere una instancia independiente de LocalAI o un mecanismo para descargar modelos no utilizados, si su versión lo admite.

¿Por qué el modelo responde de forma incoherente, repite texto o ignora el prompt del sistema?

Normalmente el problema está en un chat template incompatible, no en la CPU. Cada modelo instruct tiene su propio formato de roles y tokens especiales. Consulte la model card oficial y compare la plantilla recomendada con el archivo YAML de LocalAI. Reduzca también temperature a 0.2–0.5, asegúrese de haber elegido la versión instruct del modelo y no mezcle la plantilla de Qwen con Llama o Mistral. Para el diagnóstico, envíe una solicitud breve sin un historial largo.

Conclusiones y próximos pasos

Esquema: Conclusiones y próximos pasos
Esquema: Conclusiones y próximos pasos

Ahora el servidor ejecuta LocalAI con inferencia en CPU, un modelo GGUF local, una API compatible con OpenAI, HTTPS y protección básica. Esta pila es adecuada para herramientas de AI privadas y carga moderada sin comprar ni alquilar una GPU.

  1. Mida la velocidad de generación, el uso de RAM y las latencias reales en solicitudes típicas de su tarea.
  2. Añada RAG: un modelo de embeddings, vector store y control de acceso a los documentos.
  3. Cuando aumente la carga, migre a CPU más rápidas, un servidor dedicated, varias instancias detrás de un reverse proxy o inferencia con GPU.

Antes de implementar en production, fije las versiones de la Docker image y los modelos, documente los SHA256 de los archivos GGUF, compruebe periódicamente la restauración de backups y no publique la API sin autenticación.

¿Te fue útil esta guía?

Tus comentarios nos ayudan a mejorar nuestras guías.

Compartir esta publicación:

Envía esta guía a alguien a quien pueda resultarle útil.

Telegram VKVK WhatsApp Facebook LinkedIn XX

LocalAI en servidor con CPU: LLM sin tarjeta gráfica
support_agent
Valebyte Support
Usually replies within minutes
Hi there!
Send us a message and we'll reply as soon as possible.