speichereffiziente – chatgpz.de – KI-Tools & Praxiswissen https://chatgpz.de Unabhängige Tests, Anleitungen und Hintergründe zu KI-Tools. Wed, 17 Jun 2026 03:07:24 +0000 de-DE hourly 1 https://wordpress.org/?v=6.4.2 234900186 So erstellen Sie speichereffiziente Transformer mit xFormers unter Verwendung gepackter Sequenzen, GQA, ALiBi, SwiGLU und kausaler Aufmerksamkeit https://chatgpz.de/artificial-intelligence/so-erstellen-sie-speichereffiziente-transformer-mit-xformers-unter-verwendung-gepackter-sequenzen-gqa-alibi-swiglu-und-kausaler-aufmerksamkeit/ https://chatgpz.de/artificial-intelligence/so-erstellen-sie-speichereffiziente-transformer-mit-xformers-unter-verwendung-gepackter-sequenzen-gqa-alibi-swiglu-und-kausaler-aufmerksamkeit/#respond Wed, 17 Jun 2026 03:07:24 +0000 https://chatgpz.de/artificial-intelligence/so-erstellen-sie-speichereffiziente-transformer-mit-xformers-unter-verwendung-gepackter-sequenzen-gqa-alibi-swiglu-und-kausaler-aufmerksamkeit/ [ad_1]

print("n" + "="*70 + "n4. Variable-length packed batch — no padding wasten" + "="*70)
seqlens = (37, 120, 8, 200)
whole = sum(seqlens)
H, Ok = 8, 64
q = torch.randn(1, whole, H, Ok, machine=machine, dtype=torch.float16)
okay = torch.randn(1, whole, H, Ok, machine=machine, dtype=torch.float16)
v = torch.randn(1, whole, H, Ok, machine=machine, dtype=torch.float16)
attempt:
   bias = ab.BlockDiagonalMask.from_seqlens(seqlens)
   out_packed = xops.memory_efficient_attention(q, okay, v, attn_bias=bias)
   s0 = seqlens(0)
   ref0 = vanilla_attention(q(:, :s0), okay(:, :s0), v(:, :s0)).half()
   print("packed form         :", tuple(out_packed.form), "(all", whole, "tokens, no pad)")
   print("segment-0 max diff   : {:.2e}".format((out_packed(:, :s0) - ref0).abs().max().merchandise()))
   cbias = ab.BlockDiagonalCausalMask.from_seqlens(seqlens)
   _ = xops.memory_efficient_attention(q, okay, v, attn_bias=cbias)
   print("-> additionally did a packed CAUSAL move. That is how vLLM-style engines")
   print("   batch requests of various lengths with zero padding overhead.")
   splits = bias.cut up(out_packed)
   print("recovered segments   :", (tuple(t.form) for t in splits))
besides Exception as e:
   print("BlockDiagonalMask path skipped on this model/backend:", repr(e))
print("n" + "="*70 + "n5. Grouped-query consideration (5-D BMGHK format)n" + "="*70)
B, M, Ok = 2, 256, 64
n_q_heads, n_kv_heads = 8, 2
G, Hq = n_kv_heads, n_q_heads // n_kv_heads
attempt:
   qg = torch.randn(B, M, G, Hq, Ok, machine=machine, dtype=torch.float16)
   kg = torch.randn(B, M, G, 1,  Ok, machine=machine, dtype=torch.float16)
   vg = torch.randn(B, M, G, 1,  Ok, machine=machine, dtype=torch.float16)
   out_gqa = xops.memory_efficient_attention(qg, kg, vg)
   print("GQA output form     :", tuple(out_gqa.form), "= (B, M, G, Hq, Ok)")
   print(f"-> {n_q_heads} question heads, solely {n_kv_heads} KV heads: smaller KV-cache,")
   print("   which is strictly what Llama-/Mistral-class fashions use at inference.")
besides Exception as e:
   print("GQA 5-D path skipped on this model/backend:", repr(e))

[ad_2]

]]>
https://chatgpz.de/artificial-intelligence/so-erstellen-sie-speichereffiziente-transformer-mit-xformers-unter-verwendung-gepackter-sequenzen-gqa-alibi-swiglu-und-kausaler-aufmerksamkeit/feed/ 0 19317
Vector Streaming: Speichereffiziente Indizierung mit Rust https://chatgpz.de/data-analytics/vector-streaming-speichereffiziente-indizierung-mit-rust/ https://chatgpz.de/data-analytics/vector-streaming-speichereffiziente-indizierung-mit-rust/#respond Tue, 17 Sep 2024 10:44:19 +0000 https://chatgpz.de/data-analytics/vector-streaming-speichereffiziente-indizierung-mit-rust/ [ad_1]

