guides

Driftsätt en LLM med Modal: från pip install till produktionsendpoint

Skriven av Mert Batur
Mar 27, 2026
9 läsning
Driftsätt en LLM med Modal: från pip install till produktionsendpoint

Driftsätt en LLM med Modal: från pip install till produktionsendpoint

De flesta guider om att självhosta LLM:er hoppar över den svåraste delen: infrastrukturen. Man kämpar med CUDA-drivrutiner, hanterar Docker-images, konfigurerar autoskalning och betalar ändå för inaktiva GPU:er klockan 3 på natten. Modal eliminerar allt det. Du skriver Python, du driftsätter, du får en URL.

Den här guiden tar dig igenom hur du driftsätter en open source-LLM på Modal med vLLM som inferensmotor. I slutet har du en live OpenAI-kompatibel API-endpoint på H100-GPU:er som skalar till noll när ingen använder den.

Vad är Modal (och varför använda det för LLM:er)?

Modal är en serverlös beräkningsplattform byggd specifikt för AI-arbetsbelastningar. Tänk AWS Lambda, men med GPU-stöd, sekundfakturering och en Python-nativ utvecklarupplevelse. Ingen YAML, inga Dockerfiles, ingen Kubernetes — du definierar hela din infrastruktur i ett Python-skript och driftsätter med ett enda kommando.

Här är varför det blivit standardvalet för LLM-driftsättning:

  • Scale-to-zero-fakturering — du betalar ingenting när din endpoint inte hanterar förfrågningar
  • GPU-priser per sekund — H100:or till ~$3,95/tim, A100 80 GB till ~$2,50/tim, fakturerat per sekund
  • Sub-sekunds kallstarter — containrar startar snabbt, särskilt med minnessnapshots
  • $30/månad i gratis krediter — tillräckligt för att experimentera utan kreditkortsavgifter
  • Ingen DevOps — inga Docker-byggen, ingen Terraform, ingen klusterhantering

Om du kör LLM:er lokalt och vill ge dem ett ordentligt API utan att hantera servrar, är Modal den kortaste vägen dit.

FunktionModalRunPodLambda
FaktureringsmodellPer sekund, scale-to-zeroPer sekund, minsta avgiftPer timme, alltid aktiv
Kallstart2-4 sekunder6-12 sekunder (stor)Ej aktuellt (persistent)
GPU-tillgänglighetH100, A100, L40S, T4A100, H100, A6000H100, A100
InfrastrukturRen Python, inga konfigfilerDocker-baserad, mer kontrollFull VM-åtkomst
Gratisnivå$30/månad i krediterIngenIngen
Bäst förBurstig/dev-arbetsbelastningStabil inferenstrafikIntensiv träning

Slutsats: Modal vinner för burstig arbetsbelastning och utveckling. Om din GPU-användning konsekvent överstiger 40% är en dedikerad instans på RunPod eller Lambda billigare. För allt annat — prototypning, intermittenta API:er, demos — sparar Modals scale-to-zero-modell riktiga pengar.

Förutsättningar

Innan du börjar behöver du tre saker:

  1. Python 3.10+ installerat lokalt
  2. Ett Modal-konto — registrera dig gratis på modal.com
  3. Ett Hugging Face-konto — för modelltillgång (de flesta modeller är begränsade)

Det är allt. Ingen GPU på din lokala maskin, inget CUDA-verktygspaket, ingen Docker.

Steg 1: Installera Modal och autentisera

Öppna en terminal och installera Modal Python-paketet:

bash
pip install modal

Kör sedan installationskommandot för att koppla din lokala miljö till ditt Modal-konto:

bash
modal setup

Det öppnar ett webbläsarfönster för autentisering. När du bekräftar sparar Modal en token lokalt. Du behöver aldrig göra det igen.

Steg 2: Definiera containerbilden

