JA ▾
API キーを取得

PythonでのOllama API、そしてホストエンドポイント

Ollama API Pythonクライアントを使用するには約10行で済みます:パッケージのインストール、サーバーの起動、チャットの呼び出しです。このチュートリアルではそれらの手順をカバーし、環境変数を変更するだけで同じプログラムをホストされたOpenAI互換エンドポイントで動作させる方法を示します。

更新

デスクトップタワーからサーバークラウドへと光を放つ蛇が巻き付き、Pythonがローカルコードをホスト環境に移行する様子を示しています
光るケーブルでローカルコンピュータとクラウドサーバーに接続されたチャットウィンドウ

カード不要。サインアップ後、ワンクリックで$0.50の無料テストクレジットを受け取れます(1人1回限り)。

API キーを取得

主要ポイント

  • pip install ollamaし、ポート11434でOllamaサーバーを起動し、取得したモデルでollama.chatを呼び出します。
  • ストリーミングはstream=Trueであり、message.contentを持つチャンクを返します。
  • モデルがない場合はResponseError、サーバーが停止している場合はConnectionErrorを捕捉します。
  • ホスト版を使用するには、OpenAI SDKに切り替え、ベースURL、キー、モデルを環境変数で設定します。

Pythonクライアントを設定する

まずOllama自体をインストールし、起動し、ターミナルからモデルをプルします:ollama pull llama3。サーバーはhttp://localhost:11434でリッスンします。その後、仮想環境でPythonパッケージをインストールします:

python -m venv .venv
source .venv/bin/activate
pip install ollama openai

ollamaパッケージは/api下のOllamaのネイティブルートにアクセスします。openaiパッケージはこのチュートリアルの後半、ターゲットがホストエンドポイントである場合に使用します。コーディング前に視覚的なツールを好む場合は、GUIでOllamaを使用するに関するノートをご覧ください。

ターミナルでollama listを実行してインストールを確認します。モデルがそこに表示されれば、Pythonはそれを見つけます。後で接続エラーが発生した場合、サーバーが実行されていない可能性があります。

最初のチャット呼び出し

これはollama api pythonの基礎を1つのスニペットにまとめたものです:システムメッセージ、ユーザーメッセージ、および2つのオプションが含まれます。

import ollama

resp = ollama.chat(
    model="llama3",
    messages=[
        {"role": "system", "content": "Answer in one short paragraph."},
        {"role": "user", "content": "What is a context window?"},
    ],
    options={"temperature": 0.4, "num_ctx": 8192},
)
print(resp["message"]["content"])

返信は辞書のようなオブジェクトであり、テキストはmessage.contentにあります。optionsで生成パラメータを設定できます。temperatureはランダム性を制御し、num_ctxはその呼び出しのコンテキストウィンドウの長さを設定します。Ollamaはデフォルトでかなり小さなコンテキストウィンドウを持ち、上げない限り、長いドキュメントを貼り付けても始まりを無視する回答が返ってくるので驚く人がいます。

マルチターンチャットでは、メッセージのリストを保持し、各返信を自分で追加します。Ollamaは、他のほとんどのチャットAPIと同様に、呼び出し間でステートレスです。

ストリーミングレスポンス

ストリーミングなしでは、完全な回答を待つ必要があります。stream=Trueを指定すると、関数はジェネレーターを返し、到着するたびにチャンクを出力します:

import ollama

for part in ollama.chat(
    model="llama3",
    messages=[{"role": "user", "content": "Explain recursion with a cooking analogy."}],
    stream=True,
):
    print(part["message"]["content"], end="", flush=True)

各チャンクには小さなmessage.contentが含まれます。最後のチャンクにはdoneがtrueに設定され、タイミングとトークン数を含みます。Webアプリでは、サーバー送信イベントまたはWebSocketを介してこれらのチャンクをブラウザに転送します。

実際に遭遇するエラー

2つの失敗が初心者の問題の大部分を占めます。

import ollama

try:
    ollama.chat(model="llama3", messages=[{"role": "user", "content": "hi"}])
except ollama.ResponseError as exc:
    if exc.status_code == 404:
        print("Model missing. Run: ollama pull llama3")
    else:
        raise
except ConnectionError:
    print("Cannot reach Ollama. Is the server running on port 11434?")

ResponseErrorからの404は、モデル名がプルしたものと一致しないことを意味します。名前にはタグが含まれるため、llama3とllama3:70bは異なるモデルです。接続エラーは、サーバーが起動していないか、localhostがホストではなくコンテナを指すコンテナ内にあることを意味します。その場合、正しいホストを持つクライアントを渡します:ollama.Client(host="http://host.docker.internal:11434")。

その他のパターンは一般的なOllama APIの間違いにまとめられています。

同じプログラム、ホストエンドポイント