Einführung

Vektor-Streaming wird in EmbedAnything eingeführt, eine Funktion, die das Einbetten von Dokumenten in großem Maßstab optimieren soll. Das Aktivieren von asynchronem Chunking und Einbetten mithilfe der Parallelität von Rust reduziert den Speicherverbrauch und beschleunigt den Prozess. Heute zeige ich, wie man es in die Weaviate-Vektordatenbank integriert, um Bilder nahtlos einzubetten und zu suchen.

In meinem vorherigen Artikel Optimieren Sie Ihre Embeddings-Pipeline mit EmbedAnythingIch habe die Idee hinter EmbedAnything erläutert und wie es das Erstellen von Einbettungen aus mehreren Modalitäten vereinfacht. In diesem Artikel möchte ich eine neue Funktion von EmbedAnything namens Vektor-Streaming vorstellen und zeigen, wie sie mit der Weaviate-Vektordatenbank funktioniert.

Vector Streaming: Speichereffiziente Indizierung mit Rus

Überblick

  • Vektor-Streaming in EmbedAnything optimiert das Einbetten großer Dokumente durch asynchrones Chunking mit der Parallelität von Rust.
  • Es löst Speicher- und Effizienzprobleme bei herkömmlichen Einbettungsmethoden durch die parallele Verarbeitung von Blöcken.
  • Die Integration mit Weaviate ermöglicht die nahtlose Einbettung und Suche in einer Vektordatenbank.
  • Die Implementierung von Vektor-Streaming umfasst das Erstellen eines Datenbankadapters, das Initiieren eines Einbettungsmodells und das Einbetten von Daten.
  • Dieser Ansatz bietet eine effizientere, skalierbarere und flexiblere Lösung für die Einbettung umfangreicher Dokumente.

Was ist das Downside?

Untersuchen wir zunächst das aktuelle Downside bei der Erstellung von Einbettungen, insbesondere in umfangreichen Dokumenten. Die aktuelle Einbettungsframeworks arbeiten in einem zweistufigen Prozess: Chunking und Embedding. Zuerst wird der Textual content aus allen Dateien extrahiert und Chunks/Knoten werden erstellt. Dann werden diese Chunks einem Embedding-Modell mit einer bestimmten Batch-Größe zugeführt, um die Embeddings zu verarbeiten. Während dies geschieht, verbleiben die Chunks und die Embeddings im Systemspeicher.

Dies ist kein Downside, wenn die Dateien und Einbettungsdimensionen klein sind. Es wird jedoch zu einem Downside, wenn viele Dateien vorhanden sind und Sie mit großen Modellen und, noch schlimmer, mit Multi-Vektor-Einbettungen arbeiten. Um damit arbeiten zu können, ist additionally viel RAM erforderlich, um die Einbettungen zu verarbeiten. Wenn dies synchron erfolgt, geht außerdem viel Zeit verloren, während die Chunks erstellt werden, da das Chunking kein rechenintensiver Vorgang ist. Während die Chunks erstellt werden, wäre es effizient, sie an das Einbettungsmodell zu übergeben.

Unsere Lösung des Issues

Die Lösung besteht darin, eine asynchrone Chunking- und Embedding-Aufgabe zu erstellen. Wir können Threads effektiv erstellen, um diese Aufgabe mithilfe der Parallelitätsmuster und Threadsicherheit von Rust zu bewältigen. Dies geschieht mithilfe von Rusts MPSC-Modul (Multi-producer Single Shopper), das Nachrichten zwischen Threads überträgt. Dadurch wird ein Datenstrom von Chunks erstellt, der mit einem Puffer an den Einbettungsthread übergeben wird. Sobald der Puffer vollständig ist, bettet er die Chunks ein und sendet die Einbettungen zurück an den Hauptthread, der sie dann an die Vektordatenbank sendet. Dadurch wird sichergestellt, dass keine Zeit für einen einzelnen Vorgang verschwendet wird und keine Engpässe auftreten. Darüber hinaus speichert das System nur die Chunks und Einbettungen im Puffer und löscht sie aus dem Speicher, sobald sie in die Vektordatenbank verschoben werden.