Modal-containrar definieras i Python. Du anger basbilden, installerar beroenden och ställer in miljövariabler — allt som kod. Skapa en fil som heter app.py:

python
import modal

# Definiera containerbilden med CUDA, Python och 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)

Några saker att notera. Det finns ingen Dockerfile — den modal.Image-kedjan ersätter den helt. Basbilden inkluderar NVIDIA CUDA 12.8 med Ubuntu 22.04, och vi installerar vLLM och Hugging Face Hub-klienten ovanpå.

Steg 3: Konfigurera modelllagring med Volumes

LLM-vikter är stora (en modell med 7 miljarder parametrar är ~14 GB i fp16). Du vill inte ladda ner dem varje gång en container startar. Modal Volumes ger dig persistent lagring som monteras direkt i dina containrar:

python
# Persistenta volumes för att cacha modellvikter
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"

Vi använder Qwen3-4B-Thinking (FP8) här — en kvantiserad modell med 4 miljarder parametrar som är snabb, kapabel och passar på en enda GPU. Du kan byta ut den mot vilken Hugging Face-modell som helst: Llama 3.1 8B, Mistral 7B, eller vad som helst som vLLM stödjer.

Varför FP8? Det halverar ungefär minnesanvändningen jämfört med fp16, vilket innebär att du kan köra större modeller på samma GPU — eller mindre modeller på billigare GPU:er. Om du är nyfiken på kvantiseringsavvägningarna täcker vår guide om att köra LLM:er lokalt precisionsformaten i detalj.

Steg 4: Skapa vLLM-serverfunktionen

Det är här Modals magi sker. Du dekorerar en Python-funktion med GPU-krav, skalningskonfiguration och en webbserverannotation. Modal sköter allt annat:

python
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",  # Snabbare kallstarter
    ]

    subprocess.Popen(" ".join(cmd), shell=True)

Låt oss bryta ner de viktigaste dekoratörerna:

  • gpu="H100:1" — begär en enda H100-GPU. Ändra till "A100-80GB:1" för billigare inferens, eller "H100:2" för 70B+-modeller
  • scaledown_window=15 * MINUTES — håller containern varm i 15 minuter efter den senaste förfrågan, sedan skalar den till noll
  • @modal.concurrent(max_inputs=32) — tillåter upp till 32 samtidiga förfrågningar per container (vLLM hanterar batching internt)
  • @modal.web_server(port=8000) — exponerar vLLM HTTP-servern direkt som en Modal-webbendpoint
  • --enforce-eager — hoppar över CUDA-grafkompilering för snabbare kallstarter (avvägning: något lägre toppgenomströmning)

scaledown_window är din huvudsakliga kostnadspak. Ställ in den på 5 minuter för dev, 15-30 minuter för produktions-API:er med regelbunden trafik.

Steg 5: Driftsätt till produktion

Ett kommando. Det är allt:

bash
modal deploy app.py

Modal bygger containerbilden, laddar upp den till sitt register och returnerar en live-URL:

text
✓ 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.run

Den första driftsättningen tar några minuter eftersom den laddar ner modellvikter till volymen. Efterföljande driftsättningar (och kallstarter) är mycket snabbare eftersom vikterna är cachade.

Använd modal serve app.py under utveckling istället — det laddar om vid filändringar och ger dig en tillfällig URL.

Steg 6: Anropa din endpoint (OpenAI-kompatibel)

Din driftsatta vLLM-server exponerar ett OpenAI-kompatibelt API på /v1/chat/completions. Du kan använda standard OpenAI Python SDK för att anropa det — peka bara bas-URL:en mot din Modal-endpoint:

python
from openai import OpenAI

client = OpenAI(
    api_key="not-needed",  # vLLM kräver inte autentisering som standard
    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)

Det fungerar också med curl:

bash
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
  }'

