#!/usr/bin/env bash # La tarjeta, y quien la esta usando. # # Va la primera porque es la que explica los fallos de las demas. En 4 GB no # caben el verde y el naranja a la vez: si el naranja esta cargado, el verde # dara "cudaMalloc failed" y parecera que el modelo esta roto cuando lo que # pasa es que no hay sitio. # # El caso que mas ha costado en este proyecto es whisper-server: lo lanza # flatpak-spawn --host, vive FUERA del sandbox y no se entera de que la app # cerro. Cada reinicio deja uno agarrado a ~850 MiB. Dos o tres y ya no cabe # nada. Por eso se cuentan, no solo se mira si hay alguno. cd "$(dirname "$0")" && . ./comun.sh titulo "La tarjeta" USADA=$(vram) if [ -z "$USADA" ]; then echo " $(rojo FALLO) no hay nvidia-smi: esto necesita la grafica" exit 1 fi TOTAL=$(nvidia-smi --query-gpu=memory.total --format=csv,noheader | tr -d ' MiB') nota "$USADA MiB usados de $TOTAL" nvidia-smi --query-compute-apps=used_memory,process_name --format=csv,noheader 2>/dev/null \ | sed 's/^/ /' titulo "Nadie compitiendo por ella" # pgrep -c YA imprime 0 cuando no encuentra nada, y ademas devuelve 1. Un # "|| echo 0" detras parece prudente y lo que hace es imprimir DOS ceros, que # no son iguales a "0" y hacen fallar una prueba que en realidad pasa. cuantos() { local n; n=$(pgrep -cf "$1" 2>/dev/null); echo "${n:-0}"; } cuantos_x() { local n; n=$(pgrep -cx "$1" 2>/dev/null); echo "${n:-0}"; } # dataset.py genera pares con el NARANJA: mientras corra, ollama recarga el # modelo naranja en segundos aunque se le haga stop. No es un fallo de ollama. comprueba "dataset.py no esta corriendo" "$(cuantos 'entrena/dataset.py')" "0" comprueba "el nucleo naranja no esta corriendo" "$(cuantos 'nucleo/jarvis.py')" "0" comprueba "sin whisper-server huerfanos" "$(cuantos_x whisper-server)" "0" CARGADO=$(curl -fsS --max-time 5 "$OLLAMA/api/ps" 2>/dev/null | python3 -c " import json, sys try: m = json.load(sys.stdin).get('models', []) except Exception: m = [] print(','.join(x['name'] for x in m) or 'ninguno') " 2>/dev/null) nota "en ollama ahora: $CARGADO" case "$CARGADO" in *"$NARANJA"*) echo " $(rojo FALLO) el naranja esta cargado: no cabe el verde encima" echo " $(gris "ollama stop $NARANJA")" _fallo=$((_fallo + 1)) ;; *) echo " $(verde OK) el naranja no ocupa la tarjeta" _ok=$((_ok + 1)) ;; esac # Sitio para el verde: 2795 MiB medidos el 16 ago a num_ctx 65536 con 16 de 32 # capas en GPU. La cifra anterior (3301) era la del modelo a 24576 con las 32 # capas dentro, que Hermes rechaza por su suelo de 64k. # # Si el modelo ya esta dentro, la comprobacion no aplica: el hueco ya se uso. case "$CARGADO" in *"$MODELO"*) nota "el verde ya esta cargado, no hace falta hueco" ;; *) mayor_que "queda hueco para el verde (MiB libres)" \ "$((TOTAL - USADA))" 2800 ;; esac resumen