Vektor-Streaming

Beispiel-Anwendungsfall mit EmbedAnything

Sehen wir uns diese Funktion nun in Aktion an:

Mit EmbedAnything können Sie die Vektoren aus einem Verzeichnis mit Dateien in das Vektordatenbank ist ein einfacher dreistufiger Prozess.

  1. Erstellen Sie einen Adapter für Ihre Vektordatenbank: Dies ist ein Wrapper um die Funktionen der Datenbank, der es Ihnen ermöglicht, einen Index zu erstellen, Metadaten vom EmbedAnything-Format in das von der Datenbank benötigte Format zu konvertieren und die Funktion zum Einfügen der Einbettungen in den Index bereitzustellen. Adapter für die wichtigsten Datenbanken wurden bereits erstellt und sind vorhanden. Hier.
  1. Initiieren Sie ein Einbettungsmodell Ihrer Wahl: Sie können zwischen verschiedenen lokalen Modellen oder sogar Cloud-Modellen wählen. Die Konfiguration kann auch durch Festlegen der Blockgröße und der Puffergröße bestimmt werden, je nachdem, wie viele Einbettungen gleichzeitig gestreamt werden müssen. Idealerweise sollte dies so hoch wie möglich sein, aber der System-RAM begrenzt dies.
  1. Rufen Sie die Einbettungsfunktion von EmbedAnything auf: Übergeben Sie einfach den einzubettenden Verzeichnispfad, das Einbettungsmodell, den Adapter und die Konfiguration.

In diesem Beispiel betten wir ein Verzeichnis mit Bildern ein und senden es an die Vektordatenbanken.

Schritt 1: Erstellen des Adapters

In EmbedAnything werden die Adapter außerhalb erstellt, um die Bibliothek nicht zu schwer zu machen, und Sie können auswählen, mit welcher Datenbank Sie arbeiten möchten. Hier ist ein einfacher Adapter für Weaviate:

from embed_anything import EmbedData

from embed_anything.vectordb import Adapter

class WeaviateAdapter(Adapter):

    def __init__(self, api_key, url):

        tremendous().__init__(api_key)

        self.shopper = weaviate.connect_to_weaviate_cloud(

            cluster_url=url, auth_credentials=wvc.init.Auth.api_key(api_key)

        )

        if self.shopper.is_ready():

            print("Weaviate is prepared")

    def create_index(self, index_name: str):

        self.index_name = index_name

        self.assortment = self.shopper.collections.create(

            index_name, vectorizer_config=wvc.config.Configure.Vectorizer.none()

        )

        return self.assortment

    def convert(self, embeddings: Record(EmbedData)):

        information = ()

        for embedding in embeddings:

            property = embedding.metadata

            property("textual content") = embedding.textual content

            information.append(

                wvc.information.DataObject(properties=property, vector=embedding.embedding)

            )

        return information

    def upsert(self, embeddings):

        information = self.convert(embeddings)

        self.shopper.collections.get(self.index_name).information.insert_many(information)

    def delete_index(self, index_name: str):

        self.shopper.collections.delete(index_name)

### Begin the shopper and index

URL = "your-weaviate-url"

API_KEY = "your-weaviate-api-key"

weaviate_adapter = WeaviateAdapter(API_KEY, URL)

index_name = "Test_index"

if index_name in weaviate_adapter.shopper.collections.list_all():

    weaviate_adapter.delete_index(index_name)

weaviate_adapter.create_index("Test_index")

Schritt 2: Erstellen des Einbettungsmodells

Da wir hier Bilder einbetten, können wir das Clip-Modell verwenden

import embed_anything import WhichModel

mannequin = embed_anything.EmbeddingModel.from_pretrained_cloud(

        embed_anything.WhichModel.Clip,     

        model_id="openai/clip-vit-base-patch16")

Schritt 3: Verzeichnis einbetten

information = embed_anything.embed_image_directory(

    "image_directory",

    embeder=mannequin,

    adapter=weaviate_adapter,

    config=embed_anything.ImageEmbedConfig(buffer_size=100),

)

Schritt 4: Abfrage der Vektordatenbank

query_vector = embed_anything.embed_query(("picture of a cat"), embeder=mannequin)(0).embedding

Schritt 5: Abfrage der Vektordatenbank

response = weaviate_adapter.assortment.question.near_vector(

    near_vector=query_vector,

    restrict=2,

    return_metadata=wvc.question.MetadataQuery(certainty=True),

)