ローカルモデルはメモリと速度によって制限されます。スクリプトをサーバーで実行する必要がある場合、多くの並列ジョブを処理する必要がある場合、または大きなウィンドウを使用する必要がある場合は、ホストエンドポイントの方が簡単です。トリックは、OpenAI SDKに対してプログラムを書き、ベースURL、キー、モデルを構成として扱うことです:

import os
from openai import OpenAI

client = OpenAI(
    base_url=os.environ.get("LLM_BASE_URL", "https://api.ollamansfw.com/v1"),
    api_key=os.environ["LLM_API_KEY"],
)
MODEL = os.environ.get("LLM_MODEL", "uncensored")

def ask(prompt, history=None):
    messages = (history or []) + [{"role": "user", "content": prompt}]
    out = ""
    for chunk in client.chat.completions.create(model=MODEL, messages=messages, stream=True):
        if chunk.choices and chunk.choices[0].delta.content:
            piece = chunk.choices[0].delta.content
            out += piece
            print(piece, end="", flush=True)
    return out

ask("Explain recursion with a cooking analogy.")

ローカルのOllamaの場合、LLM_BASE_URL=http://localhost:11434/v1、LLM_API_KEY=ollama(空でない文字列はすべて受け入れられます)およびLLM_MODEL=llama3を設定します。ホストAPIの場合、上記のデフォルト、実際のキー、およびモデルuncensoredを使用します。コードの他の部分は変更されません。

APIキーページでキーを取得します。新しいアカウントは、支払いなしでワンクリックで$0.50のトライアルを請求でき、7日間有効です。モデルは独立したプロバイダーからの1つのオープンウェイトモデルで、合法的な成人利用に対してコンテンツ拒否なしで回答するように調整されています。テキストのみであり、大手ラボの公式APIではありません。

並列で多くのプロンプトを実行

1台のマシン上のローカルモデルは通常、一度に1つのリクエストしか処理できないため、ループは逐次的になります。ホストエンドポイントは同時実行を許可し、バッチ作業を大幅に高速化します。ワーカー数をキーの制限以下に保ってください:フルキーの場合は8つの同時リクエスト、トライアルキーの場合は2つです。

from concurrent.futures import ThreadPoolExecutor
from openai import OpenAI

client = OpenAI(base_url="https://api.ollamansfw.com/v1", api_key="YOUR_KEY")

def summarize(text):
    r = client.chat.completions.create(
        model="uncensored",
        messages=[{"role": "user", "content": "Summarize in one line: " + text}],
        max_tokens=60,
    )
    return r.choices[0].message.content

docs = ["first text", "second text", "third text"]
with ThreadPoolExecutor(max_workers=6) as pool:
    results = list(pool.map(summarize, docs))
print(results)

6つのワーカーは8の制限を下回る余裕を残します。ワーカーが429を受け取った場合、OpenAI SDKはデフォルトで数回再試行しますが、長時間の実行には独自のバックオフを追加してください。また、ストリーミングされたリクエストはストリームが終了するまでスロットを保持するため、同じトライアルキーで長時間のストリーミングチャットと大きなバッチを混在させないでください。

計画するべき違い

  • ローカル固有のオプションなし。 num_ctxおよびkeep_aliveはホスト側では意味を持ちません。ウィンドウは100,000トークンで、プロンプトと補完を合計したものです。
  • レート制限。 フルキーは8つの同時リクエストと1分あたり300リクエストを許可します。トライアルキーは2および60を許可します。それを超えると、rate_limitedまたはconcurrencyで429が返されます。一時停止後に再試行します。一時的な過負荷の場合、レスポンスにはRetry-After: 5が含まれます。
  • コスト。 入力は1Mトークンあたり$0.15、出力は1Mトークンあたり$0.50です。2,000件のプロンプト(入力600トークン、出力400トークン)を送信するスクリプトは、2,000 x (600 x $0.15 + 400 x $0.50) / 1M = 2,000 x $0.00029 = $0.58を費やします。
  • 請求。 前払いクレジット、$20から$500、暗号資産(TRC20上のUSDTまたはBase上のUSDC)で支払われます。失敗または拒否されたリクエストは請求されません。

エンドポイントの並列比較については、API価格表またはドキュメントをお読みください。

質問と回答

PythonからOllamaを呼び出すには?

ollamaパッケージをインストールし、サーバーを起動し、モデルをプルします。その後、モデル名とメッセージのリストを指定してollama.chatを呼び出します。

OpenAI Python SDKをOllamaで使用できますか?

はい。base_urlをhttp://localhost:11434/v1に設定し、空でないAPIキーを使用してください。OllamaはそこにOpenAI互換レイヤーを提供します。

PythonでOllamaの出力をストリーミングするには?

ollama.chatにstream=Trueを渡して返されたチャンクをループし、各チャンクからmessage.contentを出力します。

ホスティングされたエンドポイントに切り替えると何が変わりますか?

ベースURL、APIキー、モデル名です。num_ctxのようなローカルオプションは適用されず、429レート制限レスポンスを処理する必要があります。