Deep Dive in die LLM-Inferenz im großen Maßstab — Harshul Jain, Audible & Tanmay Sah, unabhängiger KI-Forscher

AAI Engineer
컴퓨터/소프트웨어경제 뉴스AI/미래기술

스크립트

00:00:00Guten Tag allerseits. Mein Name ist Harshal Jain und das ist Tanmisha. Wir
00:00:21möchten Sie alle zu diesem zweistündigen Workshop zum Thema LLM-Inferenz begrüßen.
00:00:26Das Ziel dieses Workshops ist es, diesen Bereich von Grund auf zu verstehen,
00:00:33tiefer einzutauchen und nachzuvollziehen, was in der gesamten Branche vorgeht.
00:00:39Ein kurzer Hintergrund zu uns. Ich bin Senior Software Engineer bei
00:00:47Audible. Ich baue seit fünf Jahren ML- und KI-Datenplattformen auf und
00:00:53nebenbei schreibe ich dieses Open-Source-Handbuch zur LLM-Inferenz.
00:00:59Und Tanmay ist Senior Quantitative Modeler bei der Xi'an's Bank Corporation.
00:01:06Er hat kürzlich seinen PhD abgeschlossen und forscht aktiv an Agenten,
00:01:12Verifizierern und Weltmodellen. Wer von Ihnen ist zum ersten Mal bei der LLM-Inferenz dabei? Bitte einmal Handzeichen.
00:01:24Okay, großartig. Und wer hat diese Modelle bereits in der Produktion eingesetzt?
00:01:33Sie haben sie optimiert und den Produktionsverkehr bedient. Okay, sehr gut. Dieser
00:01:42Workshop richtet sich an Anfänger und Fortgeschrittene. Alle
00:01:48Folien und Übungen befinden sich im Repository, das ich gleich teilen werde. Hier ist eine kurze
00:01:56Agenda für den Workshop. Wir beginnen mit der Problemstellung. Wir versuchen,
00:02:01einige der Schwachstellen rund um die LLM-Inferenz zu verstehen. Dann schauen wir uns an, was diese
00:02:08Schwachstellen verursacht, und legen damit unsere Grundlagen. Danach widmen wir uns zwei
00:02:14Arten von Optimierungen: Modelloptimierungen und
00:02:19Serving-Optimierungen. Anschließend lernen wir verschiedene Serving-Engines kennen,
00:02:25die für die Bereitstellung unserer LLM-Inferenz-Lösungen in der Produktion verfügbar sind. Wir zeigen einige
00:02:32Benchmarks und ein Entscheidungssdiagramm dazu, welche Engine zu verwenden ist.
00:02:39Gut. Um die Schwachstellen zu verstehen, müssen wir zunächst wissen, was eine LLM-Inferenz eigentlich ist.
00:02:47Das wissen die meisten von uns wahrscheinlich ohnehin schon. Aber alles, was Sie Ihre KI tun lassen,
00:02:55sei es das Generieren von Videos, Audio, das Analysieren von Text, medizinischen Berichten oder
00:03:02Steuerrechnungen – das alles ist eine LLM-Inferenz. Und dieser Markt ist heute etwa 23 Milliarden US-Dollar schwer.
00:03:12SemiAnalysis hat kürzlich mitgeteilt, dass man für die Modellierung von Google-Suchanfragen mit LLMs einen Kapitalaufwand von rund 36 Milliarden Dollar benötigt.
00:03:25Und die Kosten pro Abfrage müssen unter 0,5 Cent liegen, damit das Suchgeschäft profitabel bleibt.
00:03:33Andererseits erwähnte Business Insider, dass KI richtig eingesetzt werden muss und jeder damit beginnen sollte, seine Token-Nutzung zu prüfen und zu budgetieren.
00:03:43Und all dies geschieht, weil die Hardware begrenzt ist, Rechenleistung teuer ist und die Inferenz teuer ist.
00:03:50Mit der steigenden Nachfrage nach immer mehr KI-Nutzung steigen auch diese Inferenzkosten kontinuierlich an.
00:04:03Diese Statistik ist zwar schon älter von OpenAI, aber sie gilt immer noch.
00:04:11Wenn man sich die Trainingskosten von GPT-3 ansieht, lagen diese bei rund 4,6 Millionen US-Dollar. Das waren einmalige Kosten.
00:04:19Aber die Inferenzkosten sind wiederkehrende Betriebskosten, die mit jedem neuen Benutzer, jedem verarbeiteten Token und jeder neu gestarteten Sitzung auf der KI skalieren.
00:04:36Es gibt im Grunde nur zwei Wege, dem entgegenzuwirken: Entweder man reduziert die Token-Nutzung.
00:04:47Die Alternative ist, dass Sie versuchen sollten, Ihre Inferenzlösungen als Inferenz-Dienstanbieter für Ihre Kunden und sich selbst zu optimieren.
00:04:58Daher sehen wir ständig, dass immer mehr neue Lösungen auf den Markt kommen.
00:05:06Die Idee ist also, genau jene Grundlagen aufzubauen, die uns helfen, alles, was als Nächstes erscheint, zu verstehen und zu bewerten.
00:05:18Zu Beginn machen wir eine kurze Demo, eine kurze Demonstration der verschiedenen Schwachstellen rund um die Inferenz.
00:05:28Das hier ist ein Repository.
00:05:31Sie können es klonen oder auch auf GitHub öffnen.
00:05:36Es heißt „LLM inference at scale“.
00:05:39Ein kurzer Hintergrund dazu: Vor vier Monaten, als ich noch nichts über LLM-Inferenz wusste, fing ich an, mich damit zu beschäftigen.
00:05:46Ich merkte, dass viele Ressourcen verstreut waren.
00:05:49Also haben wir begonnen, alles an einem Ort zusammenzutragen, um den Leuten zu helfen.
00:05:55Ich werde jetzt diesen Diashow-Modus verlassen und in den erweiterten Modus wechseln.
00:06:11In diesem Repository finden Sie in der Readme-Datei einen Link zu den Folien.
00:06:27Das führt zu einem Ordner mit einer PPTX und einem Benchmark-Bericht darin.
00:06:34Sie können ihn jederzeit herunterladen, und für die Demos haben wir einige Jupyter-Notebooks.
00:06:43Wir haben mit Molab zusammengearbeitet, einer Alternative zu Google Colab, die eine kostenlose RTX 6000 GPU bereitstellt.
00:06:54Das ist eine GPU mit 100 GB RAM, und wir haben diese Notebooks bereits vorbereitet, damit das Experimentieren einfach ist und alle Ressourcen voreingestellt sind.
00:07:09Wir beginnen mit einer einfachen Demo A.
00:07:16Lassen Sie mich kurz nachschauen.
00:07:31Wenn es um die Inferenz geht, muss man diese auf einem bestimmten Modell ausführen, richtig?
00:07:40Für die Zwecke dieses Workshops verwenden wir ein einfaches Mistral 7B-Modell.
00:07:45Es ist ein kleines Modell mit einer Größe von etwa 15 GB.
00:07:49Wir werden es also in die GPU laden.
00:07:53Dazu sehen wir uns auch einige GPU-Statistiken an.
00:07:58Wir sehen also, dass wir auf der 6000 Blackwell arbeiten.
00:08:01Und Sie denken vielleicht, ich führe die Zellen nicht aus, weil ich dem WLAN auf Konferenzen nicht vertraue.
00:08:08Daher gehe ich einfach auf die Ergebnisse ein, die wir zuvor ausgeführt haben.
00:08:18Wir haben also eine GPU mit 102 GB.
00:08:22Als Erstes frage ich mich, wie mein Speicherverbrauch bei der LLM-Inferenz aussieht.
00:08:31Ich lade dieses Modell und sehe, dass wir etwa 15 GB haben.
00:08:37Es verbleiben also grob 87,5 GB.
00:08:40Und wenn ich nun die Inferenz durchführe, stelle ich fest: Je mehr Eingaben ich übergebe, desto mehr Speicher wird benötigt.
00:08:52Der Speicher steigt langsam an, aber er steigt kontinuierlich.
00:08:56Stellen Sie sich vor, Sie haben eine Kontextlänge von etwa 4.000, 16.000 oder 32.000 Token.
00:09:03Dieser Speicherbedarf kann drastisch wachsen, sodass man schnell in Out-of-Memory-Probleme gerät.
00:09:12Das ist also definitiv Ihr erstes Problem: Der Speicher wächst mit der Anzahl der Token.
00:09:18Als einfache Visualisierung sieht das folgendermaßen aus.
00:09:24Das zweite Problem ist, dass die Zeit bis zum ersten Token sehr, sehr langsam ist.
00:09:32Wir messen dies mit einer Metrik namens TTFT.
00:09:35Das ist die Abkürzung dafür.
00:09:37Wenn Sie versuchen, die TTFT in Abhängigkeit von der Eingabegröße zu messen, sehen Sie, dass die TTFT bei längerem Kontext langsamer wird.
00:09:52Es gibt also zwei Probleme.
00:09:54Ihr Speicher wächst mit der Token-Größe.
00:09:56Ihre TTFT wächst mit der Token-Größe.
00:09:59Entschuldigung, nicht der Token-Größe, sondern der Kontextgröße.
00:10:07Und das dritte Problem ist der Durchsatz.
00:10:09Der Durchsatz bestimmt, wie viele Token pro Sekunde verarbeitet werden können.
00:10:13Und wie viele Benutzer pro Sekunde bedient werden können.
00:10:16Wenn Sie eine sehr, sehr simple Implementierung auf Ihrem lokalen System verwenden, läuft das stark sequenziell ab.
00:10:24Wenn Sie also fünf Anfragen senden, werden alle fünf Anfragen nacheinander statt parallel bearbeitet.
00:10:31Dadurch dauert die Bearbeitung Ihrer Anfrage bei mehreren Benutzern entsprechend länger.
00:10:40Das sind also diese drei Probleme.
00:10:43Es gibt noch ein viertes.
00:10:44Das habe ich hier noch nicht beschrieben.
00:10:45Das werden wir im Laufe der Zeit wahrscheinlich noch genauer verstehen.
00:10:48Aber merken wir uns: Das sind die drei Probleme – Speicher, TTFT und Durchsatz.
00:10:55Gut.
00:10:56Ich gehe zurück zu den Folien.
00:11:02Okay.
00:11:03Perfekt.
00:11:04Es müsste das hier sein.
00:11:17Ist es sichtbar?
00:11:18Ja.
00:11:19Es ist sichtbar.
00:11:20Es ist sichtbar.
00:11:21Ja.
00:11:22Es ist sichtbar.
00:11:23Es ist sichtbar.
00:11:24Es ist sichtbar.
00:11:25Ja.
00:11:26Es ist sichtbar.
00:11:27Es ist sichtbar.
00:11:28Ja.
00:11:29Es ist sichtbar.
00:11:30Ja.
00:11:31Es ist sichtbar.
00:11:32Ja.
00:11:33Es ist sichtbar.
00:11:34Ja.
00:11:35Es ist sichtbar.
00:11:36Es ist sichtbar.
00:11:37Ja.
00:11:38Es ist sichtbar.
00:11:39Ja.
00:11:40Es ist sichtbar.
00:11:41Ja.
00:11:42Es ist sichtbar.
00:11:43Ja.
00:11:44Es ist sichtbar.
00:11:45Ja.
00:11:46Ja.
00:11:47Wenn Sie in diesem Repository den Workshop-Ordner sehen, finden Sie dort die README und die README
00:11:55enthält alle Links, Folien und Demos.
00:12:01Klappt das?
00:12:06Okay.
00:12:07Perfekt.
00:12:09Okay.
00:12:10Perfekt.
00:12:16Okay.
00:12:17Beginnen wir nun mit den Grundlagen.
00:12:19Lassen Sie uns verstehen, was die Gründe für diese Schwachstellen sind.
00:12:25Dazu müssen wir uns diese Inferenz-Pipeline ansehen.
00:12:32Wir erhalten also einen eingehenden Text.
00:12:35Dieser Text kann eine beliebige Anzahl an Wörtern haben.
00:12:38Man konvertiert diese in Tokens.
00:12:41Zur Vereinfachung kann man davon ausgehen, dass ein Wort einem Token entspricht.
00:12:46Dann wandelt man sie quasi in Embeddings um und leitet sie an die Transformer weiter.
00:12:53Es gibt zum Beispiel 32 Transformer-Schichten, was jedoch spezifisch für Mistral 7 ist.
00:12:58Verschiedene Modelle haben eine unterschiedliche Anzahl an Schichten.
00:13:01Und dann generiert man ein neues Token.
00:13:04Dieses Token fließt im Grunde wieder in die Eingabe ein.
00:13:06Dann generiert man ein weiteres Token und so geht das immer weiter.
00:13:09In diesem gesamten Prozess sieht man, dass etwa 95 % der Rechenleistung von diesen Transformer-Schichten beansprucht werden.
00:13:18Daher lohnt es sich zu betrachten, was innerhalb dieser Transformer-Schicht vorgeht.
00:13:24Innerhalb dieser Transformer-Schicht gibt es noch weitere Schichten.
00:13:28Es gibt eine Normierungsschicht.
00:13:30Es gibt eine Attention-Schicht.
00:13:32Es gibt eine Feed-Forward-Schicht und so weiter.
00:13:35Und die Attention-Schicht ist meiner Meinung nach diejenige, die sehr, sehr berühmt geworden ist.
00:13:40“Attention is all you need”-Leute.
00:13:42Das ist denke ich sehr gut bekannt.
00:13:44Attention ist also die rechenintensivste Schicht.
00:13:48Und wir müssen verstehen, was innerhalb dieser Attention-Schicht vor sich geht.
00:13:53Was macht Attention also?
00:13:56Wenn man einen Eingabetext hat, muss dieser die Attention-Scores jedes Tokens in Bezug auf alle vorherigen Tokens ermitteln.
00:14:05Um das zu tun, muss jedes Token in einen Key-, Query- und Value-Raum projiziert werden.
00:14:14Um es einfacher auszudrücken, verstehen wir Folgendes.
00:14:20Wenn man 10 Tokens hat, benötigt man 10 verschiedene Query-, Key- und Value-Vektoren.
00:14:26Gibt es 100 Tokens, braucht man 100 Key- und Value-Vektoren.
00:14:31Gibt es 1000 Tokens, benötigt man 1000 Key-Value-Vektoren.
00:14:35Die Anzahl der Key- und Value-Vektoren steigt also, wenn man die Eingabegröße erhöht.
00:14:45Und wenn man die KV-Größe pro Token für ein Mistral 7b berechnet, beläuft sie sich auf 131 KV.
00:14:54Das liegt daran, dass man zwei Vektoren hat, K und V.
00:14:59Man muss die Größe multiplizieren.
00:15:02Ein Vektor hat beispielsweise 128 Dimensionen.
00:15:04Das muss man mit 32 Transformer-Schichten multiplizieren.
00:15:08Und dann muss man es mit den KV-Heads multiplizieren.
00:15:11Für Mistral 7b sind es KV-Heads.
00:15:15Es sind nicht 32, da es eine andere Art von Attention-Mechanismus verwendet, worüber wir gewiss noch sprechen werden.
00:15:23Aber ja, die KV-Größe pro Token beträgt also 131 KV.
00:15:30Stellen Sie sich nun vor, Sie haben einen 4K-Kontext, dann beträgt diese Größe etwa ein halbes GB.
00:15:37Wenn Sie einen 16K-Kontext verwenden, beläuft sich die Größe auf 2,1 GB.
00:15:42Multiplizieren Sie das nun mit den Benutzern.
00:15:45Nehmen wir an, Sie können mehrere Benutzer gleichzeitig bedienen.
00:15:49Gleichzeitig auf dieser GPU wären das etwa 42 GB bei einem 4K-Kontext und 80 Benutzern.
00:15:58Und wenn Ihre GPU nur etwa 24 GB hat, geht Ihnen bereits der Speicher aus.
00:16:04Sie können also nicht so viele Benutzer mit so viel Kontext bedienen.
00:16:11Um sich das zu veranschaulichen, betrachten wir den GPU-Speicher.
00:16:14Der GPU-Speicher enthält die Modellgewichte, die ziemlich fest vorgegeben sind.
00:16:19Das sind vortrainierte Gewichte.
00:16:21Es gibt auch einen Overhead, der ebenfalls fest ist.
00:16:24Der ändert sich zwar, aber eben nicht allzu stark.
00:16:29Im Großen und Ganzen kann man davon ausgehen, dass er fest ist.
00:16:32Und dann gibt es noch den verbleibenden Speicher.
00:16:35Dieser verbleibende Speicher wird von Ihrem KV-Speicher genutzt, also den Key- und Value-Vektoren.
00:16:41Nehmen wir also an, Sie haben einen Benutzer.
00:16:46Sie können nur so viele Key- und Value-Vektoren oder so viele Tokens bedienen, wie in diesen gesamten restlichen Speicher von 80 GB passen.
00:17:00Das können wir auch an einer einfachen Demo zeigen.
00:17:07Okay, gut.
00:17:08Okay, gut.
00:17:08Mal sehen, ob ich das tatsächlich ausführen kann.
00:17:14Okay, gut.
00:17:15Mal sehen, ob ich das tatsächlich ausführen kann.
00:17:15Wo zum Teufel ist das?
00:17:15Okay, gut.
00:17:16Mal sehen, ob ich das tatsächlich ausführen kann.
00:17:21Wo zum Teufel ist das?
00:17:22Okay, gut.
00:17:23Okay, gut.
00:17:24Ja.
00:17:25Ja.
00:17:25Sie werden also sehen – mal sehen, ob ich das tatsächlich ausführen kann.
00:17:31Mal sehen, ob ich das tatsächlich ausführen kann.
00:17:33Mal sehen, ob ich das ausführen kann.
00:17:34Mal sehen, ob ich das ausführen kann.
00:17:35Mal sehen, ob ich das ausführen kann.
00:17:36Mal sehen, ob ich das ausführen kann.
00:17:37Okay, gut.
00:17:38Ja.
00:17:39Sie werden also sehen, dass die GPU angeschlossen ist.
00:17:43Okay, gut.
00:17:44Ja.
00:17:45Sie werden also sehen, dass die GPU angeschlossen ist.
00:17:56Hier versuchen wir lediglich den Speicher basierend auf der Mathematik und unserer gewonnenen Intuition zu bestätigen.
00:18:13die wir aufgebaut haben.
00:18:14Der Modellspreicher – nehmen wir an, Sie haben 7 Milliarden Parameter und verwenden
00:18:19eine 16-Bit-Präzision.
00:18:20Ihr Gesamtspeicher beläuft sich auf 14,6 GB.
00:18:23Das kann man im Grunde mit der Mathematik nachprüfen.
00:18:27Wenn man also all diese Berechnungen anstellt, kommt man auf 14,6 GB.
00:18:33Nun kommen wir zu KV und der KV-Größe.
00:18:37Diese KV-Größe entspricht also Ihren 131 KV pro Token.
00:18:42Und wenn man diese Berechnungen anstellt und versucht, sich das zu veranschaulichen.
00:18:47Oh, sicher.
00:18:52Warten Sie.
00:18:53Okay.
00:18:54Und lassen Sie uns das Ganze nun einfach visualisieren.
00:19:07Okay, gut.
00:19:10Großartig.
00:19:11Ja.
00:19:12Das ist also das Speicherdiagramm.
00:19:15Wenn Sie also sehen – mit zunehmendem Kontext steigt auch Ihr Speicherbedarf kontinuierlich an.
00:19:21Ein weiterer Aspekt, den man sich bewusst machen muss: Wenn die Anzahl der Benutzer steigt, wächst auch der Speicherbedarf.
00:19:28Wenn Sie also etwa 160 Benutzer auf einer GPU bedienen möchten, können Sie nur eine
00:19:37geringere Kontextlänge unterstützen.
00:19:40Es gibt also stets einen Kompromiss zwischen der Kontextlänge, die Sie bedienen können, und den Kosten,
00:19:47die Sie einsparen können, indem Sie mehrere Benutzer oder gleichzeitige Benutzer auf einer einzigen GPU unterbringen.
00:19:54Sie müssen also immer diesen Kompromiss eingehen.
00:19:57Und wir werden das in ein paar weiteren Folien noch durchgehen.
00:20:06Können Sie das bitte wiederholen?
00:20:10Es tut mir leid.
00:20:11Ich kann Sie nicht hören.
00:20:12Sehen Sie einen anderen Pool mit einer anderen Kontextlänge, sodass man den geringeren Speicher
00:20:25des Richtigen bedienen kann?
00:20:26Ja.
00:20:27Cool.
00:20:28Cool.
00:20:29Okay.
00:20:30Gut.
00:20:31Kehren wir also wieder zurück.
00:20:32Das war also der Speicher.
00:20:33Wir müssen verstehen, warum wir eine längere Zeit bis zum ersten Token hatten, wenn wir die Kontextlänge erhöhten.
00:20:53vergrößerten.
00:20:54Dazu müssen wir die beiden Inferenzphasen verstehen.
00:20:58Diese Phasen sind die Pre-Fill- und die Decode-Phase.
00:21:01Ich schätze, das schien wie eine Menge Artikel, aber wir wollten es einfach erklären.
00:21:06Wenn man also viele – wenn man diese Eingabetokens sendet, möchte man genau die erwähnten Key- und Value-Vektoren für alle Tokens erstellen.
00:21:20Dann möchte man die Attention-Scores jedes Tokens in Bezug auf die vorherigen Tokens berechnen.
00:21:27All diese Operationen, die man durchführt, sind sehr, sehr matrixlastig.
00:21:31Es ist ein sehr, sehr rechenintensiver Vorgang.
00:21:34Und wir alle wissen, dass GPUs hervorragend für rechenintensive Workloads geeignet sind.
00:21:41Deshalb nennen wir die Pre-Fill-Phase rechengebunden (compute bound).
00:21:46Und sie nimmt einige Zeit in Anspruch, um abgeschlossen zu werden.
00:21:49Die Zeit, die diese Phase benötigt, ist also Ihre Zeit bis zum ersten Token (TTFT).
00:21:55Wenn Sie also mehr Eingabetokens haben, müssen Sie mehr Key-Value-Vektoren generieren.
00:22:02Sie müssen viel mehr Attention-Berechnungen durchführen.
00:22:05Und aus diesem Grund wird Ihre TTFT immer langsamer.
00:22:12Wenn Sie dagegen einmal ein Token generieren, müssen Sie das fortlaufend wiederholen, um nacheinander weitere Tokens zu erzeugen.
00:22:20Dabei müssen Sie jedoch jedes Mal die Key- und Value-Vektoren aller vorherigen Tokens erstellen, was genau dem Pre-Fill entspricht.
00:22:30Wie Sie dort Key-Value-Vektoren aufgebaut haben, so tun Sie das auch hier.
00:22:34In der Decode-Phase berechnen Sie die Attention-Berechnungen jedoch nur für das neue Token.
00:22:40Und deshalb ist das Ganze viel weniger rechenintensiv.
00:22:45Man bezeichnet es auch als speichergebunden (memory bound).
00:22:48Wir werden gleich sehen, warum es speichergebunden genannt wird.
00:22:54In einem klassischen Zeitstrahl würden Sie die Pre-Fill- und Decode-Phase so sehen.
00:22:59Die Zeit, die das Pre-Fill benötigt, ist also Ihre Zeit bis zum ersten Token.
00:23:03Und die Zeit, die jeder Decode-Schritt beansprucht, entspricht im Grunde Ihrer Latenz zwischen den Tokens.
00:23:12Das ist also die vierte Metrik, über die Sie sich Gedanken machen müssen.
00:23:18Wie viel Zeit nimmt Ihr Decode-Schritt in Anspruch?
00:23:21Okay.
00:23:22Okay.
00:23:23Gut.
00:23:24Warum braucht der Decode-Schritt bzw. das Decodieren nun Zeit?
00:23:34Und warum wird es als speichergebundener Vorgang bezeichnet?
00:23:38Versuchen wir das zu verstehen.
00:23:40Um das zu verstehen, müssen wir uns ansehen, wie Matrixmathematik auf der GPU im Großen und Ganzen funktioniert.
00:23:47Eine GPU verfügt also über zwei Arten von Speicher.
00:23:50Sie haben einen High-Bandwidth Memory.
00:23:52Sie haben einen Shared Memory (Gemeinsamer Speicher).
00:23:55Der High-Bandwidth Memory ist größer, hat aber eine geringere Bandbreite.
00:24:01Mit geringerer Bandbreite meine ich, dass Sie Daten mit einer geringeren Rate daraus übertragen können.
00:24:06Im Vergleich dazu ist der Shared Memory kleiner in der Größe, hat aber eine sehr, sehr hohe Bandbreite.
00:24:13Das bedeutet, Sie können Daten sehr schnell in ihn hinein und aus ihm heraus übertragen.
00:24:19Wenn Sie also Matrixmathematik durchführen müssen, müssen Sie die Daten in Blöcken aus dem High-Bandwidth Memory abrufen.
00:24:27Sie müssen sie in den Shared Memory laden.
00:24:30Die Berechnungen durchführen.
00:24:32Und das Ergebnis zurück in den High-Bandwidth Memory schreiben.
00:24:38Für die Pre-Fill-Phase, wenn Sie das tun müssen, müssen Sie diese Matrixberechnung nur einmal durchführen.
00:24:46Für die Decode-Phase müssen Sie diese Matrixberechnung jedoch immer wieder durchführen, da Sie jedes einzelne Token nacheinander generieren.
00:24:59Und deshalb spielt es keine Rolle, wie schnell Ihr Decodieren ist, denn Sie können Ihre Daten nur mit einer bestimmten Geschwindigkeit aus dem High-Bandwidth Memory in den Shared Memory übertragen.
00:25:14Da Sie durch die Bandbreitengeschwindigkeit des High-Bandwidth Memory eingeschränkt sind.
00:25:18Und das bestimmt Ihre Obergrenze für Tokens – also mit welcher Rate Sie tatsächlich Tokens aus dem Decode-Schritt generieren können.
00:25:32Wenn Sie sich das in einem Roofline-Diagramm ansehen, gibt es einen linken Bereich, der als speichergebunden bezeichnet wird.
00:25:42Mathematisch wird er durch die arithmetische Intensität bestimmt.
00:25:47Die arithmetische Intensität ist die Anzahl der Fließkommaintensivoperationen, die Sie pro übertragenem Datenbyte ausführen.
00:25:55Da Sie beim Decode-Schritt eine Menge Daten übertragen – wie die Key- und Value-Vektoren aller vorherigen Tokens und die Modellgewichte –
00:26:08aber weniger Berechnungen durchführen, da Sie die Attention-Mathematik nur für ein einziges Token berechnen,
00:26:13ist seine arithmetische Intensität sehr gering.
00:26:18In der Pre-Fill-Phase hingegen übertragen Sie die Daten einmal, führen danach aber diese schweren Berechnungen aus.
00:26:27Und deshalb ist seine arithmetische Intensität sehr hoch.
00:26:30Sie wissen also nun mathematisch, warum die Rechenleistung bzw. warum die arithmetische Intensität des Pre-Fills im Vergleich zum Decodieren so hoch ist.
00:26:44Okay.
00:26:46Das ist also eine weitere kleine Demo.
00:26:51Okay.
00:26:52Jedes Mal muss ich.
00:26:53Okay.
00:26:54Okay.
00:26:55Großartig.
00:26:56Ich hoffe, das ist bereits so weit.
00:26:58Also, ja.
00:26:59Wieder laden wir das Modell.
00:27:04Nun, das ist sozusagen der Pre-Fill-Aufwand.
00:27:09Was wir im Grunde tun, ist, dass wir den Eingabetext entgegennehmen und dann versuchen, diesen zu generieren – den Pre-Fill-Schritt und die Zeit, die er dafür benötigt.
00:27:22Wir sehen, dass mit zunehmender Größe der Eingabetokens auch dieser Pre-Fill-Aufwand steigt.
00:27:28Das wissen Sie, und das ist der Grund, warum sich Ihre DTFT erhöht.
00:27:33Und dann eben Ihre Decode-Zeit.
00:27:36Die Decode-Zeit bleibt also im Durchschnitt ungefähr gleich.
00:27:41Wenn man also den Kaltstart ignoriert, liegt Ihre Decode-Zeit ungefähr auf Höhe der Durchschnittslinie.
00:27:50Sie wird dennoch von der Eingabegröße beeinflusst.
00:27:57Es ist nicht so, dass es eine konstante Zeit ist.
00:28:00Und das liegt daran, dass immer noch die Key- und Value-Vektoren aus dem Speicher für alle vorherigen Tokens abgerufen werden müssen.
00:28:07Es gibt also nach wie vor diesen geringen Zeitaufwand, den Sie beim Decode-Schritt beobachten können.
00:28:15Und das ist das klassische Roofline-Diagramm.
00:28:20Okay.
00:28:22Okay.
00:28:23Präsentation.
00:28:24Okay.
00:28:25Okay.
00:28:26Okay.
00:28:27Versuchen wir nun, die Durchsatzdimension zu verstehen.
00:28:43Sie möchten verstehen, wie viele Benutzer Sie tatsächlich bedienen können.
00:28:48Und ich denke, wir haben ein Diagramm des GPU-Speichers gesehen, in dem wir sahen: Okay, es gibt etwas Speicher, der für das Wachstum der Key- und Value-Vektoren frei ist.
00:28:56Okay.
00:28:57Nehmen wir also an, Sie haben nur einen einzigen Benutzer.
00:29:01Was ist die gesamte KV-Größe, die Ihnen zur Verfügung steht und die Sie unterstützen können?
00:29:09Sie wird durch Ihr Kontextlimit definiert.
00:29:11Die maximale Anzahl an Benutzern, die Sie unterstützen können, ergibt sich daraus, dass Sie den verfügbaren Speicher auf der GPU durch die Key- und Value-Größe pro Benutzer teilen.
00:29:25Wenn Sie das tun, ergibt das die Anzahl der gleichzeitigen Benutzer.
00:29:32Nehmen wir nun an, Ihre GPU ist fest, Ihr Modell ist fest, sodass Ihre KV-Größe pro Token fest ist.
00:29:46Es bleiben hier nur zwei Dimensionen übrig: der Kontext und Ihre gleichzeitigen Benutzer.
00:29:53Wenn Sie mehr gleichzeitige Benutzer bedienen möchten, müssen Sie die Kontextlänge reduzieren.
00:29:57Wenn Sie die Kontextlänge reduzieren, könnte dies Ihre Qualität beeinträchtigen.
00:30:02Das sind also die beiden Dimensionen, zwischen denen wir im Moment abwägen.
00:30:09Wenn wir aber... können Sie tatsächlich die maximale Anzahl an gleichzeitigen Benutzern bedienen?
00:30:17In einer idealen Welt wahrscheinlich nicht, denn jedes Unternehmen hat ein Latenz-SLO, das wir einhalten müssen.
00:30:27Wenn Sie sich also erinnern, sagte ich im Decode-Schritt, dass die Zeit für das Decodieren weiter zunimmt, wenn Sie mehr Eingaben haben.
00:30:37Sie steigt auch, wenn Sie mehr Benutzer haben.
00:30:40Letztendlich wird also auch Ihre Latenz zwischen den Tokens beeinträchtigt, wenn Sie eine höhere Batch-Größe haben.
00:30:51Und auch Ihr TTFT wird dadurch beeinträchtigt.
00:30:53Jetzt gibt es also eine dritte Dimension, um die Sie sich kümmern müssen: Ihre Latenz.
00:30:58Die drei Dimensionen, die Sie haben, sind also Qualität, Latenz und Durchsatz.
00:31:04Das führt zu diesem Kompromiss-Dreieck, bei dem Sie zwischen den Optionen wählen müssen.
00:31:11Für eine Premium-Chat-Anwendung möchten Sie definitiv die Qualität priorisieren und Sie möchten die Latenz priorisieren.
00:31:21Sie möchten nicht, dass Ihre Benutzer warten – zwar nicht unendlich lange, aber wahrscheinlich auf eine höhere Latenz.
00:31:30Sie können immer die Anzahl der Benutzer opfern, die Sie auf der GPU unterstützen können, und diese Kosten möglicherweise tragen, um kundenorientierter zu sein.
00:31:39Wenn Sie hingegen ein Agenten-Szenario betrachten, Entschuldigung, die asynchrone Agenten-Workload, möchten Sie definitiv Qualität und Durchsatz priorisieren.
00:31:53Denn das sind langfristig laufende Aufgaben.
00:31:56Und Sie möchten so viele gleichzeitige Aufgaben wie möglich bedienen, allerdings mit einer sehr, sehr viel höheren Qualität.
00:32:06Und oft denken wir: Okay, wenn die GPU eine sehr teure GPU ist, ist sie vielleicht nicht die richtige Wahl für uns.
00:32:19Aber es stellt sich heraus, dass sie Ihnen tatsächlich die geringsten Kosten pro Million Tokens einbringen kann.
00:32:27Aber Sie müssen Ihren Berechnungen hinsichtlich der maximalen Benutzer wirklich vertrauen und diese Schätzungen korrekt anstellen.
00:32:40Wir haben also... lassen Sie mich einfach... okay, großartig.
00:32:55Für den Kapazitätsrechner gibt es einen Link zu Colab, weil ich damit vertraut war.
00:33:01Ich musste aus der gesamten Widget-Bibliothek migrieren und hatte keine Zeit.
00:33:16Da ich faul war, habe ich stattdessen einfach Colab gewählt.
00:33:20Entschuldigung an mein Lab.
00:33:23Mein V-RAM ist also verbunden.
00:33:34Okay.
00:33:45Es liegt also wahrscheinlich am WLAN.
00:33:46Okay, großartig.
00:34:02Was wir hier also getan haben, ist, dass wir einige GPUs mit ihren V-RAMs und Bandbreiten, den Fließkommaoperationen und den Kosten pro Stunde dargestellt haben.
00:34:11Danach haben wir sozusagen diesen einfachen Kapazitätsrechner gebaut.
00:34:19Das ist nur ein KV-Visualisierer, bei dem Sie sehen: Wenn Sie die Anzahl der Tokens erhöhen, vergrößert sich die KV-Größe.
00:34:29Und wenn Sie die Anzahl der Benutzer erhöhen, wächst die Größe viel schneller.
00:34:37Und in diesem Kapazitätsrechner lassen wir das Ganze laufen.
00:34:47Wir haben also ein Modell ausgewählt, bei dem es sich um ein Modell mit 7 Milliarden Parametern handelt.
00:34:56Wir haben die Präzision auf FP16 eingestellt.
00:35:01Bei der Entscheidung für eine GPU gehen wir nun so vor, dass Sie sich zuerst für eine Dimension entscheiden müssen, die Ihnen am wichtigsten ist.
00:35:15Für einen Premium-Chat erwähnte ich bereits, dass die Latenz definitiv entscheidend ist.
00:35:21Und für die asynchronen Workloads ist die minimale Batch-Größe, die Sie auf einer einzigen GPU verarbeiten möchten, die zweite Dimension.
00:35:31Sie sollten diese also zuerst festlegen.
00:35:34Ich gehe also von einer Premium-Chat-Anwendung aus.
00:35:39Ich kann mich also für etwa 10 Millisekunden Latenz entscheiden.
00:35:44Eine minimale Batch-Größe ist mir egal.
00:35:46Ich bin also mit vermutlich zwei einverstanden.
00:35:53Okay.
00:35:54Also wahrscheinlich mit sieben gleichzeitigen Benutzern auf einer einzigen GPU.
00:35:59Und mein Kontextlimit ist mir sehr wichtig, weil ich mich auch auf die Qualität konzentrieren möchte.
00:36:07Und deshalb sehe ich mir einige der GPUs an.
00:36:10Die H100 mit 80 GB kostet etwa 8 Dollar pro Stunde.
00:36:15Aber wie sieht es mit meiner 300x aus?
00:36:19Ist das so?
00:36:20Ja.
00:36:21Das kostet also etwa 10 Dollar pro Stunde.
00:36:24Wenn man also all diese Durchsatzberechnungen anstellt, die wir vorhin mathematisch gezeigt haben, kann man seine Kosten pro Million Dollar-Token ermitteln.
00:36:34Das könnte sehr, sehr viel geringer sein.
00:36:37Man muss also solche Berechnungen durchführen, indem man diese Dimensionen festlegt, und die GPU so wählen, dass die Inferenzkosten gesenkt werden.
00:36:49Das ist zumindest der erste Schritt zur Optimierung der Inferenz.
00:36:56Okay.
00:37:01Also, kommen wir zur nächsten Folie.
00:37:04Lassen Sie mich...
00:37:08Okay, großartig.
00:37:10Als Nächstes geht es nun um die Modelloptimierung.
00:37:15Wir haben also im Grunde die Grundlage geschaffen und einige Schwachstellen sowie deren Ursachen verstanden.
00:37:23Wie wir das Problem mit der GPU-Kapazität angehen könnten.
00:37:29Wir müssen verstehen, was wir weiter dagegen tun können.
00:37:33Es geht also um Modelloptimierung, und ich möchte Tanmay bitten.
00:37:39Er kann mehr über diese Modelloptimierungen erzählen, da er während seiner Forschungszeit daran gearbeitet hat.
00:37:47Okay.
00:37:48Okay.
00:37:49Ich kann übernehmen.
00:37:50Ich kann übernehmen.
00:37:54Ja.
00:37:55Hier.
00:37:56Okay.
00:37:57Hallo zusammen.
00:37:58Mikrofontest.
00:37:59Bin ich endlich zu hören?
00:38:00Ja.
00:38:01Okay.
00:38:02Also, hallo.
00:38:03Ich bin Tanmay Shah.
00:38:04Ich arbeite als Senior Quant Modeler und bin auch KI-Forscher.
00:38:08Mein Schwerpunkt liegt auf Agentenverifikation und derzeit dem Aufbau von Weltmodellen.
00:38:13Zu diesem Thema: Modelloptimierung.
00:38:16Bevor wir mit der Modelloptimierung beginnen, habe ich eine Forschungsvorlage erstellt, damit wir diese komplexen Dinge leichter verstehen können.
00:38:25Unsere Vorlage ist einfach.
00:38:28Erstens identifizieren wir das Problem.
00:38:30Zweiter Schritt: Wir lösen das Problem mit zwei Algorithmen.
00:38:34Das sind nur erfundene Algorithmen.
00:38:35Der erste Algorithmus heißt Strauß-Algorithmus.
00:38:39Wann immer wir ein Problem sehen – genau wie ein Strauß –, stecken wir den Kopf in den Sand.
00:38:46Genau das Gleiche werden wir tun.
00:38:47Wann immer wir auf ein Problem stoßen, ignorieren wir es einfach.
00:38:51Das ist also ein wichtiger Algorithmus, den wir befolgen sollten.
00:38:55Der zweite wurde entwickelt und heißt Weltcup-Algorithmus.
00:38:59Zum Beispiel wissen wir nicht, wer diese FIFA-Weltmeisterschaft gewinnen wird.
00:39:03Also haben die Veranstalter die 48 Teams in 12 Gruppen aufgeteilt.
00:39:11Dann die Runde der letzten 32 – die läuft derzeit.
00:39:16Dann Achtelfinale, Viertelfinale, Halbfinale und Finale.
00:39:21Sie machen also folgendes: Sie brechen es in kleinere Probleme herunter und die nützlichen Ergebnisse kommen weiter.
00:39:30Dasselbe Prinzip oder denselben Algorithmus werden wir verwenden, um diese Modelloptimierung und all diese Dinge zu verstehen.
00:39:38Also gut, fangen wir an.
00:39:41Ich habe also eine H100 GPU.
00:39:46Ich muss dieses Open-Source-Modell verwenden, das sich GPT OSS 120 Billion Parameter Model nennt.
00:39:54Im Moment ist es so, dass sie es mit BF float 16 trainiert haben und das Gewicht bei 240 Gigabyte liegt.
00:40:02Was soll ich tun?
00:40:04Das ist das Problem, vor dem wir stehen.
00:40:07Das Erste, was wir tun müssen, sind diese 240 Gigabyte und die 80 GB H100.
00:40:16Und ich muss es auf nur eine GPU passen, nicht auf mehrere GPUs.
00:40:21Was können wir also tun?
00:40:22Ich denke, der einfache Schritt ist: Einfach komprimieren.
00:40:27Aber wie sollen wir es komprimieren?
00:40:29Das ist eine weitere Herausforderung.
00:40:30Wenn wir BF float 16 auf FP8 komprimieren, sind es ungefähr 120 Gigabyte.
00:40:38Aber unsere H100 GPU hat nach wie vor 80 Gigabyte.
00:40:42Ich glaube, sie haben es dann weiter auf MXFP4 komprimiert.
00:40:49Und ich denke, die Größe liegt bei etwa 65 Gigabyte.
00:40:53Das ist also etwas, das wir tun können – komprimieren –, aber es bleibt die Frage.
00:40:59Wir wenden dabei auch den Strauß-Algorithmus an.
00:41:03Wir gehen davon aus, dass es keinen Qualitätsverlust gibt, wenn man ein größeres Modell auf eine kleinere Größe komprimiert.
00:41:10Das Zweite dabei ist, okay, ja.
00:41:16Auf dieser Folie haben wir Mistral 7B verwendet.
00:41:20Also sieben Milliarden Parameter.
00:41:22Es ist also ein kleines Modell, sieben Milliarden Parameter.
00:41:25Wenn man das mit zwei Bytes multipliziert, liegt das Gewicht bei etwa 14.
00:41:3114,5 Gigabyte, was problemlos auf eine H100 oder sogar A40 passt.
00:41:38Als Nächstes können wir anstelle der Gleitkomma-16-Komprimierung von Mistral 7B verschiedene Techniken wie int8, int4 oder nf4 anwenden.
00:41:53Im Grunde müssen wir nur den Strauß-Algorithmus anwenden und einfach glauben, dass es sozusagen keinen Qualitätsverlust gibt.
00:42:01Irgenwie müssen wir das aber auch mathematisch nachweisen, indem wir Tests auf externen Benchmarks durchführen, um zu sehen, ob es funktioniert oder nicht.
00:42:10Das fällt in den Bereich der Post-Training-Quantisierung.
00:42:16Man kann das Ganze auch während des Fine-Tunings machen.
00:42:20Man kann auch diese Art von Quantisierung durchführen.
00:42:22Das fällt in den Bereich des Quantization-Aware Training.
00:42:25Kommen wir nun zu unserem nächsten Problem.
00:42:31Wir haben diese riesigen Matrizen.
00:42:37Stellen Sie sich einfach eine 1000-mal-1000-Dimension vor, Matrix A, und eine weitere Matrix mit 1000 mal 1000.
00:42:51Wenn man diese beiden Matrizen multipliziert, beträgt die Anzahl der Operationen 1000 hoch 3.
00:43:00Und das ist rechentechnisch ein ziemliches Problem.
00:43:06Wir möchten also, dass unsere Matrizenmultiplikation schnell ist und Speicher spart.
00:43:13Was sollten wir also tun?
00:43:15Wir haben eine riesige Matrix.
00:43:17Okay, nehmen wir diese hier: 4096 mal 4096.
00:43:23Was sollten wir tun, um unser Problem der Beschleunigung und Speicherersparnis bei 4096 mal 4096 zu lösen?
00:43:33Als Erstes nutzen wir einfach unseren Weltcup-Algorithmus.
00:43:37Wir können eine zufällige Zahl bestimmen und den Block einfach vertikal aufteilen.
00:43:42Es spielt keine Rolle, was Sie dafür wählen.
00:43:45Nehmen wir also an, wir haben 4096 Spalten.
00:43:51Wir unterteilen sie in Gruppen von jeweils 128 Spalten.
00:43:57Also 128, 128, 128, 128, 128 vertikal.
00:44:03Wir erhalten dann diese 32 Blöcke, wenn wir die 4096 aufteilen.
00:44:09Was passiert dann, wenn wir das tun?
00:44:13Wenn wir das einfach vertikal aufteilen, können wir mehrere GPUs verwenden, um den Prozess zu beschleunigen.
00:44:21Diese Art von Ansatz nennt sich Multi-Head Attention.
00:44:26Was können wir sonst noch tun?
00:44:29Wir haben eine große Matrix – wie ich bereits erwähnte, der Strauß-Algorithmus.
00:44:36Unser Hauptproblem ist die Größe.
00:44:39Was wir also tun können, ist, anstatt all dieser 31 vertikalen Blöcke einfach 31 Blöcke wegzulassen.
00:44:49Und wir nehmen an, dass ein einzelner Block völlig ausreicht, damit alle Abfragen verarbeitet werden können.
00:44:57Unser Verlust ist dabei nahezu vernachlässigbar.
00:45:00Und wir entwickeln diesen Algorithmus.
00:45:04Dieser Algorithmus wird als Multi-Query Attention bezeichnet.
00:45:08Wie wir sehen können, befinden wir uns jetzt an zwei Extremen.
00:45:12Das eine ist Multi-Head Attention, bei dem wir in 32 Blöcke aufteilen und verschiedene GPUs nutzen oder parallele Verarbeitung betreiben.
00:45:22Und gleichzeitig lassen wir einfach 31 Blöcke weg.
00:45:26Und das nennen wir Multi-Query Attention.
00:45:31An diesen beiden Extremen sollten wir also einen Mittelweg finden.
00:45:38Man könnte sagen: Anstatt alle 31 wegzulassen, fassen wir vielleicht einige der Blöcke zusammen.
00:45:49Und wir können annehmen, dass ähnliche Blöcke auf ähnliche Arten von Abfragen achten.
00:45:58Diese Art von Technik fällt unter Grouped Query Attention, die derzeit sehr beliebt ist.
00:46:04Sogar bei Mistral oder anderen Modellen funktioniert diese Grouped Query Attention.
00:46:11Wir haben also nun verstanden, dass wir eine große Matrix haben.
00:46:16Wir können sie beliebig aufteilen und durch mathematische Berechnungen...
00:46:19nachweisen, dass der Verlust sozusagen fast vernachlässigbar ist.
00:46:23Was können wir sonst noch tun?
00:46:25Danach, nach dieser Grouped Query Attention...
00:46:34sehen Sie, wir haben eine große Matrix.
00:46:38Eines davon ist Key und das andere Value.
00:46:42Lassen Sie uns diese Matrix in einen latenten Vektor komprimieren.
00:46:47Und dann einen Algorithmus entwickeln, um aus dem latenten Vektor unsere ursprüngliche Matrix zu rekonstruieren.
00:46:55Diese Art von Strategie gehört hierher.
00:46:59Multi-Head Latent Attention.
00:47:02Aber auch hier gibt es Probleme mit RoPE, da RoPE positionsabhängig ist und das andere positionsunabhängig.
00:47:10Man muss also auch für Keys einen Index einbeziehen, damit man sie zuordnen kann.
00:47:16Aber das Hauptproblem bleibt: Warum multiplizieren wir all diese großen Matrizen?
00:47:25Weil der Aufmerksamkeitsmechanismus nun mal so funktioniert, dass jedes Token jedem Token Aufmerksamkeit schenkt.
00:47:33Wie wäre es also, wenn wir nicht allen vorherigen Token Aufmerksamkeit schenken, sondern nur den für uns wichtigen Token?
00:47:42Dieser Bereich entwickelt sich also ständig weiter.
00:47:46Das fällt also unter Sparse Attention, DeepSeek Sparse Attention.
00:47:51Also ja.
00:47:53Und ja, also, gut.
00:47:56Weiter.
00:47:59Ja, das Nächste ist Flash Attention.
00:48:02Das Hauptproblem bei Flash Attention ist also folgendes:
00:48:09Derzeit – also im Moment, oder sagen wir, aktuell verwendet fast jeder Flash Attention, aber im Jahr 2022 oder 2023 war das noch anders.
00:48:20Und so funktioniert das Ganze.
00:48:23Die Funktionsweise ist so, dass diese Q- und K-Matrizen (Query und Key) sich im HBM befanden.
00:48:34Sie werden zuerst in unseren Tensor Core geladen, es werden einige Berechnungen durchgeführt und danach werden sie wieder in den HBM zurückgeschrieben.
00:48:47Und dieser Prozess wiederholt sich mehrmals.
00:48:51Bei Flash Attention hat man nun Folgendes gemacht: Anstatt die gesamten Matrizen zu multiplizieren,
00:48:59wurden sie einfach aufgeteilt – ähnlich wie bei unserem World-Cup-Algorithmus –, sodass die größeren Matrizen in kleine Kacheln unterteilt werden,
00:49:05und nur diese kleinen Kacheln in den SBM geladen, damit die Multiplikation schnell verarbeitet werden kann,
00:49:13wobei einige wenige Variablen im Blick behalten werden, um dieses Online-Softmax zu berechnen.
00:49:20Also ja, das ist reine Mathematik: Wenn wir eine Multi-Head Attention haben und es sich um 524 KV handelt,
00:49:34dann hängt es davon ab, wie viel Gruppierung wir wollen. Wenn wir also anstelle von 32 KV-Heads nur 8 KV-Heads verwenden möchten,
00:49:47dann können wir eine vierfache Komprimierung erreichen, und das ist die Multi-head Latent Attention.
00:49:54Diese Formel hängt von Modell zu Modell davon ab, wie viele Schichten Ihr Modell besitzt.
00:50:00Im originalen DeepSeek-Paper haben sie glaube ich eine Dimension von 128 verwendet, ich erinnere mich nicht an die genaue Dimension, aber entsprechend
00:50:11haben sie diesen einen latenten Vektor genutzt, bei dem sie 512 als Dimension und etwa 64 für den RoPE-Index verwendet haben,
00:50:23und dann gezeigt, dass er 56-mal stärker komprimiert ist als die Multi-Head Attention.
00:50:32Okay.
00:50:33Ja, das ist also das Kompromiss-Diagramm. Hier haben wir glaube ich noch nicht über lineare Attention oder Mamba gesprochen.
00:50:50Das Hauptproblem sind all diese Matrixmultiplikationen; im Moment verwendet jeder Attention.
00:50:56Angenommen, wir möchten in Zukunft keine Attention mehr verwenden und stattdessen Tokens nicht sequenziell generieren, sondern vielleicht Diffusionsmodelle nutzen,
00:51:07bei denen wir alles gleichzeitig erzeugen können – dann werden sich auch all diese Algorithmen ändern.
00:51:14Aber hier gibt es glaube ich noch zwei weitere: einmal lineare Attention und einmal Mamba.
00:51:19Gemäß dieser Folie: Wenn wir nichts komprimieren, dann bedeutet MHA einfach, dass wir den Prozess parallelisieren.
00:51:29Es gibt also keinen Qualitätsverlust, was gut ist. Und dann haben wir Grouped Query Attention, das mittlerweile von fast jedem Modell in Form von GQA und DSA genutzt wird.
00:51:42Ja.
00:51:43Ich denke, dasselbe bieten wir auch in der Scorecard für den Attention-Mechanismus an: Die Qualität von MHA ist gut, der Durchsatz ist in Ordnung.
00:51:56Und bei Grouped Query Attention hängt es auch von Ihrem Anwendungsfall ab; zwar ist die Qualität fast ähnlich wie bei Multi-Head Attention, aber der Anwendungsfall spielt ebenfalls eine große Rolle.
00:52:10Ja, Multi-Query Attention ist einfach ein Extrem.
00:52:13Wir gehen – ich weiß nicht warum – einfach davon aus, dass wir nur einen Block benötigen und alle Queries sich auf diese kleineren Blöcke beziehen.
00:52:24Daher ist die Qualität bei MQA nicht ganz so großartig.
00:52:29Und was diese Multi-head Latent Attention angeht: Ja, wenn Sie einige dieser DeepSeek-Modelle ausprobiert haben, machen sie abgesehen davon einen großartigen Job bezüglich der Qualität, genau wie Sliding Window.
00:52:44All dies sind also einige Techniken, wie das Anpassen von Fenstern und Ähnlichem. Und anstatt alles zu multiplizieren, besagt die lineare Attention im Grunde: Fasse erst alles zusammen und schlage dann darin nach. Und Mamba ist einfach ein State-Space-Modell, ja.
00:53:09Für Modelloptimierungen haben wir hier außerdem zwei Notebooks.
00:53:28Da muss ich also hingehen.
00:53:35Gut, was die Quantisierung angeht, etwa als Demo: Ist das hier schon gelaufen? Nein.
00:53:51Ich lasse das mal eben laufen.
00:53:54Wir laden also das Modell, was in etwa Mistral 7B entspricht.
00:54:10Das hier ist also mit der FP16-Baseline.
00:54:20Moment.
00:54:21Ist es gelaufen?
00:54:21Moment.
00:54:22Ist es gelaufen?
00:54:23Okay.
00:54:24Es ist also, äh, zwei Millisekunden lief es.
00:54:27Ist das gelaufen?
00:54:28Okay.
00:54:29Ja, diesmal wird das Modell mit FP16-Präzision abgerufen.
00:54:35Okay.
00:54:36Es ist also, äh, zwei Millisekunden lief es.
00:54:40Ist das gelaufen?
00:54:41Okay.
00:54:42Ja, diesmal wird das Modell mit FP16-Präzision abgerufen.
00:54:47Das WLAN.
00:54:58Das wird Zeit in Anspruch nehmen.
00:55:03Okay.
00:55:08Ja, weil es die Gewichte von Hugging Face herunterlädt.
00:55:14Hä?
00:55:17Ja, Colab läuft also quasi online.
00:55:22Ja.
00:55:23Weil es einen Netzwerkaufruf über Hugging Face machen und Daten abrufen muss.
00:55:30Ich weiß nicht, aber es dauert wahrscheinlich etwas herunterzuladen.
00:55:35Okay.
00:55:36Okay.
00:55:37Okay.
00:55:38Okay.
00:55:39Okay.
00:55:40Hier sehen wir also, dass die Speichergröße bei FP16-Präzision etwa 15 GB beträgt.
00:56:00Wir versuchen die zweifache Komprimierung durchzuführen, wie Talmud angesprochen hat, und zwar mit int8.
00:56:15Okay.
00:56:16Wir sehen also, dass Ihre Speichergröße jetzt bei etwa 0,7 bis 0,5 GB liegt.
00:56:21Das bedeutet, dass Sie jetzt mehr Speicher für das Wachstum Ihres KV-Caches zur Verfügung haben.
00:56:27Das heißt, Sie können entweder ein höheres Kontextlimit bedienen oder mehr gleichzeitige Benutzer unterstützen.
00:56:36Wenn man also int4 verwendet, führt man im Grunde eine vierfache Komprimierung durch.
00:56:41Mit dieser vierfachen Komprimierung wäre es also noch geringer.
00:56:45Es dürfte schätzungsweise bei etwa 3 bis 4 GB liegen.
00:56:50Ja, 4,5 GB.
00:56:51Und ja.
00:56:52Das ist also, Moment.
00:56:53Das ist also nur ein einfaches Diagramm von – das sind sozusagen die theoretischen Zahlen.
00:57:09Wir führen hier keinerlei Durchsatztests durch.
00:57:12Aber normalerweise würden Sie sehen, dass Ihr Speicher ansteigt.
00:57:15Dadurch hätten Sie auch einen etwas höheren Durchsatz.
00:57:21Einige der von uns untersuchten Benchmarks zeigten, dass die int8-Komprimierung
00:57:26tatsächlich einen geringeren Durchsatz aufweist.
00:57:32Okay.
00:57:33Und dann gibt es noch eine Demo zu den Attention-Mechanismen.
00:57:42Also bezüglich Attention, gut.
00:57:45Das muss ich ausführen.
00:57:58Okay.
00:57:59Es wurde also ausgeführt.
00:58:02Oh.
00:58:03Moment.
00:58:04Warum steht da, dass keine GPU erkannt wurde?
00:58:09Da sollte stehen, dass die GPU erkannt wurde.
00:58:18Oh.
00:58:19Okay.
00:58:29Moment.
00:58:30Moment.
00:58:30Moment.
00:58:50Das ist überraschend.
00:58:57Vermutlich kann die GPU aus irgendeinem Grund nicht erkannt werden.
00:59:05Wir haben hier doch eine GPU.
00:59:11Okay.
00:59:12Egal.
00:59:14Ja.
00:59:14Aber die grundlegende Idee hierbei war eher, dass wenn man versucht, die Berechnung zu komprimieren – etwa durch die Verwendung verschiedener Attention-Mechanismen
00:59:26wie den Wechsel von Multi-Head zu Grouped Query Attention und dann zu MLA –, man
00:59:33beginnt, einige Optimierungen zu sehen.
00:59:38Gestern Abend haben wir glaube ich einige Benchmarks durchgeführt.
00:59:43Ich wollte diesen Teil korrigieren.
00:59:45Es waren also nicht 56-mal.
00:59:48Es waren 14-mal.
00:59:50Im Grunde gab es in der Demo einen Berechnungsfehler, bei dem die Anzahl der Schichten nicht multipliziert wurde.
01:00:02Ja.
01:00:03Entschuldigung also dafür.
01:00:04Diese MLA bringt also im Vergleich zu Ihrer Multi-Head Attention Einsparungen um das 14-Fache.
01:00:15Nun, da wir die Schwachstellen, die Grundlagen und die eine Seite der Optimierungen verstanden haben – nämlich die Modelloptimierungen –, möchten wir darüber sprechen, was Sie auf der Serverseite tun können.
01:00:31Das Erste ist, wie wir gesehen haben: Wenn man einen einfachen Dekodierungsschritt ausführt, zieht man die Modellgewichte heran und berechnet im Grunde die Key- und Value-Vektoren für alle vorherigen Tokens neu,
01:00:50obwohl Sie diese Vektoren für alle Tokens bereits berechnet hatten.
01:00:55Es gibt hier also definitiv eine Menge Rechenverschwendung.
01:01:02Und wenn man die zeitliche Komplexität analysiert, beläuft sie sich auf O von N Quadrat.
01:01:07Der Weg zur Lösung dieses Problems ist ein klassischer Kompromiss in Bezug auf den Speicher.
01:01:12Man kann einen Speicher für diese Vektoren im Verhältnis zu den Tokens vorhalten und auf diesen Speicher verweisen.
01:01:19Dieser Speicher wurde als KV-Cache bezeichnet.
01:01:24Und der Ablauf sieht ungefähr so aus.
01:01:27Und basierend auf diesem KV-Cache gab es im Grunde vier Optimierungen, die wirklich möglich waren.
01:01:35Die erste betrifft Paged Attention.
01:01:42Was ist also der Unterschied, was ist heutzutage das Problem?
01:01:45Wenn man also mehrere Anfragen als Eingabe an die GPU sendet, befinden sich diese Anfragen in einem Batch.
01:01:52Jeder Anfrage wird sozusagen ein zusammenhängender Speicherplatz zugewiesen.
01:01:58Nehmen wir an, ich nehme einfach ein Beispiel, sagen wir, 2 KV.
01:02:05Deine Anfrage benötigte jedoch schätzungsweise nur 1 KV.
01:02:11Es kommt also zu einer Speicherfragmentierung von etwa 50 %.
01:02:19Und diese Fragmentierung führt im Grunde zu Speicherverschwendung.
01:02:24Das bedeutet, es gab im Speicher Platz, mit dem du mehr Anfragen hättest bedienen können, was aber nicht ging, weil du nach diesem zusammenhängenden Speicherblock gesucht hast.
01:02:36Man hat sich also von der Funktionsweise von Betriebssystemen inspirieren lassen.
01:02:41Man verwaltet einen logischen Speicher und hat im Grunde einen physischen Speicher.
01:02:47Im logischen Speicher fühlt es sich also weiterhin so an, als sei der KV-Vektor für jeden Token zusammenhängend.
01:02:59Aber er wird auf eine andere physische Adresse abgebildet.
01:03:06Das hat also wirklich dabei geholfen, eine Menge Speicher zu sparen.
01:03:11Und das war nur möglich, weil man den Speicher als eine Menge von Blöcken betrachtet hat.
01:03:18Und diese Blöcke werden dynamisch zugewiesen, je nachdem, was die Anfragen benötigen.
01:03:22Je nachdem, wie neue Token hinzukommen und diese Art von Speicher brauchen.
01:03:27Ein weiterer Hebel ist, wenn man mehrere Anfragen in einem Batch sendet,
01:03:39nimmt die GPU diese Anfragen entgegen.
01:03:42Sie akzeptiert jedoch keinen neuen Batch, bevor nicht alle Anfragen in diesem Batch abgeschlossen sind.
01:03:49Das Diagramm sieht also eher wie ein Paged Attention aus.
01:03:52Aber hier geht es eher darum, wann die GPU verfügbar ist, um den nächsten Batch anzunehmen.
01:03:59Es gibt also eine Zeitspanne, in der die GPU wirklich im Leerlauf ist.
01:04:04Und das möchte man irgendwie lösen.
01:04:08Und die Idee dazu war: Okay, machen wir kontinuierliches Batching.
01:04:17Das kontinuierliche Batching half also auch sehr beim Durchsatz, weil man nun mehr Anfragen ziemlich schnell verschicken kann.
01:04:24Man stellt sicher, dass die GPU immer ausgelastet ist und nicht im Leerlauf herumsteht.
01:04:33Man spart also bei dieser Rechenleistung.
01:04:36Das dritte ist die Präfix-Zwischenspeicherung.
01:04:39Ihr erinnert euch also, dass der KV-Cache geholfen hat, die Berechnung für eine einzelne Anfrage über die Token hinweg zu sparen.
01:04:46Aber was ist, wenn man dieselben Token über mehrere Anfragen hinweg hat?
01:04:53Wie spart man im Grunde dagegen an?
01:04:55Die Präfix-Zwischenspeicherung, die von VLLM eingeführt wurde, wirkt genau dem entgegen.
01:05:04Und dann ist da das dritte – oder wir haben über das vierte gesprochen.
01:05:10Wir haben also über die Quantisierung des Modells gesprochen, aber man kann auch die KV-Gewichte quantisieren.
01:05:21Das bedeutet, dass man jetzt weniger Speicherplatz für die Key- und Value-Vektoren benötigt.
01:05:28Das heißt, man kann mehr Key- und Value-Vektoren im Speicher halten.
01:05:32Und das bedeutet, man kann mehr Token verarbeiten.
01:05:34Das bedeutet, man kann ein größeres Kontextlimit bedienen.
01:05:37Und das bedeutet, man kann eine höhere Modellqualität anbieten.
01:05:41Und all das ist bereits in VLLM vorhanden.
01:05:51Man muss das Rad wirklich nicht neu erfinden.
01:05:56Und man kann VLLM in der Produktion einsetzen und im Grunde dieses Wachstum sehen.
01:06:03Als Nächstes haben wir also einen Benchmark, den wir durchgeführt haben.
01:06:08Dieser Benchmark war – mal sehen, ob ich das habe.
01:06:14Hier.
01:06:17Die Demos.
01:06:22Die Durchführung dieses Benchmarks dauert etwa eine Stunde, weil man die VLLM-Server kontinuierlich stoppen und neu starten muss und die Modelle laden muss und so weiter.
01:06:35Es nimmt also viel Zeit in Anspruch, die Tests durchzuführen, aber ich kann euch hier wirklich erzählen, was wir machen.
01:06:41Wir haben das Modell also unverändert gelassen, wie die Mistral 7B.
01:06:46Und dann haben wir eine Reihe von Eingabefragen, die wir absenden.
01:06:53Betrachte sie als die Prompts.
01:06:56Dann haben wir hier ein paar Hilfsfunktionen, wie zum Beispiel die Überprüfung, ob der Server läuft oder nicht.
01:07:01Dieser Server ist der VLLM-Server.
01:07:04Dann gibt es Hilfsfunktionen, um die VLLM-Metriken abzurufen.
01:07:09Und ich werde darüber sprechen, was diese Metriken sind.
01:07:14Dann gibt es eine Menge Benchmarks und so weiter.
01:07:17Und dann muss man die KV-Auslastung messen und all das.
01:07:22Das sind also diese Hilfsfunktionen.
01:07:24Die Baseline ist also sehr einfach.
01:07:26Wir haben eine Hugging-Face-Baseline.
01:07:29Das ist das pure Senden des Textes an das LLM und das Zurückbekommen der Antwort.
01:07:36Wir sehen hier einige Ergebnisse.
01:07:38Wir sahen, dass Hugging Face einen Durchsatz von etwa 51 Token pro Sekunde hat.
01:07:44Die Zeit bis zum ersten Token lag bei etwa 54.
01:07:46Und die Latenz zwischen den Token betrug 19.
01:07:49Das lief alles auf der H100.
01:07:56Und dann starten wir einen ganz standardmäßigen VLLM-Server.
01:08:00Standardmäßig bietet VLLM also Paged Attention, kontinuierliches Batching und KV-Caching.
01:08:08Drei Dinge sind also standardmäßig vorhanden.
01:08:13Und wenn man versucht, diese Benchmarks zu vergleichen, sieht man, dass der Durchsatz fast das 15-fache beträgt.
01:08:21Man ist in der Lage, mehr Token pro Sekunde zu verarbeiten.
01:08:24Dann steigt auch die Zeit bis zum ersten Token.
01:08:34Und die Latenz zwischen den Token sinkt gewissermaßen.
01:08:38Und die KV-Nutzung im Vergleich zu den Nutzern und zum Kontext nimmt definitiv zu.
01:08:43Wenn man nun die Präfix-Zwischenspeicherung darauf anwendet.
01:08:51Mit der Präfix-Zwischenspeicherung sieht man also, dass der Durchsatz noch weiter steigt.
01:08:57Die TTFT sinkt.
01:08:59Die Latenz zwischen den Token bleibt ungefähr gleich.
01:09:02Und die KV-Cache-Nutzung im Vergleich zu den Nutzern geht ein wenig zurück.
01:09:09Im Vergleich zum Kontext geht sie nicht zurück.
01:09:12Sie ist ungefähr gleich.
01:09:14Ich denke, das ist auch ungefähr gleich.
01:09:16Das ist sozusagen keine so große Sache.
01:09:19Wenn man nun noch die KV-Quantisierung obendrauf anwendet.
01:09:25Dann sieht man also, dass der Durchsatz fast ähnlich ist.
01:09:33Die Zeit bis zum ersten Token ist ähnlich.
01:09:36Die Token-Latenz ist ähnlich.
01:09:39Aber die KV-Nutzung geht tatsächlich zurück.
01:09:42Das liegt daran, dass man den Key-Value-Speicher quantisiert hat.
01:09:49Und dann gibt es ein Konzept des spekulativen Decodierens, über das Tanmay sprechen wird.
01:09:54Wenn man diese also banstmarkt, sieht man auch, dass dort ein bisschen weniger KV-Nutzung stattfindet.
01:10:06Obwohl die Ergebnisse ungefähr gleich sind.
01:10:08Also ja, ich meine, insgesamt sind dies die Metriken im Vergleich.
01:10:21Wahrscheinlich sollte ich herauszoomen.
01:10:25Okay.
01:10:26Es geht nicht.
01:10:27Herauszoomen.
01:10:28Es funktioniert nicht.
01:10:29Großartig.
01:10:30Also ja, das sind die VLLM-Benchmarks.
01:10:35Das ist übrigens eure Standardeinstellung für die Produktion.
01:10:38Wir werden diesen Entscheidungsbaum auch teilen, wenn wir über die anderen Engines sprechen.
01:10:48Also gut, wir sollten darüber sprechen, welche anderen Inferenzoptimierungen wir zusätzlich vornehmen können.
01:10:58Und was für andere Lösungen noch hervorgegangen sind.
01:11:02Daher möchte ich erneut Tanmay einladen.
01:11:07Er wird über einige dieser Optimierungen sprechen.
01:11:11Oh, Entschuldigung.
01:11:12Es tut mir so leid.
01:11:13Ich habe die Folien nicht eingeblendet.
01:11:26Was war das?
01:11:27Okay.
01:11:28Großartig.
01:11:29Perfekt.
01:11:30Welche davon?
01:11:31Das spekulative Decodieren.
01:11:32Ja.
01:11:33Danke, Harshal.
01:11:34Ja.
01:11:35Das ist also alles spekulatives Decodieren.
01:11:40Das sind alles verschiedene Geschmacksrichtungen derselben Limonade, sozusagen.
01:11:46Diese Technik gehört also zu den Decodierungsbeschleunigern.
01:11:51Das erste – wir sprechen nur über dieses spekulative Decodieren, aber es gibt noch andere Varianten wie Self-Speculative, Eagle, Medusa.
01:12:01Ich mag glaube ich nur diese hier, den Eagle-Algorithmus.
01:12:05Fangen wir also mit dem spekulativen Decodieren an.
01:12:06Okay.
01:12:07Okay.
01:12:08Beginnen wir also damit, was spekulatives Decodieren ist.
01:12:09Das Hauptproblem ist, dass in der Transformer-Architektur all diese Token nacheinander, einzeln, eines nach dem anderen generiert werden.
01:12:26Wie wäre es, einfach ein kleineres Modell zu verwenden und dieses vielleicht vier oder fünf Token generieren zu lassen?
01:12:37Und dieses Lehrermodell, oder sagen wir, gemäß unserem WM-Algorithmus, können wir Schiedsrichter nennen.
01:12:43Der Schiedsrichter entscheidet also, wie viele Token er akzeptiert.
01:12:48Und diese Schleife läuft immer weiter.
01:12:51Und unsere Annahme ist, dass es bestimmte Bereiche gibt, in denen diese Art von Vorgehen funktioniert.
01:12:59Wie vielleicht beim Programmieren, wo es fast keine Kreativität gibt.
01:13:05Jeder Code und jede Syntax ist fast ähnlich.
01:13:08Vielleicht kann es also dabei helfen.
01:13:10Aber basierend auf meinen persönlichen Tests fand ich dieses spekulative Decoding überhaupt nicht nützlich.
01:13:18Aber andere Techniken wie Self-Speculative Decoding, bei denen das Lehrmodell ebenfalls einen Kopf hat, einen Hilfskopf, und ähnliche Dinge tut, wie das Basismodell oder kleine Modell es tut.
01:13:35Aber dann kam EGLE, EGLE 1, 2, 3, ich weiß nicht, wie viele Versionen es gibt, aber es besagt einfach, dass wir, anstatt Tokens zu generieren, ein kleines Modell trainieren und unsere Features von einer der Schichten des Hauptmodells nehmen, sodass es anstelle von Tokens dieses Feature generiert.
01:14:02Daher ist EGLE im Vergleich zu diesen anderen Technologiearten besser.
01:14:10Und eine andere ist MEDUSA, die einfach besagt: Generiere einfach all diese Tokens parallel.
01:14:17Okay, also hier, also hier auf dieser Folie.
01:14:21Ja.
01:14:22Die nächste Folie.
01:14:24Okay.
01:14:25Okay.
01:14:26Okay, ja.
01:14:27Okay.
01:14:28Jetzt kommen wir zu, jetzt kommen wir zu diesem hier: Prefix Caching.
01:14:34Ich weiß also nicht, ob die Leute dieses statische Prefix Caching verwenden oder nicht.
01:14:39Aber die Sache ist die: Das Hauptproblem beim Prefix Caching ist, dass wir manchmal tippen und einen kleinen Fehler machen.
01:14:47Und dieses standardmäßige statische Prefix Caching nimmt im Grunde einen Prompt und macht etwas Hashing.
01:14:53Und wenn der Benutzer das nächste Mal eine ähnliche Frage stellt, versucht es, den Hash abzugleichen.
01:14:58Wenn also der Hash gleich ist, dann nimmt es das Ganze einfach aus dem Speicher, anstatt all diese K und V neu zu berechnen.
01:15:09Aber Sie wissen, dass wir manchmal einen Fehler machen oder vielleicht ein Wort oder einen Buchstaben ändern oder so etwas.
01:15:15Dann haben wir eine viel höhere Cache-Miss-Rate.
01:15:21Deshalb gibt es diesen hier: Radix Tree.
01:15:25Der Radix Tree wird also sehr beliebt, auch wegen Agents.
01:15:30Ich denke also, fast jeder macht Agents und die meiste Berechnung findet während der Testzeit statt, also beim Inferenzieren.
01:15:38Wo wir immer wieder dieselben Arten von Fragen und Prompts stellen.
01:15:42Zum Beispiel: Du bist ein erfahrener Softwareentwickler, multipliziert mit 200 Mal.
01:15:48Diese Art von Schleife läuft ständig in diesen agentenbasierten Dingen ab.
01:15:55Wo es notwendig ist, ähnliche Dinge in einem Radix Tree zu behalten oder zu speichern.
01:16:03Ein Radix Tree ist also nur eine fortgeschrittene Version dieses Präfixbaums, bei dem wir einen Knoten einfach zusammenführen, wenn er keinen Zweig hat.
01:16:17Und für diese Art von Arbeit, bei der wir ständig dasselbe wiederholen.
01:16:24Hilft dieser Radix Tree sehr und sglang verwendet diese Art von Algorithmus für das Prefix Caching.
01:16:35Okay, ja, dann gibt es noch etwas.
01:16:38Das eine ist Tensor RT LLM.
01:16:41Das ist sehr verwirrend.
01:16:42Als ich anfangs anfing, war ich einfach verwirrt.
01:16:46Was ist Tensor RT LLM?
01:16:49Also, ja, Tensor RT ist einfach eine standardmäßige SDK-Art von Ding.
01:16:55Tensor RT LLM ist einfach eine Inferenz-Engine.
01:16:59Genau wie vLLM, sglang.
01:17:01Aber das Problem ist, dass es mit NVIDIA zusammenhängt.
01:17:05Sie haben jede einzelne Schicht und jedes Problem optimiert.
01:17:10Wie ich in unserem Weltcup-Algorithmus erwähnt habe, brechen sie einfach alles auf und optimieren alles auch auf Hardware-Ebene.
01:17:18Also, ja, okay, weiter.
01:17:23Ja, für diesen Workshop haben wir auch ein Benchmarking durchgeführt, um zu sehen, was am besten ist.
01:17:33Unser Setup war also ähnlich.
01:17:36Wir haben also zwei Arten von Tests durchgeführt.
01:17:39Der erste ist ohne agentenbasierte Tests, bei denen wir einfach...
01:17:44Wir haben also den ShareGPT-Datensatz verwendet und diese Fragen einfach mit vLLM und sglang gestellt.
01:17:57Okay.
01:18:05Ja, okay.
01:18:07Und lassen Sie mich das heranzoomen.
01:18:12Okay, super.
01:18:13Okay, ja, für diesen Workshop haben wir H100 verwendet und unser erster Test war, dass wir einfach fragten...
01:18:23Wir nehmen Fragen von ShareGPT und geben sie in vLLM, sglang ein und wir stellten fest, dass es eigentlich keinen statistischen Unterschied gibt, welches besser ist.
01:18:34Beide haben also fast ein ähnliches...
01:18:37Beide erfüllen also ähnliche Anforderungen pro Sekunde, TTFT und Latenz.
01:18:43Der einzige Unterschied, den wir gesehen haben, trat beim agentenbasierten Branching auf.
01:18:50Was wir also taten, war, dass wir eine ähnliche Frage stellten: Du bist der beste Softwareentwickler der Welt.
01:18:59Löse also das Problem der Verkehrsüberlastung in der Stadt oder so etwas.
01:19:04Dann haben wir das in das LLM eingespeist.
01:19:08Das LLM generiert eine Ausgabe.
01:19:10Dann haben wir auch eine zweite Runde gemacht.
01:19:13Sobald dieses LLM diese Ausgabe generiert hat, haben wir in Runde zwei speziell erwähnt...
01:19:22Überprüfe den Vorschlag und gib Bewertungen von eins bis zehn ab.
01:19:28Das waren also zwei Durchläufe, die wir gemacht haben, und diese Schleife wiederholt sich ständig.
01:19:35Was wir herausgefunden haben, ist, dass für diese Art von Workflow, bei dem alles standardisiert ist, alle diese Prompts und Context Engineering ins Spiel kommen.
01:19:47Wenn wir also dieses agentenbasierte Branching richtig durchführen, dann ist SGLang schätzungsweise drei- bis viermal besser.
01:19:54Aber auch das hängt möglicherweise von den verschiedenen Setups ab.
01:19:58Wenn Sie das tun, erhalten Sie möglicherweise andere Ergebnisse.
01:20:02Okay.
01:20:03Ja.
01:20:04Ich denke also...
01:20:06Haben wir es auf GitHub hochgeladen?
01:20:08Ja.
01:20:09Okay.
01:20:10Ja.
01:20:11Das PDF ist also auch im Drive.
01:20:15Es ist derselbe Link wie zu den Folien.
01:20:18Hier also eine kurze Zusammenfassung.
01:20:22Bei einem Standard-API-Workload-Durchsatz würden Sie sehen, dass vLLM und SGLang gleich sind.
01:20:31Wenn Sie also kein...
01:20:33Wenn Sie einen Standard-Workload haben, nehmen Sie definitiv vLLM.
01:20:36Es ist ohnehin der Produktionsstandard.
01:20:38Aber was Tanmay auch sagte, ist: Wenn Sie versuchen, agentenbasierte Workloads zu erstellen, glänzt SGLang wirklich.
01:20:50Und es bietet Ihnen sozusagen all diese Vorteile.
01:20:55Also ja.
01:20:58Behalten Sie vLLM als Standard bei.
01:21:00Aber wenn Sie agentenbasierte Workloads haben, versuchen Sie wahrscheinlich zu SGLang zu wechseln.
01:21:05Wenn Sie mit dem vLLM-Teil nicht zufrieden sind.
01:21:09Okay.
01:21:10Lassen Sie mich...
01:21:15Warten Sie.
01:21:18Okay.
01:21:21Und dann gibt es noch das...
01:21:29Wie einen Vergleich, der bei 120 Milliarden durchgeführt wurde.
01:21:33Wie für das GPT OSS 120B.
01:21:36Dies ist ein Benchmark, der von PlayPy vorbereitet wurde.
01:21:42Es gibt hier also einen Blog-Link.
01:21:46Oh, nett.
01:21:48Okay.
01:21:49Ja.
01:21:50Sie haben also einen ähnlichen Benchmark durchgeführt und TensorRT LLM darin einbezogen.
01:21:57Sie können diese Benchmarks natürlich jederzeit durchgehen und versuchen zu verstehen, was im Grunde zu Ihrem Anwendungsfall passt.
01:22:05Wie wir erwähnt haben, versucht TensorRT auch die Hardwareseite zu optimieren und die maximale Hardwareleistung herauszuholen.
01:22:16Und was die Auswahl Ihrer Engines angeht, sobald Sie sich zwischen vLLM, SGLang und TensorRT entschieden haben, tauchen einige neue Engines auf.
01:22:29NVIDIA Dynamo auf jeden Fall.
01:22:43Sie sind auch für das agentenbasierte Session-Routing gedacht.
01:22:49Hugging Face ist immer da.
01:22:51Es ist ein einfacher Einstieg.
01:22:53Dann gibt es noch die MSTAR-Engine, die kürzlich von Stanford vorgeschlagen wurde.
01:23:00NVIDIA Dynamo für Multimodelle.
01:23:05Sie können diese also definitiv erkunden.
01:23:08Und wenn Sie versuchen, um eine kurze Zusammenfassung zu geben, wir beginnen mit einer Baseline.
01:23:15Wir versuchen herauszufinden, welches Modell zu unseren Anwendungsfällen passen könnte.
01:23:22Sie könnten also DeepSeek wählen.
01:23:27Sie könnten nicht Mistral 7B wählen.
01:23:30Ich meine, es ist nicht gut.
01:23:32Aber ja.
01:23:35Sie wählen also Ihr Modell und möchten weniger Speicher verwenden und versuchen, dieses größere Modell in einen kleineren Speicher einzupassen.
01:23:44Damit Sie bei den GPU-Kosten sparen können.
01:23:47Sie können also all diese Quantisierung durchführen.
01:23:51Dann können Sie all diese Serving-Optimierungen anwenden, indem Sie die richtige Serving-Engine im Hintergrund verwenden.
01:23:58Das kann Ihnen wirklich den Durchsatz liefern, den Sie sich wünschen.
01:24:07Und nun etwas, das Sie nach der Rückkehr nach Hause tun können, da wir hier nicht das gesamte Material durchgehen können: Lesen Sie sich unbedingt über einige Quellinformationen wie verschiedene Aufmerksamkeitsmechanismen und diese verschiedenen Engines ein.
01:24:27Versuchen Sie einfach, die verschiedenen Benchmarks zu lesen, die auch online verfügbar sind.
01:24:34Und dann gibt es viele eingehende Leitfäden oder die nächsten Phasen davon, wie das Erlernen einiger KV-Eviction-Strategien.
01:24:45Die Welt bewegt sich also in Richtung eines separaten Fachbereichs für KV-Cache-Engineering.
01:24:50Sie möchten also verstehen, was dort vor sich geht.
01:24:52KV-Eviction, Cache-Kompressionen, hybride Speicher.
01:24:57Es gibt also eine Menge Lösungen, die in diesem Bereich entstehen.
01:25:01Versuchen Sie also immer, sich an diese Grundlagen oder Ersten Prinzipien zu halten.
01:25:08Und versuchen Sie zu sehen, welche Lösung welches Problem im Grunde löst und ob Sie dieses Problem für Ihren Anwendungsfall überhaupt gelöst haben müssen.
01:25:17Und dann gibt es noch die verteilte LLM-Inferenz, was ein völlig anderer Schwerpunkt ist.
01:25:26Dazu bräuchten Sie wahrscheinlich auch einen zweistündigen Workshop, um alle Interna durchzugehen und die Praxisübungen zu machen.
01:25:40Ja, und das ist etwas, das wir für die AI Engineer Session in New York vorschlagen möchten: tiefer in die fortgeschrittenen Abschnitte der LLM-Inferenz einzutauchen.
01:25:51Dieser Workshop war also eher für Anfänger und Fortgeschrittene gedacht.
01:25:55In diesem Formular gibt es also Feedback und auch die Möglichkeit,
01:26:02ihr Interesse zu bekunden. Wenn Sie der Meinung sind, dass bestimmte Bereiche verbessert werden sollten,
01:26:09geben Sie uns dieses Feedback unbedingt. Und wenn Sie diesen Workshop auch in New York sehen möchten, tragen Sie sich gerne ein.
01:26:22Hä?
01:26:24Oh, wie ist das möglich?
01:26:27Bumm.
01:26:32Ich überprüfe das nur kurz.
01:26:37Okay.
01:26:38Hä?
01:26:39Ja.
01:26:40Die URL funktioniert, oder?
01:26:41Ja.
01:26:42Nicht der QR-Code?
01:26:43Okay.
01:26:44Vermutlich habe ich vergessen, die beiden zu verknüpfen.
01:26:45Okay.
01:26:46Gut.
01:26:46Ja.
01:26:47Also, wenn Sie das angeben können.
01:26:49Okay.
01:26:50Gut.
01:26:51Ja.
01:26:52Also, wenn Sie das angeben können.
01:26:53Okay.
01:26:54Ja.
01:26:55Okay.
01:26:56Gut.
01:26:57Ja.
01:26:58Also, wenn Sie das angeben können.
01:26:59Lassen Sie mich kurz...
01:27:00Okay.
01:27:00Okay.
01:27:01Gut.
01:27:02Ja.
01:27:02Also, wenn Sie das angeben können.
01:27:03Lassen Sie mich kurz...
01:27:04Okay.
01:27:05Das wird in Ordnung sein.
01:27:06Äh und ja, ich denke, wir würden diesen Workshop dann gerne abschließen.
01:27:13Und ich bin sicher, viele von Ihnen haben eine Menge Fragen.
01:27:14Wir können diese also offline klären.
01:27:15Äh, wir können uns treffen und über diese Fragen sprechen.
01:27:16Ja.
01:27:17Klar.
01:27:18Klar.
01:27:19Äh, vielen Dank an alle.
01:27:20Danke fürs Mitmachen.
01:27:21Äh, ich denke, es war wirklich...
01:27:22Äh, vielen Dank an alle.
01:27:23Äh, vielen Dank an alle.
01:27:24Danke fürs Mitmachen.
01:27:25Äh, vielen Dank an alle.
01:27:26Danke fürs Mitmachen.
01:27:27Äh, ich denke, es war wirklich...
01:27:28Oh, okay.
01:27:29Äh, okay.
01:27:30Das wird in Ordnung sein.
01:27:31Äh und ja, ich denke, wir würden diesen Workshop dann gerne abschließen.
01:27:33Äh und ja, ich denke, wir würden diesen Workshop dann gerne abschließen.
01:27:36Und ich bin sicher, viele von Ihnen werden eine Menge Fragen haben.
01:27:39Wir können diese also alle offline klären.
01:27:41Äh, wir können uns treffen, äh, und wir können, äh, über diese Fragen sprechen.
01:27:42Ja, sicher.
01:27:43Äh, vielen Dank an alle.
01:27:44Äh, ich denke, es war wirklich sinnvoll und dass Sie alle hierhergekommen sind.
01:27:49Äh, vielen herzlichen Dank.
01:27:50Ja, danke.