Vilket verktyg som helst som stödjer ett OpenAI-kompatibelt API fungerar — LangChain, LlamaIndex, din egna app. Om du dirigerar förfrågningar över flera LLM-endpoints kan ett LLM-gateway-verktyg hjälpa dig att hantera failover och lastbalansering.

Tips för kostnadsoptimering

Modals sekundfakturering är redan mer effektivt än timdebitering, men du kan pressa ut ännu mer:

1. Använd FP8-kvantiering

FP8-modeller använder ungefär hälften av VRAM jämfört med deras fp16-motsvarigheter. En Qwen3-8B i FP8 passar på en enda H100, medan fp16-versionen behöver det mesta av den GPU:ns 80 GB. Mindre VRAM innebär att du kan använda billigare GPU:er (A100 40 GB, L40S) för mindre modeller.

2. Justera nedskaleringsfönstret

Parametern scaledown_window styr hur länge en container förblir varm efter den senaste förfrågan:

ScenarioRekommenderat fönsterVarför
Utveckling/testning5 minuterSpara pengar, kallstarter är okej
Internt API (ibland)10-15 minuterBalans mellan kostnad och latens
Produktion (regelbunden trafik)20-30 minuterMinimera kallstarter
HögtrafikproduktionAnvänd min_containers=1Håll en alltid varm

3. Välj rätt GPU

Välj inte alltid H100. Mindre modeller behöver den inte:

ModellstorlekRekommenderad GPUUngefärlig kostnad/tim
1-4B parametrarL4 eller T4$0,59 – $0,80
7-8B parametrarA10 eller L40S$1,10 – $1,95
13-14B parametrarA100 40 GB$2,10
30-70B parametrarA100 80 GB eller H100$2,50 – $3,95
70B+ parametrarH100 x2$7,90

4. Aktivera prompt-cachning

Om dina arbetsbelastningar involverar upprepade systemprompter eller delade prefix kan vLLM:s automatiska prefixcachning avsevärt minska latens och beräkning. Aktivera det genom att lägga till --enable-prefix-caching till vLLM serve-kommandot. För en djupare genomgång av hur cachning fungerar hos olika leverantörer, kolla in vår guide om LLM-promptcachning.

5. Använd --enforce-eager för kallstartsoptimering

Som standard kompilerar vLLM CUDA-grafer vid uppstart, vilket tar 1-3 extra minuter. Flaggan --enforce-eager hoppar över den kompileringen. Du byter ~10-15% toppgenomströmning mot dramatiskt snabbare kallstarter. För burstig arbetsbelastning där latens är viktigare än rå genomströmning är det nästan alltid rätt val.

Att gå vidare: finjusterade modeller

När du är bekväm med att driftsätta basmodeller är nästa naturliga steg att driftsätta din egna finjusterade version. Arbetsflödet är identiskt — du pekar bara MODEL_NAME på ditt Hugging Face-repo eller en Modal-volym som innehåller dina finjusterade vikter.

Modal stödjer också att köra finjusteringsjobb direkt på deras GPU:er. Du kan träna en LoRA-adapter på Modal, spara den i en volym och driftsätta den sammanslagna modellen — allt utan att lämna plattformen. Vår guide om LLM-finjustering täcker träningssidan på djupet.

Den kompletta app.py

Här är det fullständiga driftsättningsskriptet i ett enda kopieringsklart block:

python
import modal

# --- Bilddefinition ---
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 för modellcachning ---
hf_cache = modal.Volume.from_name("huggingface-cache", create_if_missing=True)
vllm_cache = modal.Volume.from_name("vllm-cache", create_if_missing=True)

# --- Modellkonfiguration ---
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)

Driftsätt med modal deploy app.py, byt ut MODEL_NAME mot vilken Hugging Face-modell som helst, och du är live.

Vanliga frågor

Hur mycket kostar det att köra en LLM på Modal?

