From bdf42e74a3121197ac5b0adbaf618f41d7ab3134 Mon Sep 17 00:00:00 2001 From: Carlos Tello Date: Sun, 20 Sep 2026 13:43:58 -0300 Subject: [PATCH] first commit --- .gitignore | 61 +++++ Makefile | 89 +++++++ README.md | 187 ++++++++++++++ requirements.txt | 22 ++ scripts/backup.sh | 54 ++++ scripts/health-check.sh | 88 +++++++ scripts/install.sh | 534 ++++++++++++++++++++++++++++++++++++++++ scripts/monitor.sh | 100 ++++++++ scripts/update.sh | 53 ++++ 9 files changed, 1188 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 README.md create mode 100644 requirements.txt create mode 100644 scripts/backup.sh create mode 100644 scripts/health-check.sh create mode 100644 scripts/install.sh create mode 100644 scripts/monitor.sh create mode 100644 scripts/update.sh diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3e21b20 --- /dev/null +++ b/.gitignore @@ -0,0 +1,61 @@ +# Models & Large Files +.ollama/ +models/ +*.safetensors +*.gguf +*.bin +*.pth + +# Workspace +workspace/ +uploads/ +backups/ + +# Python +__pycache__/ +*.pyc +*.pyo +*.egg-info/ +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +.venv/ +venv/ +ENV/ + +# IDE +.vscode/ +.idea/ +*.swp +*.swo +*~ +.DS_Store + +# Environment +.env +.env.local +.env.*.local + +# Logs +logs/ +*.log + +# Temporary +*.tmp +*.cache +.pytest_cache/ +.coverage + +# OS +.DS_Store +Thumbs.db \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..79ace9c --- /dev/null +++ b/Makefile @@ -0,0 +1,89 @@ +.PHONY: help install update monitor health-check backup clean reinstall logs + +help: + @echo "LLM Server - Comandos disponibles:" + @echo "" + @echo " make install - Instalar todo desde cero (requiere sudo)" + @echo " make update - Actualizar código y dependencias" + @echo " make monitor - Ver monitoreo en tiempo real" + @echo " make health-check - Verificar estado del sistema" + @echo " make backup - Hacer backup de configuración" + @echo " make logs - Ver logs de servicios" + @echo " make status - Ver estado de servicios" + @echo " make start - Iniciar servicios" + @echo " make stop - Detener servicios" + @echo " make restart - Reiniciar servicios" + @echo " make clean - Limpiar archivos temporales" + @echo " make reinstall - Reinstalar (redownload modelos)" + +install: + @echo "Instalando LLM Server..." + sudo bash scripts/install.sh + +install-quick: + @echo "Instalación rápida (sin modelos)..." + sudo bash scripts/install.sh --quick + +install-gpu-only: + @echo "Instalando solo GPU drivers..." + sudo bash scripts/install.sh --gpu-only + +update: + bash scripts/update.sh + +monitor: + bash scripts/monitor.sh + +health-check: + bash scripts/health-check.sh + +backup: + bash scripts/backup.sh + +logs: + @echo "Logs de Ollama:" + sudo journalctl -u ollama -f + +logs-api: + @echo "Logs de API:" + sudo journalctl -u llm-api -f + +status: + @echo "Ollama:" + @sudo systemctl status ollama --no-pager + @echo "" + @echo "LLM API:" + @sudo systemctl status llm-api --no-pager + +start: + sudo systemctl start ollama llm-api + @echo "✅ Servicios iniciados" + +stop: + sudo systemctl stop ollama llm-api + @echo "✅ Servicios detenidos" + +restart: + sudo systemctl restart ollama llm-api + @echo "✅ Servicios reiniciados" + +clean: + rm -rf __pycache__ .pytest_cache .venv venv + find . -type f -name "*.pyc" -delete + @echo "✅ Limpiado" + +reinstall: + @echo "Reinstalando LLM Server..." + sudo bash scripts/install.sh --gpu-only + make update + @echo "✅ Reinstalación completada" + +info: + @echo "========== INFORMACIÓN DEL SERVIDOR ==========" + @echo "Hostname: $$(hostname)" + @echo "IP: $$(hostname -I)" + @echo "SO: $$(lsb_release -d | cut -f2)" + @echo "CPU: $$(lscpu | grep 'Model name' | cut -d: -f2)" + @echo "RAM: $$(free -h | awk 'NR==2 {print $$2}')" + @echo "GPU: $$(nvidia-smi --query-gpu=name --format=csv,noheader 2>/dev/null || echo 'No disponible')" + @echo "==============================================" \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..69b70e5 --- /dev/null +++ b/README.md @@ -0,0 +1,187 @@ +# LLM Server - Deployment Automatizado + +Sistema completo de IA agentica con LLMs locales (Phi + DeepSeek 33B) en Ubuntu 22.04. + +## Requisitos Mínimos + +- **CPU**: Intel i3-10105 (4 cores) +- **RAM**: 16GB DDR4 +- **GPU**: NVIDIA RTX 3090 (24GB VRAM) +- **SSD**: 1TB NVMe (Samsung PM991A o similar) +- **PSU**: 850W+ +- **SO**: Ubuntu 22.04 LTS + +## Instalación Rápida + +```bash +# 1. Clonar repositorio +git clone https://github.com/tuuser/llm-server-setup.git +cd llm-server-setup + +# 2. Instalar (con sudo) +sudo make install + +# 3. Verificar estado +make health-check + +# 4. Ver monitoreo +make monitor +``` + +## Comandos Disponibles + +```bash +make install # Instalación completa +make install-quick # Sin descargar modelos +make update # Actualizar código +make monitor # Monitoreo en tiempo real +make health-check # Verificar estado +make logs # Ver logs +make status # Estado de servicios +make start/stop/restart # Control de servicios +make backup # Hacer backup +``` + +## Estructura de Directorios + +``` +llm-server-setup/ +├── scripts/ # Scripts de deployment +│ ├── install.sh # Instalación principal +│ ├── update.sh # Actualización +│ ├── monitor.sh # Monitoreo +│ ├── health-check.sh # Verificación +│ └── backup.sh # Backup +├── config/ # Configuración +│ └── server.json # Config del servidor +├── static/ # Web UI +├── workspace/ # Workspace de trabajo +├── logs/ # Archivos de log +├── backups/ # Backups automáticos +├── requirements.txt # Dependencias Python +├── Makefile # Automatización +├── .env # Variables de entorno +└── README.md # Este archivo +``` + +## Servicios + +### Ollama (LLM Runtime) +- **Puerto**: 11434 +- **Modelos**: Phi (2.7B), DeepSeek Coder (33B) +- **Status**: `sudo systemctl status ollama` + +### LLM API (FastAPI) +- **Puerto**: 8000 +- **Health**: `curl http://localhost:8000/health` +- **Status**: `sudo systemctl status llm-api` + +## Modelos Disponibles + +| Modelo | Tamaño | VRAM | Velocidad | Uso | +|--------|--------|------|-----------|-----| +| Phi | 2.7B | 1.6GB | ⚡⚡⚡ | Rápido, simple | +| DeepSeek 33B | 33B | 18GB | ⚡ | Potente, razonamiento | + +## Monitoreo + +```bash +# Monitor en tiempo real +make monitor + +# Ver logs +make logs +make logs-api + +# Health check +make health-check +``` + +## API Endpoints + +```bash +# Health check +curl http://localhost:8000/health + +# Listar modelos +curl http://localhost:8000/models + +# Generar código +curl -X POST http://localhost:8000/code \ + -H "Content-Type: application/json" \ + -d '{"message":"Hola","model":"phi"}' +``` + +## Troubleshooting + +### GPU no se detecta +```bash +# Verificar driver +nvidia-smi + +# Reinstalar GPU drivers +sudo make install-gpu-only +``` + +### Servicios no inician +```bash +# Ver logs detallados +sudo journalctl -u ollama -f +sudo journalctl -u llm-api -f + +# Reiniciar +sudo systemctl restart ollama llm-api +``` + +### Espacio en disco lleno +```bash +# Ver uso +df -h + +# Limpiar +make clean + +# Hacer backup y restaurar +make backup +rm -rf ~/.ollama/models/* +ollama pull phi:latest +``` + +## Seguridad + +- SSH habilitado con key-based auth +- Firewall: Permitir solo puertos necesarios +- Usuarios: Crear usuario `charle` sin permisos sudo +- Backups automáticos en `/backups` + +## Performance + +Con tu hardware (RTX 3090 + i3-10105): + +- **Phi**: ~50 tokens/sec +- **DeepSeek 33B**: ~6-7 tokens/sec + +## Actualización + +```bash +# Pull latest from git +git pull origin main + +# Actualizar dependencias +make update +``` + +## Soporte + +Para errores o dudas: +1. Ver logs: `make logs` +2. Ejecutar health-check: `make health-check` +3. Verificar hardware: `make info` + +## License + +MIT + +## Autor + +Setup para servidor LLM local con hardware específico. \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..e2fc263 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,22 @@ +# API & Web Framework +fastapi==0.104.1 +uvicorn[standard]==0.24.0 +python-multipart==0.0.6 +aiofiles==23.2.1 + +# LLM & AI +langchain==0.1.0 +requests==2.31.0 + +# Data Processing +pillow==10.1.0 +pydantic==2.5.0 + +# Configuration +python-dotenv==1.0.0 + +# Development (opcional) +pytest==7.4.3 +pytest-asyncio==0.21.1 +black==23.12.0 +flake8==6.1.0 \ No newline at end of file diff --git a/scripts/backup.sh b/scripts/backup.sh new file mode 100644 index 0000000..8444fde --- /dev/null +++ b/scripts/backup.sh @@ -0,0 +1,54 @@ +#!/bin/bash + +################################################################################ +# BACKUP SCRIPT +# Realiza backup de modelos y configuración +################################################################################ + +set -e + +RED='\033[0;31m' +GREEN='\033[0;32m' +BLUE='\033[0;34m' +NC='\033[0m' + +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +PROJECT_DIR="$(dirname "$SCRIPT_DIR")" +BACKUP_DIR="$PROJECT_DIR/backups" +TIMESTAMP=$(date +%Y%m%d_%H%M%S) + +log() { echo -e "${BLUE}[$(date '+%H:%M:%S')]${NC} $@"; } +log_success() { echo -e "${GREEN}✅ $@${NC}"; } + +log "Iniciando backup..." + +mkdir -p "$BACKUP_DIR" + +# Backup configuración +log "Haciendo backup de configuración..." +tar -czf "$BACKUP_DIR/config_$TIMESTAMP.tar.gz" \ + -C "$PROJECT_DIR" \ + config/ \ + .env \ + requirements.txt \ + 2>/dev/null || true + +# Backup modelos (OPCIONAL - muy grandes) +read -p "¿Hacer backup de modelos Ollama? (y/n - muy grande, ~20GB): " -n 1 -r +echo +if [[ $REPLY =~ ^[Yy]$ ]]; then + log "Haciendo backup de modelos (esto tardará)..." + tar -czf "$BACKUP_DIR/models_$TIMESTAMP.tar.gz" \ + /home/charle/.ollama/models \ + 2>/dev/null || true +fi + +# Backup workspace +log "Haciendo backup de workspace..." +tar -czf "$BACKUP_DIR/workspace_$TIMESTAMP.tar.gz" \ + -C "$PROJECT_DIR" \ + workspace/ \ + 2>/dev/null || true + +log_success "Backups completados en: $BACKUP_DIR" +ls -lh "$BACKUP_DIR" \ No newline at end of file diff --git a/scripts/health-check.sh b/scripts/health-check.sh new file mode 100644 index 0000000..2641387 --- /dev/null +++ b/scripts/health-check.sh @@ -0,0 +1,88 @@ +#!/bin/bash + +################################################################################ +# HEALTH CHECK SCRIPT +# Verifica que todo funcione correctamente +################################################################################ + +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' + +FAILURES=0 + +check() { + local name=$1 + local cmd=$2 + local expected=$3 + + echo -n "Verificando $name... " + + if eval "$cmd" &>/dev/null; then + echo -e "${GREEN}✅${NC}" + return 0 + else + echo -e "${RED}❌${NC}" + ((FAILURES++)) + return 1 + fi +} + +echo -e "${BLUE}========================================${NC}" +echo -e "${BLUE} LLM SERVER HEALTH CHECK${NC}" +echo -e "${BLUE}========================================${NC}\n" + +# Sistema +echo -e "${YELLOW}Sistema:${NC}" +check "Ubuntu 22.04" "grep -q '22.04' /etc/os-release" +check "Internet" "ping -c 1 8.8.8.8" + +# Drivers & GPU +echo -e "\n${YELLOW}GPU & Drivers:${NC}" +check "NVIDIA Driver" "command -v nvidia-smi" +check "CUDA 12.3" "command -v nvcc" +check "RTX 3090" "nvidia-smi | grep -q 'RTX 3090'" +check "cuDNN" "ldconfig -p | grep -q cudnn" + +# Software +echo -e "\n${YELLOW}Software:${NC}" +check "Python 3.11" "python3.11 --version" +check "Docker" "command -v docker" +check "Git" "command -v git" + +# Services +echo -e "\n${YELLOW}Servicios:${NC}" +check "Ollama service" "sudo systemctl is-active ollama" +check "API service" "sudo systemctl is-active llm-api" + +# Conectividad +echo -e "\n${YELLOW}API Connectivity:${NC}" +check "Ollama API" "curl -s http://localhost:11434/api/tags" +check "FastAPI" "curl -s http://localhost:8000/health" + +# Modelos +echo -e "\n${YELLOW}Modelos Ollama:${NC}" +check "Phi disponible" "curl -s http://localhost:11434/api/tags | grep -q 'phi'" +check "DeepSeek disponible" "curl -s http://localhost:11434/api/tags | grep -q 'deepseek'" + +# Disk Space +echo -e "\n${YELLOW}Espacio en Disco:${NC}" +root_usage=$(df / | awk 'NR==2 {print int($5)}') +if [ "$root_usage" -lt 90 ]; then + echo -e "Uso de disco (root): ${GREEN}${root_usage}%${NC}" +else + echo -e "Uso de disco (root): ${RED}${root_usage}%${NC}" + ((FAILURES++)) +fi + +# Summary +echo -e "\n${BLUE}========================================${NC}" +if [ "$FAILURES" -eq 0 ]; then + echo -e "${GREEN}✅ TODOS LOS CHECKS PASARON${NC}" + exit 0 +else + echo -e "${RED}❌ $FAILURES CHECKS FALLARON${NC}" + exit 1 +fi \ No newline at end of file diff --git a/scripts/install.sh b/scripts/install.sh new file mode 100644 index 0000000..08f8ce8 --- /dev/null +++ b/scripts/install.sh @@ -0,0 +1,534 @@ +#!/bin/bash + +################################################################################ +# LLM SERVER DEPLOYMENT SCRIPT +# Ubuntu 22.04 LTS + ASUS H510M + RTX 3090 +# +# Uso: bash scripts/install.sh [--quick] [--gpu-only] +# +# Opciones: +# --quick Salta verificaciones lentas +# --gpu-only Solo instala GPU drivers (para re-install) +################################################################################ + +set -e # Exit si hay error + +# Colores +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +# Variables +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +PROJECT_DIR="$(dirname "$SCRIPT_DIR")" +WORKSPACE_DIR="$PROJECT_DIR/workspace" +VENV_DIR="$PROJECT_DIR/venv" +LOG_FILE="$PROJECT_DIR/logs/install.log" + +# Crear directorio de logs +mkdir -p "$PROJECT_DIR/logs" + +# Function: Log con timestamp +log() { + local level=$1 + shift + local message="$@" + local timestamp=$(date '+%Y-%m-%d %H:%M:%S') + echo -e "${BLUE}[$timestamp]${NC} ${level}: ${message}" | tee -a "$LOG_FILE" +} + +# Function: Log success +log_success() { + echo -e "${GREEN}✅ $@${NC}" | tee -a "$LOG_FILE" +} + +# Function: Log error +log_error() { + echo -e "${RED}❌ $@${NC}" | tee -a "$LOG_FILE" +} + +# Function: Log warning +log_warning() { + echo -e "${YELLOW}⚠️ $@${NC}" | tee -a "$LOG_FILE" +} + +# Function: Check command exists +command_exists() { + command -v "$1" >/dev/null 2>&1 +} + +# Function: Check if running as root +check_root() { + if [[ $EUID -ne 0 ]]; then + log_error "Este script debe ejecutarse con sudo" + exit 1 + fi +} + +################################################################################ +# MAIN INSTALLATION +################################################################################ + +main() { + local quick_mode=false + local gpu_only=false + + # Parse arguments + while [[ $# -gt 0 ]]; do + case $1 in + --quick) + quick_mode=true + shift + ;; + --gpu-only) + gpu_only=true + shift + ;; + *) + log_error "Opción desconocida: $1" + usage + exit 1 + ;; + esac + done + + log "LOG" "==========================================" + log "LOG" "LLM Server Installation" + log "LOG" "==========================================" + log "LOG" "Project Dir: $PROJECT_DIR" + log "LOG" "Workspace: $WORKSPACE_DIR" + log "LOG" "Quick Mode: $quick_mode" + log "LOG" "GPU Only: $gpu_only" + log "LOG" "==========================================" + + # Checks iniciales + check_root + check_os + check_hardware + + if [ "$gpu_only" = false ]; then + install_dependencies + install_docker + fi + + install_nvidia_drivers + install_cuda_toolkit + install_ollama + setup_python_venv + create_services + + if [ "$quick_mode" = false ]; then + download_models + fi + + setup_directories + generate_config + + log_success "==========================================" + log_success "✨ INSTALACIÓN COMPLETADA" + log_success "==========================================" + print_next_steps +} + +################################################################################ +# FUNCIONES AUXILIARES +################################################################################ + +check_os() { + log "LOG" "Verificando Sistema Operativo..." + + if [ ! -f /etc/os-release ]; then + log_error "No se pudo detectar el SO" + exit 1 + fi + + . /etc/os-release + if [[ "$ID" != "ubuntu" ]]; then + log_error "Este script solo soporta Ubuntu" + exit 1 + fi + + if [[ "$VERSION_ID" != "22.04" ]]; then + log_warning "Se recomienda Ubuntu 22.04, detectado: $VERSION_ID" + fi + + log_success "Ubuntu $VERSION_ID detectado" +} + +check_hardware() { + log "LOG" "Verificando Hardware..." + + # Check GPU + if ! command_exists nvidia-smi; then + log_warning "nvidia-smi no disponible aún (se instalará)" + else + gpu_info=$(nvidia-smi --query-gpu=name,memory.total --format=csv,noheader) + log_success "GPU detectada: $gpu_info" + fi + + # Check CPU + cpu_count=$(nproc) + log_success "CPU: $cpu_count cores" + + # Check RAM + ram_gb=$(free -h | awk '/^Mem:/ {print $2}') + log_success "RAM: $ram_gb" + + # Check Disk + disk_info=$(df -h / | awk 'NR==2 {print $2}') + log_success "Disco: $disk_info disponible" +} + +install_dependencies() { + log "LOG" "Instalando dependencias del sistema..." + + apt update + apt install -y \ + build-essential \ + git \ + wget \ + curl \ + htop \ + nano \ + openssh-server \ + python3.11 \ + python3.11-venv \ + python3.11-dev \ + pkg-config \ + libssl-dev \ + libffi-dev + + log_success "Dependencias instaladas" +} + +install_docker() { + log "LOG" "Instalando Docker..." + + if command_exists docker; then + log_success "Docker ya está instalado" + return + fi + + curl -fsSL https://get.docker.com -o /tmp/get-docker.sh + sh /tmp/get-docker.sh + + # Agregar usuario al grupo docker + if id "charle" &>/dev/null; then + usermod -aG docker charle + log_success "Usuario 'charle' agregado al grupo docker" + fi + + systemctl start docker + systemctl enable docker + + log_success "Docker instalado" +} + +install_nvidia_drivers() { + log "LOG" "Instalando NVIDIA Drivers..." + + if command_exists nvidia-smi; then + current_driver=$(nvidia-smi --query-gpu=driver_version --format=csv,noheader | head -1) + log_success "Driver NVIDIA $current_driver ya instalado" + return + fi + + # Agregar repositorio NVIDIA + apt-key adv --keyserver keyserver.ubuntu.com --recv-keys A4B469963BF863CC 2>&1 | grep -v "Warning" || true + + add-apt-repository "deb http://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/x86_64/ /" 2>&1 | grep -v "already" || true + + apt update + apt install -y cuda-drivers + + log_success "NVIDIA Drivers instalados" + + log_warning "Se recomienda reiniciar: sudo reboot" +} + +install_cuda_toolkit() { + log "LOG" "Instalando CUDA Toolkit 12.3..." + + if [ -d "/usr/local/cuda-12.3" ]; then + log_success "CUDA 12.3 ya está instalado" + return + fi + + log "LOG" "Descargando CUDA 12.3.0..." + cd /tmp + wget -q https://developer.download.nvidia.com/compute/cuda/12.3.0/local_installers/cuda_12.3.0_545.23.06_linux.run \ + -O cuda_12.3.0_545.23.06_linux.run + + log "LOG" "Instalando CUDA (esto puede tardar 10-15 minutos)..." + chmod +x cuda_12.3.0_545.23.06_linux.run + ./cuda_12.3.0_545.23.06_linux.run --silent --driver=false --toolkit + + # Configurar PATH + if ! grep -q "cuda-12.3" /root/.bashrc; then + cat >> /root/.bashrc << 'EOF' + +# CUDA 12.3 +export PATH=/usr/local/cuda-12.3/bin:$PATH +export LD_LIBRARY_PATH=/usr/local/cuda-12.3/lib64:$LD_LIBRARY_PATH +EOF + fi + + source /root/.bashrc + + # Verificar + if command_exists nvcc; then + cuda_version=$(nvcc --version | grep "release" | awk '{print $5}') + log_success "CUDA $cuda_version instalado" + fi + + # Install cuDNN + log "LOG" "Instalando cuDNN..." + apt install -y libcudnn8 + + log_success "CUDA Toolkit instalado" +} + +install_ollama() { + log "LOG" "Instalando Ollama..." + + if command_exists ollama; then + log_success "Ollama ya está instalado" + else + curl https://ollama.ai/install.sh | sh + log_success "Ollama instalado" + fi + + # Configurar servicio systemd + log "LOG" "Configurando servicio Ollama..." + + mkdir -p /etc/systemd/system + + cat > /etc/systemd/system/ollama.service << 'EOF' +[Unit] +Description=Ollama +After=network-online.target + +[Service] +ExecStart=/usr/local/bin/ollama serve +User=charle +Group=charle +Restart=always +RestartSec=3 +Environment="OLLAMA_HOST=0.0.0.0:11434" +Environment="OLLAMA_MODELS=/home/charle/.ollama/models" +Environment="OLLAMA_NUM_GPU=1" + +[Install] +WantedBy=default.target +EOF + + systemctl daemon-reload + systemctl enable ollama + systemctl restart ollama + + sleep 2 + + if systemctl is-active --quiet ollama; then + log_success "Servicio Ollama activo" + else + log_error "Error iniciando Ollama" + fi +} + +setup_python_venv() { + log "LOG" "Creando Python Virtual Environment..." + + if [ -d "$VENV_DIR" ]; then + log_success "VEnv ya existe" + return + fi + + python3.11 -m venv "$VENV_DIR" + + source "$VENV_DIR/bin/activate" + + pip install --upgrade pip setuptools wheel + + pip install \ + fastapi \ + uvicorn \ + python-multipart \ + aiofiles \ + pillow \ + python-dotenv \ + requests \ + langchain \ + pydantic + + log_success "Python VEnv configurado" +} + +create_services() { + log "LOG" "Creando systemd services..." + + # API Service + cat > /etc/systemd/system/llm-api.service << EOF +[Unit] +Description=LLM API Server +After=network.target ollama.service + +[Service] +Type=simple +User=charle +WorkingDirectory=$PROJECT_DIR +Environment="PATH=$VENV_DIR/bin" +Environment="OLLAMA_URL=http://localhost:11434" +ExecStart=$VENV_DIR/bin/python $PROJECT_DIR/backend.py +Restart=always +RestartSec=10 + +[Install] +WantedBy=multi-user.target +EOF + + systemctl daemon-reload + systemctl enable llm-api + + log_success "Systemd services creados" +} + +download_models() { + log "LOG" "Descargando modelos (esto puede tardar 20-30 minutos)..." + log_warning "Esto es OPCIONAL. Presiona Ctrl+C para cancelar." + + sleep 5 + + source "$VENV_DIR/bin/activate" + + # Esperar a que Ollama esté listo + for i in {1..30}; do + if curl -s http://localhost:11434/api/tags > /dev/null; then + log_success "Ollama está listo" + break + fi + log "LOG" "Esperando Ollama... ($i/30)" + sleep 2 + done + + log "LOG" "Descargando Phi..." + ollama pull phi:latest + + log "LOG" "Descargando DeepSeek Coder 33B..." + ollama pull deepseek-coder:33b + + log_success "Modelos descargados" +} + +setup_directories() { + log "LOG" "Creando directorios..." + + mkdir -p "$WORKSPACE_DIR" + mkdir -p "$PROJECT_DIR/uploads" + mkdir -p "$PROJECT_DIR/logs" + + # Cambiar permisos + chown -R charle:charle "$PROJECT_DIR" + chmod -R 755 "$PROJECT_DIR" + + log_success "Directorios creados" +} + +generate_config() { + log "LOG" "Generando archivos de configuración..." + + # .env file + if [ ! -f "$PROJECT_DIR/.env" ]; then + cat > "$PROJECT_DIR/.env" << EOF +# LLM Server Configuration +LLM_SERVER_URL=http://localhost:8000 +LLM_FAST_MODEL=phi +LLM_POWER_MODEL=deepseek-coder:33b +OLLAMA_URL=http://localhost:11434 +WORKSPACE_DIR=$WORKSPACE_DIR + +# Server +HOST=0.0.0.0 +API_PORT=8000 +WEB_PORT=5000 + +# Logging +LOG_LEVEL=INFO +EOF + log_success ".env creado" + fi + + # Config JSON + if [ ! -f "$PROJECT_DIR/config/server.json" ]; then + mkdir -p "$PROJECT_DIR/config" + cat > "$PROJECT_DIR/config/server.json" << 'EOF' +{ + "server": { + "host": "0.0.0.0", + "api_port": 8000, + "web_port": 5000, + "workers": 4 + }, + "models": { + "fast": "phi", + "power": "deepseek-coder:33b" + }, + "gpu": { + "memory_fraction": 0.9, + "max_batch_size": 8 + }, + "logging": { + "level": "INFO", + "format": "%(asctime)s - %(name)s - %(levelname)s - %(message)s" + } +} +EOF + log_success "config/server.json creado" + fi +} + +print_next_steps() { + cat << EOF + +${BLUE}=========================================${NC} +${GREEN}✨ PRÓXIMOS PASOS:${NC} +${BLUE}=========================================${NC} + +1. ${YELLOW}Verificar instalación:${NC} + sudo systemctl status ollama + sudo systemctl status llm-api + +2. ${YELLOW}Ver logs:${NC} + sudo journalctl -u ollama -f + sudo journalctl -u llm-api -f + +3. ${YELLOW}Iniciar servicios:${NC} + sudo systemctl start ollama + sudo systemctl start llm-api + +4. ${YELLOW}Acceder a la API:${NC} + curl http://localhost:8000/health + +5. ${YELLOW}Descargar modelos (si no se descargaron):${NC} + source $VENV_DIR/bin/activate + ollama pull phi:latest + ollama pull deepseek-coder:33b + +6. ${YELLOW}Ver estado en tiempo real:${NC} + watch -n 1 nvidia-smi + +${BLUE}=========================================${NC} +${GREEN}📁 Archivos importantes:${NC} +${BLUE}=========================================${NC} + Config: $PROJECT_DIR/config/server.json + .env: $PROJECT_DIR/.env + Logs: $PROJECT_DIR/logs/ + Workspace: $WORKSPACE_DIR/ + +${BLUE}=========================================${NC} +EOF +} + +# Ejecutar main +main "$@" \ No newline at end of file diff --git a/scripts/monitor.sh b/scripts/monitor.sh new file mode 100644 index 0000000..86b9606 --- /dev/null +++ b/scripts/monitor.sh @@ -0,0 +1,100 @@ +#!/bin/bash + +################################################################################ +# MONITOR SCRIPT +# Monitorea servicios y hardware en tiempo real +################################################################################ + +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' + +clear_screen() { + clear +} + +print_header() { + echo -e "${BLUE}=================================================${NC}" + echo -e "${BLUE} LLM SERVER MONITOR - $(date '+%Y-%m-%d %H:%M:%S')${NC}" + echo -e "${BLUE}=================================================${NC}" +} + +print_section() { + echo -e "\n${YELLOW}>>> $1${NC}" +} + +check_service() { + local service=$1 + if sudo systemctl is-active --quiet "$service"; then + echo -e "${GREEN}✅ $service - ACTIVO${NC}" + sudo systemctl status "$service" --no-pager | grep -E "(Active|ExecStart)" | sed 's/^/ /' + else + echo -e "${RED}❌ $service - INACTIVO${NC}" + fi +} + +get_ip() { + hostname -I | awk '{print $1}' +} + +main() { + while true; do + clear_screen + print_header + + # System Info + print_section "SISTEMA" + echo "Hostname: $(hostname)" + echo "IP: $(get_ip)" + echo "Uptime: $(uptime -p)" + echo "Usuarios conectados: $(who | wc -l)" + + # CPU & RAM + print_section "CPU & MEMORIA" + free -h | awk 'NR==1 {print ""; print $0} NR==2 {print $0}' + echo "" + top -bn1 | head -3 | tail -1 + + # Disk + print_section "DISCO" + df -h / | awk 'NR==2 {printf "Root: %s used / %s total (%.1f%%)\n", $3, $2, ($3/$2)*100}' + + # GPU + print_section "GPU - NVIDIA RTX 3090" + nvidia-smi --query-gpu=index,name,driver_version,memory.used,memory.total,temperature.gpu,utilization.gpu \ + --format=csv,noheader | while read line; do + echo " $line" + done + + # Services + print_section "SERVICIOS" + check_service "ollama" + echo "" + check_service "llm-api" + + # Network + print_section "RED" + echo "API (port 8000): $(curl -s http://localhost:8000/health | jq '.' 2>/dev/null || echo 'NO RESPONDE')" + echo "Ollama (port 11434): $(curl -s http://localhost:11434/api/tags | jq '.models | length' 2>/dev/null || echo '0') modelos" + + # Logs recientes + print_section "ÚLTIMOS ERRORES (últimas 5 líneas)" + echo "Ollama:" + sudo journalctl -u ollama -n 3 --no-pager | sed 's/^/ /' + echo "" + echo "API:" + sudo journalctl -u llm-api -n 3 --no-pager | sed 's/^/ /' + + # Footer + echo "" + echo -e "${BLUE}=================================================${NC}" + echo "Presiona Ctrl+C para salir | Se actualiza cada 10 segundos" + echo -e "${BLUE}=================================================${NC}" + + sleep 10 + done +} + +main \ No newline at end of file diff --git a/scripts/update.sh b/scripts/update.sh new file mode 100644 index 0000000..d8531e9 --- /dev/null +++ b/scripts/update.sh @@ -0,0 +1,53 @@ +#!/bin/bash + +################################################################################ +# UPDATE SCRIPT +# Actualiza código, modelos y dependencias +################################################################################ + +set -e + +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' + +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +PROJECT_DIR="$(dirname "$SCRIPT_DIR")" +VENV_DIR="$PROJECT_DIR/venv" + +log() { echo -e "${BLUE}[$(date '+%H:%M:%S')]${NC} $@"; } +log_success() { echo -e "${GREEN}✅ $@${NC}"; } +log_error() { echo -e "${RED}❌ $@${NC}"; exit 1; } + +log "Actualizando LLM Server..." + +# Pull latest from git +log "Descargando cambios de git..." +cd "$PROJECT_DIR" +git pull origin main || log "Git pull completado con warnings" + +# Update Python dependencies +log "Actualizando dependencias Python..." +source "$VENV_DIR/bin/activate" +pip install --upgrade pip +pip install -r requirements.txt --upgrade + +# Update Ollama models (opcional) +read -p "¿Actualizar modelos Ollama? (y/n): " -n 1 -r +echo +if [[ $REPLY =~ ^[Yy]$ ]]; then + log "Actualizando Phi..." + ollama pull phi:latest + + log "Actualizando DeepSeek..." + ollama pull deepseek-coder:33b +fi + +# Restart services +log "Reiniciando servicios..." +sudo systemctl restart ollama +sudo systemctl restart llm-api + +log_success "Actualización completada" \ No newline at end of file