핵심 요약

LLM-Inferenz verursacht wiederkehrende Betriebskosten, die durch Modellquantisierung, effiziente Attention-Mechanismen wie Flash-Attention und optimierte Serving-Engines wie vLLM und SGLang kontrolliert werden müssen.

하이라이트

  • Der globale Markt für LLM-Inferenz hat ein Volumen von rund 23 Milliarden US-Dollar, wobei Google-Suchanfragen mit LLMs einen Kapitalaufwand von circa 36 Milliarden US-Dollar erfordern.

  • Die Inferenzkosten skalieren als wiederkehrende Betriebskosten linear mit jedem neuen Benutzer, jedem verarbeiteten Token und jeder neuen Sitzung.

  • In der rechengebundenen Pre-Fill-Phase steigt die Zeit bis zum ersten Token (TTFT) direkt mit der Größe des Eingangskontexts an.

  • Der KV-Cache belegt den verbleibenden GPU-Speicher nach Abzug der Modellgewichte, wodurch ein direkter Kompromiss zwischen Kontextlänge und Anzahl gleichzeitiger Benutzer entsteht.

  • Paged-Attention-Mechanismen und kontinuierliches Batching in Serving-Engines wie vLLM und SGLang steigern den Durchsatz in Produktionsumgebungen drastisch.

  • Durch den Einsatz von Post-Training-Quantisierung auf int8 oder int4 sinkt der Modell-Speicherbedarf von Mistral 7B signifikant, wodurch mehr VRAM für den KV-Cache frei wird.

