La terminal sin miedo
Quien domina la terminal trabaja el doble de rápido en cualquier servidor con GPU.
Qué vas a aprender
- Usar tuberías (pipes), redirecciones y
greppara filtrar y procesar logs de entrenamiento desde la línea de comandos - Crear sesiones persistentes de tmux con varios paneles para entrenar y vigilar la GPU a la vez
- Monitorizar el sistema y la GPU con
htop,nvtopynvidia-smi - Transferir archivos entre tu máquina y máquinas remotas con SSH,
scpyrsync
Por qué importa
Vas a pasar más tiempo en la terminal que en cualquier editor: entrenamientos, monitorización de la GPU, seguir logs, sesiones SSH remotas, gestión de entornos. Todos los flujos de trabajo de IA pasan por la shell. Si aquí eres lento, eres lento en todo.
Esta lección cubre las habilidades de terminal que importan para trabajar en IA. Sin historia de Unix. Sin profundizar en scripting de Bash. Solo lo que necesitas.
La idea clave
graph TD
subgraph tmux["sesión de tmux: training"]
subgraph arriba["Fila superior"]
P1["Panel 1: entrenamiento<br/>python train.py<br/>Epoch 12/100 ..."]
P2["Panel 2: monitor de GPU<br/>watch -n1 nvidia-smi<br/>GPU: 78% | Mem: 14/24G"]
end
P3["Panel 3: logs y experimentos<br/>tail -f logs/train.log | grep loss"]
end
Tres cosas a la vez en una sola terminal. Puedes desconectarte, irte a casa, volver a entrar por SSH y reconectarte. El entrenamiento sigue en marcha.
Paso a paso
Paso 1: conoce tu shell
Comprueba qué shell usas:
echo $SHELL
La mayoría de sistemas usan bash o zsh. Las dos sirven, y los comandos del curso funcionan en ambas.
Lo básico que debes saber:
# Moverte por las carpetas
cd ~/mi-curso-ia
pwd
ls -la
# Buscar en el historial (el atajo más útil que vas a aprender)
# Ctrl+R y escribe parte de un comando anterior
# Pulsa Ctrl+R otra vez para recorrer las coincidencias
# Limpiar la terminal
clear # o Ctrl+L
# Cancelar el comando en ejecución
# Ctrl+C
# Suspender el comando en ejecución (reanúdalo con fg)
# Ctrl+Z
Paso 2: tuberías y redirecciones
Las tuberías conectan comandos entre sí. Así se procesan logs, se filtran salidas y se encadenan herramientas. Lo usarás constantemente.
# Cuenta cuántas veces aparece "loss" en un log
cat train.log | grep "loss" | wc -l
# Extrae solo los valores de pérdida de la salida del entrenamiento
grep "loss:" train.log | awk '{print $NF}' > losses.txt
# Sigue un log en tiempo real, filtrando los errores
tail -f train.log | grep --line-buffered "ERROR"
# Ordena los experimentos por su accuracy final
grep "final_accuracy" results/*.log | sort -t= -k2 -n -r
# Envía stdout y stderr a archivos distintos
python train.py > output.log 2> errors.log
# Envía ambos al mismo archivo
python train.py > train_full.log 2>&1
Las redirecciones que necesitas:
| Símbolo | Qué hace |
|---|---|
> |
Escribe la salida estándar (stdout) en un archivo (sobrescribe) |
>> |
Añade stdout al final de un archivo |
2> |
Escribe la salida de errores (stderr) en un archivo |
2>&1 |
Envía stderr al mismo sitio que stdout |
\| |
Envía el stdout de un comando como entrada (stdin) del siguiente |
Paso 3: procesos en segundo plano
Los entrenamientos duran horas. No quieres tener la terminal abierta todo ese tiempo.
# Ejecuta en segundo plano (la salida sigue saliendo por la terminal)
python train.py &
# En segundo plano e inmune al cierre de la terminal
nohup python train.py > train.log 2>&1 &
# Mira qué se está ejecutando en segundo plano
jobs
ps aux | grep train.py
# Trae un trabajo al primer plano
fg %1
# Mata un proceso en segundo plano
kill %1
# o busca su PID y mátalo
kill $(pgrep -f "train.py")
Diferencias entre &, nohup y screen/tmux:
| Método | ¿Sobrevive al cerrar la terminal? | ¿Puedes reconectarte? |
|---|---|---|
comando & |
No | No |
nohup comando & |
Sí | No (mira el archivo de log) |
screen / tmux |
Sí | Sí |
Para cualquier cosa que dure más de unos minutos, usa tmux.
Paso 4: tmux
tmux crea sesiones de terminal persistentes con varios paneles. Es la herramienta más útil para gestionar entrenamientos.
# Instalación
# macOS
brew install tmux
# Ubuntu
sudo apt install tmux
# Crea una sesión con nombre
tmux new -s training
# Divide en horizontal
# Ctrl+B y luego "
# Divide en vertical
# Ctrl+B y luego %
# Muévete entre paneles
# Ctrl+B y luego las flechas
# Desconéctate (la sesión sigue en marcha)
# Ctrl+B y luego d
# Vuelve a conectarte
tmux attach -t training
# Lista las sesiones
tmux ls
# Cierra una sesión
tmux kill-session -t training
Una sesión típica de trabajo en IA:
tmux new -s train
# Panel 1: lanza el entrenamiento
python train.py --epochs 100 --lr 1e-4
# Ctrl+B, " para dividir, y vigila la GPU
watch -n1 nvidia-smi
# Ctrl+B, % para dividir en vertical, y sigue los logs
tail -f logs/experiment.log
# Ahora desconéctate con Ctrl+B, d
# Sal del SSH, ve a por un café, vuelve
# tmux attach -t train
Paso 5: monitorización con htop y nvtop
# Procesos del sistema (mejor que top)
htop
# Procesos de la GPU (si tienes NVIDIA)
# Instalación: sudo apt install nvtop (Ubuntu) o brew install nvtop (macOS)
nvtop
# Comprobación rápida de la GPU sin nvtop
nvidia-smi
# Uso de la GPU actualizado cada segundo
watch -n1 nvidia-smi
# Qué procesos están usando la GPU
nvidia-smi --query-compute-apps=pid,name,used_memory --format=csv
Teclas de htop que usarás:
- F6 o > para ordenar por una columna (ordena por memoria para encontrar fugas)
- F5 para la vista en árbol (procesos hijos)
- F9 para matar un proceso
- / para buscar un proceso por nombre
Paso 6: SSH a máquinas remotas con GPU
Cuando alquilas una GPU en la nube (Lambda, RunPod, Vast.ai…), te conectas por SSH.
# Conexión básica
ssh usuario@ip-maquina-gpu
# Con una clave concreta
ssh -i ~/.ssh/mi_clave_gpu usuario@ip-maquina-gpu
# Copia archivos a la máquina remota
scp model.pt usuario@ip-maquina-gpu:~/models/
# Copia archivos desde la máquina remota
scp usuario@ip-maquina-gpu:~/results/metrics.json ./
# Sincroniza una carpeta entera (más rápido con muchos archivos)
rsync -avz ./data/ usuario@ip-maquina-gpu:~/data/
# Redirección de puertos (usa el Jupyter/TensorBoard remoto en local)
ssh -L 8888:localhost:8888 usuario@ip-maquina-gpu
# Ahora abre localhost:8888 en tu navegador
rsync solo transfiere lo que ha cambiado: si se corta la conexión a mitad de subir un dataset, vuelve a lanzarlo y continuará donde se quedó.
Paso 7: alias útiles para IA
Descarga alias_ia.sh desde «Archivos de la lección», guárdalo en tu carpeta personal (~) y añade esta línea al final de tu ~/.bashrc o ~/.zshrc:
source ~/alias_ia.sh
O copia solo los que quieras. Los más importantes:
# Estado de la GPU de un vistazo
alias gpu='nvidia-smi --query-gpu=index,name,utilization.gpu,memory.used,memory.total,temperature.gpu --format=csv,noheader'
# Mata todos los procesos de entrenamiento en Python
alias matar_entreno='pkill -f "python.*train"'
# Activa rápido el entorno virtual
alias ae='source .venv/bin/activate'
# Sigue la pérdida del entrenamiento
alias verloss='tail -f logs/*.log | grep --line-buffered "loss"'
Paso 8: patrones de terminal habituales en IA
Te los encontrarás una y otra vez:
# Entrena, guarda todo el log y avisa al terminar
python train.py 2>&1 | tee train.log; echo "DONE" | mail -s "Entrenamiento terminado" tu@email.com
# Compara dos logs de experimentos
diff <(grep "accuracy" exp1.log) <(grep "accuracy" exp2.log)
# Encuentra los archivos de modelo más grandes (para liberar disco)
find . -name "*.pt" -o -name "*.safetensors" | xargs du -h | sort -rh | head -20
# Descarga un modelo de Hugging Face
wget https://huggingface.co/model/resolve/main/model.safetensors
# Descomprime un dataset
tar xzf dataset.tar.gz -C ./data/
# Cuenta las líneas de todos los archivos Python (el tamaño de tu proyecto)
find . -name "*.py" | xargs wc -l | tail -1
# Espacio en disco (los datos de entrenamiento llenan discos muy rápido)
df -h
du -sh ./data/*
# Revisa las variables de entorno antes de entrenar
env | grep -i cuda
env | grep -i torch
Cuando el filtrado se complica, suele ser más cómodo hacerlo en Python. Este ejemplo hace lo mismo que grep + awk sobre un log de entrenamiento inventado: extrae la pérdida de cada época y detecta en cuál fue mínima. Ejecútalo aquí y prueba a cambiar la expresión regular:
import random, re
random.seed(0)
log = "\n".join(
f"2026-05-01 10:{i:02d}:00 [INFO] epoch {i} loss: {1 / i + random.uniform(0, 0.05):.4f} lr: 0.001"
for i in range(1, 31)
)
print(log.splitlines()[0], "...\n")
patron = re.compile(r"epoch (\d+) loss: ([\d.]+)")
perdidas = {int(e): float(l) for e, l in patron.findall(log)}
mejor = min(perdidas, key=perdidas.get)
print(f"Épocas leídas: {len(perdidas)}")
print(f"Pérdida mínima: {perdidas[mejor]:.4f} en la época {mejor}")
for epoca in (1, 10, 20, 30):
barra = "█" * int(perdidas[epoca] * 40)
print(f"época {epoca:>2} {barra} {perdidas[epoca]:.3f}")
En la práctica
Cuándo usarás cada herramienta durante el curso:
| Herramienta | Cuándo la usas |
|---|---|
| tmux | En cada entrenamiento (del módulo 3 en adelante) |
tail -f + grep |
Para vigilar los logs de entrenamiento |
nohup / & |
Para tareas rápidas en segundo plano |
htop / nvtop |
Para depurar entrenamientos lentos y errores de memoria (OOM) |
SSH + rsync |
Para trabajar con GPUs en la nube |
| Tuberías + redirecciones | Para procesar resultados de experimentos |
| Alias | Para ahorrar tiempo en comandos repetitivos |
Retos para tu ordenador
- Instala tmux, crea una sesión con tres paneles y ejecuta
htopen uno,watch -n1 dateen otro y un script de Python en el tercero. Desconéctate y vuelve a conectarte. - Añade
alias_ia.sha tu configuración de la shell, recárgala consource ~/.zshrc(o~/.bashrc) y pruebadiscoyae. - Crea un log de entrenamiento falso con
for i in $(seq 1 100); do echo "epoch $i loss: $(echo "scale=4; 1/$i" | bc)"; sleep 0.1; done > fake_train.logy usagrep,tailyawkpara extraer solo los valores de pérdida. - Crea una entrada en tu configuración SSH para un servidor al que tengas acceso (o usa
localhostpara practicar la sintaxis).
Glosario de la lección
| Término | Como se suele decir | Qué es exactamente |
|---|---|---|
| Shell | «La terminal» | El programa que interpreta tus comandos (bash, zsh, fish) |
| tmux | «Multiplexor de terminal» | Un programa para tener varias sesiones de terminal en una ventana, y desconectarte y reconectarte |
| Tubería (pipe) | «La barrita» | El operador \|, que envía la salida de un comando como entrada de otro |
| PID | «El ID del proceso» | El número único de cada proceso en ejecución; sirve para vigilarlo o matarlo |
| nohup | «No hangup» | Ejecuta un comando inmune a la señal de cuelgue: cerrar la terminal no lo mata |
| SSH | «Conectarse al servidor» | Secure Shell: un protocolo cifrado para ejecutar comandos en una máquina remota |