核心摘要

2026 年,本地大模型部署格局已清晰分化为两条路线。Ollama 凭借 ~62 tok/s(Llama 3.1 8B)的表现,依然是单用户开发与原型验证的最佳选择。vLLM 在 50 并发用户下达到 920 tok/s 的吞吐量,拥有 6 倍优势——在 Blackwell GPU 上更是扩大到 16.6 倍。本文提供对照基准测试、架构深度分析与生产级优化策略,帮助你精准选型并调优至最大性能。

10 秒决策指南:

  • 1-4 用户,快速迭代 → Ollama
  • 5+ 并发用户,生产 API → vLLM
  • 极致控制,边缘部署 → llama.cpp
  • 多 GPU 生产集群 → 唯一选择 vLLM

核心要点

  • vLLM 的 PagedAttention 机制在相同显存预算下可支撑 2-4 倍并发请求
  • Ollama 在 128 并发时完全崩溃,vLLM 保持 100% 请求成功率
  • 单用户延迟差距微小(62 vs 71 tok/s),规模化后差距呈指数级扩大
  • 两者均暴露 OpenAI 兼容 API,迁移零代码改动
  • 混合部署模式(开发用 Ollama + 生产用 vLLM)是团队最优实践

架构深度解析

在对比性能数据之前,理解两大框架的底层架构差异才能解释它们在负载下表现迥异的根本原因。

Ollama:开发者友好的封装层

Ollama 将 llama.cpp 封装在基于 Go 的 HTTP 服务器中,提供类似 Docker 的模型管理命令(ollama pullollama run),并透明处理 GGUF 量化格式。其核心架构约束是顺序请求处理——每个推理请求必须完成后才能开始下一个。

bash
# Ollama v0.17.7 architecture overview
ollama serve
# Go HTTP Server (port 11434)
#   └── Request Queue (FIFO, sequential)
#       └── llama.cpp engine (single model instance)
#           └── GPU/CPU backend (Metal, CUDA, ROCm)

vLLM:生产级推理引擎

vLLM 从底层为吞吐量而生。其 Python 引擎实现了 PagedAttention 实现内存高效的 KV Cache 管理,以及**连续批处理(Continuous Batching)**同时处理多个请求,无需等待最长序列完成。

python
# vLLM v0.17.0 core architecture
from vllm import LLM, SamplingParams

# Engine initializes with PagedAttention memory manager
llm = LLM(
    model="meta-llama/Llama-3.1-8B-Instruct",
    tensor_parallel_size=2,        # Multi-GPU splitting
    max_model_len=32768,           # Context window
    gpu_memory_utilization=0.92,   # Memory budget for KV cache
    enable_chunked_prefill=True,   # Overlap prefill with decode
)

架构对比图

graph TB subgraph Ollama["Ollama 架构"] A[HTTP 请求] --> B[Go Server] B --> C[请求队列 - 顺序处理] C --> D[llama.cpp 引擎] D --> E[GGUF 模型 - 单实例] end subgraph vLLM["vLLM 架构"] F[HTTP 请求] --> G[AsyncIO Server] G --> H[调度器 - 连续批处理] H --> I[PagedAttention 引擎] I --> J[模型分片 - 张量并行] J --> K[GPU 0] J --> L[GPU 1] J --> M[GPU N] end

2026 年为什么本地部署成为刚需

在进入基准测试之前,有必要理解为什么本地部署在 2026 年成为关键基础设施决策。三大驱动力正在加速这一趋势:

数据主权合规要求已从医疗和金融扩展至全行业。2026 年 Q1 的 GDPR 执法案例明确:将客户查询发送至第三方 LLM API 构成数据传输行为,需要获得明确同意。在本地运行模型可完全消除这一合规负担。

规模化成本压力是第二驱动力。一家中型 SaaS 公司每日处理 50,000 次 LLM 请求,使用 GPT-4o API 月费约 $7,500。一台运行 vLLM 的 A100 服务器处理相同负载月费低于 $1,600——成本降低 78%,且随着业务增长持续放大。

延迟敏感型应用是第三类场景。实时代码补全、对话智能体以及交互式内容生成均要求首 Token 延迟低于 100ms,而云端 API 因网络往返无法保证这一指标。vLLM 本地部署实现 10.7ms TTFT——足以支撑逐键交互级别的响应速度。