타임라인

Einführung in die LLM-Inferenz und deren wirtschaftliche Herausforderungen

  • LLM-Inferenz umfasst jede Anwendung von KI zur Generierung oder Analyse von Text, Video und Audio.
  • Der weltweite Markt erreicht ein Volumen von 23 Milliarden US-Dollar bei enormen Hardware- und Betriebskosten.
  • Im Gegensatz zu einmaligen Trainingskosten verhalten sich Inferenzkosten als wiederkehrende Betriebskosten.

Die Inferenz bildet das Fundament jeder kommerziellen KI-Anwendung, verursacht jedoch aufgrund begrenzter Hardwareressourcen konstant steigende Kosten. Während das Training von GPT-3 einmalige Kosten von 4,6 Millionen US-Dollar verursachte, skalieren Inferenzkosten mit jedem neuen Benutzer und verarbeiteten Token. Um profitabel zu bleiben, müssen Entwickler die Token-Nutzung streng budgetieren und die Bereitstellungsinfrastruktur gezielt optimieren.

Inferenzphasen, Speicherbedarf und Engpässe

  • Die Pre-Fill-Phase ist rechengebunden und bestimmt maßgeblich die Zeit bis zum ersten Token (TTFT).
  • Der KV-Cache speichert Key- und Value-Vektoren aller bisherigen Token und wächst linear mit der Kontextlänge.
  • Die Decode-Phase ist speichergebunden, da Daten aus dem High-Bandwidth Memory (HBM) übertragen werden müssen.

