FR ▾
NSFW Video Generator

API sans censure pour les pipelines vidéo pour adultes

LLMs gratuits pour Python : modèles locaux vs API hébergée

Les LLMs gratuits pour Python se divisent en deux catégories : les modèles à poids ouverts que vous exécutez sur votre propre machine, et les endpoints hébergés qui coûtent quelques centimes. Ce guide les compare et vous fournit du code fonctionnel pour la route hébergée.

Mis à jour le

Illustration isométrique d'une machine locale connectée à un cluster de serveurs hébergés, comparant les LLMs locaux et hébergés

Points clés

  1. Les modèles locaux à poids ouverts ne coûtent rien par token mais nécessitent de la mémoire, du temps de configuration et de la maintenance.
  2. L'API hébergée est compatible OpenAI : installez le package openai, définissez l'URL de base, utilisez l'ID de modèle uncensored.
  3. Le streaming, l'appel de fonctions et le mode JSON fonctionnent tous via l'appel standard de complétions de chat.
  4. Une clé d'essai fournit $0,50 de crédit pendant 7 jours, avec 2 requêtes simultanées et 60 requêtes par minute.

Deux façons d'intégrer un LLM gratuit dans un script Python

Lorsque les gens recherchent des LLM gratuits pour Python, ils veulent généralement dire l'une des deux choses suivantes. La première est un modèle à poids ouverts que vous téléchargez et exécutez vous-même, en utilisant par exemple Ollama, llama.cpp ou la bibliothèque transformers de Hugging Face. La seconde est un endpoint hébergé qui coûte si peu, ou qui est accompagné d'un crédit d'essai suffisant, qu'il semble gratuit pour un prototype. Les deux sont légitimes et conviennent à des tâches différentes.

L'exécution locale signifie aucune facture par token et aucune donnée quittant votre machine. Cela signifie aussi que vous avez besoin de suffisamment de RAM ou de mémoire GPU pour le modèle que vous choisissez, que vous attendez les téléchargements, et que les petits modèles qui tiennent sur un ordinateur portable répondent moins bien que les grands. Une API hébergée supprime la question du matériel, mais vous payez par token une fois l'essai terminé. Cette page couvre les deux honnêtement, puis montre le code Python pour l'option hébergée sur ce site, qui est compatible OpenAI et fonctionne avec le package standard openai.

Modèles locaux et API hébergée côte à côte

QuestionFaites-le tourner vous-mêmeAPI hébergée prépayée
Coût par tokenAucun, mais vous payez pour le matériel et l'électricité$0,15 par 1M d'entrée, $0,50 par 1M de sortie
Temps de configurationInstaller le runtime, télécharger les poids, ajuster les paramètresInstaller un package, coller une clé
Longueur du contexteLimité par votre mémoire100 000 tokens, prompt plus complétion
ConcurrenceTout ce que votre machine peut gérer8 requêtes à la fois sur une clé complète, 2 sur une clé d'essai
RefusDépend des poids que vous choisissezAjusté pour répondre sans refus de contenu pour un usage adulte légal
Utilisation hors ligneOuiNon

Si vous disposez d'un GPU capable et que votre travail est privé ou hors ligne, le local est une bonne réponse et vous pouvez arrêter de lire ici. Si vous voulez un modèle plus grand sans posséder la machine, ou si vous voulez que votre script se comporte de la même manière sur un ordinateur portable, un serveur et un runner CI, la route hébergée est plus simple. De nombreux projets utilisent les deux : un petit modèle local pendant le développement, l'hébergé en production, commutés en changeant une seule URL de base.

Configurez l'endpoint hébergé en cinq minutes

Vous avez besoin d'une clé d'abord. Inscrivez-vous avec Google ou avec un e-mail et un mot de passe, puis réclamez le crédit d'essai de $0,50 en un clic sur la page des clés API. L'essai est valable 7 jours, un par personne, et ne nécessite aucun paiement. Ensuite, installez le SDK et gardez la clé hors de votre code source.