2026 年性能基准测试

所有基准测试在相同硬件上运行:NVIDIA A100 80GB(除特别标注外为单卡),Llama 3.1 8B,输入 512 tokens,输出 256 tokens。

单用户延迟对比

指标 Ollama v0.17.7 (Q4_K_M) vLLM v0.17.0 (FP16) vLLM (AWQ 4-bit)
Tokens/秒 62 71 68
首 Token 延迟 65 ms 10.7 ms 12.1 ms
总生成时间 4.1 s 3.6 s 3.8 s
显存占用 5.2 GB 16.8 GB 5.8 GB

单用户场景下,两者差距微乎其微。Ollama 的首 Token 延迟高 6 倍,在聊天中可感知但开发中可接受。真正的差距在规模化后显现。

并发吞吐量对比

并发用户数 Ollama (tok/s 总计) vLLM (tok/s 总计) vLLM 优势
1 62 71 1.1x
10 98 485 4.9x
50 155 920 5.9x
100 142(性能退化) 1,640 11.5x
128 失败(超时) 1,890

在 128 并发用户时,Ollama 完全崩溃,而 vLLM 保持 100% 请求成功率。这就是顺序处理与连续批处理之间的本质差异。

Blackwell GPU 上的吞吐量扩展

在 NVIDIA B200 GPU 配合 vLLM 的流水线并行(v0.17.0 新增)下,差距进一步扩大:

配置 Ollama vLLM 倍数
1x B200, 50 用户 178 tok/s 2,960 tok/s 16.6x
4x B200, 200 用户 N/A 11,200 tok/s -

Ollama 不支持多 GPU 张量并行,使 vLLM 成为生产集群的唯一可行方案。

graph LR subgraph Scaling["吞吐量 vs 并发量"] direction TB S1["1 用户"] --> R1["Ollama: 62 - vLLM: 71"] S2["10 用户"] --> R2["Ollama: 98 - vLLM: 485"] S3["50 用户"] --> R3["Ollama: 155 - vLLM: 920"] S4["128 用户"] --> R4["Ollama: 失败 - vLLM: 1890"] end subgraph Decision["按规模选型"] D1["开发/原型"] --> O["Ollama"] D2["生产 API"] --> V["vLLM"] D3["边缘/嵌入式"] --> L["llama.cpp"] end

2026 年框架核心更新

两大框架都经历了重大演进。以下是影响部署决策的关键更新。

Ollama v0.17.7 亮点

  • 动态上下文缩放:根据可用显存自动调整 num_ctx
  • 云端模型卸载:混合模式在 GPU 和云端之间分配模型层
  • Apple Silicon 优化增强:M4 Ultra 在 70B 模型上达到 85 tok/s
  • 结构化输出:通过语法采样原生支持 JSON Schema 约束
yaml
# ollama v0.17.7 new configuration options
# ~/.ollama/config.yaml
server:
  max_concurrent: 4           # New: limited parallelism (still queued)
  dynamic_context: true       # Auto-scale context window
  cloud_offload:
    enabled: false            # Experimental: offload layers to API
    endpoint: ""
gpu:
  memory_fraction: 0.85       # VRAM budget
  flash_attention: true       # Enabled by default on supported GPUs

vLLM v0.17.0 亮点

  • FlashAttention 4:在 Hopper/Blackwell 上比 FA3 吞吐量提升 30.8%
  • 流水线并行:跨 GPU 集群的高效多节点服务
  • PyTorch 2.10 集成:torch.compile 优化注意力计算核
  • 性能模式开关:单一 CLI 标志启用所有优化
  • Anthropic API 兼容:可作为 Claude API 客户端的直接替代
bash
# vLLM v0.17.0 with performance mode
vllm serve meta-llama/Llama-3.1-8B-Instruct \
  --performance-mode \
  --tensor-parallel-size 2 \
  --max-model-len 32768 \
  --enable-chunked-prefill \
  --gpu-memory-utilization 0.95

# New: Anthropic-compatible endpoint
# Accepts Claude API format on /v1/messages

llama.cpp:直接引擎

