OllamaのAPIをPythonから叩いてDeepSeekモデルでチャットしてみる

Python環境の準備(Jupyter)

インタラクティブPythonを実行できる環境(Jupyter Notebook)を用意する。今回は、Docker環境で準備をする。

実行ディレクトリに行き、以下を実行する。

docker run -d --name jupyter \
  -p 8888:8888 \
  --add-host=host.docker.internal:host-gateway \
  -v ./jupyter_workspace:/home/jovyan/work \
  jupyter/datascience-notebook \
  start-notebook.sh --NotebookApp.token='' --NotebookApp.password=''

コマンドの詳細

  • -d: コンテナをバックグラウンドで実行。
  • --name jupyter: コンテナ名を「jupyter」に設定。
  • --add-host=host.docker.internal:host-gateway: すでにコンテナとして起動しているollamaがホストの44444にアクセスする必要があるため、これが必要
  • -p 8888:8888: ホストのポート8888とコンテナのポート8888をバインド。
  • -v ./jupyter_workspace:/home/jovyan/work:実行ディレクトリ配下のディレクトリ(jupyter_workspace)をコンテナ内の作業ディレクトリにマウント。
  • --NotebookApp.token='': トークン認証を無効化。
  • --NotebookApp.password='': パスワード認証も無効化。

コンテナ中でpipでollamaのライブラリを入れる

コンテナを起動していることを確認し、docker exec -it jupyter /bin/bashを実行して、コンテナでシェル(bash)を実行。

シェルで、pip install ollamaを実行し、ollamaのライブラリを入れる。

入れたら、Ctrl + Dでシェルを抜けて、ブラウザでhttp://localhost:8888を開く。

Jupyter NotebookからollamaのPythonクライアント経由でAPIを叩き、使用可能なモデル一覧を出力する

以下を実行する

from ollama import Client

client = Client(
  host='http://host.docker.internal:44444',
  #headers={'x-some-header': 'some-value'}
)
for a in client.list()["models"]:
    print(a["model"])

出力結果↓

llava:13b
hf.co/mmnga/cyberagent-DeepSeek-R1-Distill-Qwen-14B-Japanese-gguf:latest
deepseek-r1:8b
deepseek-r1:14b
deepseek-r1:7b

すでに別件でダウンロード(ollama pull)した際に保存したモデル名の一覧が出力されていることがわかる。

今回はリモート(といっても同じホストの別コンテナではあるが)のollamaサーバを指定したので、host='http://host.docker.internal:44444',とした。ollamaサーバはホストの44444ポートにアクセス可能な状態で起動しているので、このようなコマンドになる。

【参考】

github.com

さきほど取得したモデル名を指定して、チャットしてみる

今回はcyberagentが日本語で学習したdeepseekのモデル(14B)を指定して、チャットしてみる。

以下を実行する。hostは、先ほど言及したものを指定し、model名も同じように先ほど取得した一覧の中から、今回のモデル(deepseekの14B)を指定する。

from ollama import Client
import time

start = time.time()
client = Client(
  host='http://host.docker.internal:44444',
  #headers={'x-some-header': 'some-value'}
)
response = client.chat(model='hf.co/mmnga/cyberagent-DeepSeek-R1-Distill-Qwen-14B-Japanese-gguf:latest', messages=[
  {
    'role': 'user',
    'content': 'どうして空は青いの?',
  },
])
end = time.time()

print(f"所要時間: {end-start}(s)")
print(f"生成結果↓\n{response['message']['content']}")

実行結果↓

所要時間: 116.41288232803345(s)
生成結果↓
<think>
そうだな、空が青い理由を考えてみよう。まず、太陽光が大気を通じて散乱される現象について知っているよね。ブルーイングと呼ばれる現象だっけ?でも具体的に何が起こっているのか分からないから、もっと詳しく調べる必要がある。

太陽光は白熱光で、青や紫の波長が短いけど、赤やオレンジは長い波長だ。空気中にあるガス分子や微粒子がこれらの光を散乱するんだけど、短い波長はより強く散乱されるらしい。だから、青や紫が空に見えるはずだけど、実際には空は青でないことが多い。なぜだろう?

あ、そうか!ブルーイングでは短い波長の光が大気中で散乱されるけど、人間の目には青色と緑色の範囲が広く効果的だから、その結果として空に見えるのが青なのかも。でも紫の光も散乱されるとしたら、なぜ空は紫ではないのかな?

調べてみると、大気中の酸素や窒素などの分子は主に紫外線を散乱させるらしいけど、私たちが見ている可視光の中では青色の波長が強い。また、人間の目の感覚も関係しているみたい。網膜の桜水晶体が赤や橙色の光をフィルターし、残る青色と緑色が強調されるからかな。

でも、空が真っ暗な時や日没時には青ではなくオレンジ色になるのは、太陽光が大気を通る時間が長いから散乱されやすい波長が赤系統のものだからだ。つまり、時間帯によっても空の色は変わるってこと?

そういえば、惑星の空の色も異なっているよね。土星や木星のようなガス巨行星は濃厚な大気があるから、異なる光を散乱するかもしれない。地球の場合、窒素と酸素で青が優勢なんだ。

まとめると、太陽光の散乱によるブルーイング現象、波長ごとの散乱効率、人間の視覚への影響、時間帯や天候などの要因が複合的に作用して空は青く見えるんだって。でももっと深く調べてみる必要があるな。
</think>

**答え:地球の大気中の光散乱現象と人間の視覚による効果的な色表現が原因です。**

### 詳細解説:
1. **太陽光のスペクトル構成**  
   太陽からの光は「白熱光」であり、波長ごとに異なる強さで分布しています。短い青や紫の光は強度が高い一方、赤やオレンジは弱めです。

2. **大気中の散乱現象(ブルーイング)**  
   大気分子(主に窒素と酸素)は、波長が短い青や紫外線を強く散乱します。この効果が「空の青さ」の基盤です。

3. **人間の視覚への影響**  
   - 人間の網膜には、赤/緑色(メラノピン)と青/黄緑色(オーガノピリン)の感光細胞があります。  
   - 赤やオレンジは空気中で散乱されにくいため、残った青が目立つように感じられます。  
   - 加えて、人間の視覚では「暗視効果」により、紫より青の方が優先的に認識されます。

4. **時間帯による変化**  
   - 日没時や日の出時は、太陽光が大気を横切るため赤系統の散乱が強く、空はオレンジ色になります。  
   - 一方、日中は太陽が天頂に近いため青の散乱が顕著です。

5. **他の惑星との比較**  
   - 土星や木星のようなガス巨行星では、濃厚な大気による散乱で異なる色(例:土星はオレンジ)が現れます。  
   - 火星は大気が薄いため赤に近い色になります。

### まとめ:
空の青さは、太陽光の波長分布と大気中の分子散乱が組み合わさり、人間の視覚が効果的に受け取る結果です。この現象を「**リッジウッドの法則(Riddell's Law)**」と呼ぶこともあります。

114秒もかかっているのは遅い気がする。