first commit

This commit is contained in:
Carlos Tello
2026-09-20 13:43:58 -03:00
commit bdf42e74a3
9 changed files with 1188 additions and 0 deletions
+54
View File
@@ -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"
+88
View File
@@ -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
+534
View File
@@ -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 "$@"
+100
View File
@@ -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
+53
View File
@@ -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"