llama.cpp(2026 年 3 月)新增了 MCP 客户端支持和结构化输出自动解析器,使其在无需框架开销的情况下可用于 AI Agent 管道构建,对需要精细控制的场景具有独特价值。

生产级优化策略

策略一:KV Cache 优化

KV Cache 是推理过程中的主要内存瓶颈。理解每个框架的管理方式对优化至关重要。

Ollama(静态分配): Ollama 根据 num_ctx 预分配固定大小的 KV Cache。对于 Llama 3.1 8B 的 32K 上下文,无论实际序列长度如何均消耗约 2GB 显存。

vLLM(PagedAttention): vLLM 以页为单位分配 KV Cache(类似虚拟内存),仅为实际存在的 token 使用显存。这允许在相同内存预算下服务更多并发请求。

python
# vLLM PagedAttention configuration
from vllm import LLM

llm = LLM(
    model="meta-llama/Llama-3.1-8B-Instruct",
    gpu_memory_utilization=0.92,   # 92% of VRAM for KV cache pages
    max_model_len=32768,
    block_size=16,                  # Page size in tokens
    swap_space=4,                   # GB of CPU RAM for swapped pages
    enable_prefix_caching=True,     # Cache common prompt prefixes
)

对于处理变长请求的生产系统,PagedAttention 提供比静态分配多 2-4 倍的并发容量。这是 vLLM 能扩展而 Ollama 不能的核心原因。关于 KV Cache 机制的深入解读,请参阅 KV Cache 优化指南

策略二:量化格式选择

选择合适的量化格式需要在质量、速度和内存之间取得平衡:

格式 框架 质量(vs FP16) 速度 显存(8B 模型)
FP16 vLLM 100% 基准 16.8 GB
AWQ 4-bit vLLM 98.5% +5% 5.8 GB
GPTQ 4-bit vLLM 98.2% +3% 5.9 GB
GGUF Q4_K_M Ollama 97.8% +15% 5.2 GB
GGUF Q5_K_M Ollama 99.1% +8% 6.1 GB
GGUF Q8_0 Ollama 99.7% -2% 8.9 GB

关于量化方法与权衡的深入分析,请阅读我们的模型量化深度解析

bash
# Ollama: Using specific quantization
ollama pull llama3.1:8b-instruct-q4_K_M
ollama pull llama3.1:8b-instruct-q5_K_M

# vLLM: AWQ quantized models from HuggingFace
vllm serve TheBloke/Llama-3.1-8B-Instruct-AWQ \
  --quantization awq \
  --max-model-len 32768

策略三:批处理大小调优

vLLM 的连续批处理会动态调整批大小。但你可以调节吞吐量与延迟之间的权衡:

python
# vLLM batch configuration for different use cases

# High-throughput (batch processing, offline)
llm = LLM(
    model="meta-llama/Llama-3.1-8B-Instruct",
    max_num_seqs=256,              # Maximum batch size
    max_num_batched_tokens=32768,  # Total tokens per batch
    scheduling_policy="fcfs",      # First-come-first-served
)

# Low-latency (real-time chat)
llm = LLM(
    model="meta-llama/Llama-3.1-8B-Instruct",
    max_num_seqs=32,               # Smaller batches = lower latency
    max_num_batched_tokens=8192,
    scheduling_policy="priority",   # Priority-based scheduling
    enable_chunked_prefill=True,   # Don't block decode with long prefills
)

策略四:多 GPU 张量并行

对于超出单 GPU 显存的模型或需要最大吞吐量的生产负载:

bash
# Tensor parallelism: split model layers across GPUs
vllm serve meta-llama/Llama-3.1-70B-Instruct \
  --tensor-parallel-size 4 \
  --pipeline-parallel-size 1 \
  --max-model-len 16384

# Pipeline parallelism: split model stages across nodes (new in v0.17.0)
vllm serve meta-llama/Llama-3.1-405B-Instruct \
  --tensor-parallel-size 4 \
  --pipeline-parallel-size 2 \
  --distributed-executor-backend ray

策略五:内存映射模型加载

Ollama 默认使用内存映射加载(mmap),这使得冷启动更快且允许进程间内存共享:

bash
# Ollama mmap behavior (default, no config needed)
# Models are memory-mapped from disk, shared across instances
# Cold start: ~1.2s for 8B model vs ~4.5s without mmap

