Ollama Pythonライブラリ 完全ガイド:ローカルLLMを手軽に動かそう 🚀

AI / 機械学習

大規模言語モデル(LLM)を自分のコンピューターで動かせたら便利だと思いませんか?それを簡単に実現してくれるのが Ollama です。そして、Pythonプログラマーにとって嬉しいことに、OllamaをPythonから簡単に操作できる公式ライブラリ ollama が提供されています。 この記事では、OllamaとそのPythonライブラリについて、基本的な使い方から少し応用的な機能まで、網羅的に解説していきます。ローカル環境でLLMを動かすメリットを最大限に活かし、あなたの開発プロジェクトを加速させましょう!

Ollamaとは? 🤔

Ollamaは、Llama 3、Mistral、Gemma、Phi-3など、様々なオープンソースの大規模言語モデル(LLM)を自分のローカルマシンで簡単に実行するためのツールです。2024年初頭にはMacOSとLinux向けに提供され、Windows版もWSL2経由で利用可能でしたが、その後正式にWindowsにも対応しました。

Dockerがコンテナを扱うように、OllamaはLLMのモデルファイル(モデルの重み、設定、データセットなどをまとめたもの)を管理し、複雑なセットアップなしにローカルでLLMを起動・実行できるようにします。これにより、以下のようなメリットが得られます。

  • プライバシー保護: データがローカルマシンから外に出ないため、機密情報を扱う場合でも安心です。
  • コスト削減: クラウドベースのLLM API利用料がかかりません。
  • オフライン利用: インターネット接続がない環境でもLLMを利用できます。
  • カスタマイズ性: 自分でモデルをファインチューニングしたり、Modelfileを使って動作をカスタマイズしたりできます。
  • 低レイテンシ: ネットワーク遅延がないため、応答が速い場合があります(マシンスペックによります)。
Ollama自体は、コマンドラインインターフェース(CLI)とREST APIを提供しています。Pythonライブラリは、このREST APIを内部的に利用して、PythonコードからOllamaを操作しやすくするためのラッパーとして機能します。

Ollama Pythonライブラリのセットアップ 🛠️