Det beror på GPU:n och hur länge din endpoint förblir varm. En Qwen3-4B på en H100 kostar ~$3,95/tim aktiv användning. Med scale-to-zero och ett 15-minuters nedskaleringsfönster kan en lättutnyttjad endpoint kosta $5-15/månad. De $30 i gratis månadskrediter täcker en hel del experimentering.

Skalar Modal till noll?

Ja — det är en av dess viktigaste fördelar. När inga förfrågningar anländer under din scaledown_window-tid stängs containern av och du slutar betala. Nästa förfrågan utlöser en kallstart (vanligtvis 2-10 sekunder beroende på modellstorlek och om du använder --enforce-eager).

Kan jag driftsätta Llama 3.1 eller Mistral på Modal?

Absolut. Byt ut MODEL_NAME-konstanten mot vilken modell som helst som vLLM stödjer: meta-llama/Llama-3.1-8B-Instruct, mistralai/Mistral-7B-Instruct-v0.3, eller hundratals andra på Hugging Face. För 70B+-modeller, ändra N_GPU till 2 och använd gpu="H100:2".

Hur jämförs kallstarter med RunPod?

Modals kallstarter är typiskt 2-4 sekunder för själva containern, plus modellinläsningstid. Med modellvikter cachade i en Volume och --enforce-eager aktiverat handlar det om 10-30 sekunder totalt för en 7-8B-modell. RunPods serverlösa kallstarter sträcker sig från under 200 ms (cachad) till 6-12 sekunder för större containrar — men deras always-on-modell undviker kallstarter helt.

Är Modals vLLM-endpoint verkligen OpenAI-kompatibel?

Ja. vLLM implementerar samma /v1/chat/completions-, /v1/completions- och /v1/models-endpoints som OpenAI använder. Du kan peka den officiella openai Python SDK mot din Modal-URL och det fungerar direkt. Streaming, function calling och JSON-läge fungerar alla.

Behöver jag en GPU på min lokala maskin?

Nej. Din lokala maskin kör bara Modal CLI. Allt GPU-arbete sker på Modals molninfrastruktur. Du kan driftsätta från en Chromebook om du ville.

Hur lägger jag till autentisering till min endpoint?

Modal-webbendpoints är publika som standard. Lägg till en enkel API-nyckelkontroll i din applikationskod för produktion, eller använd Modals inbyggda webbautentiseringsfunktioner. Du kan också sätta upp ett proxylager med ett LLM-gateway som hanterar autentisering, hastighetsbegränsning och routing.

Vad är skillnaden mellan modal serve och modal deploy?

modal serve skapar en tillfällig endpoint som laddar om vid kodändringar — perfekt för utveckling. modal deploy skapar en persistent, produktionsklar endpoint med en stabil URL. Använd serve under iteration, deploy när du är redo att leverera.

Kan jag använda SGLang istället för vLLM?

Ja. Modals dokumentation innehåller SGLang-exempel vid sidan av vLLM. SGLang tenderar att ha mindre overhead för decode-tunga arbetsbelastningar och mindre modeller. vLLM är generellt sett bättre för blandade arbetsbelastningar med tung prefill. Båda producerar OpenAI-kompatibla endpoints.

Hur jämförs detta med att driftsätta på Railway eller Render?

Plattformar som Railway, Render och Fly.io är utmärkta för webbapplikationer, men de erbjuder inga GPU-instanser. Modal är byggd specifikt för GPU-arbetsbelastningar med sekundfakturering och autoskalning. Om du behöver serva en LLM är Modal (eller RunPod) rätt verktyg — traditionella PaaS-plattformar kan inte göra det.

Källor

Taggar

driftsätta llm modalmodal serverlös gpuvllm driftsättningllm inferens apiserverlös llmmodal labs guidesjälvhosta llm

Dela denna artikel

Starta ditt projekt

Redo att bygga något utöver det vanliga?

Låt oss göra verklighet av din idé. Vårt team hjälper dig gärna att bygga mjukvara som gör skillnad.