「ローカルLLMをインタラクティブに実験できる環境が手元に欲しいが、JupyterとOllamaをどう組み合わせるのか分からない」
そんな悩みを抱えるPython開発者やデータエンジニアは多いはずです。この記事では、Ubuntu Server上にJupyterLabをセットアップし、OllamaのAPIをノートブックから直接呼び出す手順を解説します。
シンプルなAPIコールから始まり、ストリーミング表示・会話履歴の保持・テキスト埋め込みによる類似度計算まで、AI実験環境として必要な機能をひとつずつ組み立てていきます。
この記事のポイント
・JupyterLabとOllamaはlocalhost:11434でそのまま連携できる
・ollama PythonパッケージのstreamオプションでCell内リアルタイム表示が実現できる
・会話履歴はPythonのリストで管理し、messagesに渡すだけで実装できる
・Embedding APIとnumpyのコサイン類似度でRAG前の挙動確認をノートブック上で完結できる
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
なぜJupyterLabでOllamaを使うのか
VS CodeにContinue.devを入れれば補完AIはできる。StreamlitでチャットUIを作れば社内に公開できる。それでもJupyterLabが必要になる場面があります。「コードとAI出力を並べて、その場で仮説を試せる」インタラクティブ性は、ノートブック以外では代替が難しいのです。
データ加工のコードを書いて、すぐ隣のセルでLLMに要約させて、出力をDataFrameに格納してグラフ化する。
このサイクルがJupyterノートブックなら数十秒で回ります。スクリプトを書いて実行してログを見て、という往復が不要になるのは大きな違いです。
Streamlitはウェブアプリとして公開するもので、実験フェーズには向いていません。試行錯誤が多い初期検討・プロトタイプ・研究ログには、JupyterLabが最も素直な選択です。
Ubuntu ServerへのOllama基本構築が済んでいる方は、このままセットアップに進んでください。
事前準備:JupyterLabと仮想環境のセットアップ
1. Python仮想環境を作成する
システムのPythonに直接パッケージを入れるのは避けてください。仮想環境を使えば、ライブラリのバージョン衝突を防げますし、不要になったら環境ごと削除できます。
Python 3.10以上が前提です。
# Python バージョン確認 $ python3 --version Python 3.12.3 # 仮想環境を作成して有効化 $ python3 -m venv ~/llm-notebook-env $ source ~/llm-notebook-env/bin/activate # プロンプトが変わったことを確認 (llm-notebook-env) $
セッションをまたぐ場合は毎回 `source ~/llm-notebook-env/bin/activate` が必要です。
2. JupyterLabとollamaパッケージをインストールする
必要なパッケージは4つです。(llm-notebook-env) $ pip install jupyterlab ollama requests numpy # インストール後にバージョン確認 (llm-notebook-env) $ jupyter --version Selected Jupyter core packages... JupyterLab : 4.2.5
3. リモートサーバーの場合はSSHポート転送を設定する
ローカルPCからUbuntu Serverに接続している場合は、SSHポート転送でJupyterLabの8888番とOllamaの11434番を転送してください。2つを同時に転送するには `-L` オプションを2回書くだけです。
# ローカルPCのターミナルで実行(SSH接続と同時にポート転送) $ ssh -L 8888:localhost:8888 -L 11434:localhost:11434 user@your-server-ip # サーバー側でJupyterLabを起動(ブラウザ自動起動なし・127.0.0.1バインド) (llm-notebook-env) $ jupyter lab --no-browser --ip=127.0.0.1 --port=8888 [I 2026-07-30 10:00:00.000 ServerApp] Jupyter Server 2.14.2 is running at: [I 2026-07-30 10:00:00.000 ServerApp] http://127.0.0.1:8888/lab?token=abc123...
IP指定を `127.0.0.1` にしているのは、外部からの直接アクセスをSSH転送に限定するためです。公開サーバーでは重要な設定です。
OllamaのAPIをPythonから呼び出す基本
1. ollamaパッケージを使ったシンプルな呼び出し
JupyterLabのノートブックを開き、新しいセルに以下を貼り付けてShift+Enterで実行してください。import ollama response = ollama.chat( model='llama3.3:70b-instruct-q4_0', messages=[ {'role': 'user', 'content': 'Linuxのプロセス管理コマンドを3つ教えて'} ] ) print(response['message']['content'])
モデル名は `ollama list` で確認したものを使ってください。手元に `mistral:7b-instruct-q8_0` しかない場合はそちらを指定してもかまいません。
モデル選定の考え方についてはローカルLLMのモデル比較ガイドも参照してください。
2. requestsで直接REST APIを呼ぶ方法
ollamaパッケージが使えない制限環境では、requestsでOllamaのREST APIを直接叩けます。`/api/chat` エンドポイントにJSON形式でPOSTするだけです。
import requests, json payload = { "model": "llama3.3:70b-instruct-q4_0", "messages": [ {"role": "user", "content": "Linuxのinotifyとは何か、一段落で説明して"} ], "stream": False } resp = requests.post("http://localhost:11434/api/chat", json=payload) data = resp.json() print(data["message"]["content"])
長い回答が返るまで待ちたくない場合は、次の章のストリーミング実装に進んでください。
ストリーミングレスポンスをJupyterセルにリアルタイム表示する
70bクラスのモデルでは応答に数十秒かかることがあります。全部出力されるまで待つより、生成されたトークンをリアルタイムで見る方がストレスが少なく、出力の方向性をその場で確認できます。
1. IPython.displayのclear_outputでトークンを逐次表示する
import ollama from IPython.display import clear_output full_text = "" stream = ollama.chat( model='llama3.3:70b-instruct-q4_0', messages=[{'role': 'user', 'content': 'ssコマンドの基本的な使い方を説明して'}], stream=True ) for chunk in stream: token = chunk['message']['content'] full_text += token clear_output(wait=True) print(full_text, end='', flush=True) print() # 最後に改行
毎チャンクのたびにセル出力をクリアして最新テキスト全体を再描画します。若干ちらつきますが、スクロールなしで常に最新の状態が見えます。
2. requestsのiter_linesでストリーミングする方法
ollamaパッケージを使わずにストリーミングしたい場合はこちらです。import requests, json payload = { "model": "llama3.3:70b-instruct-q4_0", "messages": [{"role": "user", "content": "pingコマンドの使い方を教えて"}], "stream": True } with requests.post("http://localhost:11434/api/chat", json=payload, stream=True) as resp: for line in resp.iter_lines(): if line: data = json.loads(line) token = data.get("message", {}).get("content", "") print(token, end='', flush=True) print()
ログとして残したい場合はこちらの方が都合が良いこともあります。
会話履歴を保持したマルチターン対話を実装する
1. messagesリストに履歴を積み上げる
OllamaのChat APIはステートレスです。「前の質問に続けて答えて」を実現するには、過去のやり取りをすべて messages に含めて渡す必要があります。
仕組み自体はシンプルで、リストに追記していくだけです。
import ollama messages = [] def chat(user_input: str, model: str = 'llama3.3:70b-instruct-q4_0') -> str: messages.append({'role': 'user', 'content': user_input}) response = ollama.chat(model=model, messages=messages) assistant_msg = response['message']['content'] messages.append({'role': 'assistant', 'content': assistant_msg}) return assistant_msg # 1ターン目 print(chat("Linuxのsystemctlとserviceコマンドの違いを教えて")) # 2ターン目(前の文脈が引き継がれる) print(chat("では、systemctlでサービスを再起動するコマンドは?"))
Ollamaはリストを先頭から読んで文脈を理解するため、順番の管理だけ意識してください。
2. 会話履歴のリセット関数を用意する
別テーマに切り替えたいときは `messages.clear()` するだけです。以下のように別セルに書いておくと、ワンクリックでリセットできます。
def reset_conversation(): messages.clear() print(f"会話履歴をリセットしました(現在: {len(messages)}件)") reset_conversation() # 出力例: # 会話履歴をリセットしました(現在: 0件)
知人のMLエンジニアが試したところ、「直近10ターンだけ保持するローリングウィンドウ方式」で速度が安定したとのことでした。
実装は `messages = messages[-20:]`(user/assistantのペアで20要素=10ターン)をchat関数の先頭に入れるだけです。
3. systemプロンプトでAIのペルソナを固定する
回答スタイルを統一したい場合は、messagesの先頭にsystemロールを入れておきます。messages = [ { 'role': 'system', 'content': 'あなたはLinux専門のシニアインフラエンジニアです。' '回答は必ず具体的なコマンド例を含め、簡潔かつ実用的に答えてください。' } ] print(chat("sudoとsuの違いは何ですか?"))
Embedding APIとnumpyでテキスト類似度をノートブック上で確認する
テキストのベクトル化(Embedding)はRAGやセマンティック検索の基礎です。本格的なシステムを作る前に、JupyterLab上で挙動を確認しておくと設計の見通しが立ちます。
社内導入の文脈についてはローカルLLMの社内導入比較も参考にしてください。
1. OllamaのEmbedding APIでベクトルを取得する
import ollama import numpy as np def get_embedding(text: str) -> np.ndarray: resp = ollama.embeddings(model='nomic-embed-text', prompt=text) return np.array(resp['embedding']) def cosine_similarity(a: np.ndarray, b: np.ndarray) -> float: return float(np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))) # テスト用テキスト texts = [ "Linuxのファイル権限を変更する方法", "chmodコマンドでパーミッションを設定する手順", "Pythonで機械学習モデルを学習させる方法", ] base_vec = get_embedding(texts[0]) for t in texts: vec = get_embedding(t) sim = cosine_similarity(base_vec, vec) print(f"類似度 {sim:.4f}: {t}")
2. 実行結果の例と読み方
類似度 1.0000: Linuxのファイル権限を変更する方法 類似度 0.8324: chmodコマンドでパーミッションを設定する手順 類似度 0.4105: Pythonで機械学習モデルを学習させる方法
0.8超えであれば「同じ検索意図」と判断できるラインです。
0.5未満はほぼ無関係と考えてよいでしょう。
このノートブック実験でEmbeddingの挙動を把握してからRAGパイプラインを設計すると、精度チューニングの見通しが立ちやすくなります。
`nomic-embed-text` は日本語テキストにも対応していますが、精度を上げたい場合は `mxbai-embed-large` も試してみてください。
よくあるエラーと対処法
「Connection refused」が出てAPIが呼べない
JupyterLabとOllamaが別プロセスで起動していることを確認してください。まずOllamaのプロセスとポートの状態を確認します。
# Ollamaサービスの状態を確認 $ systemctl status ollama * ollama.service - Ollama Service Active: active (running) since 2026-07-30 10:00:00 JST # ポート11434が開いているか確認 $ ss -tlnp | grep 11434 LISTEN 0 128 127.0.0.1:11434 0.0.0.0:* users:(("ollama",pid=12345,...))
表示されない場合は `sudo systemctl start ollama` で起動してください。
リモートサーバーの場合はSSHポート転送(-L 11434:localhost:11434)が有効かも確認してください。
「Kernel died」とJupyterが止まる
メモリ不足が原因です。70bクラスのモデルをq4_0量子化で動かすには40GB以上のRAMまたはVRAMが必要です。
`ollama list` で手元にあるモデルを確認し、小さめのモデルを選んでください。
応急処置として、`num_ctx`(コンテキスト長)を減らすと消費メモリが下がります。
response = ollama.chat( model='llama3.3:70b-instruct-q4_0', messages=[{'role': 'user', 'content': '質問内容'}], options={'num_ctx': 2048} # デフォルト4096 → 2048に削減 )
SSH切断後にJupyterへアクセスできなくなる
SSH接続が切断されるとポート転送も止まります。サーバー側で `tmux` または `screen` を使い、JupyterLabをセッション内で起動しておくと切断後も継続します。
# tmuxセッションを作成してJupyterを起動 $ tmux new -s jupyter (llm-notebook-env) $ jupyter lab --no-browser --ip=127.0.0.1 --port=8888 # SSH切断後に再接続してセッションへ戻る $ tmux attach -t jupyter
ollamaパッケージのインポートエラー
JupyterLabのKernelが仮想環境を参照していない場合に起きます。以下のコマンドで仮想環境のKernelをJupyterに登録してください。
(llm-notebook-env) $ pip install ipykernel (llm-notebook-env) $ python -m ipykernel install --user --name=llm-env --display-name="LLM Notebook" Installed kernelspec llm-env in /home/user/.local/share/jupyter/kernels/llm-env
本記事のまとめ
JupyterLabとOllamaを組み合わせると、ローカルLLMの実験サイクルが大幅に短くなります。スクリプトを書いて実行してログを見るのではなく、セル単位でプロンプトを変えて即座に結果を確認できるのが最大の利点です。
今回実装した機能を整理します。
| やりたいこと | コマンド・実装方法 |
|---|---|
| シンプルなAIへの質問 | ollama.chat(model=..., messages=[...]) |
| ストリーミングで逐次表示 | ollama.chat(..., stream=True) + clear_output(wait=True) |
| 会話履歴の保持 | messagesリストにuser/assistantを順番に追加して渡す |
| systemプロンプトの設定 | messagesの先頭に {'role': 'system', 'content': ...} を追加 |
| テキスト埋め込みの取得 | ollama.embeddings(model='nomic-embed-text', prompt=...) |
| コサイン類似度の計算 | np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b)) |
| コンテキスト長の削減(OOM対策) | ollama.chat(..., options={'num_ctx': 2048}) |
機密データを外に出さずにAIを活用したい場合は情シス向けの導入比較記事も参考にしてください。
JupyterLabとOllamaを使ったAI実験環境を2日間ハンズオンで体験する
ノートブックでのプロンプト実験からRAGパイプライン構築まで、実機GPU環境で手を動かしながら習得したい方向けに、「ローカルAIマスターセミナー」を開催しています。
少人数(最大8名)ZOOMハンズオン形式で実施しています。
・Ubuntu ServerでローカルLLMを構築する方法|Ollamaで機密データを外に出さず業務AIを動かす完全ガイド
・社内でChatGPTが使えないときの代替手段|機密データを守るローカルLLMという選択肢
・ローカルLLMのモデルを比較する方法|Llama3.3・Mistral・Gemma・Phi-4をUbuntuで使い分けるポイント
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら
- 前のページへ:OllamaのモデルファイルをLinuxで管理する方法|OLLAMA_MODELS・外付けHDD・バックアップでストレージを最適化する
- この記事の属するカテゴリ:ローカルLLMへ戻る

無料メルマガで学習を続ける
Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。
登録無料・いつでも解除できます