TR ▾
API anahtarı al

Python'da Ollama API'si ve Barındırılan Alternatif

Python'da Ollama API'si yaklaşık on satır sürer ve aynı kod yapısı barındırılan bir uç noktada da çalışır. Bu makale her ikisini de gösterir ve hangisini seçmeniz gerektiğini açıklar.

güncellendi

Temel noktalar

  • Ollama, 11434 portunda dinler ve yerel bir API ile OpenAI tarzı /v1 uç noktası sunar.
  • ollama paketi, ham HTTP istekleri ve OpenAI SDK'sı hepsi çalışır; OpenAI SDK'sı en taşınabilir olandır.
  • Barındırılan bir API'ye geçmek temel URL'yi, anahtarı ve model adını değiştirmeyi gerektirir.
  • Yerel kullanım çevrimdışı çalışma ve sabit donanım için en iyisidir; GPU'nuz yoksa barındırılan daha basittir.
Bulut sunucusuna parlayan bir kablo ile bağlı yerel bir bilgisayar, yerel ve barındırılan LLM API'lerini temsil eder

Kısa özet

ollama api python araması yaparsanız, genellikle üç şeyden birini yapmak istersiniz: kendi makinenizde çalışan bir modele çağrı yapmak, ondan token'ları akış olarak almak veya aynı betiği başka bir yerde çalıştırmak. Ollama size üçünü de sunar. Varsayılan olarak http://localhost:11434 adresinde yerel bir sunucu çalıştırır ve ona ollama Python paketiyle, ham HTTP ile veya /v1 yoluna işaret eden herhangi bir OpenAI istemcisiyle konuşursunuz.

Buradaki dikkat edilmesi gereken nokta modelin donanımınızda çalışması gerektiğidir. İyi bir GPU'su olmayan bir dizüstü bilgisayar büyük modellerde yavaş olur ve bir sunucu da buna uygun değildir. Bu durum için barındırılan OpenAI uyumlu bir API daha kolay bir yoldur ve istek formatı aynı olduğu için geçiş yapmak üç satır yapılandırma maliyetine mal olur. Her iki yol da aşağıda, yapıştırabileceğiniz kodlarla ele alınmıştır.

Yerel bir modeli ollama paketiyle çağırma

Ollama'yı yükleyin, bir model çekin ve sunucunun çalıştığından emin olun. Ardından Python istemcisini yükleyin:

pip install ollama
ollama pull llama3.2

Temel bir sohbet isteği şöyle görünür. Model adı, çektiğiniz modele bağlıdır; llama3.2 sadece bir örnektir.

import ollama

response = ollama.chat(
    model="llama3.2",
    messages=[{"role": "user", "content": "Explain DNS in two sentences."}],
)
print(response["message"]["content"])

Akış

stream=True parametresini geçerseniz, tek bir yanıt yerine parçaların bir yineleyicisi (iterator) alırsınız. Her parça, yanıtın bir parçasını message.content içinde taşır.

import ollama

stream = ollama.chat(
    model="llama3.2",
    messages=[{"role": "user", "content": "Write a haiku about servers."}],
    stream=True,
)
for chunk in stream:
    print(chunk["message"]["content"], end="", flush=True)
print()

İstemciyi başka bir makineye yönlendirme

Ollama farklı bir ana makinede çalışıyorsa, açık bir adresle bir istemci oluşturun, örneğin ollama.Client(host="http://192.168.1.20:11434"). Varsayılan olarak sunucu yalnızca yerel makinede dinler, bu nedenle uzaktan erişim için sunucu tarafında bilinçli bir ayar gerekir. Önünde bir proxy ve kimlik doğrulama olmadan genel internete açmayın, çünkü yerel API'nin kendi anahtarı kontrolü yoktur.

requests ile düz HTTP