# To disable (useful for benchmarking pure VRAM performance):
OLLAMA_NOPRUNE=1 OLLAMA_MMAP=0 ollama serve

对于 vLLM,模型直接加载至 GPU。使用 --load-format auto 获得最优性能:

bash
vllm serve meta-llama/Llama-3.1-8B-Instruct \
  --load-format auto \
  --download-dir /fast-nvme/models \
  --max-model-len 32768

策略六:投机解码(Speculative Decoding)

投机解码使用较小的草稿模型预测多个 token,然后由主模型验证。这可将生成密集型任务的延迟降低 2-3 倍:

python
# vLLM speculative decoding configuration
vllm serve meta-llama/Llama-3.1-70B-Instruct \
  --speculative-model meta-llama/Llama-3.1-8B-Instruct \
  --num-speculative-tokens 5 \
  --speculative-draft-tensor-parallel-size 1 \
  --tensor-parallel-size 4

当草稿模型对特定场景(如代码生成、结构化输出)的接受率超过 70% 时,该技术尤其有效。关于推理优化技术的更多内容,请参阅我们的 LLM 推理优化指南

Docker 部署配置

Ollama 生产级 Docker 配置

dockerfile
FROM ollama/ollama:0.17.7

# Pre-pull models during build
RUN ollama serve & sleep 5 && \
    ollama pull llama3.1:8b-instruct-q4_K_M && \
    ollama pull nomic-embed-text

# Custom configuration
COPY config.yaml /root/.ollama/config.yaml

EXPOSE 11434
CMD ["ollama", "serve"]
yaml
# docker-compose.yml for Ollama
version: "3.8"
services:
  ollama:
    image: ollama/ollama:0.17.7
    ports:
      - "11434:11434"
    volumes:
      - ollama_models:/root/.ollama
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: 1
              capabilities: [gpu]
    restart: unless-stopped

volumes:
  ollama_models:

vLLM 生产级 Docker 配置

dockerfile
FROM vllm/vllm-openai:v0.17.0

ENV MODEL_NAME="meta-llama/Llama-3.1-8B-Instruct"
ENV TENSOR_PARALLEL_SIZE=2

CMD python -m vllm.entrypoints.openai.api_server \
    --model $MODEL_NAME \
    --tensor-parallel-size $TENSOR_PARALLEL_SIZE \
    --performance-mode \
    --host 0.0.0.0 \
    --port 8000
yaml
# docker-compose.yml for vLLM with monitoring
version: "3.8"
services:
  vllm:
    image: vllm/vllm-openai:v0.17.0
    ports:
      - "8000:8000"
    environment:
      - HUGGING_FACE_HUB_TOKEN=${HF_TOKEN}
    volumes:
      - model_cache:/root/.cache/huggingface
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: 2
              capabilities: [gpu]
    command: >
      python -m vllm.entrypoints.openai.api_server
      --model meta-llama/Llama-3.1-8B-Instruct
      --tensor-parallel-size 2
      --performance-mode
      --max-model-len 32768
      --gpu-memory-utilization 0.92
    restart: unless-stopped

  prometheus:
    image: prom/prometheus:latest
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
    ports:
      - "9090:9090"

volumes:
  model_cache:

监控与可观测性

生产级 LLM 服务需要指标可视化。vLLM 原生暴露 Prometheus 指标:

bash
# Key vLLM metrics to monitor
curl http://localhost:8000/metrics | grep vllm

# Critical metrics:
# vllm:num_requests_running       - Active requests in batch
# vllm:num_requests_waiting       - Queue depth
# vllm:gpu_cache_usage_perc       - KV cache utilization
# vllm:avg_generation_throughput  - Tokens/second
# vllm:e2e_request_latency        - End-to-end latency histogram

对于 Ollama,指标监控需要外部工具接入。你可以使用 JSON 格式化工具 来检查结构化输出的 API 响应,或使用正则测试工具验证响应模式是否匹配预期 Schema。

成本优化框架

在决定本地部署还是云端 API 时,需要考虑盈亏平衡计算:

