PL ▾
NSFW Video Generator

API bez cenzury dla potoków wideo dla dorosłych

Darmowe LLM dla Pythona: Modele lokalne vs API hostowane

Darmowe LLM dla Pythona dzielą się na dwa rodzaje: modele o otwartych wagach uruchamiane na własnym sprzęcie oraz endpointy hostowane, które kosztują kilka centów. Ten przewodnik porównuje je i dostarcza działającego kodu dla opcji hostowanej.

Zaktualizowano

Izometryczna ilustracja lokalnej maszyny połączonej z klastrami serwerów hostowanych, porównująca lokalne i hostowane LLM

Kluczowe punkty

  1. Lokalne modele o otwartych wagach nie kosztują nic za token, ale wymagają pamięci, czasu na konfigurację i utrzymania.
  2. API hostowane jest zgodne z OpenAI: zainstaluj pakiet openai, ustaw bazowy URL, użyj ID modelu uncensored.
  3. Strumieniowanie, wywoływanie funkcji i tryb JSON działają przez standardowe wywołanie chat completions.
  4. Klucz trial daje $0.50 kredytu na 7 dni, z 2 równoległymi zapytaniami i limitem 60 zapytań na minutę.

Dwa sposoby na dodanie darmowego LLM do skryptu Python

Gdy ludzie szukają darmowych LLM dla Pythona, zwykle mają na myśli jedną z dwóch rzeczy. Pierwsza to model o otwartych wagach, który pobierasz i uruchamiasz samodzielnie, używając np. Ollama, llama.cpp lub biblioteki Hugging Face transformers. Druga to endpoint hostowany, który kosztuje tak mało lub ma wystarczająco dużo kredytu trial, że wydaje się darmowy dla prototypu. Oba są poprawne i pasują do różnych zadań.

Uruchomienie lokalnie oznacza brak rachunku za token i to, że dane nie opuszczają Twojego komputera. Oznacza to też, że potrzebujesz wystarczająco dużo pamięci RAM lub pamięci GPU dla wybranego modelu, czekasz na pobranie, a małe modele mieszczące się na laptopie odpowiadają gorzej niż duże. Hostowane API usuwa kwestię sprzętu, ale płacisz za token, gdy skończy się okres próbny. Ta strona omawia oba podejścia uczciwie, a następnie pokazuje kod Pythona dla opcji hostowanej na tej stronie, która jest kompatybilna z OpenAI i działa ze standardowym pakietem openai.

Modele lokalne i API hostowane obok siebie

PytanieUruchom samodzielnieHostowane API pre-paid
Koszt za tokenBrak, ale płacisz za sprzęt i energię$0,15 za 1M wejściowych, $0,50 za 1M wyjściowych
Czas konfiguracjiZainstaluj środowisko, pobierz wagi, dostosuj ustawieniaZainstaluj jeden pakiet, wklej klucz
Długość kontekstuOgraniczone przez Twój kontekst100 000 tokenów, prompt plus uzupełnienie
Równoległe zapytaniaCo obsłuży Twój sprzęt8 żądań jednocześnie dla pełnego klucza, 2 dla klucza trial
OdmowyZależy od wybranych wagDostosowany do odpowiadania bez odmów treści dla prawnego użytku przez dorosłych
Praca offlineTakNie

Jeśli masz wydajną kartę GPU i praca jest prywatna lub offline, lokalne rozwiązanie jest dobre i możesz przestać czytać. Jeśli chcesz większy model bez posiadania sprzętu lub chcesz, by Twój skrypt zachowywał się tak samo na laptopie, serwerze i w CI, opcja hostowana jest prostsza. Wiele projektów używa obu: małego modelu lokalnego podczas rozwoju, hostowanego w produkcji, przełączając je zmianą jednego bazowego URL.

Skonfiguruj endpoint hostowany w pięć minut

Najpierw potrzebujesz klucza. Zarejestruj się za pomocą Google lub e-maila i hasła, a następnie odbierz kredyt próbny $0,50 jednym kliknięciem na stronie klucza API. Kredyt próbny jest ważny przez 7 dni, jeden na osobę i nie wymaga płatności. Następnie zainstaluj SDK i trzymaj klucz z dala od kodu źródłowego.

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

