<НА ГЛАВНУЮ

Запуск локального 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

Switch to English