Test the response;

Ausgabe

Mithilfe des Clip-Modells haben wir das gesamte Verzeichnis mit Bildern von Katzen, Hunden und Affen vektorisiert. Mit der einfachen Abfrage „Bilder von Katzen“ konnten wir alle Dateien nach Bildern von Katzen durchsuchen.

Ausgabe

Den Code finden Sie im Notizbuch hier auf Zusammenarbeit.

Abschluss

Ich denke, dass Vektor-Streaming eine der Funktionen ist, die viele Ingenieure dazu befähigen wird, sich für eine optimiertere Lösung ohne technische Schulden zu entscheiden. Anstatt sperrige Frameworks in der Cloud zu verwenden, können Sie eine leichte Streaming-Choice nutzen.

Schauen Sie sich das GitHub-Repository hier an: EmbedAnything-Repository.

Häufig gestellte Fragen

Frage 1. Was ist Vektor-Streaming in EmbedAnything?

Antwort: Vektor-Streaming ist eine Funktion, die das Einbetten von Dokumenten in großem Maßstab optimiert, indem sie die Parallelität von Rust für asynchrones Chunking und Einbetten nutzt, wodurch der Speicherverbrauch reduziert und der Prozess beschleunigt wird.

Frage 2. Welches Downside löst Vektor-Streaming?

Antwort: Es behebt den hohen Speicherverbrauch und die Ineffizienz herkömmlicher Einbettungsmethoden, indem es Blöcke asynchron verarbeitet, Engpässe reduziert und die Ressourcennutzung optimiert.

Frage 3. Wie funktioniert Vektor-Streaming mit Weaviate?

Antwort: Es verwendet einen Adapter, um EmbedAnything mit der Weaviate-Vektordatenbank zu verbinden, was ein nahtloses Einbetten und Abfragen von Daten ermöglicht.

Frage 4. Welche Schritte sind zur Verwendung von Vektor-Streaming erforderlich?

Antwort: Hier sind die Schritte:
1. Erstellen Sie einen Datenbankadapter.
2. Initiieren Sie ein Einbettungsmodell.
3. Betten Sie das Verzeichnis ein.
4. Abfrage der Vektordatenbank.

Frage 5. Warum sollte man Vektor-Streaming herkömmlichen Methoden vorziehen?

Antwort: Es bietet im Vergleich zu herkömmlichen Einbettungsmethoden eine bessere Effizienz, einen geringeren Speicherverbrauch, Skalierbarkeit und Flexibilität.

KI-Entwickler @ Serpentine AI || TU Eindhoven Entwicklung von Starlight – semantische Suchmaschine für Home windows in Rust 🦀. Entwicklung von EmbedAnything – eine minimale Einbettungspipeline, die auf Candle basiert. Ich liebe es, beim Coaching großer KI-Modelle zuzusehen.

[ad_2]

]]>
https://chatgpz.de/data-analytics/vector-streaming-speichereffiziente-indizierung-mit-rust/feed/ 0 3940
So führen Sie mit Pandas speichereffiziente Operationen an großen Datensätzen durch https://chatgpz.de/data-analytics/so-fuehren-sie-mit-pandas-speichereffiziente-operationen-an-grossen-datensaetzen-durch/ https://chatgpz.de/data-analytics/so-fuehren-sie-mit-pandas-speichereffiziente-operationen-an-grossen-datensaetzen-durch/#respond Mon, 29 Jul 2024 21:27:40 +0000 https://chatgpz.de/data-analytics/so-fuehren-sie-mit-pandas-speichereffiziente-operationen-an-grossen-datensaetzen-durch/ [ad_1]

So führen Sie mit Pandas speichereffiziente Operationen an großen Datensätzen durch
Bild vom Herausgeber | Midjourney

Lassen Sie uns lernen, wie Sie in Pandas Operationen mit großen Datensätzen durchführen.

Vorbereitung

Da wir über das Pandas-Paket sprechen, sollten Sie eines installiert haben. Zusätzlich würden wir auch das Numpy-Paket verwenden. Installieren Sie additionally beide.

Kommen wir dann zum zentralen Teil des Tutorials.

Führen Sie speichereffiziente Operationen mit Pandas durch