Klient wymaga dwóch zmian względem standardowego ustawienia OpenAI: bazowego URL i klucza. ID modelu to uncensored, a dostępny jest tylko jeden model.

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)

Autoryzacja to standardowy nagłówek Authorization: Bearer, który dodaje za Ciebie SDK. Dostępne są dwie metody: POST /v1/chat/completions i GET /v1/models. Połączenie możesz potwierdzić za pomocą client.models.list(), które zwraca dostępne ID modelu. Pełna lista parametrów znajduje się na stronie dokumentacji.

Odpowiedzi strumieniowe

Dla wszystkiego, co ogląda człowiek, użyj strumieniowania. Ustaw stream=True i iteruj po fragmentach, gdy przychodzą zdarzenia wysyłane przez serwer (SSE). Użycie jest raportowane na końcu strumienia, więc nadal możesz logować liczbę tokenów.

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)

Jedna rzecz, która często myli użytkowników: żądanie strumieniowania zajmuje slot równoległości do momentu zakończenia strumienia. Na kluczu trial z 2 slotami dwa otwarte strumienie oznaczają, że trzecie wywołanie zwróci błąd 429 z kodem concurrency. Zawsze konsumuj lub zamykaj strumień.

Wywoływanie narzędzi i tryb JSON

Endpoint obsługuje tools, tool_choice, strumieniowane tool_calls i wyniki zwracane jako role: "tool". Oto kompletna transmisja z jedną funkcją.

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)

Zawsze parsuj arguments ostrożnie; model zwraca go jako ciąg JSON, a każdy model może czasami wyprodukować niepoprawny ciąg. Dla wyjścia strukturalnego bez narzędzi użyj trybu 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"])

Wymów słowo JSON i nazwij klucze w prompt, a utrzymaj niską temperaturę. Owiń json.loads w blok try dla kodu produkcyjnego.

Limity zapytań, błędy i retry

Pełny klucz pozwala na 8 równoległych zapytań i 300 zapytań na minutę. Klucz próbny pozwala na 2 i 60. Przekroczenie limitu skutkuje kodem HTTP 429 z kodem błędu rate_limited (zbyt wiele na minutę) lub concurrency (zbyt wiele naraz). Przy tymczasowym przeciążeniu API zwraca również 429 z nagłówkiem Retry-After: 5. SDK ponawia niektóre błędy automatycznie; dla skryptu rozpraszającego zapytania, mały jawny wrapper jest bardziej przejrzysty.

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

Dopasowanie max_workers do limitu równoległych zapytań klucza zapobiega większości błędów 429 zanim się zdarzą. Każda odpowiedź zawiera również X-Request-Id, X-Balance-USD i dwa nagłówki limitu zapytań, które możesz odczytać przez client.chat.completions.with_raw_response.create(...), gdy potrzebujesz ich do debugowania lub wsparcia.

Jak wybrać między lokalnym a hostowanym

Pomiń ideologię i odpowiedz na cztery pytania o swój projekt.

  1. Czy dane muszą pozostać na Twojej maszynie? Jeśli umowa lub nawyk nakazują tak, uruchom lokalnie. Prompty hostowane nie są używane do trenowania tutaj, ale podróżują przez sieć.
  2. Ile masz pamięci? Rozmiar modelu determinuje jakość. Laptop bez dedykowanej karty graficznej ogranicza Cię do małych modeli, a odpowiedzi to pokażą. Model hostowany daje Ci duży model z oknem kontekstu 100 000 tokenów, które trudno jest dorównać w domu.
  3. Ile wyślesz zapytań? Kilka setek w tygodniu to trywialna sprawa po obu stronach. Setki tysięcy na miesiąc zamienia rachunek za hosting na realną liczbę, a lokalna maszyna zaczyna wyglądać atrakcyjnie, jeśli w innym czasie stoi bezczynnie. Oblicz sumę: 100 000 zapytań po 1 000 tokenów wejściowych i 500 tokenów wyjściowych kosztuje 100 000 x $0,0004 = $40.
  4. Czy potrzebujesz specyficznej obsługi odrzuceń? Wiele modeli o otwartych wagach ma wbudowane zachowania odrzucania, a inne są dostrojone tak, aby je usuwać. Model hostowany tutaj jest dostrojony do odpowiadania bez odrzuceń treści dla prawnego użytku dorosłych, więc nie musisz polować na odpowiednie wagi.

