Künstliche Intelligenz
Asynchrone LLM-API-Anfragen in Python: Ein umfassender Leitfaden

Als Entwickler und Data-Scientists stoßen wir oft auf die Notwendigkeit, mit diesen leistungsstarken Modellen über APIs zu interagieren. Wenn jedoch unsere Anwendungen an Komplexität und Umfang wachsen, wird die Notwendigkeit effizienter und leistungsstarker API-Interaktionen entscheidend. Hier kommt die asynchrone Programmierung ins Spiel, die es uns ermöglicht, die Durchsatzleistung zu maximieren und die Latenz zu minimieren, wenn wir mit LLM-APIs arbeiten.
In diesem umfassenden Leitfaden werden wir die Welt der asynchronen LLM-API-Anfragen in Python erkunden. Wir werden alles von den Grundlagen der asynchronen Programmierung bis hin zu fortgeschrittenen Techniken für die Verarbeitung komplexer Workflows behandeln. Am Ende dieses Artikels werden Sie ein solides Verständnis dafür haben, wie Sie die asynchrone Programmierung nutzen können, um Ihre LLM-basierten Anwendungen zu optimieren.
Bevor wir uns auf die spezifischen Aspekte asynchroner LLM-API-Anfragen einlassen, sollten wir eine solide Grundlage in asynchroner Programmierung schaffen.
Asynchrone Programmierung ermöglicht die gleichzeitige Ausführung mehrerer Operationen ohne Blockierung des Hauptthreads. In Python wird dies hauptsächlich durch das asyncio-Modul erreicht, das eine Framework für die Erstellung von konkurrierendem Code mit Coroutinen, Ereignisschleifen und Futures bietet.
Schlüsselkonzepte:
- Coroutinen: Funktionen, die mit async def definiert sind und die pausiert und fortgesetzt werden können.
- Ereignisschleife: Der zentrale Ausführungsmechanismus, der asynchrone Aufgaben verwaltet und ausführt.
- Wartbare Objekte: Objekte, die mit dem await-Schlüsselwort verwendet werden können (Coroutinen, Aufgaben, Futures).
Hier ist ein einfaches Beispiel, um diese Konzepte zu veranschaulichen:
import asyncio
async def greet(name):
await asyncio.sleep(1) # Simuliere eine I/O-Operation
print(f"Hello, {name}!")
async def main():
await asyncio.gather(
greet("Alice"),
greet("Bob"),
greet("Charlie")
)
asyncio.run(main())
In diesem Beispiel definieren wir eine asynchrone Funktion greet, die eine I/O-Operation mit asyncio.sleep() simuliert. Die main-Funktion verwendet asyncio.gather(), um mehrere Begrüßungen gleichzeitig auszuführen. Trotz der Verzögerung durch die Sleep-Funktion werden alle drei Begrüßungen nach etwa 1 Sekunde ausgegeben, was die Leistungsfähigkeit der asynchronen Ausführung demonstriert.
Die Notwendigkeit von Async in LLM-API-Anfragen
Wenn wir mit LLM-APIs arbeiten, stoßen wir oft auf Szenarien, in denen wir mehrere API-Anfragen stellen müssen, entweder sequenziell oder parallel. Traditionelle synchrone Code kann zu erheblichen Leistungsengpässen führen, insbesondere bei der Verarbeitung von Operationen mit hoher Latenz wie Netzwerkanfragen an LLM-Dienste.
Betrachten wir ein Szenario, in dem wir Zusammenfassungen für 100 verschiedene Artikel mit einer LLM-API erstellen müssen. Mit einem synchronen Ansatz würde jede API-Anfrage blockieren, bis sie eine Antwort erhält, was möglicherweise mehrere Minuten dauern kann, um alle Anfragen abzuschließen. Ein asynchroner Ansatz ermöglicht es uns hingegen, mehrere API-Anfragen gleichzeitig zu initiieren, was die Gesamtausführungszeit erheblich reduziert.
Einrichten Ihrer Umgebung
Um mit asynchronen LLM-API-Anfragen zu beginnen, müssen Sie Ihre Python-Umgebung mit den erforderlichen Bibliotheken einrichten. Hier sind die Anforderungen:
- Python 3.7 oder höher (für native asyncio-Unterstützung)
- aiohttp: Eine asynchrone HTTP-Client-Bibliothek
- openai: Der offizielle OpenAI Python-Client (wenn Sie OpenAI-GPT-Modelle verwenden)
- langchain: Ein Framework für die Erstellung von Anwendungen mit LLMs (optional, aber empfehlenswert für komplexe Workflows)
Sie können diese Abhängigkeiten mit pip installieren:
pip install aiohttp openai langchain <div class="relative flex flex-col rounded-lg">
Grundlegende asynchrone LLM-API-Anfragen mit asyncio und aiohttp
Lassen Sie uns mit einer einfachen asynchronen Anfrage an eine LLM-API beginnen, die aiohttp verwendet. Wir verwenden OpenAI-GPT-3.5-API als Beispiel, aber die Konzepte gelten auch für andere LLM-APIs.
import asyncio
import aiohttp
from openai import AsyncOpenAI
async def generate_text(prompt, client):
response = await client.chat.completions.create(
model="gpt-3.5-turbo",
messages=[{"role": "user", "content": prompt}]
)
return response.choices[0].message.content
async def main():
prompts = [
"Erkläre Quantencomputing in einfachen Worten.",
"Schreibe ein Haiku über künstliche Intelligenz.",
"Beschreibe den Prozess der Photosynthese."
]
async with AsyncOpenAI() as client:
tasks = [generate_text(prompt, client) for prompt in prompts]
results = await asyncio.gather(*tasks)
for prompt, result in zip(prompts, results):
print(f"Prompt: {prompt}\nResponse: {result}\n")
asyncio.run(main())
In diesem Beispiel definieren wir eine asynchrone Funktion generate_text, die eine Anfrage an die OpenAI-API mit dem AsyncOpenAI-Client stellt. Die main-Funktion erstellt mehrere Aufgaben für verschiedene Prompts und verwendet asyncio.gather(), um sie gleichzeitig auszuführen.
Dieser Ansatz ermöglicht es uns, mehrere Anfragen an die LLM-API gleichzeitig zu senden, was die Gesamtausführungszeit erheblich reduziert.
Fortgeschrittene Techniken: Batch-Verarbeitung und Konkurrenzkontrolle
Während das vorherige Beispiel die Grundlagen asynchroner LLM-API-Anfragen demonstriert, erfordern reale Anwendungen oft anspruchsvollere Ansätze. Lassen Sie uns zwei wichtige Techniken erkunden: Batch-Verarbeitung und Konkurrenzkontrolle.
Batch-Verarbeitung: Wenn Sie mit einer großen Anzahl von Prompts arbeiten, ist es oft effizienter, sie in Gruppen zu bündeln, anstatt für jeden Prompt eine separate Anfrage zu stellen. Dies reduziert den Overhead mehrerer API-Anfragen und kann zu einer besseren Leistung führen.
import asyncio
from openai import AsyncOpenAI
async def process_batch(batch, client):
responses = await asyncio.gather(*[
client.chat.completions.create(
model="gpt-3.5-turbo",
messages=[{"role": "user", "content": prompt}]
) for prompt in batch
])
return [response.choices[0].message.content for response in responses]
async def main():
prompts = [f"Erzähle mir eine Tatsache über die Zahl {i}" for i in range(100)]
batch_size = 10
async with AsyncOpenAI() as client:
results = []
for i in range(0, len(prompts), batch_size):
batch = prompts[i:i+batch_size]
batch_results = await process_batch(batch, client)
results.extend(batch_results)
for prompt, result in zip(prompts, results):
print(f"Prompt: {prompt}\nResponse: {result}\n")
asyncio.run(main())
Konkurrenzkontrolle: Obwohl asynchrone Programmierung eine gleichzeitige Ausführung ermöglicht, ist es wichtig, die Konkurrenz zu kontrollieren, um den API-Server nicht zu überlasten oder Rate-Limits zu überschreiten. Wir können asyncio.Semaphore für diesen Zweck verwenden.
import asyncio
from openai import AsyncOpenAI
async def generate_text(prompt, client, semaphore):