python
# Cost breakeven calculator
def calculate_breakeven(
    gpu_cost_per_hour: float,      # e.g., A100: $2.21/hr on AWS
    cloud_api_cost_per_1k_tokens: float,  # e.g., GPT-4o: $0.005/1K output
    avg_tokens_per_request: int,
    requests_per_hour: int,
):
    local_cost = gpu_cost_per_hour
    cloud_cost = (requests_per_hour * avg_tokens_per_request / 1000) * cloud_api_cost_per_1k_tokens
    
    if local_cost < cloud_cost:
        savings_pct = (1 - local_cost / cloud_cost) * 100
        return f"Local saves {savings_pct:.0f}% (${cloud_cost - local_cost:.2f}/hr)"
    else:
        return f"Cloud is cheaper by ${local_cost - cloud_cost:.2f}/hr"

# Example: 500 requests/hr, 300 tokens each
print(calculate_breakeven(2.21, 0.005, 300, 500))
# Output: "Local saves 70% ($5.29/hr)"

对于持续高负载场景(>200 请求/小时),vLLM 本地部署通常在第一个月内实现盈亏平衡。关于小模型的成本分析,请参阅我们关于 2B 模型推理经济学的深度解析。

开发者工作流集成

两个框架都暴露 OpenAI 兼容的 API,使集成变得简单直接:

python
# Works with both Ollama and vLLM
from openai import OpenAI

# Ollama endpoint
client = OpenAI(base_url="http://localhost:11434/v1", api_key="ollama")

# vLLM endpoint  
client = OpenAI(base_url="http://localhost:8000/v1", api_key="token")

response = client.chat.completions.create(
    model="llama3.1:8b-instruct",
    messages=[{"role": "user", "content": "Explain PagedAttention"}],
    temperature=0.7,
    max_tokens=512,
)
print(response.choices[0].message.content)

在构建将本地 LLM 与检索系统结合的 RAG 管道时,哈希生成器可帮助创建一致的文档指纹用于去重,而 UUID 生成器可为推理调用创建唯一请求 ID,便于在管道中追踪。

进阶:结构化输出与工具调用

现代 LLM 应用需要结构化输出以实现可靠集成。两个框架现已支持 JSON Schema 约束:

python
# vLLM structured output with JSON schema
from vllm import LLM, SamplingParams

llm = LLM(model="meta-llama/Llama-3.1-8B-Instruct")

schema = {
    "type": "object",
    "properties": {
        "sentiment": {"type": "string", "enum": ["positive", "negative", "neutral"]},
        "confidence": {"type": "number", "minimum": 0, "maximum": 1},
        "keywords": {"type": "array", "items": {"type": "string"}}
    },
    "required": ["sentiment", "confidence", "keywords"]
}

params = SamplingParams(
    temperature=0.1,
    max_tokens=256,
    guided_json=schema,  # Enforces valid JSON matching schema
)

outputs = llm.generate(["Analyze sentiment: Great product, fast shipping!"], params)

这一能力对于构建可靠的 AI Agent 系统至关重要——多步 LLM 调用链需要精确的输出格式保证。有效的提示工程结合结构化输出约束,可消除生产管道中的解析失败问题。

选型决策框架

graph TD Start["你的使用场景是什么?"] --> Q1{"并发用户数?"} Q1 -->|"1-4 用户"| Q2{"需要简单易用?"} Q1 -->|"5-50 用户"| Q3{"GPU 资源?"} Q1 -->|"50+ 用户"| VLLM["vLLM + 张量并行"] Q2 -->|"是"| OLLAMA["Ollama - 快速上手"] Q2 -->|"否 - 需要控制"| LLAMACPP["llama.cpp 直接使用"] Q3 -->|"单 GPU"| VLLM_SINGLE["vLLM 单卡"] Q3 -->|"多 GPU"| VLLM Q3 -->|"仅 CPU"| OLLAMA_CPU["Ollama + Q4 量化"] OLLAMA --> NOTE1["最适合: 原型验证 - 本地开发 - 隐私优先应用"] VLLM --> NOTE2["最适合: 生产 API - 高吞吐 - 多租户服务"] LLAMACPP --> NOTE3["最适合: 边缘设备 - 自定义内核 - MCP 集成"]

总结对比矩阵