Pakete hiç ihtiyacınız yok. Yerel sohbet uç noktası POST /api/chat şeklindedir. Akış burada varsayılandır ve akış, SSE değil, satır sonu ile ayrılmış JSON'dur. Tek bir nesne döndürmesini istiyorsanız "stream": false ayarlayın.

import requests

r = requests.post(
    "http://localhost:11434/api/chat",
    json={
        "model": "llama3.2",
        "messages": [{"role": "user", "content": "Name three HTTP status codes."}],
        "stream": False,
    },
    timeout=120,
)
r.raise_for_status()
print(r.json()["message"]["content"])

Cömert bir zaman aşımı ayarlayın. Çekmeden sonraki ilk istek, modeli belleğe yüklemek zorundadır ve bu, sonraki isteklerden çok daha uzun sürebilir.

Akışı manuel olarak okumak yalnızca birkaç satır daha fazla kod gerektirir. requests.post(..., stream=True) çağrısı yapın, r.iter_lines() üzerinde döngü kurun, boş satırları atlayın ve her biri için json.loads çalıştırın. Her nesne yanıtın küçük bir parçasını içerir ve sonuncusu "done": true değerine sahiptir. Bu, başka bir paket kurmak istemediğiniz minimal bir kapsayıcıda kullanışlıdır ve kütüphanenin sizin için ne yaptığını netleştirir. Barındırılan API farklı bir şekilde akış yapar, data: ile başlayan SSE satırları olarak, bu da taşınabilir kodda akışı sizin için ayrıştırmak üzere OpenAI SDK'sını kullanmanın bir başka nedenidir.

Ollama ile OpenAI SDK'sını kullanma

Ollama ayrıca /v1 altında bir OpenAI tarzı uç nokta da sunar. Bu, resmi openai paketinin çalıştığı ve özel bir base URL ayarlamanıza izin veren yazılımın çoğunun çalıştığı anlamına gelir. Anahtar SDK tarafından gerekli kılınır ancak yerel Ollama tarafından yok sayılır, bu nedenle herhangi bir dize işe yarar.

from openai import OpenAI

client = OpenAI(base_url="http://localhost:11434/v1", api_key="ollama")
resp = client.chat.completions.create(
    model="llama3.2",
    messages=[{"role": "user", "content": "Give me a one-line summary of TCP."}],
)
print(resp.choices[0].message.content)

Bu en faydalı formdur, çünkü kodunuzu sunucudan ayırır. Aynı işlev bugün yerel bir modelle ve yarın başka bir şeyle konuşabilir, bu bir sonraki bölümdür.

Barındırılan API'de aynı kod

Buradaki barındırılan seçenek, bağımsız bir sağlayıcı tarafından yönetilen ve yasal yetişkin kullanımı için içerik reddi olmadan yanıt verecek şekilde ayarlanmış uncensored tek bir modele sahip OpenAI uyumlu bir API'dir. Sadece metin desteği vardır. Base URL https://api.ollamaapi.cc/v1 şeklindedir ve API anahtarı sayfası üzerinden Bearer anahtarı ile kimlik doğrulaması yaparsınız.

Hedefi ortam değişkenlerinden okuyan bir sürüm burada, barındırılan değerler varsayılan olarak. Yerel sunucunuza geri dönmek için iki değişkeni dışa aktarın ve başka hiçbir şeyi değiştirmeyin.

import os
from openai import OpenAI

client = OpenAI(
    base_url=os.getenv("LLM_BASE_URL", "https://api.ollamaapi.cc/v1"),
    api_key=os.getenv("LLM_API_KEY", "YOUR_API_KEY"),
)
MODEL = os.getenv("LLM_MODEL", "uncensored")

resp = client.chat.completions.create(
    model=MODEL,
    messages=[
        {"role": "system", "content": "You are a concise assistant."},
        {"role": "user", "content": "List four uses of a message queue."},
    ],
    temperature=0.7,
)
print(resp.choices[0].message.content)

