| Modelo | Propósito | Cuantización | RAM uso | Velocidad CPU | Calidad vs GPT |
|---|---|---|---|---|---|
| Mistral-7B-Instruct v0.2 TheBloke/GGUF |
Chat soporte | Q5_K_M |
~5.1 GB | ~8 tok/s | ~GPT-3.5 |
| all-MiniLM-L6-v2 SentenceTransformers |
Embeddings | F32 nativo | ~90 MB | <1 ms/req | Comparable |
| Whisper Base OpenAI Whisper |
Transcripción | INT8 | ~148 MB | ~5x RT | ~Whisper API |
| CodeLlama-7B-Instruct Meta · opcional |
SQL / código | Q4_K_M |
~4.2 GB | ~10 tok/s | Especializado |
CONTEXT_SIZE=4096 eso es 8 MB por sesión activa.
version: "3.8" services: localai: image: localai/localai:latest-cpu container_name: nexusdata-localai ports: - "8080:8080" volumes: - ./models:/build/models - ./models-cache:/build/.cache environment: - THREADS=14 # 16 cores físicos - 2 para OS - CONTEXT_SIZE=4096 # ~8MB RAM por sesión - PARALLEL_REQUESTS=4 # Hasta 4 inferencias simultáneas - GALLERIES='[{"name":"model-gallery","url":"github:mudler/LocalAI/gallery/index.yaml@master"}]' - MODELS_PATH=/build/models restart: unless-stopped healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8080/readyz"] interval: 30s timeout: 10s retries: 3 mem_limit: 32g # Límite 32 GB (la mitad del VPS) cpus: "14"
name: mistral backend: llama-cpp parameters: model: mistral-7b-instruct-v0.2.Q5_K_M.gguf temperature: 0.7 top_p: 0.9 top_k: 40 context_size: 8192 threads: 14 gpu_layers: 0 # CPU-only template: chat_message: | {{.RoleName}}: {{.Content}} chat: | [INST] {{.Input}} [/INST]
name: text-embedding-ada-002 backend: sentencetransformers parameters: model: all-MiniLM-L6-v2 # Mapea el nombre openai original # para que el código existente # funcione sin cambios --- name: whisper-1 backend: whisper parameters: model: whisper-base.bin language: es # Reuniones en español translate: false
import OpenAI from 'openai'; // ⚡ ÚNICO CAMBIO: baseURL apunta a LocalAI en lugar de api.openai.com const ai = new OpenAI({ apiKey: 'not-needed', // LocalAI no requiere API key baseURL: 'http://localai:8080/v1', // Docker service name = localai }); // ✅ Chat de soporte — funciona exactamente igual que antes export async function chatSoporte(pregunta: string): Promise<string> { const resp = await ai.chat.completions.create({ model: 'mistral', messages: [ { role: 'system', content: 'Eres asistente de análisis de datos industriales de NexusData. Responde en español.' }, { role: 'user', content: pregunta }, ], temperature: 0.6, }); return resp.choices[0].message.content ?? ''; } // ✅ Embeddings para búsqueda semántica en documentos técnicos export async function embedDocumento(texto: string): Promise<number[]> { const resp = await ai.embeddings.create({ model: 'text-embedding-ada-002', // Mismo nombre → mapeado a all-MiniLM input: texto, }); return resp.data[0].embedding; } // ✅ Transcripción de reuniones export async function transcribirReunion(audio: File): Promise<string> { const resp = await ai.audio.transcriptions.create({ model: 'whisper-1', // Mismo nombre → mapeado a whisper-base file: audio, language: 'es', }); return resp.text; }
LOCALAI_BASE_URL como variable de entorno en .env.local y úsala como baseURL. En desarrollo apunta a http://localhost:8080/v1, en producción a http://localai:8080/v1. Sin tocar código.
docker pull localai/localai:latest-cpu (~2 GB)./models y ./models-cacheGET /readyz devuelve 200LOCALAI_BASE_URL a variables de entornoai-client.ts con baseURL dinámicahttp://localai:8080/v1./models#!/bin/bash # NexusData SL — LocalAI Setup Script # VPS: Ubuntu 22.04, 16 cores, 64 GB RAM # 1. Crear directorios mkdir -p ./localai/{models,models-cache} cd ./localai # 2. Descargar modelos wget -P ./models/ \ https://huggingface.co/TheBloke/Mistral-7B-Instruct-v0.2-GGUF/resolve/main/mistral-7b-instruct-v0.2.Q5_K_M.gguf wget -P ./models/ \ https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-base.bin mv ./models/ggml-base.bin ./models/whisper-base.bin # 3. Arrancar LocalAI docker compose up -d # 4. Esperar hasta que esté listo until curl -sf http://localhost:8080/readyz; do sleep 5; done echo "✓ LocalAI listo" # 5. Instalar all-MiniLM-L6-v2 via gallery curl -X POST http://localhost:8080/models/apply \ -H "Content-Type: application/json" \ -d '{"id": "huggingface://mudler/all-MiniLM-L6-v2-gguf/all-MiniLM-L6-v2.gguf"}' # 6. Verificar modelos disponibles curl -s http://localhost:8080/v1/models | jq '.data[].id' # Output esperado: # "mistral" # "text-embedding-ada-002" # "whisper-1"