pip install openai
export NOTRACK_API_KEY="sk-your-key-here"

Le client nécessite deux modifications par rapport à une configuration OpenAI standard : l'URL de base et la clé. L'ID de modèle est uncensored, et un seul modèle est proposé.

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)

L'authentification est un en-tête Authorization: Bearer standard, que le SDK ajoute pour vous. Deux méthodes existent : POST /v1/chat/completions et GET /v1/models. Vous pouvez confirmer la connexion avec client.models.list(), qui renvoie l'ID de modèle disponible. La liste complète des paramètres se trouve sur la page de documentation.

Réponses en streaming

Pour tout ce qu'une personne regarde, utilisez le streaming. Définissez stream=True et itérez sur les chunks au fur et à mesure que les événements envoyés par le serveur arrivent. L'utilisation est signalée à la fin du flux, vous pouvez donc toujours enregistrer les comptes de tokens.

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)

Un détail surprend les gens : une requête en streaming occupe son slot de concurrence jusqu'à la fin du streaming. Sur une clé d'essai avec 2 slots, deux streams ouverts signifient qu'un troisième appel reçoit une erreur 429 avec le code concurrency. Consommez ou fermez toujours le stream.

Appel d'outils et mode JSON

L'endpoint prend en charge tools, tool_choice, le streaming tool_calls et les résultats envoyés en tant que role: "tool". Voici un aller-retour complet avec une fonction.

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)

Analysez toujours arguments de manière défensive ; le modèle le renvoie sous forme de chaîne JSON et tout modèle peut occasionnellement en produire un mal formé. Pour une sortie structurée sans outils, utilisez le mode JSON.

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"])

Dites le mot JSON et nommez les clés dans votre prompt, et gardez la température basse. Enveloppez json.loads dans un bloc try pour le code de production.

Limites de débit, erreurs et tentatives

Une clé complète permet 8 requêtes simultanées et 300 requêtes par minute. Une clé d'essai permet 2 et 60. Dépasser ces limites et vous obtenez une erreur HTTP 429 avec un code de rate_limited (trop par minute) ou concurrency (trop en même temps). En cas de surcharge temporaire, l'API renvoie également une 429, avec un en-tête Retry-After: 5. Le SDK réessaie certaines erreurs automatiquement ; pour un script qui diffuse des requêtes, un petit wrapper explicite est plus clair.

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))

Adapter max_workers à la limite de concurrence de votre clé évite la plupart des 429 avant qu'elles ne surviennent. Chaque réponse inclut également X-Request-Id, X-Balance-USD et deux en-têtes de limite de débit, que vous pouvez lire via client.chat.completions.with_raw_response.create(...) lorsque vous en avez besoin pour le débogage ou le support.

Comment choisir entre le local et l'hébergé

Évitez l'idéologie et répondez à quatre questions sur votre projet.

  1. Les données doivent-elles rester sur votre machine ? Si un contrat ou une habitude dit oui, exécutez localement. Les prompts hébergés ne sont pas utilisés pour l'entraînement ici, mais ils voyagent sur le réseau.
  2. Combien de mémoire avez-vous ? La taille du modèle détermine la qualité. Un ordinateur portable sans GPU dédié vous limite aux petits modèles, et les réponses le montreront. Un modèle hébergé vous donne un grand modèle avec une fenêtre de contexte de 100 000 tokens, ce qui est difficile à égaler à la maison.
  3. Combien de requêtes allez-vous envoyer ? Quelques centaines par semaine sont négligeables des deux côtés. Des centaines de milliers par mois transforment la facture d'hébergement en un montant réel, et une machine locale commence à sembler attrayante si elle reste inoccupée autrement. Faites le calcul : 100 000 requêtes de 1 000 tokens d'entrée et 500 tokens de sortie coûtent 100 000 x 0,0004 $ = 40 $.
  4. Avez-vous besoin que les refus soient gérés d'une certaine manière ? De nombreux modèles à poids ouverts sont livrés avec un comportement de refus intégré, et d'autres sont ajustés pour l'éliminer. Le modèle hébergé ici est ajusté pour répondre sans refus de contenu pour un usage adulte légal, donc vous n'avez pas besoin de chercher les bons poids.