Pandas sind normalerweise nicht dafür bekannt, große Datensätze zu verarbeiten, da speicherintensive Vorgänge mit dem Pandas-Paket zu viel Zeit in Anspruch nehmen oder sogar Ihren gesamten RAM verschlingen können. Es gibt jedoch Möglichkeiten, die Effizienz von Panda-Vorgängen zu verbessern.

In diesem Tutorial zeigen wir Ihnen, wie Sie Ihre Erfahrung mit großen Datensätzen in Pandas verbessern können.

Versuchen Sie zunächst, den Datensatz mit einem Speicheroptimierungsparameter zu laden. Versuchen Sie außerdem, den Datentyp zu ändern, insbesondere in einen speicherfreundlichen Typ, und löschen Sie alle unnötigen Spalten.

import pandas as pd

df = pd.read_csv('some_large_dataset.csv', low_memory=True, dtype={'column': 'int32'}, usecols=('col1', 'col2'))

Das Konvertieren von Integer und Float mit dem kleinsten Typ würde helfen, den Speicherbedarf zu reduzieren. Die Verwendung des Kategorietyps für die kategorische Spalte mit einer kleinen Anzahl eindeutiger Werte würde ebenfalls helfen. Kleinere Spalten tragen auch zur Speichereffizienz bei.

Als Nächstes können wir den Chunk-Prozess verwenden, um die Nutzung des gesamten Speichers zu vermeiden. Es wäre effizienter, wenn es iterativ verarbeitet würde. Wir möchten beispielsweise den Spaltenmittelwert ermitteln, aber der Datensatz ist zu groß. Wir können 100.000 Daten gleichzeitig verarbeiten und das Gesamtergebnis erhalten.

chunk_results = ()

def column_mean(chunk):
    chunk_mean = chunk('target_column').imply()
    return chunk_mean

chunksize = 100000
for chunk in pd.read_csv('some_large_dataset.csv', chunksize=chunksize):
    chunk_results.append(column_mean(chunk))

final_result = sum(chunk_results) / len(chunk_results) 

Vermeiden Sie außerdem die Verwendung der Methode apply mit Lambda-Funktionen; sie könnte speicherintensiv sein. Alternativ ist es besser, vektorisierte Operationen oder die .apply Methode mit normaler Funktion.

df('new_column') = df('existing_column') * 2

Für bedingte Operationen in Pandas ist es auch schneller zu verwenden np.the placeanstatt die Lambda-Funktion direkt mit .apply

import numpy as np 
df('new_column') = np.the place(df('existing_column') > 0, 1, 0)

Dann verwenden Sie inplace=Truein vielen Pandas-Operationen ist viel speichereffizienter als die Rückzuweisung zu ihrem DataFrame. Es ist viel effizienter, weil die Rückzuweisung einen separaten DataFrame erstellen würde, bevor wir sie in dieselbe Variable einfügen.

df.drop(columns=('column_to_drop'), inplace=True)

Und schließlich: Filtern Sie die Daten möglichst frühzeitig, bevor Sie irgendwelche Operationen durchführen. Dadurch begrenzen Sie die Datenmenge, die wir verarbeiten.

df = df(df('filter_column') > threshold)

Versuchen Sie, diese Tipps zu beherrschen, um Ihre Pandas-Erfahrung mit großen Datensätzen zu verbessern.

Zusätzliche Ressourcen

Cornellius Yudha Wijaya ist Information Science Assistant Supervisor und Datenautor. Während seiner Vollzeitbeschäftigung bei Allianz Indonesien teilt er gerne Python- und Datentipps über soziale Medien und in den Medien. Cornellius schreibt über eine Vielzahl von KI- und maschinellen Lernthemen.

[ad_2]

]]>
https://chatgpz.de/data-analytics/so-fuehren-sie-mit-pandas-speichereffiziente-operationen-an-grossen-datensaetzen-durch/feed/ 0 2713
Flash Consideration (Schnelle und speichereffiziente exakte Aufmerksamkeit mit IO-Consciousness): Ein tiefer Einblick | von Anish Dubey | Mai 2024 https://chatgpz.de/machine-learning/flash-consideration-schnelle-und-speichereffiziente-exakte-aufmerksamkeit-mit-io-consciousness-ein-tiefer-einblick-von-anish-dubey-mai-2024/ https://chatgpz.de/machine-learning/flash-consideration-schnelle-und-speichereffiziente-exakte-aufmerksamkeit-mit-io-consciousness-ein-tiefer-einblick-von-anish-dubey-mai-2024/#respond Wed, 29 May 2024 14:58:19 +0000 https://chatgpz.de/machine-learning/flash-attention-schnelle-und-speichereffiziente-exakte-aufmerksamkeit-mit-io-awareness-ein-tiefer-einblick-von-anish-dubey-mai-2024/ [ad_1]