Yerel çalıştırmalar için LLM_BASE_URL=http://localhost:11434/v1, LLM_API_KEY=ollama ve LLM_MODEL=llama3.2 ayarlayın. hızlı başlangıç aynı kurulumu curl ve Node ile içerir.

Barındırılan tarafta akış, JSON modu ve araçlar

Barındırılan uç noktası SSE üzerinden akış, JSON modu, fonksiyon çağırma ve standart örnekleme parametrelerini (temperature, top_p, stop, seed ve cezalar) destekler. SDK ile akış, herhangi bir OpenAI tarzı sunucu için yazacağınız döngüyle aynıdır:

stream = client.chat.completions.create(
    model="uncensored",
    messages=[{"role": "user", "content": "Tell a two-paragraph story about a lighthouse."}],
    stream=True,
    stream_options={"include_usage": True},
)
for chunk in stream:
    if chunk.choices and chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end="", flush=True)

Yapılandırılmış çıktı için response_format={"type": "json_object"} ayarlayın ve istemde JSON istediğinizi belirtin. Her durumda yine de bir try bloğu içinde ayrıştırmalısınız; bir model hala beklemediğiniz bir şey döndürebilir.

Yerel kullanıma kıyasla kodda önemli olan bir fark sınırlamalardır. Tam bir anahtar 8 eşzamanlı istek ve dakika başına 300 istek izni verir ve akışlı bir istek, akış bitene kadar slotunu korur. İstekleri iş parçacıklarıyla dağıtırsanız, havuzu 8 ile sınırlayın ve varsa HTTP 429 durumunda Retry-After başlığını kullanarak yeniden deneyin.

Bir konuşmayı sürdürme

Ne yerel ne de barındırılan sohbet uç noktası çağrılar arasında bir şey hatırlamaz. Sunucu yalnızca gönderdiğiniz mesajları görür, bu nedenle bir sohbet botu eklediğiniz ve yeniden gönderdiğiniz bir listedir. Bu desen her iki hedef için de aynıdır, bu da OpenAI tarzı istemciyi varsayılan olarak tutmanın bir başka nedenidir.

history = [{"role": "system", "content": "You are a helpful assistant."}]

def ask(text):
    history.append({"role": "user", "content": text})
    resp = client.chat.completions.create(model=MODEL, messages=history)
    answer = resp.choices[0].message.content
    history.append({"role": "assistant", "content": answer})
    return answer

print(ask("Pick a name for a hiking app."))
print(ask("Give me a tagline for it."))

İki pratik not. Birincisi, yerel modellerin ayarladığınız ve belleğin tutması gereken bir bağlam penceresi uzunluğu vardır; geçmiş buna ulaşırsa, eski konuşmalar kesilir veya ayarlara bağlı olarak çağrı başarısız olur. Barındırılan model, tamamlama dahil olmak üzere 100.000 token'lık bir pencere kabul eder ki bu, çoğu sohbet için çok daha fazlasıdır, ancak uzun geçmişler yine de her adımda girdi token'larına mal olur. İkincisi, bir geçmiş uzun olduğunda, tümünü yeniden göndermek yerine en eski konuşmaları tek bir kısa mesajda özetleyin. Bu, her iki backend'de de gecikme süresini ve maliyeti sabit tutar.

Kibarca yeniden deneme

Barındırılan API'de geçici bir aşırı yüklenme durumunda HTTP 429 yanıtı Retry-After: 5 başlığıyla döner. Küçük bir sarmalayıcı bunu yönetir:

import time
from openai import RateLimitError

def chat_with_retry(messages, tries=4):
    for attempt in range(tries):
        try:
            return client.chat.completions.create(model=MODEL, messages=messages)
        except RateLimitError:
            time.sleep(5 * (attempt + 1))
    raise RuntimeError("still rate limited")

Yerel Ollama sizi hız limitiyle sınırlamaz, ancak model meşgulken istekleri kuyruğa alır, bu nedenle aynı sarmalayıcı orada da zarar vermez.

Yerel mi barındırılan mı: nasıl karar verilir