Die Transformer-Architektur verbraucht den Großteil der Rechenleistung in den Attention-Schichten, wo für jedes Token Key-, Query- und Value-Vektoren berechnet werden. Mit wachsender Kontextlänge erhöht sich der Speicherbedarf drastisch, was zu Out-of-Memory-Fehlern führt. Zudem schränkt die Speicherbandbreite des HBM die maximale Generierungsrate von Token im Decode-Schritt ein, wodurch ein permanenter Kompromiss zwischen Durchsatz, Latenz und Modellqualität entsteht.

Modelloptimierungen durch Quantisierung und alternative Attention-Mechanismen

  • Post-Training-Quantisierung komprimiert das Modellgewicht von FP16 auf int8 oder int4 zur Speichereinsparung.
  • Grouped Query Attention (GQA) und Multi-head Latent Attention (MLA) reduzieren die Größe des KV-Caches erheblich.
  • Flash-Attention optimiert den Datenabruf zwischen HBM und Shared Memory durch Kaching-Techniken.

Um große Modelle auf einzelnen GPUs zu betreiben, reduziert die Quantisierung die Präzision der Gewichte von FP16 auf niedrigere Bitraten. Dies setzt wertvollen VRAM frei, der stattdessen für einen größeren KV-Cache genutzt werden kann. Gleichzeitig ersetzen optimierte Attention-Varianten wie Grouped Query Attention die traditionelle Multi-Head Attention, um redundante Berechnungen zu minimieren und die Inferenzgeschwindigkeit zu maximieren.

Serving-Optimierungen und Produktions-Engines im Vergleich

  • vLLM bietet standardmäßig Paged Attention, kontinuierliches Batching und KV-Caching für Standard-Workloads.
  • SGLang verwendet Radix Trees zur effizienten Präfix-Zwischenspeicherung in agentenbasierten Workloads.
  • TensorRT-LLM maximiert die Hardwareleistung direkt auf NVIDIA-Grafikprozessoren.

Moderne Serving-Engines lösen Speicherfragmentierung und Leerlaufzeiten der GPU durch fortgeschrittene Techniken wie Paged Attention, das den KV-Cache in dynamische Blöcke aufteilt. Während vLLM als stabiler Standard für klassische API-Workloads dient, zeigt SGLang bei agentenbasierten Anwendungen mit wiederkehrenden Prompt-Strukturen durch Radix-Tree-Caching eine deutlich überlegene Leistung. Die Auswahl der passenden Engine hängt letztlich vom spezifischen Anwendungsfall und den Latenz-SLOs ab.

커뮤니티 글

아직 글이 없습니다. 이 영상에 대한 첫 번째 글을 작성해 보세요!

이 영상에 대해 글쓰기