Flash Consideration ist ein leistungsoptimierender Transformator-Consideration-Mechanismus, der eine Effizienz von 15 % bietet

Foto von Sander Traa An Unsplash

Flash Consideration ist ein Transformator-Aufmerksamkeitsmechanismus zur Leistungsoptimierung, der im Hinblick auf die Echtzeitgeschwindigkeit eine Effizienz von 15 % bietet, und zwar ohne Annäherung.

Da Transformer-Modelle bei langen Sequenzen langsam und speicherhungrig sind (Zeit- und Speicherkomplexität sind quadratischer Natur), ist Flash Consideration (Papier) bietet eine Finish-to-Finish-Beschleunigung im Echtzeittakt von 15 % auf BERT-large und die dreifache Geschwindigkeit auf GPT-2.

Wenn man bedenkt, dass das Trainieren dieser großen Modelle enorme Mengen an Energie verbraucht, kann Flash Consideration mit Software program- und Hardwareoptimierung eine Effizienz von 15 % erzielen, was hinsichtlich der Verbesserung einen enormen Gewinn darstellt.

Nachfolgend werden einige der grundlegenden Konzepte von Flash Consideration und deren Implementierung erläutert.

Grundlegende Konzepte rund um Rechenleistung und Speicher

Bevor wir tiefer in die Thematik Rechenleistung und Speicher eintauchen, wollen wir sie noch einmal betrachten:

Was ist Compute?

  • Zeit, die Ihr GPU für die Berechnung tatsächlicher Gleitkommaoperationen (FLOPS) aufwendet

Was ist Speicher?

  • Zeitaufwand für die Übertragung von Tensoren innerhalb einer GPU

Im Idealfall soll unsere gCPU ständig Matrixmultiplikationen durchführen und nicht durch den Speicher eingeschränkt werden. In Wirklichkeit hat die Rechenleistung jedoch im Vergleich zum Speicher größere Fortschritte gemacht, und wir befinden uns in einer Welt, in der die gCPU im Leerlauf wartet, bis Daten geladen sind. Dies wird normalerweise als Speicher gebunden Operation. Siehe unten das erläuternde Diagramm, das dies darstellt. Matrixmultiplikation wird als Berechnung betrachtet und der Speicher speichert die Daten (betrachten Sie ihn als Lager). Die Berechnung benötigt Daten zur Verarbeitung und die Speicherbandbreite muss diese Operation unterstützen.

Foto von https://horace.io/brrr_intro.html

Was ist Speicherhierarchie?

Die A100 GPU hat 40–80 GB von Excessive Bandwidth Reminiscence mit einer Bandbreite von 1,5–2,0 TB/s Und 192 KB On-Chip-SRAM mit jeweils 108 Streaming-Multiprozessoren mit einer Bandbreite von ca. 19 TB/s.

Foto von https://arxiv.org/abs/2205.14135

Vor dem Hintergrund des oben genannten Kontexts ist Self-Consideration-Architektur erinnerungsgebunden.

Foto vom Autor

Betrachtet man die Aufmerksamkeitsmathematik, ist es eine Softmax-Operation, die die Speicherbindung verursacht.

  • Quantitativer Beweis: Wie Sie unten sehen können, nehmen Operationen wie Softmax, Dropout und Maskierung im Vergleich zur Matrixmultiplikation (Matmul) den Großteil der Zeit in Anspruch.
Foto von https://arxiv.org/abs/2205.14135

Warum wird Softmax zu einer speichergebundenen Operation?

Der Maßstab, in dem es betrieben wird, ist unser größter Engpass. Im folgenden Diagramm

  • N -> Anzahl der Token
  • d -> Anzahl der Einbettungsdimensionen
  • Wenn Abfrage und Schlüssel multipliziert werden, explodiert die Aufmerksamkeitsmatrix auf N * N, was viel Speicher beansprucht. Als Referenz (d ~128; N ~128.000 Token; Google Gemini: ~1 Million Token)
Foto von FlashAttention — Tri Dao | Stanford MLSys #67

Unten sehen Sie den Algorithmus zur Implementierung eines Selbstaufmerksamkeitsmechanismus