评估维度 Ollama vLLM llama.cpp
安装复杂度 低(一条命令) 中(Python 环境) 高(源码编译)
单用户性能 良好 (62 tok/s) 良好 (71 tok/s) 良好 (65 tok/s)
并发性能 差(>100 崩溃) 优秀(线性扩展) 手动(需自定义服务器)
多 GPU 支持 不支持 原生张量/流水线并行 手动分片
量化格式 GGUF (Q2-Q8) AWQ, GPTQ, FP8 GGUF, 自定义
内存效率 静态 KV Cache PagedAttention (2-4x 更优) 静态 KV Cache
API 兼容 OpenAI 兼容 OpenAI + Anthropic 自定义 (llama-server)
模型生态 Ollama Hub(精选) HuggingFace(海量) GGUF 文件(手动)
生产就绪度 开发/小团队 企业级 嵌入式/边缘

从 Ollama 迁移到 vLLM

当团队规模超出 Ollama 的承载能力时,以下是迁移路径:

bash
# Step 1: Export your model configuration
ollama show llama3.1:8b-instruct --modelfile > Modelfile.bak

# Step 2: Find equivalent model on HuggingFace
# GGUF Q4_K_M → AWQ 4-bit provides similar quality at higher throughput

# Step 3: Launch vLLM with OpenAI-compatible API
pip install vllm==0.17.0
vllm serve meta-llama/Llama-3.1-8B-Instruct-AWQ \
  --quantization awq \
  --port 11434 \
  --served-model-name llama3.1:8b-instruct

# Step 4: Update client base_url (port stays same, model name stays same)
# No client code changes needed!

迁移对 API 消费者透明,因为两者都提供 OpenAI 兼容端点。对于两个框架都不适合的边缘部署场景,请探索小语言模型边缘部署方案

性能调优清单

部署到生产前,请验证以下优化项:

Ollama 部署:

  • 使用 Q4_K_M 或 Q5_K_M 量化(最佳速度/质量平衡)
  • num_ctx 设为所需最小值(减少显存浪费)
  • 启用 Flash Attention (OLLAMA_FLASH_ATTENTION=1)
  • 将模型钉在内存中 (ollama keep-alive -1)
  • 使用动态上下文缩放(v0.17.7+)

vLLM 部署:

  • 启用 --performance-mode 标志
  • 设置 --gpu-memory-utilization 0.92-0.95
  • 对混合负载启用分块预填充(chunked prefill)
  • 配置与 GPU 数量匹配的张量并行度
  • 对重复前缀启用前缀缓存
  • 通过 Prometheus 指标监控 KV Cache 使用率
  • 根据延迟目标设置合适的 max_num_seqs

管理部署基础设施中的配置文件时,YAML 转 JSON 工具可简化 Kubernetes 清单与应用配置之间的格式转换。

实战部署模式

模式一:Ollama + vLLM 混合部署

许多团队在分层架构中同时使用两个框架:

yaml
# Tiered deployment architecture
tier_1_development:
  framework: ollama
  models: ["llama3.1:8b-instruct-q4_K_M"]
  use_case: "Individual developer testing and prompt iteration"
  hardware: "Laptop GPU or Apple Silicon"

tier_2_staging:
  framework: vllm
  models: ["meta-llama/Llama-3.1-8B-Instruct"]
  use_case: "Team testing, integration tests, load testing"
  hardware: "Single A100 80GB"

tier_3_production:
  framework: vllm
  models: ["meta-llama/Llama-3.1-70B-Instruct"]
  use_case: "Customer-facing API, high concurrency"
  hardware: "4x A100 80GB with tensor parallelism"

模式二:A/B 测试框架选型

python
# Load balancer configuration for A/B testing
import random
from fastapi import FastAPI
from openai import OpenAI

app = FastAPI()

ollama_client = OpenAI(base_url="http://ollama:11434/v1", api_key="ollama")
vllm_client = OpenAI(base_url="http://vllm:8000/v1", api_key="token")

@app.post("/v1/chat/completions")
async def route_request(request: dict):
    if random.random() < 0.1:  # 10% to Ollama for comparison
        client = ollama_client
        backend = "ollama"
    else:
        client = vllm_client
        backend = "vllm"
    
    response = client.chat.completions.create(**request)
    # Log latency metrics per backend for comparison
    return {"response": response, "backend": backend}

