Per dimensionare lo scaling automatico di un endpoint TTS su Amazon SageMaker AI, misura prima la concorrenza sostenibile e poi il tempo necessario per aggiungere capacità. Nell’esempio pubblicato da AWS, questi test su Kokoro-82M e un’istanza ml.g5.xlarge portano a una soglia Q_max di 50 richieste concorrenti per istanza; non sono valori predefiniti da applicare ad altri modelli o carichi.

Prima di iniziare: metriche e prerequisiti

Q_max è il livello massimo di richieste concorrenti per istanza che rispetta l’obiettivo di latenza scelto. AWS ha usato un SLO, cioè un obiettivo di livello del servizio, di 3.000 ms per il p95 del TTFAB: il tempo entro cui arriva il primo byte dell’audio nel 95% delle richieste. Anche questo SLO è una scelta dell’esempio.

Per riprodurre il percorso descritto da AWS servono autorizzazioni per IAM, S3, ECR e SageMaker; AWS CDK v2 inizializzato nell’account e nella regione di destinazione; Python 3.11 o successivo; uv; Docker; e quota disponibile per un’istanza ml.g5.xlarge. AWS stima circa 36 minuti per la misurazione qmax e fino a circa 28 minuti per ttotal.

Il deployment crea tre stack AWS CDK in sequenza: SpeechFoundationStack prepara i ruoli e il bucket S3 per i pesi del modello; SpeechModelCacheStack sincronizza la cache; SpeechEndpointStack crea le risorse dell’endpoint e del container. Quest’ultimo genera le risorse di autoscaling e osservabilità solo se lo scaling è abilitato e c’è un piano misurato fattibile.

Esegui i cinque passaggi nell’ordine previsto

  1. Esegui drift. È un controllo in sola lettura che confronta le risorse di scaling distribuite con la configurazione. Serve a verificare lo stato prima di modificare l’endpoint.
  2. Esegui qmax. Il test mantiene una sola istanza e misura una scala di livelli di concorrenza in modalità closed-loop, cioè inviando nuove richieste in base alle risposte ricevute. È una misurazione che agisce sullo stato dell’endpoint.
  3. Esegui ttotal. Dopo qmax, forza un aumento di capacità e misura il recupero. Questo passaggio richiede l’artefatto prodotto da qmax e può impiegare fino a circa 28 minuti. Se un test qmax o ttotal viene interrotto, l’autoscaling può restare congelato: AWS indica il comando thaw per ripristinarlo prima di proseguire con altre misurazioni.
  4. Esegui plan. Usa gli artefatti di qmax e ttotal per calcolare le soglie. È un passaggio in sola lettura.
  5. Esegui validate. Confronta la policy distribuita con il piano. Anche questo passaggio è in sola lettura.

Misura la concorrenza che rispetta il tuo SLO

AWS usa la metrica nativa ConcurrentRequestsPerModel, pubblicata da SageMaker e osservata come valore massimo su una finestra di 10 secondi. Nel test su Kokoro-82M, il rapporto tra la concorrenza misurata dal client di benchmark e quella riportata in CloudWatch è stato 1,0 a ogni livello provato.

Con l’obiettivo p95 di 3.000 ms, AWS ha registrato 2.805,7 ms a 50 richieste concorrenti per istanza e 3.374,8 ms a 60. Per quel test su ml.g5.xlarge, quindi, Q_max è 50. La tabella riporta i due livelli che delimitano il risultato rispetto allo SLO scelto.

Richieste concorrenti per istanzaTTFAB p95Rispetto allo SLO di 3.000 ms
502.805,7 msEntro lo SLO
603.374,8 msOltre lo SLO

AWS riporta inoltre, a concorrenza non contesa, un tempo di servizio medio di 61,3 ms e un p95 di 66,1 ms. Sono misure dello stesso esempio, non garanzie sulle prestazioni di un altro endpoint.

Misura lo scale-out e distingui il dato dal valore di pianificazione

AWS riporta 260,2 secondi per il test forzato di scale-out. Per pianificare, aggiunge 60 secondi di margine limitato per il ritardo di rilevamento della policy, non misurato in quel test: il valore risultante è 320,2 secondi.

Le otto durate di fase pubblicate sono 30,0, 180,8, 3,7, 0,0, 6,5, 1,0, 20,7 e 47,4 secondi. Sommate, fanno 290,1 secondi, cioè 29,9 secondi in più dei 260,2 dichiarati come totale misurato. Di conseguenza, quel totale e il dettaglio delle fasi non formano una scomposizione aritmeticamente riconciliata.

Ricava le soglie e considera l’effetto dello scale-in

Dopo avere misurato Q_max, AWS applica all’esempio un rapporto di surge, cioè di aumento del carico, scelto dall’operatore pari a 1,25×. Con Q_max=50, il piano calcola una soglia di scale-out di 37,5 richieste concorrenti e una soglia di scale-in di 25:

  • Scale-out: (1 − 0,25) × 50 = 37,5.
  • Scale-in: (1 − 0,50) × 50 = 25.

La configurazione d’esempio usa ml.g5.xlarge, da 1 a 9 istanze, un cooldown di 30 secondi per lo scale-out e di 960 secondi per lo scale-in, oltre a queue_max_depth=50. Il cooldown è l’intervallo di attesa previsto dalla policy prima di un’altra azione di scaling. AWS avverte che passare da due istanze a una può riportare l’istanza rimasta a Q_max; nell’analisi dell’esempio, un minimo di tre istanze evita questa specifica condizione, mantenendo però più capacità attiva.

La coda è un controllo distinto dallo scaling: nel container d’esempio, superare la profondità configurata porta a una risposta HTTP 503 queue_saturated, che rifiuta la richiesta invece di aggiungere capacità.

Tieni conto dei limiti dichiarati nel repository

AWS Samples descrive il repository come proof-of-value, non pronto per la produzione. Il progetto fissa torch==2.6.0 e segnala l’avviso PYSEC-2026-2286, relativo a una corruzione della memoria nel deserializzatore weights_only in presenza di un checkpoint malevolo; indica torch 2.10.0 come versione correttiva. Il repository specifica inoltre che la revisione di Kokoro è fissata a un commit preciso di Hugging Face e afferma che il percorso d’attacco descritto richiederebbe la compromissione di quella revisione upstream.