Il nostro health check ha riavviato un server di modelli sano otto volte in un giorno

Ops

Il 22 luglio un watchdog ha riavviato il nostro server di modelli locale otto volte. Nessuno di quei riavvii era dovuto a un crash. Il controllo che avrebbe dovuto mantenere attivo il modello era proprio ciò che lo faceva cadere.

Cosa è successo

Il server di modelli eseguiva vLLM su una macchina NVIDIA GB10 e produceva circa 8 token al secondo per una singola richiesta. Ogni cinque minuti un watchdog inviava una vera richiesta di chat e aspettava fino a 45 secondi per la risposta. Cinque controlli falliti di fila significavano un server bloccato, e il watchdog lo riavviava. Un riavvio toglieva il modello per diversi minuti mentre circa 19 GB di pesi venivano ricaricati.

Quel giorno un job batch teneva occupate due o quattro richieste sul server per minuti alla volta. La richiesta del watchdog aspettava in coda dietro di esse, esauriva il tempo e veniva conteggiata come fallimento. Dopo cinque controlli simili, un server sano è stato riavviato. Avevamo un file flag "busy" che il watchdog rispettava, ma il job batch non lo impostava mai.

Come un falso riavvio ha portato al successivo

Ogni riavvio faceva fallire le richieste in corso con un errore 500 ("cannot schedule new futures after shutdown"). Un secondo watchdog contava gli errori 500 e riavviava il server quando ce n'erano troppi, e più errori vedeva, prima agiva. Quindi ogni falso riavvio faceva arrivare prima il successivo. In tutto, quattro watchdog separati potevano riavviare quel server, su timer di 5, 10, 15 e 30 minuti.

La regola che ne abbiamo tratto

Un health check non deve usare ciò che sorveglia. La risorsa scarsa di un server di modelli sono gli slot per le richieste in corso. Un controllo che occupa uno di quegli slot, o ne aspetta uno, fa parte del carico che dovrebbe giudicare. Controlla in modo economico e riavvia solo quando puoi dimostrare che il server è bloccato.

Il controllo che lo ha sostituito

vLLM pubblica i propri contatori su /metrics. Il nuovo controllo li legge prima:

La prima versione contava i token generati come progresso. Ha superato otto test e, alla sua prima esecuzione live, ha trovato il server occupato e sano: 2 richieste in esecuzione, 107 nuovi token tra le due letture.

Cosa abbiamo cambiato da allora

La differenza è facile da vedere. Mentre scrivevamo questa nota, entrambi i nostri server di modelli stavano gestendo 12 richieste ciascuno, il loro limite. Una richiesta di test sarebbe rimasta in coda. Il nuovo controllo ha segnalato entrambi occupati e sani, a 126 e 101 token al secondo, senza inviarne una.

Factory Floor 1.0.2 include questo controllo in models/llm-health.py, con test per server inattivi, occupati, bloccati e riavviati, un server senza metriche, un proxy e un backend morto.

Aggiornato: