Überspringen und zum Inhalt gehen →

300% Performance durch Batch-Textgenerierung

Durch die Bündelung mehrerer Texte in einem Batch und deren gleichzeitige Verarbeitung kann die Verarbeitungsgeschwindigkeit deutlich gesteigert und die Ressourcennutzung optimiert werden. Durch die die Parallelisierung auf einer GPU ist eine effizientere Auslastung der Hardware möglich, was insgesamt zu einer verbesserten Geschwindigkeit führt. Dieser Ansatz ist besonders vorteilhaft für Anwendungen, die große Mengen von Texten generieren müssen, wie beispielsweise bei der automatisierten Erstellung von synthetisch generierten Daten zum Trainieren von KI-Modellen.

Die Parallelisierung der Batch-Textgenerierung auf einer GPU bietet folgende Vorteile:

GPUs sind darauf ausgelegt, große Datenmengen parallel zu verarbeiten. Durch die Parallelisierung können mehrere Textgenerierungsaufgaben gleichzeitig ausgeführt werden, was zu einer erheblichen Beschleunigung führen kann. Ohne diese Parallelisierung könnten Teile der GPU während der Inferenz ungenutzt bleiben, da einige Kerne der GPU möglicherweise nicht ausgelastet sind. Durch die gleichzeitige Generierung mehrerer Texte können diese Ressourcen effektiver genutzt werden.

Beispiel

Das folgende Beispiel erzeugt eine JavaDoc Dokumentation für eine Java Methode mit dem „deepseek-ai/deepseek-coder-7b-instruct-v1.5“ Model. Es verwendet eine leicht angepasstes Chat Template das wie folgt aussieht.

You are a helpful AI Java programming and documentation assistant. Your goal is to provide comprehensive support to developers by assisting with Java programming tasks and documentation generation. Your capabilities include offering code suggestions, debugging assistance, and generating JavaDoc documentation for methods and classes. Your responses align with industry best practices, Java language conventions, and documentation standards. Strive for clarity, conciseness, and relevance in all interactions to enhance developers' productivity and understanding.

### Instruction:

Generate JavaDoc documentation for the provided Java method. Ensure that the documentation is clear, concise, and adheres to standard JavaDoc conventions. Describe the purpose of the method, its parameters, return value, and any exceptions it may throw. Include relevant details about the method's behavior and usage to assist developers who will utilize it. Use appropriate tags such as @param, @return, @throws, and provide examples or usage scenarios where applicable to enhance understanding.

```java

{java}

```

### Response:

Zum Test verwende ich die Java Methode similaritySearch der org.springframework.ai.vectorstore. SimpleVectorStore Klasse aus dem Spring AI Projekt.

    @Override
    public List<Document> similaritySearch(SearchRequest request) {
        if (request.getFilterExpression() != null) {
            throw new UnsupportedOperationException(
                    "The [" + this.getClass() + "] doesn't support metadata filtering!");
        }

        List<Double> userQueryEmbedding = getUserQueryEmbedding(request.getQuery());
        return this.store.values()
                .stream()
                .map(entry -> new Similarity(entry.getId(),
                        EmbeddingMath.cosineSimilarity(userQueryEmbedding, entry.getEmbedding())))
                .filter(s -> s.score >= request.getSimilarityThreshold())
                .sorted(Comparator.<Similarity>comparingDouble(s -> s.score).reversed())
                .limit(request.getTopK())
                .map(s -> this.store.get(s.key))
                .toList();
    }

Der fertige Prompt sieht dann wie folgt aus:

You are a helpful AI Java programming and documentation assistant. Your goal is to provide comprehensive support to developers by assisting with Java programming tasks and documentation generation. Your capabilities include offering code suggestions, debugging assistance, and generating JavaDoc documentation for methods and classes. Your responses align with industry best practices, Java language conventions, and documentation standards. Strive for clarity, conciseness, and relevance in all interactions to enhance developers' productivity and understanding.

