Zwei Möglichkeiten, ein kostenloses LLM in ein Python-Skript zu integrieren
Wenn Leute nach kostenlosen LLMs für Python suchen, meinen sie meist eines von zwei Dingen. Das erste ist ein Open-Weight-Modell, das du herunterlädst und selbst ausführst, z. B. mit Ollama, llama.cpp oder der Hugging Face transformers-Bibliothek. Das zweite ist ein gehosteter Endpunkt, der so wenig kostet oder genug Trial-Guthaben bietet, dass er sich für einen Prototypen wie kostenlos anfühlt. Beide sind legitim und eignen sich für unterschiedliche Aufgaben.
Lokales Ausführen bedeutet keine Abrechnung pro Token und keine Daten, die deinen Rechner verlassen. Es bedeutet auch, dass du genug RAM oder GPU-Speicher für das gewählte Modell brauchst, auf Downloads wartest und dass kleine Modelle, die auf einen Laptop passen, schlechter abschneiden als große. Eine gehostete API eliminiert die Hardware-Frage, aber du zahlst pro Token, sobald das Testguthaben aufgebraucht ist. Diese Seite behandelt beide Optionen ehrlich und zeigt anschließend den Python-Code für die gehostete Option auf dieser Website, die OpenAI-kompatibel ist und mit dem Standardpaket openai funktioniert.
Lokale Modelle und gehostete API im Seitenvergleich
| Frage | Selbst betreiben | Gehostete Prepaid-API |
|---|---|---|
| Kosten pro Token | Keine, aber du zahlst für Hardware und Strom | $0,15 pro 1M Input, $0,50 pro 1M Output |
| Einrichtungszeit | Laufzeit installieren, Gewichte herunterladen, Einstellungen optimieren | Ein Paket installieren, einen Schlüssel einfügen |
| Kontextlänge | Begrenzt durch deinen Speicher | 100.000 Token, Prompt plus Vervollständigung |
| Parallelität | Was deine Maschine verarbeitet | 8 Anfragen gleichzeitig bei einem Voll-Key, 2 bei einem Trial-Key |
| Ablehnungen | Hängt von den gewählten Gewichten ab | Abgestimmt darauf, ohne Inhaltsablehnungen für legale Erwachsenennutzung zu antworten |
| Offline-Nutzung | Ja | Nein |
Wenn du eine leistungsfähige GPU hast und deine Arbeit privat oder offline ist, ist lokal eine gute Lösung und du kannst hier aufhören zu lesen. Wenn du ein größeres Modell möchtest, ohne die Maschine zu besitzen, oder wenn dein Skript auf einem Laptop, einem Server und einem CI-Läufer gleich aussehen soll, ist der gehostete Weg einfacher. Viele Projekte nutzen beides: ein kleines lokales Modell während der Entwicklung, das gehostete in der Produktion, umgeschaltet durch Änderung einer Base URL.
Richte den gehosteten Endpunkt in fünf Minuten ein
Du brauchst zuerst einen Schlüssel. Melde dich mit Google oder mit einer E-Mail und einem Passwort an und beanspruche das $0,50 Trial-Guthaben mit einem Klick auf der API-Schlüssel-Seite. Das Trial ist 7 Tage gültig, pro Person einmal und benötigt keine Zahlung. Installiere dann das SDK und halte den Schlüssel außerhalb deines Quellcodes.
pip install openai
export NOTRACK_API_KEY="sk-your-key-here"
Der Client benötigt zwei Änderungen gegenüber einer Standard-OpenAI-Einrichtung: die Base URL und den Schlüssel. Die Modell-ID ist uncensored, und es wird nur ein Modell angeboten.
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.nsfwvideogenerator.cc/v1",
api_key=os.environ["NOTRACK_API_KEY"],
)
resp = client.chat.completions.create(
model="uncensored",
messages=[
{"role": "system", "content": "You are a concise writing assistant."},
{"role": "user", "content": "Give me three title ideas for a noir short story."},
],
temperature=0.8,
)
print(resp.choices[0].message.content)
print(resp.usage)
Die Authentifizierung erfolgt über einen standardmäßigen Authorization: Bearer-Header, den das SDK für dich hinzufügt. Es gibt zwei Methoden: POST /v1/chat/completions und GET /v1/models. Du kannst die Verbindung mit client.models.list() überprüfen, das die verfügbare Modell-ID zurückgibt. Die vollständige Parameterliste findest du auf der Dokumentationsseite.
Streaming-Antworten
Für alles, was eine Person sieht, Streamen. Setze stream=True und iteriere über Chunks, wenn Server-Sent Events eintreffen. Die Nutzung wird am Ende des Streams gemeldet, sodass du Token-Anzahlen noch protokollieren kannst.
stream = client.chat.completions.create(
model="uncensored",
messages=[{"role": "user", "content": "Write a four-line poem about rain on a tin roof."}],
stream=True,
)
for chunk in stream:
if chunk.choices and chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="", flush=True)
usage = getattr(chunk, "usage", None)
if usage:
print("\n", usage)
Ein Detail überrascht viele: Eine gestreamte Anfrage belegt ihren Concurrency-Slot, bis der Stream endet. Bei einem Trial-Key mit 2 Slots bedeuten zwei offene Streams, dass ein dritter Aufruf einen 429-Fehler mit dem Code concurrency erhält. Konsumiere oder schließe den Stream immer.
Tool Calling und JSON-Modus
Der Endpunkt unterstützt tools, tool_choice, gestreamtes tool_calls und Ergebnisse, die als role: "tool" zurückgesendet werden. Hier ist eine vollständige Roundtrip mit einer Funktion.
import json
tools = [{
"type": "function",
"function": {
"name": "word_count",
"description": "Count the words in a piece of text.",
"parameters": {
"type": "object",
"properties": {"text": {"type": "string"}},
"required": ["text"],
},
},
}]
messages = [{"role": "user", "content": "How many words are in: the quick brown fox jumps"}]
first = client.chat.completions.create(
model="uncensored", messages=messages, tools=tools, tool_choice="auto"
)
msg = first.choices[0].message
if msg.tool_calls:
messages.append(msg)
for call in msg.tool_calls:
args = json.loads(call.function.arguments)
result = len(args["text"].split())
messages.append({
"role": "tool",
"tool_call_id": call.id,
"content": str(result),
})
final = client.chat.completions.create(model="uncensored", messages=messages, tools=tools)
print(final.choices[0].message.content)
Parst arguments immer defensiv; das Modell gibt es als JSON-Zeichenfolge zurück, und jedes Modell kann gelegentlich eine fehlerhafte erzeugen. Für strukturierte Ausgabe ohne Tools verwende den JSON-Modus.
resp = client.chat.completions.create(
model="uncensored",
messages=[
{"role": "system", "content": "Reply with a JSON object with keys title and tags (list of strings)."},
{"role": "user", "content": "Describe a lighthouse keeper's diary."},
],
response_format={"type": "json_object"},
temperature=0.2,
)
data = json.loads(resp.choices[0].message.content)
print(data["title"], data["tags"])
Sage das Wort JSON und benenne die Schlüssel in deinem Prompt, und halte die Temperatur niedrig. Verpacke json.loads in einen try-Block für Produktionscode.
Ratenlimits, Fehler und Wiederholungen
Ein Vollschlüssel erlaubt 8 parallele Anfragen und 300 Anfragen pro Minute. Ein Trial-Schlüssel erlaubt 2 und 60. Überschreitest du diese Werte, erhältst du HTTP 429 mit dem Code rate_limited (zu viele pro Minute) oder concurrency (zu viele gleichzeitig). Bei einer temporären Überlastung gibt die API ebenfalls 429 zurück, mit einem Retry-After: 5-Header. Das SDK wiederholt einige Fehler automatisch; für ein Skript, das viele Anfragen parallel sendet, ist ein kleiner expliziter Wrapper übersichtlicher.
import time
from concurrent.futures import ThreadPoolExecutor
from openai import RateLimitError
def ask(prompt, tries=4):
for attempt in range(tries):
try:
r = client.chat.completions.create(
model="uncensored",
messages=[{"role": "user", "content": prompt}],
max_tokens=300,
)
return r.choices[0].message.content
except RateLimitError:
time.sleep(5 * (attempt + 1))
raise RuntimeError("still rate limited")
prompts = [f"Summarize idea number {i} in one sentence." for i in range(20)]
with ThreadPoolExecutor(max_workers=2) as pool: # 8 on a full key
results = list(pool.map(ask, prompts))
Die Anpassung von max_workers an das Limit für parallele Anfragen deines API-Schlüssels verhindert die meisten 429-Fehler, bevor sie auftreten. Jede Antwort enthält auch X-Request-Id, X-Balance-USD und zwei Ratenlimit-Header, die du durch client.chat.completions.with_raw_response.create(...) lesen kannst, wenn du sie für die Fehlerbehebung oder den Support benötigst.
Wie du zwischen lokal und gehostet wählst
Überspringe die Ideologie und beantworte vier Fragen zu deinem Projekt.
- Müssen die Daten auf deiner Maschine bleiben? Wenn ein Vertrag oder eine Gewohnung ja sagt, führe lokal aus. Gehostete Prompts werden hier nicht zum Training verwendet, aber sie werden über das Netzwerk übertragen.
- Wie viel Arbeitsspeicher hast du? Die Modellgröße bestimmt die Qualität. Ein Laptop ohne dedizierte GPU beschränkt dich auf kleine Modelle, und die Antworten werden dies zeigen. Ein gehostetes Modell gibt dir ein großes mit einem 100.000-Token-Kontextfenster, was zu Hause schwer zu erreichen ist.
- Wie viele Anfragen wirst du senden? Ein paar hundert pro Woche sind auf beiden Seiten trivial. Hunderttausende pro Monat machen die gehostete Rechnung zu einer echten Zahl, und eine lokale Maschine sieht attraktiv aus, wenn sie sonst untätig ist. Rechne die Summe aus: 100.000 Anfragen mit 1.000 Input- und 500 Output-Token kosten 100.000 x $0,0004 = $40.
- Musst du Ablehnungen auf eine bestimmte Weise handhaben? Viele Open-Weight-Modelle liefern mit eingebautem Ablehnungsverhalten, andere sind darauf abgestimmt, es zu entfernen. Das gehostete Modell hier ist darauf abgestimmt, ohne Inhaltsablehnungen für die rechtmäßige Nutzung durch Erwachsene zu antworten, sodass du nicht nach den richtigen Gewichten suchen musst.
Wenn deine Antworten in beide Richtungen zeigen, beginne mit der gehosteten Variante für die erste Woche. Das Trial kostet nichts, und du lernst, was deine Prompts benötigen, bevor du Hardware kaufst oder eine weitere mehr-Gigabyte-Datei herunterlädst.
Häufige Fehler in Python-Skripten
Die meisten Probleme, auf die Menschen stoßen, sind klein und beherrschbar.
- Falsche Base URL. Sie muss mit
/v1enden. Ein fehlendes Suffix gibt einen 404-Fehler, keine hilfreiche Nachricht. Gibclient.base_urlaus, wenn du unsicher bist. - API-Schlüssel im Code. Lies ihn aus einer Umgebungsvariable, wie oben, und füge deine
.env-Datei zu.gitignorehinzu. - Falscher Modellname. Die einzige Modell-ID ist
uncensored. Namen anderer Anbieter funktionieren nicht, also ändere sie, wenn du Code portierst. - Endlose Schleifen. Eine Tool-Calling-Schleife, die nie endet, ist ein teurer Fehler. Begrenze sie auf beispielsweise fünf Runden.
- Ignorieren des Kontextbudgets. Prompt und Antwort teilen sich die 100.000 Token. Wenn du jede Runde anhängst, wirst du irgendwann das Limit erreichen. Kürze oder fasse ältere Nachrichten zusammen.
- Die Annahme, dass JSON immer gültig ist. Prüfe auch im JSON-Modus die benötigten Schlüssel, bevor du sie verwendest.
Wenn auf Serverseite etwas falsch aussieht, zitiere den X-Request-Id-Wert aus der Antwort, wenn du support schreibst. So können die Support-Mitarbeiter deinen genauen Aufruf finden.
Was die gehostete Option für Python-Projekte kostet
Ein typischer Script-Aufruf mit 1.000 Input- und 500 Output-Token kostet $0,00015 plus $0,00025, also $0,0004. Das $0,50-Testguthaben deckt etwa 1.250 davon ab. Eine Aufladung mit 20 $, dem Mindestbetrag, deckt 50.000 ab. Guthaben verfällt nie, fehlgeschlagene oder abgelehnte Anfragen werden nicht berechnet, und Prompts werden nicht zum Training verwendet. Aufladungen gehen bis 500 $ mit einem Bonus ab 50 $, und die Zahlung erfolgt in Krypto, USDT auf TRC20 oder USDC auf Base. Sieh dir die Preisseite für die Details an.
Es ist nur Text: keine Bilder, Audio, Video, Embeddings oder Fine-Tuning. Und die eine harte Regel ist: keine sexuellen Inhalte mit Minderjährigen. Für ein Python-Projekt, das Textgenerierung mit weniger Ablehnungen benötigt, ist das der gesamte Umfang.
