Rent a cloud GPU by the hour to run models your laptop can't
Your laptop tops out at small models. For about 60 cents an hour, rent a 48GB data-centre graphics card, chat with a model several times bigger through an encrypted tunnel, then switch it off, with a timer that does it for you if you forget.
gemma4:31b (or a 70B model), which a 16GB laptop can't load- A starter kit: a GPU-fit calculator with a price table you can update, setup scripts for Ollama and vLLM, a chat client that shows tokens per second, and an auto-stop timer
- The billing rules that matter: stop versus terminate, and why a stopped pod's disk still costs money
- Run a ChatGPT-style AI on your own laptop and Pick the right AI model for your laptop done, so model sizes and
ollama runare familiar. - uv, from Put AI in your terminal. It runs the kit's Python scripts. They only use the standard library, so nothing else installs.
- An account with RunPod (runpod.io ↗) or Vast.ai (vast.ai ↗), with prepaid credit. RunPod says you can start with $10 and needs at least an hour of runtime in your balance before it rents you a pod; its credits aren't refundable. Vast.ai's minimum deposit is $5. Use a normal debit or credit card: prepaid cards are often declined.
- An SSH client. Windows 10 and 11 include OpenSSH, and so do macOS and Linux. Comfort with the terminal from the Terminal survival kit.
Pick a GPU by its memory, not its name
One number decides whether a model runs: the card's video memory (VRAM). After that, it's just price per GB.
A model runs fast only when all of it fits in the graphics card's own memory, the VRAM. If it doesn't fit, Ollama splits it between the GPU and normal RAM and it slows to a crawl, and vLLM refuses to start. So always start from the model's size, not the card's name.
For Ollama models, the size is printed on every tag at ollama.com/library ↗. A few that won't run on a 16GB laptop:
gemma4:31b, 19GB: the biggest Gemma 4, big brother of thee2byou ran on your laptop. Fits a 24GB card.qwen3-coder:30b, 19GB: a coding model. Fits a 24GB card.llama3.3:70b, 43GB: a 70B model at 4-bit. Fits a 48GB card with Ollama's default 4,096-token context, with little to spare.gpt-oss:120b, 65GB: needs an 80GB card.
For original Hugging Face files, the kind vLLM serves in step 6, RunPod's rule of thumb is about 2GB of VRAM per billion parameters. So Qwen3-14B needs about 28GB for its weights (its files are 29.5GB). A 4-bit quantised version, which is what most Ollama tags are, needs roughly a quarter of that.
Now compare cards on price per GB of VRAM, not price per card. Download the starter kit, rent-a-cloud-gpu.zip (10KB), unzip it and run the calculator for
gemma4:31b:Windowscd $HOME\Downloads Expand-Archive rent-a-cloud-gpu.zip -DestinationPath . cd rent-a-cloud-gpu uv run gpu_fit.py --model-gb 19 --hours 2Mac / Linuxcd ~/Downloads unzip rent-a-cloud-gpu.zip cd rent-a-cloud-gpu uv run gpu_fit.py --model-gb 19 --hours 2OutputModel weights: 19.0 GB -> needs about 20.9 GB of VRAM with ollama Disk to ask for: about 31 GB (stopped, that volume costs $6.20/month on RunPod) GPU VRAM $/hr $/GB/hr session ranked by: secure RTX A5000 24GB 0.27 0.0113 0.54 RTX 3090 24GB 0.50 0.0208 1.00 L4 24GB 0.59 0.0246 1.18 A40 48GB 0.59 0.0123 1.18 RTX A6000 48GB 0.59 0.0123 1.18 RTX 4090 24GB 0.89 0.0371 1.78 RTX 6000 Ada 48GB 0.99 0.0206 1.98 L40S 48GB 1.09 0.0227 2.18 RTX 5090 32GB 1.19 0.0372 2.38 A100 80GB 80GB 1.79 0.0224 3.58 RTX PRO 6000 96GB 2.49 0.0259 4.98 H100 PCIe 80GB 2.89 0.0361 5.78 H100 NVL 94GB 3.19 0.0339 6.38 H100 SXM 80GB 3.99 0.0499 7.98 Cheapest fit: RTX A5000 (24GB) at $0.27/hr. Check the console for today's price.Read the
$/GB/hrcolumn. The RTX 4090, the card everyone has heard of, is one of the most expensive ways to rent 24GB. The A40 and RTX A6000 give you 48GB for $0.59: double the memory for less money, which leaves room for a longer context or a 70B model on the same card. A 4090 generates faster when a model fits in 24GB, but for big models, memory is the limit.This mission uses
gemma4:31bon an A40. Here is the full calculator. The prices are a plain table at the top, so you can update them (prices change, so check the console before you rent):gpu_fit.py# /// script # requires-python = ">=3.10" # dependencies = [] # /// """Which rented GPU fits this model, and what will it cost? Give it the size of the model you want to run, and it lists the cards with enough VRAM, cheapest first, with the price per GB of VRAM and the cost of your session. uv run gpu_fit.py --model-gb 19 # an Ollama download size (gemma4:31b) uv run gpu_fit.py --params 14 --engine vllm # a Hugging Face model for vLLM (Qwen3-14B) uv run gpu_fit.py --model-gb 43 --hours 3 --cloud community # llama3.3:70b The prices below come from the RunPod pricing page and the Vast.ai marketplace. They change (Vast.ai's every hour), so check the console before you rent, and edit the PRICES table to update them. """ from __future__ import annotations import argparse # name, VRAM in GB, RunPod Secure Cloud $/hr, RunPod Community Cloud $/hr, # Vast.ai on-demand median $/hr (None = not listed) PRICES = [ ("RTX A5000", 24, 0.27, 0.16, None), ("RTX 3090", 24, 0.50, 0.22, 0.22), ("L4", 24, 0.59, 0.44, None), ("RTX 4090", 24, 0.89, 0.34, 0.44), ("RTX 5090", 32, 1.19, 0.69, 0.61), ("A40", 48, 0.59, 0.35, None), ("RTX A6000", 48, 0.59, 0.33, 0.40), ("RTX 6000 Ada", 48, 0.99, 0.74, None), ("L40S", 48, 1.09, 0.79, 0.67), ("A100 80GB", 80, 1.79, 1.19, 0.99), ("H100 PCIe", 80, 2.89, 1.99, None), ("H100 SXM", 80, 3.99, 2.69, 2.27), ("H100 NVL", 94, 3.19, 2.59, None), ("RTX PRO 6000", 96, 2.49, 1.69, None), ] RUNPOD_IDLE_VOLUME = 0.20 # $/GB/month for a stopped pod's volume disk (RunPod pricing page) def vram_needed(w: float, engine: str) -> float: if engine == "vllm": # vLLM claims 92% of the card by default (--gpu-memory-utilization 0.92) # and needs room inside that for the KV cache. 4GB covers about 16k tokens # of context on a 14B model. return (w + 4) / 0.92 # Ollama: weights plus about 10% for its default 4,096-token context and CUDA. return w * 1.1 def weights_gb(args: argparse.Namespace) -> float: if args.model_gb: return args.model_gb # parameters (billions) x bytes per parameter. 16-bit = 2 bytes, so 14B -> 28GB. return args.params * args.bits / 8 def main() -> None: ap = argparse.ArgumentParser(description="Find the cheapest rented GPU that fits a model.") size = ap.add_mutually_exclusive_group(required=True) size.add_argument("--model-gb", type=float, help="model file size in GB (Ollama shows it on each tag)") size.add_argument("--params", type=float, help="parameters in billions, for example 14 for a 14B model") ap.add_argument("--bits", type=float, default=16, help="bits per weight: 16 for original Hugging Face files, about 4.5 for Q4 GGUF") ap.add_argument("--engine", choices=["ollama", "vllm"], default="ollama", help="what will serve the model") ap.add_argument("--hours", type=float, default=1, help="how long you'll rent it for") ap.add_argument("--cloud", choices=["secure", "community", "vast"], default="secure", help="which price to rank by") args = ap.parse_args() w = weights_gb(args) need = vram_needed(w, args.engine) # model files + room for the runtime: vLLM's own install (PyTorch and CUDA # libraries) lives on the volume too, and is far bigger than Ollama's. disk = round(w * 1.1 + (20 if args.engine == "vllm" else 10)) col = {"secure": 2, "community": 3, "vast": 4}[args.cloud] print(f"Model weights: {w:.1f} GB -> needs about {need:.1f} GB of VRAM with {args.engine}") print(f"Disk to ask for: about {disk} GB (stopped, that volume costs ${disk * RUNPOD_IDLE_VOLUME:.2f}/month on RunPod)\n") fits = [p for p in PRICES if p[1] >= need and p[col] is not None] if not fits: print("Nothing on one card fits. Use a smaller quantisation (a Q4 tag), a smaller model, or 2+ GPUs.") return fits.sort(key=lambda p: p[col]) print(f"{'GPU':<14}{'VRAM':>6}{'$/hr':>8}{'$/GB/hr':>10}{'session':>10} ranked by: {args.cloud}") for p in fits: price = p[col] print(f"{p[0]:<14}{p[1]:>4}GB{price:>8.2f}{price / p[1]:>10.4f}{price * args.hours:>10.2f}") best = fits[0] print(f"\nCheapest fit: {best[0]} ({best[1]}GB) at ${best[col]:.2f}/hr. Check the console for today's price.") if __name__ == "__main__": main()Secure Cloud or Community Cloud?On RunPod, Secure Cloud runs in professional T3/T4 data centres. Community Cloud connects you to vetted individual providers, and is cheaper. For a model you're just trying out, Community is fine. For anything personal, or a client's data, use Secure Cloud (on Vast.ai, tick Secure Cloud (Only Trusted Datacenters)) and pick a European region. If you put other people's personal data through it, UK GDPR applies: you're handing it to a processor, often abroad, so check the provider's data processing terms first.
TipVast.ai is a marketplace where hosts set their own prices, so run the calculator with--cloud vastand confirm in its console. Skip its interruptible instances for this: they're cheaper but can be paused at any moment.
gemma4:31b (19GB) on an A40 (48GB).If it breaks'uv' is not recognised + 2 more
'uv' is not recognised
winget install --id astral-sh.uv -e on Windows, brew install uv on a Mac), then open a new terminal.It says 'Nothing on one card fits'
q4 tag instead of q8 or fp16), a smaller model, or a card with more VRAM. Splitting one model across two GPUs works, but it's beyond this mission.