はじめに
最近発展が著しかったので既存の言語モデルを手元で実行・利用する方法、言語モデルの種類等見てみようと思いさくっと作ってみた。
環境
- Google Colab 無料枠(T4 GPU ランタイム)
- モデル: qwen2.5:7b
チュートリアルみたいなの作成したのでぜひ使ってください
https://colab.research.google.com/drive/1hNY5TX9-CcaOGGunfSQToqK1RSpRfR9Z?usp=sharing
colabの内容
ollamaの依存ライブラリのインストール!apt-get install zstd
ollamaのセットアップ
!curl -fsSL https://ollama.com/install.sh | sh
ollama が入ったか確認
!ollama --help
言語モデルを実行するため環境を構築
# 1. サーバをバックグラウンド起動(1回だけ実行)
!nohup ollama serve > ollama.log 2>&1 &
import time; time.sleep(3)
# 2. モデルを取得
!ollama pull qwen2.5:7b
対話を行う
コンソールベースで実行すると伏字になってしまうのでpythonで実行
import subprocess, requests
if subprocess.run(["pgrep", "-f", "ollama serve"], capture_output=True).returncode != 0:
raise SystemExit("Ollamaサーバが起動していません。セットアップセルを先に実行してください。")
def chat_loop(model="qwen2.5:7b"):
messages = [{"role": "system", "content": "常に日本語で回答してください。"}]
while True:
user_input = input("あなた> ")
if user_input in ("exit", "quit", "終了"):
break
messages.append({"role": "user", "content": user_input})
r = requests.post("http://localhost:11434/api/chat", json={
"model": model,
"messages": messages,
"stream": False,
})
reply = r.json()["message"]["content"]
print(f"\nAI> {reply}\n")
messages.append({"role": "assistant", "content": reply})
chat_loop()
対話しようとすると入力が伏字になる
セットアップが終わったので早速対話してみる
!ollama run qwen2.5:7b
すると入力欄がパスワードのように「••••••」と伏字になってしまい、まともに対話できない

原因
ollama run は本来ターミナル上で使う対話型REPL(チャット画面)を起動するコマンド。
一方、Colabの ! はコマンドを使い捨てのシェルで実行する仕組みで、対話型の標準入力をうまく扱えない。そのため入力がパスワード風の隠し入力になってしまう。
つまりバグではなく「ノートブック上で対話型REPLを直接使うのは無理筋」ということ。
解決策: REPLをやめてAPI経由で対話する
Ollamaはバックグラウンドでサーバとして動かし、PythonからHTTPで呼ぶのがノートブックでの正しい使い方。
入力はPythonの input() を使えば、Colabがセルの下に入力ボックスを出してくれる。
import subprocess, requests
# ガード節: サーバが起動していなければここで止める
if subprocess.run(["pgrep", "-f", "ollama serve"], capture_output=True).returncode != 0:
raise SystemExit("Ollamaサーバが起動していません。セットアップセルを先に実行してください。")
def chat_loop(model="qwen2.5:7b"):
messages = [{"role": "system", "content": "常に日本語で回答してください。"}]
while True:
user_input = input("あなた> ")
if user_input in ("exit", "quit", "終了"):
break
messages.append({"role": "user", "content": user_input})
r = requests.post("http://localhost:11434/api/chat", json={
"model": model,
"messages": messages,
"stream": False,
})
reply = r.json()["message"]["content"]
print(f"\nAI> {reply}\n")
messages.append({"role": "assistant", "content": reply})
chat_loop()
「終了」と入力すればループを抜けられる。
さらに会話履歴を毎回すべて送っている
messages リストに履歴を積み、毎ターン全履歴を送り直している
LLM自体に記憶はなく、ChatGPTもClaudeも「これまでの会話全文」を毎回受け取って続きを生成しているだけ。試しに messages.append の2行を消すと、直前の発言を覚えていないAIになるので実験してみてほしい。
GPU使えてる?対話が極端に遅い
WARNING: Unable to detect NVIDIA/AMD GPU. Install lspci or lshw to automatically detect and install GPU dependencies.
しかも対話をしてみると実行が遅い...
実験
そこでGPUが使われているか確認
!ollama run qwen2.5:7b "こんにちは" --verbose 2>&1 | tail -8
!ollama ps
load duration: 39.035683319s
prompt eval count: 30 token(s)
prompt eval duration: 47.272203s
prompt eval rate: 0.63 tokens/s
eval count: 23 token(s)
eval duration: 9.960746s
eval rate: 2.31 tokens/s
NAME ID SIZE PROCESSOR CONTEXT UNTIL
qwen2.5:7b 845dbda0ea48 4.7 GB 100% GPU 4096 4 minutes from now
結果見てみると確かにGPU100%となっていて使えていそう...
load duration: 39.035683319s
読み込みに39秒は流石に時間がかかりすぎ...
表示上はGPUなのに、速度はCPU並み。この矛盾が今回の謎
考察・追加検証
LLMには、初回実行時にモデルの読み込みで時間がかかる「コールドスタート」があり得る。
そこで、上のコマンドの直後にもう一度同じ計測を行った。
!ollama run qwen2.5:7b "こんにちは" --verbose 2>&1 | tail -8
!ollama ps
load duration: 340.893281ms
prompt eval count: 30 token(s)
prompt eval duration: 33.354999ms
prompt eval rate: 899.42 tokens/s
eval count: 37 token(s)
eval duration: 1.102958s
eval rate: 33.55 tokens/s
NAME ID SIZE PROCESSOR CONTEXT UNTIL
qwen2.5:7b 845dbda0ea48 4.7 GB 100% GPU 4096 4 minutes from now
load duration: 340.893281ms
前回の検証と比較すると
load duration: 39.0s → 340ms
prompt eval duration: 47.3s → 33ms
初回の遅さの正体は生成ではなく、モデル読み込みと初回プロンプト処理(コールドスタート)だった。
結論
遅い原因はコールドスタートであり、GPUは正しく使えていた。
ollama ps の GPU 100% 表示は確認にはなるが、実速度の保証にはならない。ベンチマークは必ず2回目以降(ウォームアップ後)の値を使うこと。
あとがき
次回はOllamaで動かした「完成品」の中身を理解するため、nanoGPTでゼロからLLMを実装してみたい
