Запуск локального LLM в Colab с Ollama, REST-стримингом и интерфейсом Gradio
'Короткий гайд по настройке Ollama в Colab: установка, запуск сервера, загрузка модели, стриминг ответов через /api/chat и чат на Gradio.'
Установка и зависимости
В этом руководстве показано, как организовать самоподдерживаемый LLM-пайплайн в Google Colab с помощью Ollama, REST API Ollama и чат-интерфейса на Gradio. Поток включает установку Ollama в VM, запуск сервера Ollama, загрузку лёгкой модели для CPU-only среды, постримо́вый вывод через /api/chat и обёртку всего этого Gradio-интерфейсом для интерактивного мульти-turn чата.
Установка Ollama и подготовка окружения
Сначала установите Ollama, если его нет, и убедитесь, что Gradio доступен. Ниже — пример вспомогательной функции для выполнения shell-команд, установки Ollama официальным скриптом и установки Gradio при отсутствии.
import os, sys, subprocess, time, json, requests, textwrap
from pathlib import Path
def sh(cmd, check=True):
"""Run a shell command, stream output."""
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True)
for line in p.stdout:
print(line, end="")
p.wait()
if check and p.returncode != 0:
raise RuntimeError(f"Command failed: {cmd}")
if not Path("/usr/local/bin/ollama").exists() and not Path("/usr/bin/ollama").exists():
print(" Installing Ollama ...")
sh("curl -fsSL https://ollama.com/install.sh | sh")
else:
print(" Ollama already installed.")
try:
import gradio
except Exception:
print(" Installing Gradio ...")
sh("pip -q install gradio==4.44.0")Это готовит окружение Colab для запуска чат-интерфейса без Docker. Gradio устанавливается только при необходимости.
Запуск сервера Ollama и ожидание готовности
Запустите сервер Ollama в фоне и опрашивайте endpoint /api/tags, пока он не начнёт отвечать. Так вы гарантируете, что сервер готов к запросам.
def start_ollama():
try:
requests.get("http://127.0.0.1:11434/api/tags", timeout=1)
print(" Ollama server already running.")
return None
except Exception:
pass
print(" Starting Ollama server ...")
proc = subprocess.Popen(["ollama", "serve"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True)
for _ in range(60):
time.sleep(1)
try:
r = requests.get("http://127.0.0.1:11434/api/tags", timeout=1)
if r.ok:
print(" Ollama server is up.")
break
except Exception:
pass
else:
raise RuntimeError("Ollama did not start in time.")
return proc
server_proc = start_ollama()Функция возвращает процесс сервера, если он был запущен, или None, если сервер уже работает.
Выбор и загрузка модели
Используйте лёгкую модель, подходящую для CPU-only Colab. Скрипт проверяет наличие модели на сервере и подтягивает её, если нужно.
MODEL = os.environ.get("OLLAMA_MODEL", "qwen2.5:0.5b-instruct")
print(f" Using model: {MODEL}")
try:
tags = requests.get("http://127.0.0.1:11434/api/tags", timeout=5).json()
have = any(m.get("name")==MODEL for m in tags.get("models", []))
except Exception:
have = False
if not have:
print(f" Pulling model {MODEL} (first time only) ...")
sh(f"ollama pull {MODEL}")Это автоматизирует управление моделями, чтобы далее можно было сразу запускать сессии чата.
Клиент стриминга для /api/chat
Чтобы получать инкрементальный вывод токенов, используйте стриминг /api/chat. Функция ниже отправляет JSON-пакет с stream=True и по мере поступления отдаёт куски текста.
OLLAMA_URL = "http://127.0.0.1:11434/api/chat"
def ollama_chat_stream(messages, model=MODEL, temperature=0.2, num_ctx=None):
"""Yield streaming text chunks from Ollama /api/chat."""
payload = {
"model": model,
"messages": messages,
"stream": True,
"options": {"temperature": float(temperature)}
}
if num_ctx:
payload["options"]["num_ctx"] = int(num_ctx)
with requests.post(OLLAMA_URL, json=payload, stream=True) as r:
r.raise_for_status()
for line in r.iter_lines():
if not line:
continue
data = json.loads(line.decode("utf-8"))
if "message" in data and "content" in data["message"]:
yield data["message"]["content"]
if data.get("done"):
breakГенератор стрима позволяет UI отображать ответ по частям в реальном времени.
Быстрый smoke test
Отправьте небольшой запрос, чтобы убедиться, что клиент стриминга и модель работают:
def smoke_test():
print("n Smoke test:")
sys_msg = {"role":"system","content":"You are concise. Use short bullets."}
user_msg = {"role":"user","content":"Give 3 quick tips to sleep better."}
out = []
for chunk in ollama_chat_stream([sys_msg, user_msg], temperature=0.3):
print(chunk, end="")
out.append(chunk)
print("n Done.n")
try:
smoke_test()
except Exception as e:
print(" Smoke test skipped:", e)Успешный тест подтверждает установку, доступность сервера и работоспособность модели.
Интерфейс Gradio с потоковыми ответами
Наложите Gradio-интерфейс на стриминговый клиент. UI хранит историю, формирует сообщения в формате Ollama, стримит ответы модели в чат и открывает слайдеры для температуры и длины контекста.
import gradio as gr
SYSTEM_PROMPT = "You are a helpful, crisp assistant. Prefer bullets when helpful."
def chat_fn(message, history, temperature, num_ctx):
msgs = [{"role":"system","content":SYSTEM_PROMPT}]
for u, a in history:
if u: msgs.append({"role":"user","content":u})
if a: msgs.append({"role":"assistant","content":a})
msgs.append({"role":"user","content": message})
acc = ""
try:
for part in ollama_chat_stream(msgs, model=MODEL, temperature=temperature, num_ctx=num_ctx or None):
acc += part
yield acc
except Exception as e:
yield f" Error: {e}"
with gr.Blocks(title="Ollama Chat (Colab)", fill_height=True) as demo:
gr.Markdown("# Ollama Chat (Colab)nSmall local-ish LLM via Ollama + Gradio.n")
with gr.Row():
temp = gr.Slider(0.0, 1.0, value=0.3, step=0.1, label="Temperature")
num_ctx = gr.Slider(512, 8192, value=2048, step=256, label="Context Tokens (num_ctx)")
chat = gr.Chatbot(height=460)
msg = gr.Textbox(label="Your message", placeholder="Ask anything…", lines=3)
clear = gr.Button("Clear")
def user_send(m, h):
m = (m or "").strip()
if not m: return "", h
return "", h + [[m, None]]
def bot_reply(h, temperature, num_ctx):
u = h[-1][0]
stream = chat_fn(u, h[:-1], temperature, int(num_ctx))
acc = ""
for partial in stream:
acc = partial
h[-1][1] = acc
yield h
msg.submit(user_send, [msg, chat], [msg, chat])
.then(bot_reply, [chat, temp, num_ctx], [chat])
clear.click(lambda: None, None, chat)
print(" Launching Gradio ...")
demo.launch(share=True)Gradio предоставляет удобную среду для интерактивного тестирования подсказок, изменения параметров и наблюдения за потоковой генерацией.
Связка компонентов
- Установка и зависимости подготавливают среду.
- Сервер Ollama хостит модели и предоставляет REST API.
- Стриминг /api/chat отдаёт частичные ответы по мере генерации.
- Gradio отображает многотуровую сессию и даёт элементы управления.
Такой подход позволяет экспериментировать с лёгкими моделями в Colab без Docker или GPU, сохраняя идею "self-hosted" и давая гибкую платформу для проверки идей.
Switch Language
Read this article in English