前提条件

  • Python 3.8以上 がインストールされていること。
  • Ollama がインストールされ、実行されていること。(Ollamaのインストールは公式サイト https://ollama.com/ から簡単に行えます。)
  • 利用したいLLMモデルがOllamaにダウンロードされていること。(例: ollama pull llama3.2 コマンドでモデルをダウンロード)

インストール

Ollama Pythonライブラリのインストールはpipコマンド一つで完了します。非常に簡単です!

pip install ollama

これで、PythonスクリプトからOllamaの機能を利用する準備が整いました。

基本的な使い方 📝

Ollama Pythonライブラリは、主に以下の機能を提供します。

  • テキスト生成 (Generate): プロンプトに基づいたテキスト補完を行います。
  • チャット (Chat): 会話形式でのやり取りを行います。
  • モデル管理 (Model Management): ローカルモデルの一覧表示、詳細表示、コピー、削除、プル(ダウンロード)、プッシュ(アップロード)などを行います。
  • 埋め込み生成 (Embeddings): テキストのベクトル表現(埋め込み)を生成します。これはRAG(Retrieval-Augmented Generation)などの応用で役立ちます。

基本的な使い方をコード例とともに見ていきましょう。

ライブラリのインポート

まず、ライブラリをインポートします。

import ollama

テキスト生成 (Generate)

最も基本的な機能の一つが、与えられたプロンプトに対するテキスト生成です。`ollama.generate()` 関数を使用します。

import ollama

response = ollama.generate(model='llama3.2', prompt='日本の首都はどこですか?')

# 生成されたテキスト全体を含む辞書が出力される
print(response)

# 応答テキストのみを取得する場合
print(response['response'])

`model` 引数で使用するモデル名を指定し、`prompt` 引数にプロンプト(質問や指示)を与えます。

チャット (Chat)

会話形式のインタラクションには `ollama.chat()` 関数を使います。これまでの会話履歴を考慮した応答が可能です。

import ollama

messages = [
    {
        'role': 'user',
        'content': '空はどうして青いの?',
    },
]

# chat関数を呼び出す
response = ollama.chat(model='llama3.2', messages=messages)

# 応答メッセージ全体を含む辞書が出力される
print(response)

# 応答メッセージの内容のみを取得する場合
print(response['message']['content'])

# 会話を続ける場合
messages.append(response['message']) # アシスタントの応答を履歴に追加
messages.append({
    'role': 'user',
    'content': 'もっと詳しく教えて。',
})

response_continued = ollama.chat(model='llama3.2', messages=messages)
print(response_continued['message']['content'])

`messages` 引数には、ロール(’user’, ‘assistant’, ‘system’)と内容(’content’)を含む辞書のリストを渡します。

ローカルモデルの一覧表示

`ollama.list()` 関数で、ローカルにダウンロード済みのモデル一覧を取得できます。

import ollama

models_info = ollama.list()
print(models_info)

# モデル名だけをリストで取得する場合
model_names = [model['name'] for model in models_info['models']]
print(model_names)

モデルのプル (ダウンロード)

`ollama.pull()` 関数で、Ollamaリポジトリからモデルをダウンロードできます。

import ollama

# gemma:2b モデルをダウンロード
# stream=True にすると、ダウンロード状況が逐次表示されるジェネレーターが返る
try:
    stream = ollama.pull('gemma:2b', stream=True)
    for chunk in stream:
        print(chunk)
    print("モデルのダウンロードが完了しました。")
except Exception as e:
    print(f"モデルのダウンロード中にエラーが発生しました: {e}")

# stream=False (デフォルト) の場合、完了後にステータスが返る
# status = ollama.pull('gemma:2b')
# print(status)

大きなモデルのダウンロードには時間がかかるため、`stream=True` を指定して進捗を確認すると便利です。

モデルの削除

不要になったモデルは `ollama.delete()` 関数で削除できます。

import ollama

try:
    status = ollama.delete('gemma:2b')
    print(f"モデル 'gemma:2b' の削除ステータス: {status}")
except ollama.ResponseError as e:
    if "model 'gemma:2b' not found" in str(e):
        print("モデル 'gemma:2b' は既に削除されているか、存在しません。")
    else:
        print(f"モデルの削除中にエラーが発生しました: {e}")
except Exception as e:
    print(f"予期せぬエラーが発生しました: {e}")

削除しようとしたモデルが存在しない場合、`ollama.ResponseError` が発生することがあります。適切にエラーハンドリングを行いましょう。

埋め込み生成 (Embeddings)

テキストの意味的なベクトル表現(埋め込み)を取得するには `ollama.embeddings()` 関数を使います。これは、テキスト間の類似度計算や、RAG (Retrieval-Augmented Generation) システムの構築などに利用されます。

import ollama

# 単一テキストの埋め込みを生成
embedding_response = ollama.embeddings(model='llama3.2', prompt='こんにちは、世界!')
embedding_vector = embedding_response['embedding']
print(f"埋め込みベクトルの次元数: {len(embedding_vector)}")
# print(f"埋め込みベクトル (最初の10要素): {embedding_vector[:10]}") # ベクトル自体は長いので一部表示

# 複数テキストの埋め込みを一括で生成することも可能 (ただし、ライブラリのバージョンやOllama本体の実装による)
# 現在の ollama ライブラリ (0.4.x 時点) では embeddings 関数は単一プロンプトのみを受け付けます。
# 大量に処理する場合はループ処理が必要です。
texts = ["これは最初の文書です。", "これは二番目の文書です。"]
embeddings = []
for text in texts:
    response = ollama.embeddings(model='llama3.2', prompt=text)
    embeddings.append(response['embedding'])

print(f"{len(embeddings)}個のテキストの埋め込みを生成しました。")

生成される埋め込みベクトルは、通常、数百から数千次元の数値のリストになります。

応用的な機能とオプション ✨

基本的な使い方に加えて、Ollama Pythonライブラリはより高度な機能も提供しています。

ストリーミング応答 (Streaming Responses)

`generate` や `chat` 関数で `stream=True` を指定すると、応答が一度に返されるのではなく、生成され次第、小さなチャンク(断片)として逐次返されます。これにより、特に長い応答を生成する場合に、ユーザーインターフェースでの体感速度を向上させることができます。

import ollama

stream = ollama.chat(
    model='llama3.2',
    messages=[{'role': 'user', 'content': 'Pythonで簡単なWebサーバーを立てるコードを教えて'}],
    stream=True,
)

print("AIの応答:")
full_response = ""
for chunk in stream:
    content_part = chunk['message']['content']
    print(content_part, end='', flush=True) # flush=True でバッファリングせず即時表示
    full_response += content_part

print("\n--- 応答終了 ---")
# print(f"完全な応答:\n{full_response}") # 必要であれば完全な応答も保持できる

`stream=True` を指定すると、戻り値はイテレーター(または非同期の場合は非同期ジェネレーター)になります。これをループで処理し、各チャンクから応答の一部を取り出して表示や処理を行います。最後のチャンクには、応答時間などの統計情報が含まれる場合があります。

モデルパラメータの調整 (Options)

`generate` や `chat` 関数の `options` 引数を使うと、モデルの振る舞いを細かく制御できます。これはOllamaのModelfileで指定できるパラメータに対応します。

  • temperature: 応答のランダム性を制御します。低い値(例: 0.2)はより決定的で一貫性のある応答を、高い値(例: 1.0)はより多様で創造的な応答を生成しやすくします。
  • top_p (Nucleus sampling): 生成する単語の候補を確率の高いものから累積確率が `top_p` に達するまで絞り込みます。`temperature` と同様にランダム性を制御します。
  • num_predict: 生成する最大トークン数を指定します。
  • stop: 指定した文字列が出現したら、そこで生成を停止します。リストで複数指定可能です。
  • seed: 乱数シードを指定し、結果の再現性を高めます(完全に再現可能とは限りません)。
import ollama

response = ollama.generate(
    model='llama3.2',
    prompt='創造的な物語のアイデアを3つ教えてください。',
    options={
        'temperature': 0.9,
        'top_p': 0.95,
        'num_predict': 200,
        'stop': ['---'] # '---' が出現したら停止
    }
)

print(response['response'])

JSONモードと関数呼び出し (Format & Tools)

`generate` や `chat` 関数で `format=’json’` を指定すると、モデルはJSON形式で応答を生成しようとします。これは、APIの応答や構造化データを生成させたい場合に便利です。

import ollama
import json

response = ollama.chat(
    model='llama3.2',
    messages=[
        {'role': 'user', 'content': '東京の天気情報をJSON形式で教えてください。フィールドは location, temperature, weather です。'}
    ],
    format='json'
)

try:
    # 応答文字列をJSONオブジェクトにパース
    weather_data = json.loads(response['message']['content'])
    print("取得した天気情報 (JSON):")
    print(json.dumps(weather_data, indent=2, ensure_ascii=False))
except json.JSONDecodeError:
    print("JSON形式での応答取得に失敗しました。")
    print(response['message']['content'])
except Exception as e:
     print(f"エラーが発生しました: {e}")
     print(response['message']['content'])

さらに、2024年11月にリリースされたOllama Pythonライブラリ 0.4以降では、Pythonの関数を「ツール」としてモデルに渡し、モデルに関数を呼び出すよう指示する機能(Function Calling)が強化されました。これにより、外部APIの呼び出しやデータベース検索などをLLMの応答生成プロセスに組み込むことが可能になります。

# Ollama 0.4+ が必要
import ollama
import json

# 例: 天気を取得するダミー関数
def get_current_weather(location: str, unit: str = "celsius"):
    """指定された場所の現在の天気を取得します。"""
    print(f"関数呼び出し: get_current_weather(location='{location}', unit='{unit}')")
    # ここで実際の天気APIを呼び出すなどの処理を行う
    weather_info = {
        "location": location,
        "temperature": "25",
        "unit": unit,
        "forecast": "晴れ",
    }
    return json.dumps(weather_info)

# 利用可能なツールとして関数を定義
tools = [
    {
        'type': 'function',
        'function': {
            'name': 'get_current_weather',
            'description': '指定された場所の現在の天気を取得します',
            'parameters': {
                'type': 'object',
                'properties': {
                    'location': {
                        'type': 'string',
                        'description': '都市名 (例: 東京都千代田区)',
                    },
                    'unit': {
                        'type': 'string',
                        'enum': ['celsius', 'fahrenheit'],
                        'description': '温度の単位',
                    },
                },
                'required': ['location'],
            },
        },
    }
]

messages = [{'role': 'user', 'content': '大阪の天気は?摂氏で教えて。'}]

# 最初の呼び出し (モデルに関数呼び出しを促す)
response = ollama.chat(
    model='llama3.2', # 関数呼び出しに対応したモデルが必要
    messages=messages,
    tools=tools,
)

print("最初の応答:", response['message'])

# モデルが関数呼び出しを要求した場合
if response['message'].get('tool_calls'):
    tool_call = response['message']['tool_calls'][0] # 簡単のため最初のツール呼び出しのみ処理
    function_name = tool_call['function']['name']
    function_args = json.loads(tool_call['function']['arguments'])

    if function_name == 'get_current_weather':
        # 関数を実行
        function_response = get_current_weather(
            location=function_args.get('location'),
            unit=function_args.get('unit', 'celsius') # デフォルト値
        )

        # 関数実行結果をメッセージ履歴に追加
        messages.append(response['message']) # アシスタントの関数呼び出し要求を追加
        messages.append({
            'role': 'tool',
            'content': function_response,
        })

        # 関数結果を踏まえて再度モデルを呼び出し
        final_response = ollama.chat(model='llama3.2', messages=messages)
        print("最終的な応答:", final_response['message']['content'])
    else:
        print(f"未対応の関数呼び出し: {function_name}")
else:
    # 関数呼び出しなしで応答した場合
    print("最終的な応答:", response['message']['content'])

この機能を使うには、関数呼び出しに対応したLLMモデル(例: Llama 3.1以降など)が必要です。

カスタムクライアント (Custom Client)

Ollamaサーバーがデフォルトの `http://localhost:11434` 以外で動作している場合や、特定のHTTPヘッダー(認証トークンなど)を付与したい場合は、`ollama.Client` または `ollama.AsyncClient` を使ってカスタムクライアントを作成できます。

from ollama import Client

# Ollamaサーバーが別のホスト/ポートで動作している場合
# client = Client(host='http://192.168.1.100:11434')

# カスタムヘッダーを追加する場合
client = Client(
    host='http://localhost:11434',
    headers={'Authorization': 'Bearer YOUR_API_TOKEN'} # 例
)

response = client.chat(model='llama3.2', messages=[{'role': 'user', 'content': 'Hello!'}])
print(response['message']['content'])

非同期処理 (Async Client)

`asyncio` を利用した非同期プログラムでOllamaを使用する場合は、`ollama.AsyncClient` を使います。基本的なインターフェースは同期版の `Client` と同様ですが、メソッド呼び出しに `await` が必要になります。ストリーミング応答も非同期ジェネレーターとして扱えます。

import asyncio
from ollama import AsyncClient

async def run_async_chat():
    client = AsyncClient() # デフォルトのホストを使用
    message = {'role': 'user', 'content': '非同期処理について教えて'}
    response = await client.chat(model='llama3.2', messages=[message])
    print("非同期応答:", response['message']['content'])

async def run_async_stream():
    client = AsyncClient()
    message = {'role': 'user', 'content': 'asyncioの基本的な使い方をコードで示して'}
    print("\n非同期ストリーム応答:")
    full_response = ""
    async for part in await client.chat(model='llama3.2', messages=[message], stream=True):
        content_part = part['message']['content']
        print(content_part, end='', flush=True)
        full_response += content_part
    print("\n--- 非同期ストリーム終了 ---")

async def main():
    await run_async_chat()
    await run_async_stream()

if __name__ == "__main__":
    asyncio.run(main())

活用例とアイデア 💡

OllamaとPythonライブラリを使えば、様々なAIアプリケーションをローカル環境で構築できます。

  • シンプルなチャットボット: `ollama.chat` を使って、特定のタスク(カスタマーサポート、FAQ応答など)に特化したボットを作成。
  • テキスト要約ツール: 長い文章を `ollama.generate` に与え、「この記事を要約してください」のようなプロンプトで要約を生成。
  • コンテンツ生成支援: ブログ記事のアイデア出し、メールの下書き作成、コードスニペット生成などに活用。
  • 感情分析: テキストを入力し、「この文章の感情はポジティブですか、ネガティブですか、ニュートラルですか?」といったプロンプトで分析。
  • RAG (Retrieval-Augmented Generation): `ollama.embeddings` で独自のドキュメントをベクトル化し、関連文書を検索してから `ollama.chat` で応答を生成する、より高度なQ&Aシステムを構築。
  • コード生成・デバッグ支援: `codellama` などのコード生成に特化したモデルを使い、開発作業を効率化。
  • 多言語翻訳: 翻訳タスクに対応したモデル(例: ELYZA-tasks-11Bなど)を使って、テキスト翻訳を行う。

これらの例はほんの一部です。Ollamaがサポートする多様なモデルとPythonの柔軟性を組み合わせることで、アイデア次第で様々な応用が可能です。

まとめ 🎉

OllamaとそのPythonライブラリ (ollama) は、オープンソースの大規模言語モデルをローカル環境で手軽に利用するための強力なツールです。インストールから基本的なテキスト生成、チャット、モデル管理、埋め込み生成、さらにはストリーミング応答やパラメータ調整、関数呼び出しといった応用機能まで、Pythonから直感的に操作できます。

プライバシー、コスト、カスタマイズ性といったローカルLLMのメリットを活かし、AIを活用したアプリケーション開発の可能性を広げることができます。ぜひ、OllamaとPythonライブラリを使って、あなたのアイデアを形にしてみてください! Happy Coding! 😊

ポイントのおさらい:

機能 主な関数/オプション 概要
インストール pip install ollama ライブラリをPython環境に追加
テキスト生成 ollama.generate() プロンプトに基づいてテキストを生成
チャット ollama.chat() 会話形式でLLMと対話
モデル一覧 ollama.list() ローカルのモデルを表示
モデル取得 ollama.pull() リポジトリからモデルをダウンロード
モデル削除 ollama.delete() ローカルのモデルを削除
埋め込み生成 ollama.embeddings() テキストのベクトル表現を生成
ストリーミング stream=True 応答をチャンクで逐次受信
パラメータ調整 options={...} temperature, top_p 等で応答を制御
JSONモード format='json' JSON形式での応答を要求
関数呼び出し tools=[...] Python関数をツールとして連携 (v0.4+)
非同期処理 ollama.AsyncClient asyncio を使った非同期操作

コメント

タイトルとURLをコピーしました