
Nasazení LLM s Modal: Od pip install po produkční endpoint
Většina průvodců samostatným hostováním LLM přehlíží tu nejtěžší část: infrastrukturu. Bojujete s ovladači CUDA, spravujete Docker obrazy, konfigurujete automatické škálování a nakonec stejně platíte za nečinné GPU ve 3 ráno. Modal eliminuje vše z toho. Napíšete Python, nasadíte ho a dostanete URL adresu.
Tento průvodce vás provede nasazením open-source LLM na Modal s vLLM jako inferenčním enginem. Na konci budete mít živý, OpenAI-kompatibilní API endpoint běžící na GPU H100, který se při nepoužívání škáluje na nulu.
Co je Modal (a proč ho používat pro LLM)?
Modal je serverless výpočetní platforma postavená speciálně pro AI workloady. Představte si AWS Lambda, ale s podporou GPU, fakturací za sekundu a vývojářským prostředím nativním pro Python. Žádný YAML, žádné Dockerfiles, žádný Kubernetes – celou svou infrastrukturu definujete v Python skriptu a nasadíte jediným příkazem.
Zde je důvod, proč se stal go-to řešením pro nasazování LLM:
- Fakturace se škálováním na nulu, když váš endpoint nezpracovává požadavky, neplatíte nic
- Ceny GPU za sekundu, H100 za ~3,95 USD/hod, A100 80GB za ~2,50 USD/hod, fakturováno po sekundách
- Studené starty pod jednu sekundu, kontejnery se spouštějí rychle, zejména díky snapshotům paměti
- 30 USD měsíčně zdarma, dostatek kreditů na experimentování bez poplatku za kreditní kartu
- Žádný DevOps, žádné Docker buildy, žádný Terraform, žádná správa clusterů
Pokud jste provozovali LLM lokálně a chcete jim poskytnout pořádné API bez správy serverů, Modal je k tomu nejkratší cestou.
Modal vs. RunPod vs. Lambda
| Funkce | Modal | RunPod | Lambda |
|---|---|---|---|
| Model fakturace | Za sekundu, škálování na nulu | Za sekundu, minimální poplatek | Za hodinu, vždy zapnuto |
| Studený start | 2–4 sekundy | 6–12 sekund (velké) | N/A (trvalé) |
| Dostupnost GPU | H100, A100, L40S, T4 | A100, H100, A6000 | H100, A100 |
| Infrastruktura | Čistý Python, žádné konfigurační soubory | Na bázi Dockeru, větší kontrola | Plný přístup k VM |
| Free tier | 30 USD/měsíc kredity | Žádný | Žádný |
| Nejlepší pro | Nestálé/dev workloady | Stabilní inferenční traffic | Trénink s vysokým využitím |
Závěr: Modal vítězí u nestálých workloadů a ve vývoji. Pokud bude vaše využití GPU trvale přesahovat 40 %, dedikovaná instance na RunPod nebo Lambda je levnější. Pro všechno ostatní, prototypování, přerušovaná API, dema, model škálování na nulu od Modal šetří skutečné peníze.
Předpoklady
Než začnete, potřebujete tři věci:
- Python 3.10+ nainstalovaný lokálně
- Účet Modal, zaregistrujte se zdarma na modal.com
- Účet Hugging Face, pro přístup k modelům (většina modelů je chráněna)
To je vše. Žádné GPU na vašem lokálním stroji, žádný CUDA toolkit, žádný Docker.
Krok 1: Instalace Modal a autentizace
Otevřete terminál a nainstalujte Python balíček Modal:
pip install modalPoté spusťte setup příkaz pro propojení vašeho lokálního prostředí s účtem Modal:
modal setupTím se otevře okno prohlížeče pro autentizaci. Jakmile potvrdíte, Modal uloží token lokálně. Už to nebudete muset dělat znovu.
Krok 2: Definice obrazu kontejneru
Kontejnery Modal jsou definovány v Pythonu. Zadáte základní obraz, nainstalujete závislosti a nastavíte proměnné prostředí, vše jako kód. Vytvořte soubor nazvaný app.py:
import modal
# Define the container image with CUDA, Python, and vLLM
vllm_image = (
modal.Image.from_registry(
"nvidia/cuda:12.8.0-devel-ubuntu22.04", add_python="3.12"
)
.entrypoint([])
.pip_install(
"vllm==0.13.0",
"huggingface-hub==0.36.0",
)
)
app = modal.App("llm-endpoint", image=vllm_image)Pár věcí k povšimnutí. Neexistuje žádný Dockerfile, řetězec modal.Image jej zcela nahrazuje. Základní obraz obsahuje NVIDIA CUDA 12.8 s Ubuntu 22.04 a my na něj instalujeme vLLM a klienta Hugging Face Hub.
Krok 3: Konfigurace úložiště modelu pomocí Volume
Váhy LLM jsou velké (model s 7 miliardami parametrů má ve formátu fp16 cca 14 GB). Nechcete je stahovat při každém spuštění kontejneru. Modal Volumes vám poskytují perzistentní úložiště, které se přímo připojuje do vašich kontejnerů:
# Persistent volumes for caching model weights
hf_cache = modal.Volume.from_name("huggingface-cache", create_if_missing=True)
vllm_cache = modal.Volume.from_name("vllm-cache", create_if_missing=True)
MODEL_NAME = "Qwen/Qwen3-4B-Thinking-2507-FP8"
MODEL_REVISION = "953532f942706930ec4bb870569932ef63038fdf"Zde používáme Qwen3-4B-Thinking (FP8), kvantizovaný model se 4 miliardami parametrů, který je rychlý, schopný a vejde se na jedno GPU. Můžete jej vyměnit za jakýkoli model z Hugging Face: Llama 3.1 8B, Mistral 7B nebo cokoli, co podporuje vLLM.
Proč FP8? Snižuje využití paměti zhruba na polovinu oproti fp16, což znamená, že můžete na stejném GPU provozovat větší modely nebo menší modely na levnějších GPU. Pokud vás zajímají kompromisy kvantizace, náš průvodce provozem LLM lokálně podrobně pokrývá formáty přesnosti.
Krok 4: Vytvoření funkce serveru vLLM
Zde se děje magie Modal. Ozdobíte Python funkci požadavky na GPU, konfigurací škálování a anotací webového serveru. Modal se postará o vše ostatní:
N_GPU = 1
MINUTES = 60
VLLM_PORT = 8000
@app.function(
gpu=f"H100:{N_GPU}",
scaledown_window=15 * MINUTES,
timeout=10 * MINUTES,
volumes={
"/root/.cache/huggingface": hf_cache,
"/root/.cache/vllm": vllm_cache,
},
)
@modal.concurrent(max_inputs=32)
@modal.web_server(port=VLLM_PORT, startup_timeout=10 * MINUTES)
def serve():
import subprocess
cmd = [
"vllm", "serve",
MODEL_NAME,
"--revision", MODEL_REVISION,
"--served-model-name", MODEL_NAME,
"--host", "0.0.0.0",
"--port", str(VLLM_PORT),
"--tensor-parallel-size", str(N_GPU),
"--enforce-eager", # Faster cold starts
]
subprocess.Popen(" ".join(cmd), shell=True)Rozdělme si klíčové dekorátory:
gpu="H100:1", vyžaduje jedno GPU H100. Změňte na"A100-80GB:1"pro levnější inferenci nebo"H100:2"pro modely 70B+scaledown_window=15 * MINUTES, udržuje kontejner „teplý“ 15 minut po posledním požadavku, poté se škáluje na nulu@modal.concurrent(max_inputs=32), umožňuje až 32 souběžných požadavků na kontejner (vLLM interně zpracovává batchování)@modal.web_server(port=8000), vystavuje HTTP server vLLM přímo jako webový endpoint Modal--enforce-eager, přeskočí kompilaci CUDA grafů pro rychlejší studené starty (kompromis: mírně nižší špičková propustnost)
scaledown_window je vaším hlavním pákou pro náklady. Nastavte ji na 5 minut pro vývoj, 15–30 minut pro produkční API, kde očekáváte pravidelný traffic.
Krok 5: Nasazení do produkce
Jeden příkaz. To je vše:
modal deploy app.pyModal sestaví obraz kontejneru, odešle ho do svého registru a vrátí živou URL adresu:
✓ Created objects.
├── 🔨 Created mount /app.py
├── 🔨 Created volume huggingface-cache
├── 🔨 Created volume vllm-cache
└── 🔨 Created web function serve => https://your-workspace--llm-endpoint-serve.modal.runPrvní nasazení trvá několik minut, protože stahuje váhy modelu do volume. Následná nasazení (a studené starty) jsou mnohem rychlejší, protože jsou váhy uloženy v cache.
Pro vývoj použijte místo toho modal serve app.py, hot-reloaduje se při změnách souborů a poskytuje vám dočasnou URL adresu.
Krok 6: Volání vašeho endpointu (OpenAI-kompatibilní)
Váš nasazený server vLLM vystavuje OpenAI-kompatibilní API na /v1/chat/completions. Můžete použít standardní OpenAI Python SDK pro jeho volání, stačí nasměrovat base URL na váš endpoint Modal:
from openai import OpenAI
client = OpenAI(
api_key="not-needed", # vLLM doesn't require auth by default
base_url="https://your-workspace--llm-endpoint-serve.modal.run/v1",
)
response = client.chat.completions.create(
model="Qwen/Qwen3-4B-Thinking-2507-FP8",
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Explain what vLLM is in two sentences."},
],
temperature=0.7,
max_tokens=256,
)
print(response.choices[0].message.content)Funguje to také s curl:
curl -X POST https://your-workspace--llm-endpoint-serve.modal.run/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "Qwen/Qwen3-4B-Thinking-2507-FP8",
"messages": [{"role": "user", "content": "Hello!"}],
"max_tokens": 128
}'Jakýkoli nástroj, který podporuje OpenAI-kompatibilní API, bude fungovat, LangChain, LlamaIndex, vaše vlastní aplikace. Pokud směrujete požadavky přes více LLM endpointů, nástroj LLM gateway vám může pomoci spravovat failover a load balancing.
Tipy pro optimalizaci nákladů
Fakturace Modal za sekundu je již efektivnější než hodinová sazba, ale můžete z ní vytěžit ještě více:
1. Použijte kvantizaci FP8
Modely FP8 využívají zhruba polovinu VRAM oproti jejich protějškům fp16. Qwen3-8B ve formátu FP8 se vejde na jedno H100, zatímco verze fp16 potřebuje většinu 80 GB tohoto GPU. Méně VRAM znamená, že můžete pro menší modely používat levnější GPU (A100 40GB, L40S).
2. Ladění okna pro vypnutí (Scaledown Window)
Parametr scaledown_window určuje, jak dlouho zůstane kontejner teplý po posledním požadavku:
| Scénář | Doporučené okno | Proč |
|---|---|---|
| Vývoj/testování | 5 minut | Úspora peněz, studené starty nevadí |
| Interní API (občasné) | 10–15 minut | Vyvážení nákladů vs. latence |
| Produkce (pravidelný traffic) | 20–30 minut | Minimalizace studených startů |
| Produkce s vysokým trafficem | Použijte min_containers=1 | Udržujte jeden vždy teplý |
3. Vyberte správné GPU
Nepoužívejte automaticky H100. Menší modely ho nepotřebují:
| Velikost modelu | Doporučené GPU | Přibl. cena/hod |
|---|---|---|
| 1–4B parametrů | L4 nebo T4 | 0,59 – 0,80 USD |
| 7–8B parametrů | A10 nebo L40S | 1,10 – 1,95 USD |
| 13–14B parametrů | A100 40GB | 2,10 USD |
| 30–70B parametrů | A100 80GB nebo H100 | 2,50 – 3,95 USD |
| 70B+ parametrů | H100 x2 | 7,90 USD |
4. Povolte caching promptů
Pokud vaše workloady zahrnují opakující se systémové prompty nebo sdílené prefixy, automatické prefix caching vLLM může výrazně snížit latenci a výpočetní nároky. Můžete jej povolit přidáním --enable-prefix-caching do příkazu pro spuštění vLLM. Pro hlubší pochopení toho, jak caching funguje napříč různými poskytovateli, se podívejte na náš průvodce cachingem promptů LLM.
5. Použijte --enforce-eager pro optimalizaci studených startů
Ve výchozím nastavení vLLM kompiluje CUDA grafy při spuštění, což zabere 1–3 minuty navíc. Příznak --enforce-eager tuto kompilaci přeskočí. Vyměníte ~10–15 % špičkové propustnosti za dramaticky rychlejší studené starty. Pro nestálé workloady, kde je latence důležitější než hrubá propustnost, je to téměř vždy správná volba.
Jdeme dál: Fine-tuned modely
Jakmile se budete cítit комфортно s nasazováním základních modelů, přirozeným dalším krokem je nasazení vaší vlastní fine-tuned verze. Workflow je identické, pouze nasměrujete MODEL_NAME na svůj repozitář Hugging Face nebo na Modal volume obsahující vaše fine-tuned váhy.
Modal také podporuje spouštění úloh fine-tuning přímo na svých GPU. Můžete natrénovat LoRA adapter na Modal, uložit ho do volume a nasadit sloučený model, aniž byste opustili platformu. Naše průvodce fine-tuningem LLM podrobně pokrývá tréninkovou stránku.
Kompletní app.py
Zde je celý deploy skript v jednom bloku připraveném ke kopírování:
import modal
# --- Image Definition ---
vllm_image = (
modal.Image.from_registry(
"nvidia/cuda:12.8.0-devel-ubuntu22.04", add_python="3.12"
)
.entrypoint([])
.pip_install("vllm==0.13.0", "huggingface-hub==0.36.0")
)
# --- Volumes for Model Caching ---
hf_cache = modal.Volume.from_name("huggingface-cache", create_if_missing=True)
vllm_cache = modal.Volume.from_name("vllm-cache", create_if_missing=True)
# --- Model Config ---
MODEL_NAME = "Qwen/Qwen3-4B-Thinking-2507-FP8"
MODEL_REVISION = "953532f942706930ec4bb870569932ef63038fdf"
app = modal.App("llm-endpoint", image=vllm_image)
N_GPU = 1
MINUTES = 60
VLLM_PORT = 8000
@app.function(
gpu=f"H100:{N_GPU}",
scaledown_window=15 * MINUTES,
timeout=10 * MINUTES,
volumes={
"/root/.cache/huggingface": hf_cache,
"/root/.cache/vllm": vllm_cache,
},
)
@modal.concurrent(max_inputs=32)
@modal.web_server(port=VLLM_PORT, startup_timeout=10 * MINUTES)
def serve():
import subprocess
cmd = [
"vllm", "serve",
MODEL_NAME,
"--revision", MODEL_REVISION,
"--served-model-name", MODEL_NAME,
"--host", "0.0.0.0",
"--port", str(VLLM_PORT),
"--tensor-parallel-size", str(N_GPU),
"--enforce-eager",
]
subprocess.Popen(" ".join(cmd), shell=True)Nasaďte pomocí modal deploy app.py, vyměňte MODEL_NAME za jakýkoli model z Hugging Face a jste online.
Často kladené otázky
Kolik stojí provoz LLM na Modal?
Záleží na GPU a na tom, jak dlouho zůstává váš endpoint teplý. Qwen3-4B na H100 stojí ~3,95 USD/hod aktivního použití. Se škálováním na nulu a 15minutovým oknem pro vypnutí může lehce používaný endpoint stát 5–15 USD/měsíc. 30 USD měsíční kredit zdarma pokryje hodně experimentování.
Škáluje Modal na nulu?
Ano, to je jeden z jeho hlavních prodejních bodů. Když nepřijdou žádné požadavky po dobu trvání vašeho scaledown_window, kontejner se vypne a přestanete platit. Další požadavek spustí studený start (obvykle 2–10 sekund v závislosti na velikosti modelu a zda používáte --enforce-eager).
Mohu na Modal nasadit Llama 3.1 nebo Mistral?
Absolutně. Vyměňte konstantu MODEL_NAME za jakýkoli model, který podporuje vLLM: meta-llama/Llama-3.1-8B-Instruct, mistralai/Mistral-7B-Instruct-v0.3 nebo stovky dalších na Hugging Face. Pro modely 70B+ změňte N_GPU na 2 a použijte gpu="H100:2".
Jak se studené starty porovnávají s RunPod?
Studené starty Modal jsou obvykle 2–4 sekundy pro samotný kontejner plus čas načítání modelu. S váhami modelu uloženými v cache ve Volume a povoleným --enforce-eager se díváte na celkem 10–30 sekund pro model 7–8B. Serverless studené starty RunPod se pohybují od pod 200 ms (v cache) do 6–12 sekund pro větší kontejnery, i když jejich model „vždy zapnuto“ se studeným startům zcela vyhýbá.
Je endpoint vLLM od Modal skutečně kompatibilní s OpenAI?
Ano. vLLM implementuje stejné endpointy /v1/chat/completions, /v1/completions a /v1/models, které používá OpenAI. Můžete nasměrovat oficiální Python SDK openai na svou URL Modal a bude fungovat hned. Streaming, volání funkcí a JSON mode všechny fungují.
Potřebuji GPU na svém lokálním stroji?
Ne. Váš lokální stroj pouze spouští CLI Modal. Veškerá práce na GPU probíhá na cloudové infrastruktuře Modal. Mohli byste nasazovat dokonce z Chromebooku, pokud byste chtěli.
Jak přidám autentizaci ke svému endpointu?
Webové endpointy Modal jsou ve výchozím nastavení veřejné. Pro produkci přidejte jednoduchou kontrolu API klíče do kódu vaší aplikace nebo použijte vestavěné funkce webové autentizace Modal. Můžete také nastavit proxy vrstvu pomocí LLM gateway, která zpracovává auth, rate limiting a směrování.
Jaký je rozdíl mezi modal serve a modal deploy?
modal serve vytvoří dočasný endpoint, který se hot-reloaduje, když upravujete kód, ideální pro vývoj. modal deploy vytvoří perzistentní, produkčně připravený endpoint se stabilní URL. Používejte serve během iterací, deploy, když jste připraveni vydat.
Mohu použít SGLang místo vLLM?
Ano. Dokumentace Modal obsahuje příklady SGLang vedle vLLM. SGLang má tendenci mít nižší overhead pro workloady náročné na dekódování a menší modely. vLLM je obecně lepší pro smíšené workloady s těžkým prefill. Oba produkují endpointy kompatibilní s OpenAI.
Jak se to porovnává s nasazením na Railway nebo Render?
Platformy jako Railway, Render a Fly.io jsou skvělé pro webové aplikace, ale nenabízejí instance GPU. Modal je účelově postaven pro GPU workloady s fakturací za sekundu a automatickým škálováním. Pokud potřebujete servírovat LLM, Modal (nebo RunPod) je správný nástroj, tradiční PaaS platformy to nedokážou.