Ein Verkehrsanstieg trifft auf Ihren selbsthosteten Text-zu-Sprache- (TTS) Endpunkt, und Anfragen beginnen, in der Warteschlange zu liegen. Die Latenzzeit übersteigt den Service-Level-Zielwert (SLO), genau in dem Moment, in dem die meisten Anrufer zuhören. Die Autoskalierungspolitische hinter diesem Endpunkt sollte dies verhindern, aber der Zielwert, auf den sie skaliert wird, war eine Schätzung – und solche Schätzungen funktionieren still, bis der tatsächliche Verkehr zeigt, dass sie falsch sind.
Wenn die Zahl falsch ist, wird der Aufwand auf eine von zwei Arten bezahlt – und keine davon zeigt sich als Alarm an. Wenn man zu konservativ ist, laufen die Fahrzeuge GPU-Instanzen, die meist unbenutzt bleiben. Der Aufwand trifft auf jede Rechnung ein, aber es kommt nie zu einem Incident-Report. Wenn man zu aggressiv ist, übernimmt das Fahrzeug ein Risiko, das niemand sieht. Jede Instanz hält mehr gleichzeitige Anfragen bereit, als sie innerhalb ihres Latenzversprechens bedienen kann. Nichts scheint falsch zu sein, bis ein echter Trafficanstieg die Warteschlange über den SLO hinaus bringt. Das passiert genau in dem Moment, in dem die meisten Anrufer zuhören. Das ist der versteckte Fehler. Eine Politik, die auf der Konsole gut aussieht, kann bereits versagen, wenn es um die Menschen geht, denen sie dienen soll.
In diesem Artikel setzen wir Kokoro-82M ein, einen 82-Millionen-Parametern-TTS-Modell, als benutzerdefinierte Container auf einem Amazon SageMaker AI-Echtzeit-Endpunkt. AWS Cloud Development Kit (AWS CDK)-Stacks übernehmen die Bereitstellung. Wir ersetzen das Vermuten durch zwei Messungen, die am Live-Endpunkt durchgeführt werden. Q_max ist die höchste Konkurrenzkapazität, die eine Einheit unterliegt, bevor der SLO überschritten wird, und T_total ist die Dauer, die eine Skalierung von Anfang bis Ende dauert. Wir ermitteln den Skalierungsschwellenwert, den Skalierungsbeginnschwellenwert und beide Pausenzeiten aus diesen beiden Zahlen durch Addition. Jede Zahl in diesem Artikel stammt von einer tatsächlichen Bereitstellung und Messung des aws-samples-Repositories, auf den in diesem Artikel verwiesen wird.
Warum funktionieren die Standard-Autoskalierungmetriken für TTS nicht
Die meisten öffentlichen Richtlinien zu den Zielen für die automatische Skalierung von Amazon SageMaker AI beziehen sich auf kurze synchrone Anfrage/antwort-Anrufe oder den Dienst eines großen Sprachmodells (LLM), wobei das natürliche Maß die generierten Tokens pro Sekunde sind. Die TTS-Synthese passt weder zu diesem Muster: eine einzige Anfrage erhält eine Verbindung für mehrere Sekunden offen, ohne dass es einen Tokenschleifen gibt, an den ein Maß angehängt werden könnte. Kokoro-82M ist nicht-autoregressive, ein Nachfolger von StyleTTS2 mit einem ISTFTNet-Dekoder, der in einer antagonistischen Trainingsmethode verwendet wird – anstatt durch autoregressive Next-Token-Prediction oder iterativen Denoising. Es erzeugt eine vollständige Aussage in einer einzigen, durchnummerierten Durchgabe. Es gibt keinen Generierungszyklus, der mit einer Metrik pro Token verwaltet werden müsste. Was bestimmt, ob eine TTS-Instanz überlastet ist, ist einfacher, als es klingt: wie viele Anfragen gerade in der Warteschlange sind und darauf ausgeführt werden.
Die implementierte Policy skaliert sich basierend auf ConcurrentRequestsPerModel, einem nativen Indikator, den Amazon SageMaker AI selbst publiziert, anstatt eines, das in dem eigenen Container-Code dieses Projekts erforderlich ist. Die Skalierung auf einen von Amazon SageMaker AI veröffentlichten Indikator entfernt eine ganze Klasse von Fehlern, bei denen eine benutzerdefinierte Indikatorkonfiguration auf Papier korrekt erscheint, aber nichts tatsächlich dorthin publiziert wird.
ConcurrentRequestsPerModel publiziert eine „Maximum“-Statistik über einen 10-Sekunden-Window, eine andere Größe als die durch den Benchmarking-Client direkt gemessene Menge der im Flug erfolgenden Anfragen. Das Tool berücksichtigt dies. Bei jeder Stufe der Konkurrenzfähigkeit wird beide Größen gegenüber dem gleichen Lastwert gemessen und das Verhältnis zwischen ihnen erfasst. Anschließend verwendet das Tool dieses Verhältnis, um den vom Client gemessenen Schwellenwert in Amazon CloudWatch-Einheiten umzurechnen, bevor dieser in die deploybare Konfiguration eingetragen wird. Bei der Kokoro-82M-Runnung in diesem Artikel ergab das gemessene Verhältnis bei jeder Stufe genau 1,0, sodass der vom Client gemessene und der von Amazon CloudWatch berichtete Schwellenwert direkt übereinstimmen.
Lösungsüberblick
Diese Lösung setzt Kokoro-82M in einem benutzerdefinierten Container auf einem Amazon SageMaker AI Echtzeit-Endpunkt ein und ersetzt anschließend einen erkannten Autoskalierziel durch eines, das aus zwei Messungen gegen diesen Live-Endpunkt abgeleitet wird: Q_max, der Konkurrenzschutz-Benchmarkwert, den eine Instanz innerhalb des SLO bereitstellt, und T_total, wie lange eine echte Skalierung dauert. Ein Syntheseanruf durchläuft vier Schichten: einen Client, den Amazon SageMaker AI Endpunkt, einen benutzerdefinierten Container auf einer GPU-Instanz hinter diesem Endpunkt und das Kokoro-82M-Modell innerhalb des Containers.
Abbildung 1: Der Anfragepfad von Kokoro-82M, vom Client über den Amazon SageMaker AI Endpoint und das benutzerdefinierte Container über das Modell
Der Container unterstützt zwei Transportmöglichkeiten: den Antwortstroming (InvokeEndpointWithResponseStream), bei dem der Audio-Stream sofort nach der Synthese ausgegeben wird, sodass die Wiedergabe bereits vor dem Ende des Ausrufs beginnt, sowie den bidirektionalen Streaming (InvokeEndpointWithBidirectionalStream), bei dem eine langfristige Sitzung für mehrere Nachrichten eröffnet wird.
Das Betreiben von Kokoro-82M in einem benutzerdefinierten Container, anstatt hinter einem verwalteten Inferenztoolkit, macht den Rest dieser Beschreibung möglich. Ein von Ihnen kontrollierter Container kann seine eigene Zugangskapazität festlegen und das exakte Konkurrenzen-Signal, das Amazon SageMaker AI bereits publiziert, anzeigen – anstatt eine ausgeliehene Metrik auf eine Arbeitslast anzubringen, für die sie nicht entwickelt wurde. Die AWS CDK-Stacks, die diesen Endpunkt bereitstellen, fügen nur automatische Skalierungsressourcen hinzu, sobald eine echte, gemessene… plan Es existiert für das Modell, sodass eine vermutete Konfiguration niemals stillschweigend in die Produktion gelangen kann. Der Rest dieses Artikels bezieht sich auf diese Messung.
Voraussetzungen
Um diesen Schritt zu befolgen, benötigen Sie:
- Ein AWS-Konto mit Berechtigungen zur Erstellung von AWS Identity and Access Management (IAM)-Rollen, Amazon Simple Storage Service (Amazon S3)-Buckets, Amazon Elastic Container Registry (Amazon ECR)-Repositories und Amazon SageMaker-AI-Ressourcen.
- Hinweis: Der Beispielkörper bindet eine ältere PyTorch-Version mit einer bekannten Warnung (
PYSEC-2026-2286, fixiert in torch 2.10.0). Überprüfen und aktualisieren Sie den Bindungsprozess vor jeglicher nicht-Wertnachweislichen Nutzung.
- Hinweis: Der Beispielkörper bindet eine ältere PyTorch-Version mit einer bekannten Warnung (
- AWS CDK v2, installiert und gestartet in Ihrem Zielkonto und -region.
- Python 3.11 oder neuer, uv und Docker zur Erstellung der Container-Image.
- Eine
ml.g5.xlargeDienstquota mit mindestens einem freien Slot über Ihrem Grundniveau, bevor Sie die Skalierungseinrichtung in diesem Beitrag ausführen. - Der Deployment-Code aus dem GitHub-Repository, auf dem dieser Beitrag verweist.
Walkthrough
Am Ende dieser Durchführung haben Sie eine Live-Amazon SageMaker AI Auto-Scaling-Policy für Kokoro-82M, die vollständig aus zwei Messungen an Ihrem eigenen Endpunkt entnommen wurde und nicht aus einer Vermutung.
Verteilen der Endpunkt-Stacks
Der Endpunkt wird durch drei AWS CDK-Stacks implementiert, die in dieser Reihenfolge angewandt werden: SpeechFoundationStack erstellt die IAM-Rollen und den Amazon S3-Bucket, der die Modellgewichte speichert, SpeechModelCacheStack synchronisiert einmal die Hugging Face-Gewichte des Modells in diesen Bucket, und SpeechEndpointStack erstellt das Container-Image, stellt es auf Amazon ECR bereit und schafft das Amazon SageMaker AI-Modell, die Endpunkt-Konfiguration und den Endpunkt.
Abbildung 2: Die drei AWS CDK-Stacks und das Gate, das entscheidet, ob die Autoskalierressourcen synthetisiert werden
Die Tür auf der dritten Stapel- Ebene hält eine Standardkonfiguration ohne Messung davon ab, in den Produktionsbetrieb einzutreten. scaling_enabled ist eine statische Flagge, wahr immer max_instances ist konfiguriert größer als min_instancesUnd es sagt allein nicht etwas darüber, ob die dahinterstehenden Zahlen jemals gemessen wurden. Der Stack fügt eine zweite, unabhängige Überprüfung während der Synthesezeit hinzu: Ob es sich um echte, machbare Zahlen handelt. plan Gibt es ein Artefakt für dieses Modell? Nur wenn beide Bedingungen erfüllt sind, synthetisiert die Stack-Engine Skalierungsressourcen: EndpointAutoscaling Konstruiere das System, das die Skalierungspolitik und die Alarmen verknüpft, und ein EndpointObservability Konstruktion, die die Dashboards und Alarme hinzufügt, die zur Überwachung verwendet werden. Ein Modell mit scaling_enabled=True aber keine Messung dahinter ergibt dasselbe Keine Skalierungsressourcen Output als ein mit scaling_enabled=False.
Die CLI des Projekts umschließt die drei Stacke unter einer einzigen Anweisung und anwendet sie in abhängiger Reihenfolge:
uv run speech-infra deploy kokoro-82m
SpeechModelCacheStack führt ein AWS CodeBuild-Projekt aus, das die Gewichte des Modells von Hugging Face einmal in den gespeicherten Amazon S3-Bucket synchronisiert. Eine Startung des Endpunkts ohne Wärmeerhalt muss die Gewichte nicht aus dem Internet holen. Durch den vorherigen scaling_enabled-Test wird SpeechEndpointStack das Container-Image erstellen, es in Amazon ECR versenden und das Amazon SageMaker AI-Modell, die Endpunktkonfiguration sowie den Endpunkt erzeugen.
Die Methodik wird als Befehlskette für die Kommandozeile ausgeführt, in einer festen Reihenfolge:
Abbildung 3: Die Toolkette, ausgeführt in der richtigen Reihenfolge, bei der jede Anweisung ein Objekt an die nächste überträgt
Schritt 1: Überprüfen Sie auf Abweichungen
drift läuft jedes Mal zuerst, bevor alles, was Geld kostet oder einen Endpunkt unter Last hat. Es handelt sich um eine leseonly-Reconciliation zwischen dem tatsächlich deployeden (skalierbaren Zielen, Skalierungspolitiken, Alarmzuständen) und dem, was in der Konfigurationsdatei gesagt wird, dass deployt werden soll. Eine verwaiste Politik aus einem früheren Modell oder eine gestoppte oder abgebrochene qmax oder ttotal-Run würde sonst die Kapazität im Verlauf der Messung stillschweigend verschieben und die gemessenen Zahlen verfälschen.
uv run tts-bench drift
Ein sauberer Ergebnisbericht zeigt keine Unstimmigkeiten und endet mit einem Preflight-OK-Zustand, wodurch der Weg für qmax frei wird. Eine gestoppte oder abgebrochene qmax oder ttotal -Ausführung ist die häufigste Ursache für einen gemelten Mismatch, da sie das Automatische Skalieren auf einer einzigen Instanz blockieren kann. uv run tts-bench thaw --endpoint speech-kokoro-82m wiederherstellt die implementierte Policy, bevor man weitermacht, da qmax und ttotal beide davon ausgehen, dass der implementierte Zustand genau dem Konfigurationsfile entspricht.
Schritt 2: Messen Sie Q_max, den Konkurrenztopf
Q_max ist die maximale Konkurrenzfähigkeit, bei der die in der Warteschlange befindlichen Anfragen sowie die aktuell ausführenden Anfragen auf einer Instanz zusammenkommen, und bei der eine Anfrage immer noch das erste Audiobuchstabe innerhalb des SLO im 95. Perzentil erreicht. Dies wird mit einem geschlossenen Lastpfad gemessen: Eine konstante Konkurrenzfähigkeit N bleibt exakt beibehalten, und N steigt einzeln auf jede Stufe an, bis das SLO bricht. Ein geschlossener Kreislauf vermeidet koordinierte Auslassungen, eine Schwäche bei Tests mit festem Ankunftsrate, bei denen ein langsamer Server den Client dazu bringt, weniger Anfragen zu senden, anstatt einen echten Wartezeitverlust zu zeigen.
uv run tts-bench qmax --model kokoro-82m --dry-run
uv run tts-bench qmax --model kokoro-82m
--dry-run gibt die Schedule und eine Zeitabschätzung mit null AWS-Anfragen aus, sodass Sie zunächst den etwa 36-minütigen Kostenaufwand einer Live-Ausführung budgetieren können. Der Live-Befehl stellt das Auto-Scaling ein und fixiert die Kapazität auf eine Instanz für die gesamte Dauer, wodurch sie automatisch nach Beenden wiederhergestellt wird – daher ist die von ihm erzeugte Zahl ein echter Höchstwert pro Instanz.
Die Lastleiter erfasste die folgenden Ergebnisse:
| Konkurrenzfähigkeit | p95 TTFAB (ms) | Erfüllt 3.000 ms SLO? |
| 1 | 65.4 | ja |
| 5 | 286.2 | ja |
| 10 | 568.5 | ja |
| 20 | 1,129.3 | ja |
| 30 | 1,689.8 | ja |
| 40 | 2,245.0 | ja |
| 50 | 2,805.7 | ja (Q_max) |
| 60 | 3,374.8 | nein (bruch) |
Abbildung 4: p95-Zeit bis zum ersten Audiobuchstaben in Abhängigkeit von der Konkurrenzfrequenz, mit der SLO-Linie und dem Bruchpunkt bei Konkurrenzfrequenz 60
Q_max = 50, und es ist ein eingerichtetes Ergebnis: die 60er Runde hat tatsächlich den SLO überschritten, was bedeutet, dass 50 ein echter Höchstwert statt einer Untergrenze ist. Die gleiche Runde maß die ungezwungene Servicezeit, die Zeit, die eine Anfrage in absoluter Kehrwiederholung benötigt: durchschnittlich 61,3 ms, p95 66,1 ms. Diese Zahl löst einen zweiten, unabhängigen Alarm aus, der später in diesem Artikel beschrieben wird.
Schritt 3: Messen von T_total, der tatsächliche Skalierungszeit
T_total ist die Dauer, die benötigt wird, von einem Wanduhrzeitpunkt, vom Moment, in dem mehr Kapazität gefordert wird, bis zum Moment, in dem diese Kapazität für den gesunden Traffic zur Verfügung steht. Es wird gemessen, indem eine direkte Skalierung erzwungen wird, indem die eigene Erkennungslogik der implementierten Politik umgangen wird, und dann jede unterscheidbare Phase mit einem Zeitstempel markiert wird.
uv run tts-bench ttotal --model kokoro-82m --qmax <qmax-artifact>
ttotal erfordert das qmax Artefakt als Eingabe, da seine Wiederherstellungsbeurteilung auf den gemessenen Stufen dieser Leiter basiert und sich weigert, gegen einen Leiter, der auf einem anderen Drahttransport gemessen wurde, zu funktionieren.
Die erzwungene Skalierung zerfiel in acht gemessene Phasen:
| Stage | Dauer | Anteil von T_total |
| angeforderte Kapazität für desired_set | 30,0 s | 9.4% |
| desired_set zur sichtbaren Instanz in den Logs | 180,8 s | 56,5 % (dominanter) |
| Instanz sichtbar für Container gestartet | 3.7 s | 1.2% |
| Container begann mit framework_init | 0.0 s | 0.0% |
| framework_init bis weights_ready | 6,5 s | 2.0% |
| Gewichte bereit für die Wärme-up-Phase abgeschlossen | 1.0 s | 0.3% |
| Warm-up abgeschlossen – in Dienst | 20,7 s | 6.5% |
| In Betrieb für die wiederhergestellte Verkehrskonfiguration | 47.4 s | 14.8% |
| gemessener Gesamtwert (t_total_s) | 260,2 s | |
| + Politikerkennungsverzögerung, begrenzt (nicht gemessen) | 60,0 s | |
| T_total, geplant | 320,2 s |
Abbildung 5: Die acht gemessenen Phasen eines echten skalierbaren Systems, von der Kapazitätsanfrage bis zum wiederhergestellten Traffic
Die dominierende Phase ist die Bereitstellung von Amazon Elastic Compute Cloud (Amazon EC2)-Instanzen sowie das Herunterladen von Container-Images, was 181 Sekunden in Anspruch nimmt und 56 Prozent des geplanten Gesamtwerts ausmacht. Die effektivste Methode zur Reduzierung von T_total ist nicht der Anwendungscode, sondern die Verkleinerung der Bildgröße oder die Nutzung von warmen Kapazitätspools. Alles, was nach „Instanz sichtbar in den Logs“ liegt, dauert insgesamt nur 79 Sekunden.
Die 60-Sekunden-Zusatzzeit auf die gemessenen 260,2 Sekunden wird in dieser Runde nicht gemessen. Sie ist durch die eigene Konfiguration der Policy begrenzt (Zeiten des Alarm-Evaluierungsintervalls und der Evaluierungsintervalle plus Cooldown), weil diese Runde absichtlich die Detektionlogik der Policy umgangen hat, um den reinen Bereitstellungszeitraum zu isolieren. Die plan-Größen zeigen einen überschüssigen Raum gegenüber dem vollen 320,2-Sekunden-Total, da dieser Reaktionszeitraum ein wesentlicher Bestandteil jeder Produktionsskalierung ist, obwohl diese Messung ihn ausschließt.
Schritt 4: Erstellen Sie die implementierte Policy mit plan
plan ist der einzige Befehl, der nie auf AWS trifft. Er liest die qmax und ttotal Daten, verknüpft sie mit zwei von ihm gewählten Eingaben, einem SLO von 3.000 ms p95 TTFAB und einem Schwellenverhältnis von 1,25x (die Flotte toleriert ein Wachstum des Verkehrs um 25 Prozent innerhalb eines Scale-Out-Zyklus ohne die Einhaltung des SLO zu gefährden) und führt anschließend die folgende Berechnung durch. Danach gibt er einen Bericht mit einem Urteil für jede Erkenntnis aus: ok, warn oder, bei einem wirklich unpraktischen Plan, stop.
uv run tts-bench plan --qmax <qmax-artifact> --ttotal <ttotal-artifact> --peak-rps 5000
Die Flagge --peak-rps (hier 5.000 Anfragen pro Sekunde zusammen mit einer angenommenen Tiefphase von 10) bestimmt die Anzahl der Instanzen der Flotte. Sie wird nicht in die Berechnung des Schwellenwerts einbezogen.
h = surge_ratio - 1 = 1.25 - 1 = 0.25
C_scale_max = (1 - h) x Q_max = 0.75 x 50 = 37.50
C_scale_min = (1 - 2h) x Q_max = 0.50 x 50 = 25.00
W_max = SLO - S_p95 = 3.000s - 0.066s = 2.934s
C_scale_max ist die Konkurrenzvermögen, bei der eine weitere Instanz hinzukommt, unter Q_max durch den Aufwärtsanteil h, sodass die Flotte weiterhin Platz im Schranken hat, wenn sie mehr Kapazität benötigt. C_scale_min ist das Konkurrenzvermögen, unter dem eine Instanz entfernt wird, und wird auf (1 - 2h) von Q_max gesetzt, sodass der Scale-in-Mechanismus nur dann ausgelöst wird, wenn die Last deutlich unter den Punkt sinkt, an dem der Scale-out-Mechanismus erneut ausgelöst würde.
Die endgültige implementierte Konfiguration, genau wie sie vom Tool erstellt wurde:
"kokoro-82m": ModelEndpointConfig(
model_name="kokoro-82m",
instance_type="ml.g5.xlarge",
min_instances=1, # trough 10 rps; 3 is the smallest safe floor for scale-in
max_instances=9, # peak 5000 rps
scaling_target_value=37.500, # C_scale_max, in Amazon CloudWatch units (ratio measured as 1.0)
scale_in_threshold=25.000, # C_scale_min, in Amazon CloudWatch units
ttfab_slo_ms=3000,
queue_max_depth=50, # enforced by the container's own admission gate
scale_out_cooldown_s=30, # short: one instance added at a time
scale_in_cooldown_s=960, # long: see below
)
Die beiden Cooldowns sind absichtlich asymmetrisch. Das Skalieren nach hinten ist günstig, wenn man falsch handelt: Im schlimmsten Fall zahlt man für eine Instanz, die man nicht braucht, weitere dreißig Sekunden. Das Skalieren nach vorne ist nicht kostengünstig, da die Kapazität entfernt wird und später wieder benötigt wird – dafür sind volle T_total (320 Sekunden) erforderlich. Der Cooldown für das Skalieren nach vorne beträgt etwa dreimal T_total, sodass eine Entscheidung zum Skalieren nach vorne nur dann erfolgt, wenn die Last wirklich und langfristig abnimmt.
Die eigene Zugriffskontrolle des Containers setzt separat queue_max_depth=50 um, das dem Wert von Q_max entspricht: Über diese Tiefe wird eine Anfrage sofort abgelehnt mit einer 503 queue_saturated Antwort, anstatt dass sie über den Punkt hinaus in die Warteschlange gelangt, an dem das SLO erreicht werden kann. Ein FirstChunkLatencyP95 Alarm, dessen Schwellenwert 65 ms beträgt (der gemessene p95-Dienstzeit bei Konkurrenz 1), überwacht die Dienstzeit auf einer Instanz, die bereits bereitsteht, und ist enger als das end-to-end SLO, das das Queken einschließt.
Zwei Erkenntnisse aus der Kokoro-82M-Run sind erwähnenswert, da sie zeigen, dass das Tool richtig einen bekannten, akzeptierten Kompromiss darstellt – und nicht ein Defekt.
surge_survival(warn): Das Halten vonC_scale_max(37,5) gegenüberQ_max(50) führt dazu, dass eine Instanz mit 97,4 % Auslastung ist, sobald ein Scale-Out ausgelöst wird, und ein Ersatzteil benötigt einen vollenT_total, um anzukommen. Der Surge-Ratio reserviert zusätzliche Wartebereiche, aber das Überleben vor einem echten Surge hängt davon ab, wie schnell die Warteschlange leert wird – und bei 97,4 % Auslastung bleibt kaum noch Kapazität übrig.scale_in_safety(warn): Entfernen einer Instanz aus einer FlotteNMultipliziert die Konkurrenzfähigkeit jeder verbleibenden Instanz mitN / (N-1). Die Skalierung bleibt stabil nur dann, wenn dieser Verhältnis bestehtC_scale_max / C_scale_min(1,5 hier), was eine Anforderung istN >= 3. Mit einem Boden von 1 Instanz führt eine Skalierung von 2 auf 1 den Überlebenden genau anQ_max, direkt am Decke, der eine weitere Skalierung auslöst. Die lange Cooldown-Zeit dämpft dieses Flattern, ohne es vollständig zu beseitigen. Wenn der Boden auf 3 erhöht wird, wird es strukturell beseitigt – bei der Folge einer verringerten Standkapazität bei geringem Verkehr.
Der Dateiname jedes qmax- oder ttotal-Artefakts kodiert die Konfiguration, gegen die es gemessen wurde, den Instanztyp und das Container-Image-Digest, das in einen Slug umgewandelt wurde (zum Beispiel g5xlarge-8b1b96bc). ttotal und plan weisen jegliche Artefakte ab, deren Fingerabdruck nicht übereinstimmt. Dies kann durch den Parameter --allow-config-mismatch zu einer Warnung werden, aber die Ablehnung ist Standard.
Schritt 5: Bestätigen Sie die implementierte Politik mit validate
validate ist der letzte Befehl in der Kette und der zweite, zusammen mit drift, der nichts ändert. Er vergleicht die eingesetzte Skalierungsstrategie mit den Werten im plan-Artefakt und stellt sicher, dass beide übereinstimmen, bevor die Konfiguration als aktiv behandelt wird.
uv run tts-bench validate --model kokoro-82m --plan <plan-artifact>
Ein sauberer Ergebnis bestätigt, dass scaling_target_value, scale_in_threshold und beide Cooldowns am implementierten skalierbaren Ziel den Werten entsprechen, die von plan berechnet wurden. Jede Unstimmigkeit bedeutet, dass die implementierte Politik und der gemessene Plan sich voneinander entfernt haben, und diese muss gelöst werden, bevor man auf das Autoskalieren des Endpunkts vertraut.
Testen und Validierung
Jeder qmax, ttotal und plan Artefakt, der in diesem Beitrag erwähnt wird, ist ein eingetragenes File im Repository, nicht eine einzelne lokale Ausgabe. Das vorherige funktionierende Beispiel, einschließlich aller Zahlen, kann durch erneut ausführen des plan gegenüber den beiden eingetragenen Messdateien unabhängig reproduziert werden, mit null AWS-Aufrufen und null neuen Kosten:
$ uv run tts-bench plan --qmax <qmax-artifact> --ttotal <ttotal-artifact> --peak-rps 5000
scaling_target_value : 37.500 (C_scale_max)
scale_in_threshold : 25.000 (C_scale_min)
surge_survival : warn
scale_in_safety : warn
Säubern
Um die in dieser Anleitung erstellten Ressourcen zu entfernen, zerstören Sie die Stapel in umgekehrter Reihenfolge mit einer einzigen Befehl:
uv run speech-infra destroy kokoro-82m
speech-infra destroy entfernt das Amazon SageMaker AI-Modell, die Endpunktkonfiguration, den Endpunkt sowie alle mit ihm verbundenen Auto-Scale- oder Amazon CloudWatch-Ressourcen. Es leert jedoch nicht den Amazon S3-Bucket, der die Modellgewichte speichert, oder löscht das Amazon ECR-Repository, in dem das Containerbild erhalten ist, da beides zwischen den Modellen geteilt werden kann. Wenn Sie diese nicht mehr benötigen, leeren und löschen Sie den Amazon S3-Bucket sowie das Amazon ECR-Repository manuell, da der gespeicherte Modellcheckpoint und das Containerbild weiterhin kleine Speichergebühren verursachen, bis sie entfernt werden.
Schlussfolgerung
Deplizieren Sie Kokoro-82M als benutzerdefiniertes Container auf einem Amazon SageMaker AI Echtzeit-Endpunkt und ersetzen Sie das Vermuten durch zwei Messungen am Live-Endpunkt: Q_max, die höchste Konkurrenzfähigkeit einer Instanz, bevor die SLO überschritten wird, und T_total, wie lange eine echte Skalierung dauert. Sie erhalten den Skalierungs-Schwellenwert, den Skalierungsbeginn und beide Cooldowns aus diesen beiden Zahlen durch Berechnung. Die Skalierung basiert auf ConcurrentRequestsPerModel, einem nativem, von AWS veröffentlichten Metrik-Standard, und die direkte Messung der Einheitenkonvertierung statt die Annahme davon sorgt dafür, dass diese Konfiguration mit der tatsächlichen Konkurrenz verbunden bleibt.
Das Ergebnis ist eine Auto-Scaling-Policy, bei der jede Zahl auf eine tatsächliche Messung am eigenen Endpunkt zurückgeführt wird, nicht auf eine Annahme, die von einer anderen Arbeitslast stammt. Diese Unterscheidung macht aus einerconfig-Datei-Grundlage, die stillschweigend überzählige Kosten verursacht oder ihr SLO verletzt, eine Policy, die mit einem spezifischen Konkurrenzen-Höchstwert und einem spezifischen Scale-out-Zeitfenster verteidigt werden kann – beides wird gemessen, nicht behauptet.
Nichts über dieses vierzähnliche Modell, die ausgewählten SLO und Surge-Raten, die gemessenen Q_max und T_total, sowie der Rest, der abgeleitet wurde, ist speziell für TTS. Es wird auf Endpunkte von Amazon SageMaker AI übertragen, die auf Latenz-empfindlichkeit und Konkurrenzkapazität angewiesen sind. Beispielsweise ist ein Echtzeit-Bild-Embedding-Endpunkt, der jede Anfrage durch einen GPU-Frontpass bearbeitet, von demselben Konkurrenzkapazitätslimit begrenzt, nicht von einer Durchsatzmetrik. Die gleiche qmax/ttotal/plan-Kette bleibt unverändert erhalten. Der eigentliche Engpass ist die konkurrierende Anfrage im Fluss, nicht eine Durchsatzmetrik, die von einer anderen Arbeitslast abgeleitet wird. Die speziellen Zahlen hier, Q_max=50 und T_total=320s, gelten für Kokoro-82M auf ml.g5.xlarge. Sie werden sich für ein anderes Modell oder Typ von Instanz unterscheiden. Die Methodik und die Tools, die diese Zahlen erzeugen, bleiben unverändert. Die fünfkommando-Toolkette drift, qmax, ttotal, plan und validate überträgt sich unverändert auf das nächste Modell, das auf diese Weise deployt wird.
Klonen Sie den Beispiel-Repository, dann führen Sie die fünfkommando-Schleife drift, qmax, ttotal, plan und validate gegen Ihren eigenen Endpunkt aus, um eine gemessene Politik zu erzeugen. Prüfen Sie die Amazon SageMaker AI Auto-Scaling-Dokumentation, um die Schwellenwerte an Ihren SLO anzupassen, und öffnen Sie den SageMaker AI-Konsole, um zu sehen, wie die Politik auf den Live-Verkehr reagiert. Wenn Sie Unterstützung bei der Entwicklung einer ähnlichen, messungsgetriebenen Bereitstellung benötigen, kontaktieren Sie Ihr AWS-Account-Team.