Foto von https://arxiv.org/abs/2205.14135

Wie im obigen Abschnitt erwähnt, ist das Übertragen von Informationen an HBM (Schreiben von S an HBM) und das anschließende Zurückladen von HBM an gCPU, um Softmax zu berechnen, und das anschließende Zurückschreiben an HBM eine Menge an Informationen, die es speichergebundener Vorgang.

Zusammen mit dem Diagramm erklären die folgenden Schritte, wie die Selbstaufmerksamkeit durch Matrixmultiplikation berechnet wird.

Schritt 1:

  • Ich habe das vereinfacht. In der Praxis wird jedes Token mit Positionscodierung hinzugefügt, um Einbettungen zu generieren, die in eine lineare Schicht eingespeist werden, um zu generieren. Zur Veranschaulichung habe ich eine Dimension von 3 verwendet (normalerweise liegt sie zwischen 64 und 128). Dies ist eine Standardeingabe für die Transformer-Architektur.

Schritt 2

  • Schlüssel -> Schlüssel‘ (Transponierung) wird berechnet und mit Abfrage multipliziert, um QK‘ zu erhalten, was N*N ist. Dies enthält die Aufmerksamkeit jedes Tokens mit den übrigen Token. Das folgende Diagramm zeigt auch die Beziehung. Da es sich um Token handelt und wir die Wichtigkeit jedes Tokens im Verhältnis zueinander berechnen müssen, wird die Softmax-Operation zeilenweise angewendet, um sie von 0 -1 zu normalisieren.
  • Dieser Schritt erfordert eine Bewegung zu HBM und ist der teuerste Vorgang wie wir besprochen haben. Das gesamte Flash-Aufmerksamkeitspapier befasst sich mit der Optimierung dieses Prozesses.

Schritt 3

  • Softmax(QK‘) * V wird als endgültige Ausgabematrix berechnet. Die Dimension ist hier dieselbe wie die Eingabeeinbettungen von Schlüssel, Abfrage und Wert.
  • Letzte Zeile in der Ausgabematrix
  • 1*5 bedeutet, dass die Einbettung von „diesem“ geändert werden sollte, um Beziehungen mit anderen Token einzubinden.
  • 2*5 bedeutet, dass die Einbettung von „ist“ geändert werden sollte, um Beziehungen mit anderen Token einzubinden.
  • Dasselbe wie oben für die restlichen Zeilen
Foto des Autors: Illustratives Diagramm zur Funktionsweise des Selbstaufmerksamkeitsmechanismus

Die Grundidee wird durch das folgende Diagramm erklärt, in dem Schlüssel-, Abfrage- und Wertblöcke vom HBM zum SRAM übertragen werden. Durch einige mathematische Methods (siehe unten) ist die hier durchgeführte Berechnung keine ungefähre Antwort, sondern eine tatsächlich richtige.

Mit dieser Implementierung kann Papier die Wall-Pace-Zeit reduzieren, indem es auf Informationen in Blöcken zugreift, ohne die Korrektheit zu beeinträchtigen.

Foto von https://arxiv.org/abs/2205.14135

Algorithmus hinter dem Papier: Wie wird Flash Consideration implementiert?

Dies ist der komplexeste Teil des Dokuments. Lassen Sie uns dieses Downside in Unteraspekte aufteilen und tiefer eintauchen.

Das folgende Diagramm unterteilt die Matrix in Blöcke und zeigt, wie jeder Block zur Berechnung des partiellen Softmax und anschließend des korrekten Softmax verwendet wird.

  • Ersteingabe: Token: Dies ist ein Flash-Consideration-Papier
  • Schlüssel: 4 (Token) x 3 (Dimensionen), Abfrage: 4 (Token) x 3 (Dimensionen) und Wert: 4 (Token) x 3 (Dimensionen)
Bild vom Autor geändert. Originalbild von https://arxiv.org/abs/2205.14135

Schritt 0

  • Angenommen, der Speicher ist 24 Byte groß
  • SRAM wird in 4 Blöcke unterteilt (Abfrage, Schlüssel, Wert und Ausgabematrix)
  • Abfrage, Schlüssel, Wert und Ausgabe erhalten jeweils = 6 Bytes zum Speichern ihrer Informationen (12 Bytes/4)
  • Jede Dimension ist 3, da jede Einbettung nicht gebrochen werden kann, additionally
  • Abfrage: 6 Bytes/ 3 (Dimension) = 2. Gleiches gilt für Wert, Schlüssel und Ausgabe
  • Daher gibt (M/4d) die Größe jedes Blocks an. In diesem Fall beträgt die Blockgröße 2. Das bedeutet, dass 2 Zeilen in den SRAM geladen werden können.
  • Im Allgemeinen beträgt die Blockgröße (M/4d) und die Anzahl der Blöcke (N*4D/M).

