大規模言語モデル(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 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 を使った非同期操作 |
コメント