Si vos réponses pointent dans les deux sens, commencez par l'hébergé pour la première semaine. L'essai ne coûte rien, et vous apprendrez ce dont vos prompts ont besoin avant d'acheter du matériel ou de télécharger un autre fichier de plusieurs gigaoctets.

Erreurs courantes dans les scripts Python

La plupart des problèmes rencontrés sont petits et réparables.

  • Mauvaise URL de base. Elle doit se terminer par /v1. Un suffixe manquant donne une erreur 404, pas un message utile. Imprimez client.base_url en cas de doute.
  • Clé dans le code. Lisez-la depuis une variable d'environnement, comme ci-dessus, et ajoutez votre fichier .env à .gitignore.
  • Mauvais nom de modèle. Le seul ID de modèle est uncensored. Les noms d'autres fournisseurs ne fonctionneront pas, alors changez-les lorsque vous portez du code.
  • Boucles non bornées. Une boucle d'appel d'outils qui ne se termine jamais est un bug coûteux. Limitez-la à, disons, cinq tours.
  • Ignorer le budget de contexte. Le prompt et la complétation partagent les 100 000 tokens. Si vous ajoutez chaque tour à l'infini, vous atteindrez inévitablement la limite. Réduisez ou résumez les anciens messages.
  • Supposer que le JSON est toujours valide. Même en mode JSON, vérifiez les clés dont vous avez besoin avant de les utiliser.

Lorsque quelque chose semble incorrect du côté du serveur, citez la valeur X-Request-Id de la réponse lorsque vous écrivez à support. Cela permet aux opérateurs de retrouver votre appel exact.

Ce que coûte l'option hébergée pour les tâches Python

Un appel de script typique avec 1 000 tokens d'entrée et 500 tokens de sortie coûte $0,00015 plus $0,00025, soit $0,0004. Le crédit d'essai de $0,50 couvre environ 1 250 de ces appels. Un rechargement de $20, le minimum, en couvre 50 000. Le crédit n'expire jamais, les requêtes échouées ou refusées ne sont pas facturées, et les prompts ne sont pas utilisés pour l'entraînement. Les rechargements vont jusqu'à $500 avec un bonus à partir de $50, et le paiement est en crypto, USDT sur TRC20 ou USDC sur Base. Consultez la page de prix pour les détails.

C'est du texte uniquement : pas d'images, audio, vidéo, embeddings ou fine-tuning. Et la règle stricte est l'absence de contenu sexuel impliquant des mineurs. Pour un projet Python nécessitant une génération de texte avec moins de refus, c'est toute la surface.

Questions et réponses

Quel package Python dois-je utiliser ?

Le package openai officiel. Définissez base_url sur https://api.nsfwvideogenerator.cc/v1, passez votre clé avec api_key et utilisez l'ID de modèle uncensored.

Puis-je utiliser LangChain ou d'autres frameworks ?

Tout client qui vous permet de définir une URL de base compatible OpenAI et une clé API devrait fonctionner, car l’API suit le format des complétions de chat. Pointez-le vers l’URL de base et utilisez uncensored comme nom de modèle.

Les modèles locaux gratuits sont-ils aussi bons qu'un modèle hébergé ?

Cela dépend du modèle et de votre matériel. Les modèles qui tiennent sur un ordinateur portable sont généralement plus petits et moins performants qu’un grand modèle hébergé, mais ils ne coûtent rien par token et fonctionnent hors ligne.

Comment éviter les erreurs 429 en Python ?

Maintenez les threads de travail à un niveau inférieur ou égal à votre limite de concurrence (2 sur une clé d'essai, 8 sur une clé complète), et réessayez après une courte pause lorsque vous obtenez une réponse rate_limited, concurrency ou Retry-After: 5.

Votre clé est à un formulaire de vous

Créez un compte, copiez la clé, modifiez l'URL de base. C'est toute la configuration.