Schritt 1 und 2: Unten wird eine Tabelle hinzugefügt, die die Schritte 1 und 2 zur Funktionsweise von Flash Consideration veranschaulicht und die Speicher- und Rechenaspekte davon vergleicht.

Foto vom Autor: Schrittweise Aufschlüsselung der Speicher- und Rechenleistungsnutzung in Flash Achtung

Das folgende Diagramm hilft dabei, die in Flash Consideration verwendete Matrixmultiplikation (Block für Block) zu visualisieren.

Foto des Autors: Illustratives Diagramm zur Funktionsweise des Flash-Consideration-Mechanismus

Was ist der mathematische Aspekt von Softmax?

Einer der kritischsten Aspekte des Dokuments ist, wie das Zerlegen von Matrizen dennoch zur Berechnung der Softmax-Genauigkeit führt. Lassen wir das mathematische Beispiel unten aus, das zeigt, wie zwei verschiedene Matrizen zusammengefasst werden können, um erneut Softmax zu berechnen.

Instinct

  • Dies ist die schöne Eigenschaft von Exponenten, die hier ausgenutzt wird.
  • Jeder Softmax wird einzeln berechnet, aber gleichzeitig wird der Maximalwert der Zeile zusammen mit dem summierten Exponentenwert gespeichert.
  • Beim Zusammenführen mit einer anderen Matrix müssen wir prüfen, wie stark sich das Most vom globalen Most der beiden Matrizen unterscheidet. Und aufgrund des Exponenten werden sowohl Zähler als auch Nenner mit e^(aktuelles_Maximum – globales_Maximum) angepasst, um dies zu berücksichtigen.

Logik ist ziemlich komplex, deshalb wird unten ein Beispiel durchgegangen. Wenn Sie sich mit einem Beispiel vertraut gemacht haben, wird die obige Instinct sehr viel Sinn ergeben.

Foto vom Autor: Beispiel zur Demonstration, wie man eine Matrix in Unterkomponenten aufteilt und diese schließlich kombiniert, um Softmax zu berechnen

Schauen wir uns die Komplexitätsanalyse an, um ein Gefühl dafür zu bekommen, wie sich die Dinge verändert haben

Selbstaufmerksamkeit

  • Während der Berechnung von S = QK‘ wird eine N*N-Matrix erstellt, die zurück zum HRAM übertragen und anschließend aus dem HRAM abgerufen werden muss.
  • Daher ist O(N*N + N*N) = O(N*N) HBM-Zugriff

Blitzlicht

  • Äußere Schleife: Auf Schlüssel und Abfrage wird O(Nd) mal zugegriffen
  • Innere Schleife: Zum Laden von HBM sind nur O(Nd/M) erforderlich, da auf Blöcken gearbeitet wird
  • Insgesamt: O(N*N*d*d/M)
  • In der Praxis ist d viel kleiner als M. d liegt im Bereich von (64–128), während M im Bereich von 100 KB liegt. Daher ist der HBM-Zugriff optimiert
  • Wir begannen mit dem Ziel, den HBM-Zugriff zu optimieren, und mit dieser Komplexitätsanalyse sehen wir, dass das Papier die HBM-Zugriff über den Faktor (d*d/M) ohne Näherung.

So ein komplexes Papier mit enormer Effizienzsteigerung. Ich hoffe, die obige Erklärung vermittelt einen Eindruck davon, wie Flash Consideration die Leistung optimiert und verbessert. Ich habe Block Sparse Flash Consideration noch nicht behandelt. Wie sieht es im Vergleich zu anderen Optimierungstechniken, Forwards Cross Optimization usw. aus? Ich hoffe, das in einem zukünftigen Beitrag behandeln zu können.

Verweise

[ad_2]

]]>
https://chatgpz.de/machine-learning/flash-consideration-schnelle-und-speichereffiziente-exakte-aufmerksamkeit-mit-io-consciousness-ein-tiefer-einblick-von-anish-dubey-mai-2024/feed/ 0 995