向量数据库集成

本地 LLM 部署通常与向量数据库配对用于 RAG 管道。Ollama 和 vLLM 都支持为检索增强生成提供嵌入生成:

python
# Ollama embedding generation for RAG
import requests

def get_embeddings(texts: list[str]) -> list[list[float]]:
    response = requests.post(
        "http://localhost:11434/api/embed",
        json={"model": "nomic-embed-text", "input": texts}
    )
    return response.json()["embeddings"]

# Use with any vector DB (Qdrant, Milvus, ChromaDB)
embeddings = get_embeddings(["How does PagedAttention work?"])

效率工具:配置 vLLM 等本地推理引擎通常需要调整复杂的 JSON 配置文件。你可以使用 JSON 格式化工具 来校验你的部署配置,避免因语法错误导致的服务启动失败。

延伸阅读

常见问题排查

推理过程中显存溢出(OOM)

最常见的生产问题是负载下 GPU 内存耗尽。每个框架处理方式不同:

bash
# Ollama: OOM typically shows as
# "error: out of memory" or process killed by OOM killer

# Solution: Reduce context window and use aggressive quantization
ollama run llama3.1:8b-instruct-q4_K_M --num-ctx 2048

# vLLM: OOM shows as CUDA out of memory during KV cache allocation
# Solution: Reduce gpu_memory_utilization or max_model_len
vllm serve meta-llama/Llama-3.1-8B-Instruct \
  --gpu-memory-utilization 0.85 \
  --max-model-len 8192 \
  --max-num-seqs 64

根因分析: vLLM 在启动时预计算最大 KV Cache 容量。如果 max_model_len * max_num_seqs 超过模型权重加载后的可用显存,服务器将无法启动。计算公式为:所需显存 = 模型权重 + KV Cache 页面 + 激活内存 + 系统开销

尾延迟高(P99 毛刺)

当中位延迟可接受但 P99 出现毛刺时:

Ollama: 通常表明上下文窗口抖动。当不同长度的请求到达时,Ollama 需要重新分配内存。用 num_ctx 固定上下文大小可消除重新分配。

vLLM: P99 毛刺通常与长 prompt 请求的预填充干扰相关。启用分块预填充(--enable-chunked-prefill)将大预填充分割为小块,与解码步骤交错执行,防止解码停滞。

模型加载失败

bash
# Ollama: "model not found" or hash mismatch
ollama rm llama3.1:8b-instruct
ollama pull llama3.1:8b-instruct

# vLLM: "tokenizer not found" or weight loading timeout
# Ensure HuggingFace token is set for gated models
export HUGGING_FACE_HUB_TOKEN="hf_your_token_here"
# Clear corrupted cache
rm -rf ~/.cache/huggingface/hub/models--meta-llama--Llama-3.1-8B-Instruct
vllm serve meta-llama/Llama-3.1-8B-Instruct --download-dir /clean/path

自定义基准测试方法

在确定框架之前,应在你的硬件和实际负载模式上运行基准测试。以下是可复现的测试脚本:

python
import asyncio
import time
import aiohttp
import statistics

async def benchmark_endpoint(
    url: str,
    model: str,
    num_requests: int = 100,
    concurrency: int = 10,
    prompt: str = "Explain how transformers work in exactly 200 words.",
):
    semaphore = asyncio.Semaphore(concurrency)
    results = []
    
    async def single_request(session):
        async with semaphore:
            payload = {
                "model": model,
                "messages": [{"role": "user", "content": prompt}],
                "max_tokens": 256,
                "temperature": 0.7,
            }
            start = time.perf_counter()
            async with session.post(
                f"{url}/v1/chat/completions", json=payload
            ) as resp:
                data = await resp.json()
                elapsed = time.perf_counter() - start
                tokens = data["usage"]["completion_tokens"]
                results.append({"latency": elapsed, "tokens": tokens})
    
    async with aiohttp.ClientSession() as session:
        tasks = [single_request(session) for _ in range(num_requests)]
        await asyncio.gather(*tasks)
    
    latencies = [r["latency"] for r in results]
    total_tokens = sum(r["tokens"] for r in results)
    total_time = max(latencies)
    
    print(f"Throughput: {total_tokens / total_time:.0f} tok/s")
    print(f"P50 latency: {statistics.median(latencies)*1000:.0f} ms")
    print(f"P99 latency: {sorted(latencies)[int(0.99*len(latencies))]*1000:.0f} ms")