Jeśli Twoje odpowiedzi wskazują w obie strony, zacznij od hostowanego na pierwszy tydzień. Darmowy kredyt próbny nic nie kosztuje, a nauczysz się, czego potrzebują Twoje prompty, zanim kupisz sprzęt lub pobierzesz kolejny wielgigaabajtowy plik.

Typowe błędy w skryptach Python

Większość problemów, na które natrafiają ludzie, jest mała i łatwa do naprawienia.

  • Zły endpoint. Musi kończyć się na /v1. Brakujący sufiks daje błąd 404, a nie pomocną wiadomość. Wypisz client.base_url, jeśli masz wątpliwości.
  • Klucz w kodzie. Odczytuj go ze zmiennej środowiskowej, jak wyżej, i dodaj swój plik .env do .gitignore.
  • Zła nazwa modelu. Jedynym ID modelu jest uncensored. Nazwy od innych dostawców nie zadziałają, więc zmień je podczas przenoszenia kodu.
  • Pętle nieograniczone. Pętla wywoływania narzędzia, która nigdy się nie kończy, to kosztowny błąd. Ogranicz ją do np. pięciu rund.
  • Ignorowanie budżetu kontekstu. Prompt i uzupełnienie dzielą 100 000 tokenów. Jeśli będziesz dołączać każdą turę w nieskończoność, w końcu trafisz w limit. Obetnij lub podsumuj stare wiadomości.
  • Zakładanie, że JSON jest zawsze poprawny. Nawet w trybie JSON sprawdzaj klucze, których potrzebujesz, przed ich użyciem.

Gdy po stronie serwera coś wygląda nieprawidłowo, podaj wartość X-Request-Id z odpowiedzi, pisząc do support. Pozwoli to operatorom zlokalizować Twoje konkretne zapytanie.

Koszt opcji hostowanej dla zadań w Pythonie

Typowe wywołanie skryptu z 1 000 tokenami wejściowymi i 500 tokenami wyjściowymi kosztuje $0,00015 plus $0,00025, czyli $0,0004. Kredyt próbny $0,50 pokrywa około 1 250 takich wywołań. Doładowanie za $20, minimum, pokrywa 50 000. Kredyt nie wygasa, nieudane lub odrzucone zapytania nie są rozliczane, a prompty nie są używane do trenowania. Doładowania sięgają $500 z bonusem od $50, a płatność jest w kryptowalutach, USDT na TRC20 lub USDC na Base. Szczegóły znajdziesz na stronie z cenami.

To tylko tekst: bez obrazów, audio, wideo, embeddingów ani fine-tuning. I jedna surowa zasada to brak treści seksualnych z udziałem nieletnich. Dla projektu Python potrzebującego generowania tekstu z mniejszą liczbą odrzuceń, to jest cały zakres.

Pytania i odpowiedzi

Jakiego pakietu Pythona potrzebuję?

Oficjalny pakiet openai. Ustaw base_url na https://api.nsfwvideogenerator.cc/v1, przekaż swój klucz jako api_key i użyj ID modelu uncensored.

Czy mogę użyć LangChain lub innych frameworków?

Każdy klient, który pozwala Ci ustawić bazowy URL i klucz kompatybilne z OpenAI, powinien działać, ponieważ API jest zgodne z formatem chat completions. Wskaż bazowy URL i użyj uncensored jako nazwy modelu.

Czy darmowe modele lokalne są tak dobre jak te hostowane?

Zależy od modelu i sprzętu. Modele mieszczące się na laptopie są zwykle mniejsze i słabsze niż duże modele hostowane, ale nie kosztują nic za token i działają offline.

Jak unikać błędów 429 w Pythonie?

Utrzymaj liczbę wątków roboczych na poziomie lub poniżej limitu równoległych zapytań (2 dla klucza próbnego, 8 dla pełnego) i ponawiaj zapytanie po krótkiej przerwie, gdy otrzymasz odpowiedź z limitem zapytań, limitem równoległych zapytań lub Retry-After: 5.

Twój klucz jest o jeden formularz stąd

Utwórz konto, skopiuj klucz, zmień bazowy URL. To cała konfiguracja.