### Instruction:
Generate JavaDoc documentation for the provided Java method. Ensure that the documentation is clear, concise, and adheres to standard JavaDoc conventions. Describe the purpose of the method, its parameters, return value, and any exceptions it may throw. Include relevant details about the method's behavior and usage to assist developers who will utilize it. Use appropriate tags such as @param, @return, @throws, and provide examples or usage scenarios where applicable to enhance understanding.
```java
@Override
    public List<Document> similaritySearch(SearchRequest request) {
        if (request.getFilterExpression() != null) {
            throw new UnsupportedOperationException(
                    "The [" + this.getClass() + "] doesn't support metadata filtering!");
        }

        List<Double> userQueryEmbedding = getUserQueryEmbedding(request.getQuery());
        return this.store.values()
                .stream()
                .map(entry -> new Similarity(entry.getId(),
                        EmbeddingMath.cosineSimilarity(userQueryEmbedding, entry.getEmbedding())))
                .filter(s -> s.score >= request.getSimilarityThreshold())
                .sorted(Comparator.<Similarity>comparingDouble(s -> s.score).reversed())
                .limit(request.getTopK())
                .map(s -> this.store.get(s.key))
                .toList();
    }
```
### Response:

Dieser Prompt wird dem Model in einem Batch 5 mal übergeben, so dass auf der GPU 5 Texte gleichzeitig für den gleichen Prompt erstellt werden. Mit den Parametern top_k = 2, top_p = 0.6 und temperature = 0.3 erlaube ich eine gewisse Kreativität beim Erzeugen der JavaDoc Dokumentation, so dass im besten Fall 5 unterschiedliche JavaDoc Texte erstellt werden. Diese können dann später sehr gut genutzt werden, um damit das Finetuning für ein Corporate Model durchzuführen, das dann den spezifischen Quellcode eines Unternehmens optimal trainiert.

Da es etwas über 20 GB VRAM benötigt, ist es leider nicht möglich das auf einer T4 GPU in Google Colab laufen zu lassen. Aber man kann es auch mit einem kleineren Model testen. Z.B. das 1.3B Model (deepseek-ai/deepseek-coder-1.3b-instruct).

Vergleich Sequenziell vs. Parallel

Das Skript, das 5 Texte sequenziell generiert, benötigt ca. 273 Sekunden. Das Skript, das 5 Texte parallel generiert, benötigt nur ca. 93 Sekunden. Das ist eine Verbesserung um den Faktor 3. Das ist eine signifikante Verbesserung die nur durch optimierte Nutzung der Ressourcen der GPU-Kerne ermöglicht wird.
Hinweis: Vermutlich lässt sich die Performance noch weiter steigern, wenn man die Anzahl der parallel generierten Text noch weiter erhöht.

Python Skripte

Die beiden verwendeten Python Programme die ich zum Testen verwendet habe kann man unter github.com finden.

transformer_batch_test.py
https://gist.github.com/msoftware/99515f4348440abe77b5dce46dcec810

transformer_no_batch_test.py
https://gist.github.com/msoftware/64f8576ab2a290af2e50b20c26ad0304

Demo Videos

Die folgenden 2 Videos zeigen die Tests, die ich gemacht habe. In den Videos passiert nicht viel, aber man sieht die Auslastung der GPUs und des VRAM und die Leistungsaufnahme (MAXN Mode).

"deepseek-ai/deepseek-coder-7b-instruct-v1.5" Batch-Test Part 1
Sequenzielle Text-Generierung auf dem Jetson-Orin 64GB Developer Kit
"deepseek-ai/deepseek-coder-7b-instruct-v1.5" Batch-Test Part 2
Parallele Text-Generierung auf dem Jetson-Orin 64GB Developer Kit

Fazit

Die Nutzung von Transformer-Modellen zur parallelen Generierung von Texte in einem Batch erweist sich als sehr nützlich, um die Verarbeitungsgeschwindigkeit zu steigern und Ressourcen effizienter zu nutzen. Im Vergleich zur sequenziellen Generierung der Texte ermöglicht die Parallelisierung eine bessere Auslastung der Hardware und damit eine verbesserte Geschwindigkeit. Dieser Ansatz ist besonders sinnvoll, wenn man vergleichbar kleine Modelle auf einer GPU mit ausreichend Speicher und vielen parallelen Kernen ausführt. (Z.B. Jetson Orin Developer Kit mit 64GB Ram und 2048 Kernen)

Veröffentlicht in Allgemein