# Compare both frameworks
asyncio.run(benchmark_endpoint("http://localhost:11434", "llama3.1:8b-instruct"))
asyncio.run(benchmark_endpoint("http://localhost:8000", "llama3.1:8b-instruct"))

该脚本在受控并发下测量真实吞吐量。以递增的 concurrency 值(1、5、10、25、50、100)运行,找到 Ollama 开始退化而 vLLM 继续线性扩展的拐点。

效率工具:配置 vLLM 等本地推理引擎通常需要调整复杂的 JSON 配置文件。你可以使用 JSON 格式化工具 来校验你的部署配置,避免因语法错误导致的服务启动失败。

延伸阅读

常见问题

运行 Ollama 和 vLLM 各需要什么硬件?

Ollama 可在任何 8GB+ RAM 的机器上运行(CPU 模式),或配备 6GB+ 显存的 GPU。推荐 16GB 显存(RTX 4080 或 M2 Pro)以获得 8B 模型的舒适推理体验。vLLM 需要支持 CUDA 的 NVIDIA GPU,FP16 推理最低 16GB 显存,量化模型最低 8GB。vLLM 在生产负载中不支持 Apple Silicon 或 AMD GPU。

从 Ollama 切换到 vLLM 是否需要修改应用代码?

不需要。两个框架都暴露 OpenAI 兼容的 API 端点。你只需更改客户端配置中的 base_url。甚至可以保持相同端口(11434)和模型名称——通过配置 vLLM 的 --port--served-model-name 标志实现。Prompt、参数和响应解析逻辑无需任何改动。

vLLM 的 PagedAttention 具体如何提升吞吐量?

PagedAttention 将 KV Cache 内存视为虚拟内存页面,而非为每个序列分配连续内存块。这消除了内存碎片——当短序列完成时,其页面立即可供新请求使用。传统静态分配因为给较短序列填充(padding)而浪费 60-80% 的 KV Cache 内存。PagedAttention 实现接近零浪费,在相同显存预算下可支撑 2-4 倍并发请求。

2026 年有 Ollama 和 vLLM 的情况下 llama.cpp 还有意义吗?

绝对有。llama.cpp 在三类场景下仍是最佳选择:(1) 没有 NVIDIA GPU 的边缘设备部署(ARM、Intel、AMD);(2) 需要自定义 CUDA 内核或量化方案的极致控制场景;(3) 2026 年 3 月新增的 MCP 客户端集成,可实现无 HTTP 开销的直接工具调用管道。许多嵌入式 AI 产品直接运行 llama.cpp 以在专用硬件上实现亚 10ms token 延迟。

本地 LLM 部署与云端 API 的成本对比如何?

在每小时 500+ 请求、平均输出 300 tokens 的场景下,单张 A100 GPU(AWS 上 $2.21/小时)运行 vLLM 相比 GPT-4o API 节省约 70%。盈亏平衡点通常在每小时 150-200 请求。低于该阈值时,考虑基础设施管理开销后云端 API 更具性价比。对于已有 GPU 基础设施(ML 训练)的团队,增加推理服务的边际成本接近零。

总结

2026 年本地 LLM 部署格局提供了明确的选择路径。Ollama 为个人使用提供无与伦比的开发体验——一条命令安装、像 Docker 镜像一样拉取模型,立即开始构建。vLLM 凭借 PagedAttention、连续批处理和张量并行提供生产级性能,随硬件线性扩展。

数据清晰表明:在 50+ 并发用户下,vLLM 提供 6 倍吞吐量;在 Blackwell GPU 上规模化后,优势达到 16.6 倍。基于并发需求而非个人偏好做出选择。

对于处在十字路口的团队,混合模式效果极佳:在笔记本上用 Ollama 进行原型验证,在 GPU 服务器上用 vLLM 部署生产环境,两环境间零代码改动。关于 Ollama 高级功能(如 Modelfile 和嵌入管道)的更多内容,请参阅我们的 Ollama 高级使用指南