Vous avez entendu parler de Llama, de Mistral, de Gemma. Des modèles open source aussi capables que les grands — sans abonnement, sans envoyer vos données à une API tierce, sans dépendance à un fournisseur. Vous avez voulu les tester. Et puis vous avez vu la configuration recommandée : 16 Go de VRAM minimum, carte graphique dédiée, idéalement une RTX 4090.
Votre laptop a hoché la tête poliment et a regardé ailleurs.
Il existe une solution que beaucoup ignorent : Google Colab et Kaggle mettent gratuitement à disposition des GPUs dans le cloud — des vrais, des Tesla T4, parfois des A100. Ils sont pensés pour le machine learning, mais rien n'empêche de les utiliser comme serveurs LLM. Avec un outil de tunneling appelé ngrok, vous pouvez exposer ce serveur à Internet et l'appeler depuis votre propre machine comme si le modèle tournait en local.
Ce guide vous explique comment faire ça, de A à Z — avec le pourquoi de chaque étape.
Pourquoi cette approche, et pour qui
Avant de toucher à du code, posons le cadre.
Le problème : les LLM ont soif de GPU
Les grands modèles de langage, même dans leurs versions "légères" comme Llama 3.2 (3B paramètres), ont besoin de charger leurs poids en mémoire vidéo pour inférer. Un modèle de 7 milliards de paramètres en précision standard occupe environ 14 Go de VRAM. La plupart des laptops grand public ont 4 à 8 Go de VRAM partagée avec le CPU — insuffisant pour une exécution fluide.
La solution : emprunter un GPU
Google Colab (version gratuite) et Kaggle offrent des environnements d'exécution cloud avec GPU intégré, disponibles gratuitement dans certaines limites. Ces plateformes sont habituellement utilisées pour entraîner ou fine-tuner des modèles. Mais un GPU reste un GPU : on peut tout aussi bien s'en servir pour faire tourner un serveur d'inférence.
L'outil au centre : Ollama
Ollama est une application qui simplifie radicalement la gestion des LLM en local (ou dans un environnement serveur). Il télécharge les modèles, les optimise pour votre matériel, et expose une API HTTP standard sur le port 11434. Pensez à lui comme à un gestionnaire de modèles qui ajoute une interface REST autour d'eux.
Le pont : ngrok
Un notebook Colab ou Kaggle s'exécute dans un datacenter Google ou Amazon. Il n'a pas d'adresse IP publique accessible directement. Ngrok est un service de tunneling : il crée un lien chiffré entre ce notebook isolé et Internet, et vous donne une URL publique (genre https://abc123.ngrok-free.app) qui redirige le trafic vers votre serveur Ollama. C'est le pont entre votre ordinateur et le GPU dans le cloud.
Les avantages concrets
- Zéro coût hardware : vous utilisez le GPU de Google ou Kaggle, pas le vôtre.
- Confidentialité : le modèle tourne sur une infrastructure que vous contrôlez, vos requêtes ne passent pas par l'API d'OpenAI.
- Flexibilité des modèles : vous pouvez basculer entre Llama, Mistral, Gemma, DeepSeek selon vos besoins.
- API standard : Ollama expose une interface compatible avec le client Python officiel et avec beaucoup d'outils existants.
Les limites à connaître avant de commencer
- Durée de session limitée : Colab gratuit coupe les sessions après environ 12 heures d'inactivité, Kaggle après 12h de run total. À chaque redémarrage, vous devez relancer le serveur et obtenir une nouvelle URL ngrok.
- GPU non garanti : en version gratuite, l'accès au GPU dépend de la disponibilité. Si la plateforme est surchargée, vous pouvez vous retrouver sur CPU uniquement.
- URL changeante : ngrok génère une nouvelle URL à chaque tunnel. Votre client local doit être mis à jour à chaque session.
- Sécurité : l'URL ngrok est publique. Quiconque la connaît peut interroger votre serveur. On verra comment limiter ça.
Pour qui c'est fait ? Les développeurs qui veulent expérimenter avec des LLM open source sans investissement hardware, ou tester une intégration avant de déployer sur une infrastructure permanente.
Vue d'ensemble de l'architecture
Avant de coder, voici ce qu'on construit :
Votre PC Colab / Kaggle (cloud GPU)
┌─────────────────┐ ┌──────────────────────────┐
│ │ HTTPS │ │
│ Client Python │ ──────────▶ │ ngrok tunnel │
│ (ollama lib) │ │ │ │
│ │ │ ▼ │
└─────────────────┘ │ Ollama server │
│ (port 11434) │
│ │ │
│ ▼ │
│ LLM (Llama, Mistral...) │
└──────────────────────────┘
Votre code Python envoie une requête HTTPS à l'URL ngrok. Ngrok redirige vers le serveur Ollama qui tourne dans le notebook. Ollama interroge le modèle et renvoie la réponse. De votre côté, c'est transparent — vous parlez à une API HTTP standard.
Étape 0 : Créer un compte ngrok et récupérer votre token
Ngrok requiert un compte pour authentifier vos tunnels. L'offre gratuite est suffisante pour cet usage.
- Rendez-vous sur ngrok.com et créez un compte.
- Connectez-vous et ouvrez le dashboard.
- Trouvez votre Auth Token (une longue chaîne de caractères). Copiez-le.
Vous en aurez besoin dans quelques minutes. Gardez-le sous la main — mais ne le partagez pas publiquement, c'est votre clé d'accès au service.
Option A : Google Colab
Étape 1 — Créer le notebook et activer le GPU
Rendez-vous sur colab.research.google.com. Créez un nouveau notebook.
Ensuite, activez le GPU : Runtime → Change runtime type → T4 GPU. Sans cette étape, Ollama tournera sur CPU, ce qui sera trop lent pour être agréable.
Étape 2 — Installer Ollama dans l'environnement Colab
# Mise à jour des paquets système et installation d'un utilitaire
# pour détecter le matériel graphique (recommandé par Ollama sur Linux)
!sudo apt-get update -qq
!sudo apt-get install -y pciutils
# Installation d'Ollama via son script officiel
!curl -fsSL https://ollama.com/install.sh | sh
Pourquoi ce code ? Chaque session Colab démarre sur une machine Linux vierge. Ollama n'est pas pré-installé — il faut le télécharger à chaque fois. Le script officiel détecte automatiquement si un GPU NVIDIA est disponible et configure Ollama en conséquence. pciutils lui permet d'identifier correctement le matériel.
Étape 3 — Démarrer le serveur Ollama en arrière-plan
import subprocess
import time
import threading
def run_ollama_serve():
# Lance la commande "ollama serve" comme sous-processus
subprocess.Popen(["ollama", "serve"])
# On lance cette fonction dans un thread séparé
# pour ne pas bloquer l'exécution des cellules suivantes
thread = threading.Thread(target=run_ollama_serve)
thread.start()
# On attend 5 secondes que le serveur soit prêt à recevoir des connexions
time.sleep(5)
Pourquoi ce code ? ollama serve est un processus persistant — il tourne indéfiniment en attendant des requêtes. Si on l'exécutait directement dans une cellule, la cellule ne se terminerait jamais et bloquerait tout le notebook. En le lançant dans un Thread séparé, on lui permet de tourner en parallèle pendant qu'on continue à exécuter les cellules suivantes. Le sleep(5) est un délai pragmatique pour que le serveur ait le temps de démarrer avant qu'on essaie de s'y connecter.
Étape 4 — Installer les dépendances Python
!pip install -q pyngrok ollama
Pourquoi ce code ? On installe deux bibliothèques :
pyngrok: le wrapper Python pour ngrok, qui permet de créer et gérer des tunnels directement depuis du code Python.ollama: le client Python officiel pour parler à un serveur Ollama via son API.
Étape 5 — Créer le tunnel ngrok
from pyngrok import ngrok
# Collez ici votre auth token ngrok (récupéré à l'étape 0)
NGROK_AUTH_TOKEN = "VOTRE_TOKEN_ICI"
ngrok.set_auth_token(NGROK_AUTH_TOKEN)
# On crée un tunnel HTTPS vers le port 11434 (port par défaut d'Ollama)
# host_header est nécessaire pour que ngrok transmette correctement les requêtes
public_url = ngrok.connect(11434, host_header="localhost:11434")
print("URL publique de votre serveur Ollama :", public_url.public_url)
Pourquoi ce code ? Ollama écoute sur localhost:11434 — une adresse accessible uniquement depuis l'intérieur du notebook. Ngrok crée un pont entre ce port local et une URL publique HTTPS accessible depuis n'importe où sur Internet. Le paramètre host_header="localhost:11434" est important : il indique à ngrok comment reformuler les en-têtes HTTP pour qu'Ollama les accepte correctement. Sans lui, vous obtiendrez une page d'avertissement ngrok au lieu d'une réponse du modèle.
Copiez l'URL imprimée. Elle ressemble à https://abc123.ngrok-free.app. Vous en aurez besoin sur votre propre ordinateur.
Étape 6 — Télécharger un modèle
# Télécharge le modèle Llama 3.2 (3B paramètres, ~2 Go)
# Cette opération peut prendre quelques minutes selon la bande passante de Colab
!ollama pull llama3.2
Pourquoi ce code ? Avant de pouvoir interroger un modèle, Ollama doit télécharger ses poids depuis la bibliothèque officielle. llama3.2 est un bon point de départ — compact (3B paramètres), rapide sur GPU, et suffisamment capable pour la plupart des usages. Vous pouvez consulter tous les modèles disponibles sur ollama.com/library. Pour plus de puissance, essayez llama3.1:8b ou mistral:7b (nécessitent plus de VRAM).
Option B : Kaggle Notebook (alternative à Colab)
Kaggle offre une alternative solide, avec parfois deux GPU T4 en parallèle. La procédure est quasi-identique, avec une différence importante sur la gestion du token ngrok.
Étape 1 — Créer le notebook et activer le GPU
Sur kaggle.com/code, créez un nouveau notebook. Dans les paramètres de session, activez Accelerator → GPU T4 x2.
Étape 2 — Stocker le token ngrok de façon sécurisée
Kaggle propose un système de Secrets pour stocker des données sensibles sans les écrire en dur dans le code. C'est la bonne pratique à adopter.
Dans votre notebook Kaggle : Add-ons → Secrets → Add a new secret. Ajoutez :
- Label :
NGROK_AUTHTOKEN - Value : votre token ngrok
Ensuite, dans votre notebook :
from kaggle_secrets import UserSecretsClient
from pyngrok import ngrok
# Récupère le token depuis le coffre-fort sécurisé de Kaggle
# (jamais visible dans le code ni dans les logs publics)
user_secrets = UserSecretsClient()
ngrok_auth_token = user_secrets.get_secret("NGROK_AUTHTOKEN")
ngrok.set_auth_token(ngrok_auth_token)
Pourquoi ce code ? Hardcoder un token dans un notebook, c'est risqué — si vous partagez accidentellement le notebook, le token est exposé. Le système de Secrets de Kaggle stocke la valeur de façon chiffrée et l'injecte à l'exécution sans jamais l'écrire dans le fichier. C'est l'équivalent des variables d'environnement en développement local.
Étapes 3 à 6 — Identiques à Colab
# Installer Ollama et les dépendances
!curl -fsSL https://ollama.com/install.sh | sh
!pip install -q pyngrok ollama
# Démarrer le serveur en arrière-plan
import subprocess, time, threading
def run_ollama_serve():
subprocess.Popen(["ollama", "serve"])
thread = threading.Thread(target=run_ollama_serve)
thread.start()
time.sleep(5)
# Créer le tunnel ngrok
public_url = ngrok.connect(11434, host_header="localhost:11434")
print("URL publique :", public_url.public_url)
# Télécharger le modèle
!ollama pull llama3.2
Étape finale : interroger le serveur depuis votre ordinateur
Votre serveur tourne dans le cloud. Votre URL ngrok est copiée. Maintenant, sur votre propre machine.
Installer le client Python Ollama en local
pip install ollama
Pointer le client vers votre serveur distant
from ollama import Client
# Remplacez par votre URL ngrok (avec https://, sans slash final)
client = Client(host="https://VOTRE-URL-NGROK.ngrok-free.app")
Pourquoi ce code ? Par défaut, le client Ollama pointe vers localhost:11434 — votre machine locale. En spécifiant host, on lui dit d'envoyer toutes ses requêtes vers votre serveur distant à la place. Du point de vue du client, c'est transparent : il ne sait pas (et n'a pas besoin de savoir) que le serveur est dans un datacenter Google à des milliers de kilomètres.
Télécharger le modèle côté serveur (via Python)
# S'assure que le modèle est bien disponible sur le serveur distant
# À faire une fois par session (si ollama pull a déjà été fait dans le notebook, c'est redondant)
client.pull("llama3.2")
Envoyer une première requête
response = client.chat(
model="llama3.2",
messages=[
{"role": "user", "content": "Explique-moi la tokenisation en 3 phrases simples."}
]
)
print(response["message"]["content"])
Pourquoi ce code ? client.chat() envoie une requête de conversation au format standard (liste de messages avec rôles user/assistant/system). C'est la même interface que l'API OpenAI, volontairement compatible pour faciliter les migrations. La réponse est un dictionnaire Python dont on extrait le contenu avec ["message"]["content"].
Variante avec streaming (réponse progressive)
# Le streaming affiche chaque token au fur et à mesure de sa génération
# Utile pour les longues réponses : pas besoin d'attendre la fin
for chunk in client.chat(
model="llama3.2",
messages=[{"role": "user", "content": "Écris un court poème sur les tokens."}],
stream=True,
):
# end="" et flush=True empêchent les sauts de ligne entre chaque token
print(chunk.message.content, end="", flush=True)
print() # Saut de ligne final
Pourquoi ce code ? Sans streaming, votre script attend que le modèle ait généré toute la réponse avant de l'afficher — ce qui peut prendre 10 à 30 secondes pour une longue réponse. Avec stream=True, chaque token est envoyé dès qu'il est généré, exactement comme l'interface de ChatGPT qui "tape" progressivement. C'est meilleur pour l'expérience utilisateur et pour les longues interactions.
Template complet à copier-coller
Dans Colab (tout en un)
# ── CELLULE 1 : Installation ──────────────────────────────────────────────────
!sudo apt-get update -qq
!sudo apt-get install -y pciutils
!curl -fsSL https://ollama.com/install.sh | sh
!pip install -q pyngrok ollama
# ── CELLULE 2 : Démarrer Ollama en arrière-plan ───────────────────────────────
import subprocess, time, threading
def run_ollama_serve():
subprocess.Popen(["ollama", "serve"])
thread = threading.Thread(target=run_ollama_serve)
thread.start()
time.sleep(5)
print("Serveur Ollama démarré.")
# ── CELLULE 3 : Tunnel ngrok ──────────────────────────────────────────────────
from pyngrok import ngrok
NGROK_AUTH_TOKEN = "COLLEZ_VOTRE_TOKEN_ICI"
ngrok.set_auth_token(NGROK_AUTH_TOKEN)
public_url = ngrok.connect(11434, host_header="localhost:11434")
print("✅ Copiez cette URL :", public_url.public_url)
# ── CELLULE 4 : Télécharger le modèle ────────────────────────────────────────
!ollama pull llama3.2
print("✅ Modèle prêt.")
Sur votre ordinateur
from ollama import Client
# Remplacez par l'URL copiée depuis le notebook
client = Client(host="https://VOTRE-URL.ngrok-free.app")
# Test rapide
response = client.chat(
model="llama3.2",
messages=[{"role": "user", "content": "Bonjour, tu fonctionne ?"}]
)
print(response["message"]["content"])
Checklist et sécurité
Avant d'envoyer la première requête :
- L'URL ngrok commence bien par
https://dans votre client Python. - Vous avez copié l'URL après avoir exécuté la cellule ngrok (elle change à chaque session).
- Le modèle a bien été téléchargé (
ollama pull) avant d'être appelé.
Si ça ne répond pas :
- Vérifiez que la cellule "Démarrer Ollama" a bien été exécutée et que vous avez attendu le
time.sleep(5). - Re-exécutez la cellule ngrok pour obtenir une nouvelle URL (les tunnels peuvent expirer).
- Assurez-vous que votre runtime Colab/Kaggle est toujours actif (les sessions inactives se ferment).
Sécurité :
- Votre URL ngrok est publique. Quiconque la connaît peut interroger votre modèle. Ne la partagez pas.
- Ne commitez jamais votre auth token ngrok dans du code public (GitHub, etc.).
- Pour une utilisation prolongée, activez les restrictions d'IP ou l'authentification basique dans le dashboard ngrok.
Les limites réelles — et comment les contourner (partiellement)
Deux frictions majeures reviennent à chaque session :
1. L'URL change. Ngrok génère une nouvelle URL à chaque tunnel. Ce n'est pas contournable avec l'offre gratuite — les tunnels statiques sont réservés aux abonnements payants. La solution pragmatique : écrire un petit script sur votre PC qui lit l'URL depuis un fichier partagé (Google Drive, Gist privé) que vous mettez à jour depuis le notebook.
2. Relancer manuellement. À chaque session, vous devez ouvrir le notebook et exécuter les cellules. Il n'existe pas de moyen fiable de démarrer automatiquement un notebook Colab ou Kaggle depuis l'extérieur sans passer par leur interface — les deux plateformes ont délibérément limité cette possibilité pour éviter les abus de ressources.
Ce qui vient ensuite. Si vous avez besoin d'un serveur LLM persistant, disponible 24/7, avec une URL fixe et sans intervention manuelle, la prochaine étape logique est un déploiement sur une infrastructure dédiée : une instance GPU sur RunPod, Vast.ai, ou Lambda Labs (quelques dollars par heure), avec Ollama installé comme service système et une URL stable. C'est le sujet d'un prochain article.
La puissance de calcul qui coûtait des dizaines de milliers d'euros en hardware il y a cinq ans est maintenant accessible gratuitement, dans le cloud, à n'importe qui avec un compte Google. Ce guide vous donne les clés pour en profiter — sans attendre d'avoir un GPU dans votre tiroir.
You've heard about Llama, Mistral, Gemma. Open-source models as capable as the big ones — no subscription, no sending your data to a third-party API, no vendor dependency. You wanted to test them. Then you saw the recommended specs: 16 GB of VRAM minimum, dedicated graphics card, ideally an RTX 4090.
Your laptop politely nodded and looked away.
There's a solution most people miss: Google Colab and Kaggle provide free cloud GPUs — real ones, Tesla T4s, sometimes A100s. They're designed for machine learning, but nothing stops you from using them as LLM servers. With a tunneling tool called ngrok, you can expose that server to the internet and call it from your own machine as if the model were running locally.
This guide walks you through it, A to Z — with the why behind every step.
Why this approach, and for whom
Before touching any code, let's set the context.
The problem: LLMs are GPU-hungry
Large language models, even in their "lightweight" versions like Llama 3.2 (3B parameters), need to load their weights into video memory to run inference. A 7-billion-parameter model in standard precision occupies around 14 GB of VRAM. Most consumer laptops have 4 to 8 GB of VRAM shared with the CPU — not enough for smooth execution.
The solution: borrow a GPU
Google Colab (free tier) and Kaggle offer cloud execution environments with integrated GPU, available for free within certain limits. These platforms are usually used for training or fine-tuning models. But a GPU is a GPU: you can just as easily use one to run an inference server.
The tool at the center: Ollama
Ollama is an application that radically simplifies LLM management locally (or in a server environment). It downloads models, optimizes them for your hardware, and exposes a standard HTTP API on port 11434. Think of it as a model manager that wraps a REST interface around them.
The bridge: ngrok
A Colab or Kaggle notebook runs in a Google or Amazon datacenter. It has no directly accessible public IP address. Ngrok is a tunneling service: it creates an encrypted link between this isolated notebook and the internet, giving you a public URL (like https://abc123.ngrok-free.app) that redirects traffic to your Ollama server. It's the bridge between your computer and the GPU in the cloud.
The concrete advantages
- Zero hardware cost: you use Google's or Kaggle's GPU, not yours.
- Privacy: the model runs on infrastructure you control, your requests don't go through OpenAI's API.
- Model flexibility: you can switch between Llama, Mistral, Gemma, DeepSeek as needed.
- Standard API: Ollama exposes an interface compatible with the official Python client and many existing tools.
The limits to know before starting
- Limited session duration: free Colab cuts sessions after about 12 hours of inactivity, Kaggle after 12 hours total runtime. On each restart, you need to relaunch the server and get a new ngrok URL.
- GPU not guaranteed: on the free tier, GPU access depends on availability. If the platform is overloaded, you might end up on CPU only.
- Changing URL: ngrok generates a new URL with each tunnel. Your local client must be updated each session.
- Security: the ngrok URL is public. Anyone who knows it can query your server. We'll cover how to limit this.
Who is this for? Developers who want to experiment with open-source LLMs without hardware investment, or test an integration before deploying to permanent infrastructure.
Architecture overview
Before coding, here's what we're building:
Your PC Colab / Kaggle (cloud GPU)
┌─────────────────┐ ┌──────────────────────────┐
│ │ HTTPS │ │
│ Python Client │ ──────────▶ │ ngrok tunnel │
│ (ollama lib) │ │ │ │
│ │ │ ▼ │
└─────────────────┘ │ Ollama server │
│ (port 11434) │
│ │ │
│ ▼ │
│ LLM (Llama, Mistral...) │
└──────────────────────────┘
Your Python code sends an HTTPS request to the ngrok URL. Ngrok redirects to the Ollama server running in the notebook. Ollama queries the model and returns the response. On your end, it's transparent — you're talking to a standard HTTP API.
Step 0: Create an ngrok account and get your auth token
Ngrok requires an account to authenticate your tunnels. The free tier is sufficient for this use case.
- Go to ngrok.com and create an account.
- Log in and open the dashboard.
- Find your Auth Token (a long character string). Copy it.
You'll need it in a few minutes. Keep it handy — but don't share it publicly, it's your service access key.
Option A: Google Colab
Step 1 — Create the notebook and activate the GPU
Go to colab.research.google.com. Create a new notebook.
Then activate the GPU: Runtime → Change runtime type → T4 GPU. Without this step, Ollama will run on CPU, which will be too slow to be useful.
Step 2 — Install Ollama in the Colab environment
# System package update and installation of a hardware detection utility
# (recommended by Ollama on Linux)
!sudo apt-get update -qq
!sudo apt-get install -y pciutils
# Install Ollama via its official script
!curl -fsSL https://ollama.com/install.sh | sh
Why this code? Each Colab session starts on a fresh Linux machine. Ollama isn't pre-installed — you need to download it each time. The official script automatically detects whether an NVIDIA GPU is available and configures Ollama accordingly. pciutils allows it to correctly identify the hardware.
Step 3 — Start the Ollama server in the background
import subprocess
import time
import threading
def run_ollama_serve():
# Launch "ollama serve" as a subprocess
subprocess.Popen(["ollama", "serve"])
# We launch this function in a separate thread
# so it doesn't block subsequent cell execution
thread = threading.Thread(target=run_ollama_serve)
thread.start()
# Wait 5 seconds for the server to be ready to accept connections
time.sleep(5)
Why this code? ollama serve is a persistent process — it runs indefinitely waiting for requests. If we ran it directly in a cell, the cell would never finish and would block the entire notebook. By launching it in a separate Thread, we let it run in parallel while we continue executing subsequent cells. The sleep(5) is a pragmatic delay to give the server time to start before we try to connect to it.
Step 4 — Install Python dependencies
!pip install -q pyngrok ollama
Why this code? We're installing two libraries:
pyngrok: the Python wrapper for ngrok, enabling tunnel creation and management directly from Python code.ollama: the official Python client to talk to an Ollama server via its API.
Step 5 — Create the ngrok tunnel
from pyngrok import ngrok
# Paste your ngrok auth token here (from step 0)
NGROK_AUTH_TOKEN = "YOUR_TOKEN_HERE"
ngrok.set_auth_token(NGROK_AUTH_TOKEN)
# Create an HTTPS tunnel to port 11434 (Ollama's default port)
# host_header is required for ngrok to correctly forward requests
public_url = ngrok.connect(11434, host_header="localhost:11434")
print("Your Ollama server's public URL:", public_url.public_url)
Why this code? Ollama listens on localhost:11434 — an address only accessible from inside the notebook. Ngrok creates a bridge between this local port and a public HTTPS URL accessible from anywhere on the internet. The host_header="localhost:11434" parameter is important: it tells ngrok how to rewrite HTTP headers so Ollama accepts them correctly. Without it, you'll get an ngrok warning page instead of a model response.
Copy the printed URL. It looks like https://abc123.ngrok-free.app. You'll need it on your own computer.
Step 6 — Download a model
# Downloads the Llama 3.2 model (3B parameters, ~2 GB)
# This operation may take a few minutes depending on Colab's bandwidth
!ollama pull llama3.2
Why this code? Before querying a model, Ollama needs to download its weights from the official library. llama3.2 is a good starting point — compact (3B parameters), fast on GPU, and capable enough for most uses. You can browse all available models at ollama.com/library. For more power, try llama3.1:8b or mistral:7b (require more VRAM).
Option B: Kaggle Notebook (alternative to Colab)
Kaggle is a solid alternative, sometimes offering two T4 GPUs in parallel. The procedure is nearly identical, with one important difference in ngrok token management.
Step 1 — Create the notebook and activate the GPU
On kaggle.com/code, create a new notebook. In the session settings, enable Accelerator → GPU T4 x2.
Step 2 — Store the ngrok token securely
Kaggle offers a Secrets system for storing sensitive data without hardcoding it. This is the best practice to adopt.
In your Kaggle notebook: Add-ons → Secrets → Add a new secret. Add:
- Label:
NGROK_AUTHTOKEN - Value: your ngrok token
Then in your notebook:
from kaggle_secrets import UserSecretsClient
from pyngrok import ngrok
# Retrieves the token from Kaggle's secure vault
# (never visible in code or public logs)
user_secrets = UserSecretsClient()
ngrok_auth_token = user_secrets.get_secret("NGROK_AUTHTOKEN")
ngrok.set_auth_token(ngrok_auth_token)
Why this code? Hardcoding a token in a notebook is risky — if you accidentally share the notebook, the token is exposed. Kaggle's Secrets system stores the value encrypted and injects it at runtime without ever writing it to the file. It's the equivalent of environment variables in local development.
Steps 3 through 6 — Identical to Colab
# Install Ollama and dependencies
!curl -fsSL https://ollama.com/install.sh | sh
!pip install -q pyngrok ollama
# Start server in background
import subprocess, time, threading
def run_ollama_serve():
subprocess.Popen(["ollama", "serve"])
thread = threading.Thread(target=run_ollama_serve)
thread.start()
time.sleep(5)
# Create ngrok tunnel
public_url = ngrok.connect(11434, host_header="localhost:11434")
print("Public URL:", public_url.public_url)
# Download model
!ollama pull llama3.2
Final step: query the server from your computer
Your server is running in the cloud. Your ngrok URL is copied. Now, on your own machine.
Install the Ollama Python client locally
pip install ollama
Point the client to your remote server
from ollama import Client
# Replace with your ngrok URL (with https://, no trailing slash)
client = Client(host="https://YOUR-URL.ngrok-free.app")
Why this code? By default, the Ollama client points to localhost:11434 — your local machine. By specifying host, we tell it to send all its requests to your remote server instead. From the client's perspective, it's transparent: it doesn't know (and doesn't need to know) that the server is in a Google datacenter thousands of kilometers away.
Download the model on the server side (via Python)
# Ensures the model is available on the remote server
# (redundant if ollama pull was already run in the notebook)
client.pull("llama3.2")
Send a first request
response = client.chat(
model="llama3.2",
messages=[
{"role": "user", "content": "Explain tokenization in 3 simple sentences."}
]
)
print(response["message"]["content"])
Why this code? client.chat() sends a conversation request in the standard format (list of messages with user/assistant/system roles). It's the same interface as the OpenAI API, deliberately compatible for easy migrations. The response is a Python dictionary from which we extract the content with ["message"]["content"].
Variant with streaming (progressive response)
# Streaming displays each token as it's generated
# Useful for long responses: no need to wait for the end
for chunk in client.chat(
model="llama3.2",
messages=[{"role": "user", "content": "Write a short poem about tokens."}],
stream=True,
):
# end="" and flush=True prevent line breaks between each token
print(chunk.message.content, end="", flush=True)
print() # Final line break
Why this code? Without streaming, your script waits for the model to generate the entire response before displaying anything — which can take 10 to 30 seconds for a long response. With stream=True, each token is sent as soon as it's generated, exactly like the ChatGPT interface that progressively "types." This improves user experience and works better for long interactions.
Complete copy-paste template
In Colab (all-in-one)
# ── CELL 1: Installation ──────────────────────────────────────────────────────
!sudo apt-get update -qq
!sudo apt-get install -y pciutils
!curl -fsSL https://ollama.com/install.sh | sh
!pip install -q pyngrok ollama
# ── CELL 2: Start Ollama in background ───────────────────────────────────────
import subprocess, time, threading
def run_ollama_serve():
subprocess.Popen(["ollama", "serve"])
thread = threading.Thread(target=run_ollama_serve)
thread.start()
time.sleep(5)
print("Ollama server started.")
# ── CELL 3: ngrok tunnel ──────────────────────────────────────────────────────
from pyngrok import ngrok
NGROK_AUTH_TOKEN = "PASTE_YOUR_TOKEN_HERE"
ngrok.set_auth_token(NGROK_AUTH_TOKEN)
public_url = ngrok.connect(11434, host_header="localhost:11434")
print("✅ Copy this URL:", public_url.public_url)
# ── CELL 4: Download model ────────────────────────────────────────────────────
!ollama pull llama3.2
print("✅ Model ready.")
On your computer
from ollama import Client
# Replace with the URL copied from the notebook
client = Client(host="https://YOUR-URL.ngrok-free.app")
# Quick test
response = client.chat(
model="llama3.2",
messages=[{"role": "user", "content": "Hello, are you working?"}]
)
print(response["message"]["content"])
Checklist and security
Before sending the first request:
- The ngrok URL starts with
https://in your Python client. - You copied the URL after running the ngrok cell (it changes each session).
- The model was downloaded (
ollama pull) before being called.
If it's not responding:
- Verify the "Start Ollama" cell was executed and you waited through
time.sleep(5). - Re-run the ngrok cell to get a new URL (tunnels can expire).
- Make sure your Colab/Kaggle runtime is still active (inactive sessions close).
Security:
- Your ngrok URL is public. Anyone who knows it can query your model. Don't share it.
- Never commit your ngrok auth token to public code (GitHub, etc.).
- For extended use, enable IP restrictions or basic auth in the ngrok dashboard.
Real limits — and partial workarounds
Two major frictions come up every session:
1. The URL changes. Ngrok generates a new URL with each tunnel. This isn't avoidable on the free tier — static tunnels are reserved for paid plans. The pragmatic solution: write a small script on your PC that reads the URL from a shared file (Google Drive, private Gist) that you update from the notebook.
2. Manual relaunch. Each session requires opening the notebook and executing the cells. There's no reliable way to automatically start a Colab or Kaggle notebook from the outside without going through their interface — both platforms have deliberately limited this to prevent resource abuse.
What comes next. If you need a persistent LLM server, available 24/7, with a fixed URL and no manual intervention, the logical next step is deploying to dedicated infrastructure: a GPU instance on RunPod, Vast.ai, or Lambda Labs (a few dollars per hour), with Ollama installed as a system service and a stable URL. That's the subject of a future article.
The computing power that cost tens of thousands in hardware five years ago is now freely accessible, in the cloud, to anyone with a Google account. This guide gives you the keys to take advantage of it — no GPU required in your drawer.
