OllamaとJupyterLabを連携させる方法|ノートブック上でローカルLLMをPythonから対話利用してAI実験環境を構築する手順

宮崎智広 この記事の監修:宮崎智広(Linux実務・教育歴20年以上・受講者3,100名超)
HOMELinux技術 リナックスマスター.JP(Linuxマスター.JP)ローカルLLM > OllamaとJupyterLabを連携させる方法|ノートブック上でローカルLLMをPythonから対話利用してAI実験環境を構築する手順
「PythonコードとAIの応答を同じ画面で確認しながら試したいが、毎回スクリプトを書き直すのが手間だ」
「ローカル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前の挙動確認をノートブック上で完結できる


OllamaとJupyterLabを連携させる方法|ノートブック上でローカルLLMをPythonから対話利用してAI実験環境を構築する手順

「このままじゃマズい」と感じていませんか?
参考書を開く気力もない、同年代に取り残される不安——
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

なぜ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) $

有効化を忘れると、後でインストールしたパッケージがJupyterから見えないという問題が起きます。
セッションをまたぐ場合は毎回 `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...

ローカルPCのブラウザで `http://localhost:8888` を開き、ログに表示されたトークン付きURLでアクセスします。
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'])

数秒でLLMの回答がセルの下に出力されます。
モデル名は `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"])

`stream: False` にすることで、全応答を一度に受け取れます。
長い回答が返るまで待ちたくない場合は、次の章のストリーミング実装に進んでください。

ストリーミングレスポンスを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() # 最後に改行

`clear_output(wait=True)` がポイントです。
毎チャンクのたびにセル出力をクリアして最新テキスト全体を再描画します。若干ちらつきますが、スクロールなしで常に最新の状態が見えます。

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()

こちらは `clear_output` を使わないため、トークンが縦に流れていくシンプルな表示になります。
ログとして残したい場合はこちらの方が都合が良いこともあります。

会話履歴を保持したマルチターン対話を実装する

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でサービスを再起動するコマンドは?"))

`messages.append` でrole(user/assistant)と内容を交互に追加するだけです。
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の違いは何ですか?"))

systemプロンプトはリセット後に再設定が必要なため、reset_conversation関数を改良して初期メッセージを入れ直す設計にしておくと管理しやすくなります。

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で機械学習モデルを学習させる方法

意味的に近い文章ほどスコアが1.0に近くなります。
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,...))

`LISTEN` が表示されていればOllamaは起動しています。
表示されない場合は `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

SSHの再接続後はポート転送(-L オプション)を付けて再度接続すれば、同じURLでJupyterLabにアクセスできます。

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を再起動し、「Kernel」メニューから「LLM Notebook」を選択すれば、仮想環境のパッケージを認識します。

本記事のまとめ

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})
次のステップとして、今回のEmbeddingとPandasのDataFrameを組み合わせてローカルなFAQ検索を作ると、RAGの仕組みを体感できます。
機密データを外に出さずにAIを活用したい場合は情シス向けの導入比較記事も参考にしてください。

JupyterLabとOllamaを使ったAI実験環境を2日間ハンズオンで体験する

ノートブックでのプロンプト実験からRAGパイプライン構築まで、実機GPU環境で手を動かしながら習得したい方向けに、「ローカルAIマスターセミナー」を開催しています。
少人数(最大8名)ZOOMハンズオン形式で実施しています。

>> ローカルAIマスターセミナーの詳細を確認する
ローカルLLMの構築・運用に関する関連記事もあわせて参考にしてください。

Ubuntu ServerでローカルLLMを構築する方法|Ollamaで機密データを外に出さず業務AIを動かす完全ガイド
社内でChatGPTが使えないときの代替手段|機密データを守るローカルLLMという選択肢
ローカルLLMのモデルを比較する方法|Llama3.3・Mistral・Gemma・Phi-4をUbuntuで使い分けるポイント

無料メルマガで学習を続ける

Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。

登録無料・いつでも解除できます

暗記不要・1時間後にはサーバーが動く

3,100名以上が実践した「型」を無料で公開中

プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。

姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

Linux無料マニュアル(図解60P) 名前とメールで30秒登録
宮崎 智広

この記事を書いた人

宮崎 智広(みやざき ともひろ)

株式会社イーネットマーキュリー代表。現役のLinuxサーバー管理者として20年以上の実務経験を持ち、これまでに累計3,100名以上のエンジニアを指導してきたLinux教育のプロフェッショナル。「現場で本当に使える技術」を体系的に伝えることをモットーに、実践型のLinuxセミナーの開催や無料マニュアルの配布を通じてLinux人材の育成に取り組んでいる。

趣味は、キャンプにカメラ、トラウト釣り。好きな食べ物は、ラーメンにお酒。休肝日が作れない、酒量を減らせないのが悩み。最近、ドラマ「フライトエンジェル」を観て涙腺が崩壊しました。