Genel olarak hiçbir seçim diğerinden daha iyi değildir. Aşağıdaki noktaları bir kontrol listesi olarak kullanın.

  • Yerel Ollama'yı seçin eğer çevrim dışı çalışmanız gerekiyorsa, verilerin makineden asla ayrılmaması gerekiyorsa, zaten uygun bir GPU'nuz varsa veya hızlıca birçok farklı açık modeli denemek istiyorsanız.
  • Barındırılan bir API seçin eğer GPU'nuz yoksa, küçük bir VPS'te veya CI'da çalışıyorsanız, birden fazla kişi veya hizmet tek bir arka ucu paylaşıyorsa veya belleği kendiniz boyutlandırmadan uzun bir bağlam penceresi istiyorsanız. Barındırılan model, 100.000 token'a kadar prompt ve tamamlama kabul eder.
  • Geliştirme sırasında her ikisini de karıştırın: yerel olarak iterasyon yapın, ardından üretim için ortam değişkenleri aracılığıyla barındırılan URL'ye yönlendirin.

Barındırılan kullanım token başına faturalandırılır, 1M girdi token başına $0.15 ve 1M çıktı token başına $0.50, ön ödemeli krediden. fiyatlandırma sayfası bakiye yükleme miktarlarını listeler ve yeni hesaplar tek tıkla $0.50 deneme kredisi alabilir, kart gerekmez. İstemler eğitim için kullanılmaz.

Karşılaşacağınız hatalar

BelirtiOlası nedenÇözüm
11434 portunda bağlantı reddedildiOllama sunucusu çalışmıyorUygulamayı başlatın veya ollama serve komutunu çalıştırın
Model bulunamadıModel hiç çekilmedi veya adında bir yazım hatası varollama list çalıştırın, ardından ollama pull kullandığınız model adını çekin
İlk çağrı zaman aşımına uğradıModel hala yükleniyorZaman aşımını artırın veya bir ısınma isteği gönderin
Barındırılan API'de kimlik doğrulama hatasıEksik veya yanlış Bearer anahtarıLLM_API_KEY ve base URL'i kontrol edin
HTTP 429 kodu concurrency ile8'den fazla istek devam ediyor (deneme anahtarında 2)İşçi sayısını düşürün
HTTP 429 kodu rate_limited ileDakika başına istek sınırının üzerine çıkmaGeri çekilin ve yeniden deneyin

Barındırılan taraftaki başarısız veya reddedilen istekler için ücret alınmaz, bu nedenle yeniden deneme mantığı başarısız denemeler için size maliyet çıkarmaz.

Sorular ve cevaplar

Varsayılan Ollama API adresi nedir?

Yerel bir Ollama sunucusu http://localhost:11434 adresinde dinler. Yerel uç noktalar /api altında, örneğin /api/chat ve OpenAI tarzı uç nokta /v1 altında bulunur.

Ollama ile OpenAI Python SDK'sını kullanabilir miyim?

Evet. base_url'i http://localhost:11434/v1 olarak ayarlayın ve API anahtarı olarak herhangi bir dize geçirin. SDK, ardından yerel modelinize standart sohbet tamamlama isteklerini gönderir.

Ollama'dan barındırılan bir API'ye nasıl geçiş yaparım?

Temel URL'yi, anahtarı ve model adını değiştirin. Kodunuz bunları ortam değişkenlerinden okuyorsa, kod değişikliğine gerek yoktur.

Barındırılan API tarafımda GPU olmadan çalışır mı?

Evet. Model sağlayıcıda çalışır, bu nedenle betiğinizin yalnızca bir internet bağlantısına ve bir Bearer anahtarına ihtiyacı vardır. Ön ödemeli krediden token başına ödeme yaparsınız.

Anahtarınız tek bir formun uzağında

Bir hesap oluşturun, anahtarı kopyalayın ve base URL'yi değiştirin. Kurulum bu kadar basit.

API anahtarı al