6.13 LLM 自托管完整方案——ollama、Open WebUI 与本地推理

预计阅读时间:19 分钟

📖 目录

6.12:AI 基础设施 介绍了 GPU 驱动安装和 vLLM/Triton 等高性能推理服务。对于个人使用或小规模部署,ollama + Open WebUI 提供了更简单的本地 LLM 运行方案——一行命令启动模型,浏览器即用。

学习目标

  • 理解本地 LLM 推理的技术路径:模型量化、显存需求与推理速度的权衡
  • 用 ollama 完成模型安装、运行与 OpenAI 兼容 API 调用
  • 部署 Open WebUI 提供浏览器交互界面,配置多用户与多模型
  • 掌握 systemd 服务化、HTTPS 反向代理、访问控制等生产配置
  • 根据硬件条件(CPU/GPU/显存)选择正确的模型与量化级别
  • 评估自托管 LLM 与云 API 的适用边界(成本、隐私、性能)

前置知识

方案对比

方案GPU 要求适合场景复杂度
ollama可选(CPU 可跑小模型)个人/开发环境极简
Open WebUI + ollama同上团队共享 Web 界面
vLLM需要 GPU生产 API 服务中等
Triton Inference Server需要 GPU多模型/多框架

1. ollama 安装与使用

# 一行安装(Linux)
curl -fsSL https://ollama.com/install.sh | sh

# 启动服务
ollama serve

# 下载并运行模型(首次下载约 4-7GB)
ollama run llama3.1:8b          # Meta Llama 3.1 8B(推荐入门)
ollama run qwen2.5:14b           # 通义千问 14B(中文优秀)
ollama run deepseek-r1:7b        # DeepSeek R1 7B(推理能力强)
ollama run codellama:13b         # Code Llama 13B(代码专用)

# 交互式对话
ollama run llama3.1:8b
>>> 你好,请介绍一下 Linux 的文件系统层次结构

常用命令

# 列出已下载的模型
ollama list

# 查看模型详情(参数量、量化格式)
ollama show llama3.1:8b

# 删除模型
ollama rm llama3.1:8b

# 停止运行中的模型
ollama stop

# API 调用(兼容 OpenAI 格式)
curl http://localhost:11434/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "llama3.1:8b",
    "messages": [{"role": "user", "content": "什么是 Docker?"}]
  }'

模型选择指南

模型参数量内存需求特点
qwen2.5:3b3B4GB轻量,中文支持好
llama3.1:8b8B8GB通用,英文优秀
qwen2.5:14b14B16GB中文最佳,推理能力强
codellama:13b13B16GB代码生成专用
deepseek-r1:14b14B16GB深度推理、数学、逻辑
量化格式 ollama 默认使用 Q4_K_M(4-bit 量化),在质量和速度间平衡。对质量要求高可用 :q8_0(8-bit)格式,精度更高但速度更慢。

2. Open WebUI——浏览器界面

Open WebUI 提供类似 ChatGPT 的 Web 界面,支持多用户、文件上传、知识库(RAG)。

# Docker 一键部署(连接本机 ollama)
docker run -d \
  --name open-webui \
  -p 3000:8080 \
  -e OLLAMA_BASE_URL=http://host.docker.internal:11434 \
  -v open-webui:/app/backend/data \
  --restart unless-stopped \
  ghcr.io/open-webui/open-webui:main

# 首次访问 http://localhost:3000
# 管理员账户自动创建,后续可添加用户

Open WebUI 核心功能:

  • 多模型切换:侧边栏选择不同 ollama 模型
  • 文件上传:上传 PDF/TXT/图片,自动提取内容作为上下文
  • 知识库(RAG):上传文档建立向量索引,模型基于文档回答
  • 多用户管理:独立会话、角色权限、使用统计
  • 对话历史:完整保存,支持导出和搜索

3. 生产环境配置

# ollama 系统服务
# /etc/systemd/system/ollama.service
[Unit]
Description=Ollama LLM Server
After=network.target

[Service]
User=ollama
Group=ollama
Environment="OLLAMA_HOST=0.0.0.0:11434"
Environment="OLLAMA_MODELS=/data/ollama/models"
Environment="OLLAMA_NUM_PARALLEL=4"
Environment="OLLAMA_MAX_LOADED_MODELS=2"
ExecStart=/usr/local/bin/ollama serve
Restart=always

[Install]
WantedBy=multi-user.target

# 启动
sudo systemctl enable --now ollama

资源限制

# 限制 ollama 使用 16GB 内存
# /etc/systemd/system/ollama.service.d/override.conf
[Service]
MemoryMax=16G
CPUQuota=400%

# 重启生效
sudo systemctl daemon-reload && sudo systemctl restart ollama

4. 网络部署与远程访问

# 仅内网访问(推荐)
OLLAMA_HOST=192.168.1.100:11434

# 通过 Nginx 反向代理 + HTTPS
# /etc/nginx/conf.d/ollama.conf
server {
    listen 443 ssl;
    server_name llm.example.com;

    location / {
        proxy_pass http://127.0.0.1:11434;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_read_timeout 300s;  # LLM 响应慢,超时放长
    }
}

# Open WebUI 部署(带 HTTPS)
docker run -d \
  --name open-webui \
  -p 127.0.0.1:3000:8080 \
  -e OLLAMA_BASE_URL=http://host.docker.internal:11434 \
  -e WEBUI_AUTH=true \
  -v open-webui:/app/backend/data \
  --restart unless-stopped \
  ghcr.io/open-webui/open-webui:main

Nginx 网关加认证与限流

# ollama API 无认证,反向代理层必须兜底:
# 1. Basic Auth(个人简单场景)
# 生成密码哈希:openssl passwd -apr1
auth_basic "LLM API";
auth_basic_user_file /etc/nginx/htpasswd-llm;

# 2. 或 API Key 校验(OpenResty / lua-resty 实现)
# 3. 团队场景推荐直接走 Open WebUI 的用户认证

# 反向代理层统一做限流,防止 API Key 被滥用
limit_req_zone $binary_remote_addr zone=llm_api:10m rate=10r/m;
location /v1/chat/completions {
    limit_req zone=llm_api burst=5;
    proxy_pass http://127.0.0.1:11434;
}

5. 安全注意事项

  • 不要暴露 ollama API 到公网——无认证机制,任何人都能调用
  • 通过 Open WebUI(有认证)或 Nginx 反向代理 + mTLS 暴露
  • 模型文件存放在 /data/ollama/models,注意磁盘空间(每个模型 4-20GB)
  • GPU 服务器建议物理隔离或 VPC 网络

6. 与 6.12:AI 基础设施 AI 基础设施的关系

维度本章(ollama + Open WebUI)6.12:AI 基础设施(vLLM + Triton)
适合个人、小团队、开发测试生产 API、高并发
性能单请求,响应式批处理、高吞吐
GPU 利用率低(模型按需加载)高(持续推理)
API 格式兼容 OpenAI API自定义 / gRPC

7. 模型量化原理

量化(Quantization)把 FP32/FP16 的模型权重用更低精度表示,换取显存下降与推理加速。看懂量化,才能理解 ollama 模型标签里 :q4_K_M:q8_0 的含义,以及为什么同一模型不同 tag 显存差好几倍。

7.1 精度格式对比

格式每权重位数相对 FP16 显存精度损失推理速度典型场景
FP3232 bit200%训练
FP1616 bit100%几乎无基准服务基准(vLLM 默认)
BF1616 bit100%几乎无(动态范围更大)≈FP16A100/H100 训练与推理
INT88 bit50%轻微快 20-40%性价比均衡
INT44 bit25%可感知(复杂任务降级)最快个人本地部署

量化只压缩权重部分,KV cache 与激活值仍需另算(见第 8 节)。以 7B 模型为例:FP16 权重约 14GB,INT8 约 7GB,INT4 约 3.5GB。质量上 INT8 对多数任务不可感知,INT4 在代码生成、数学等复杂任务上偶有降级。

7.2 量化格式:GPTQ / AWQ / GGUF

格式适用推理后端特点选择建议
GPTQGPU(vLLM、TGI)离线量化,推理时开销低,生态成熟GPU 上 vLLM 服务首选
AWQGPU(vLLM、TGI)按权重重要性保护关键通道,同精度下质量优于 GPTQ追求质量时选 AWQ
GGUFllama.cpp / ollama支持 CPU 运行与 KV cache 量化,单文件易分发ollama/无 GPU 环境必选

ollama 直接使用 GGUF 格式,ollama run llama3.1:8b-q8_0 指定位宽;vLLM 更常用 GPTQ/AWQ 量化后的 safetensors 权重。同一模型不同量化版本的显存差可达 4 倍,先小后大验证效果是标准流程。

7.3 KV cache 量化

KV cache 是长上下文场景显存的大头(公式见 8.1),llama.cpp 支持把它从 FP16 量化到 8/4 bit,代价是长上下文下精度略降,对多数对话场景不可感知:

# llama.cpp 服务端:KV cache 量化到 8bit,32K 上下文的显存可降 60%+
llama-server -m qwen2.5-7b-q4_k_m.gguf -c 32768 \
  --cache-type-k q8_0 --cache-type-v q8_0
# 不指定时默认 f16(精度最高),-c 32768 表示 32K 上下文窗口

8. GPU 内存规划

8.1 显存计算示例

总显存 = 模型权重 + KV cache + 激活值 + CUDA 开销。以 7B 模型、FP16、4K 上下文、batch=8 为例:

# 权重:70 亿参数 × 2 字节 = 约 14GB
# KV cache:2(K/V) × 层数(32) × KV 头数(8) × 头维度(128) × seq_len(4096) × batch(8) × 2 字节
#          = 2×32×8×128×4096×8×2 ≈ 4.3GB
# 激活值:与隐藏层维度、batch 相关,约占权重 5-10% ≈ 1GB
# CUDA 上下文 + 运行时开销:0.5-1GB
# 合计 ≈ 14 + 4.3 + 1 + 1 ≈ 20GB(RTX 3090/4090 24G 可跑,12G 卡必须 INT4)

8.2 不同规模模型的显存需求

模型FP16INT8INT4推荐硬件
7B(Qwen2.5-7B、Llama3-8B)16-18GB12-13GB8-9GBRTX 4070 12G 起步(INT4)
13B(CodeLlama-13B)28-30GB20-22GB13-15GBRTX 4090 24G
70B(Llama3-70B、Qwen2.5-72B)140-150GB75-85GB42-45GB2×A100 80G 或 4×A100 40G

表中数值含 4K 上下文 KV cache 与运行开销,实际以 nvidia-smi 观测为准。个人场景的黄金公式:INT4 下 7B 是 12G 卡的甜点,14B 需要 24G,70B 与单机个人部署基本无缘

8.3 多卡并行:张量并行 vs 流水线并行

维度张量并行(Tensor Parallel)流水线并行(Pipeline Parallel)
原理单层内切分权重到多卡,每层结束后卡间同步按层分段,段边界传输中间结果
通信量大(每层 all-reduce),需要 NVLink 高速互联小(只在段边界),万兆网络即可
适合单机多卡(同机内互联)跨机集群
vLLM 配置--tensor-parallel-size 2/4/8--pipeline-parallel-size(vLLM 2.x 支持)

8.4 CPU offload 场景

显存不足时可以把部分层加载到内存。llama.cpp 用 --n-gpu-layers 控制"前 N 层上 GPU";ollama 通过 Modelfile 的 num_gpu 参数设置。代价是每跨层一次 PCIe 拷贝,速度可能跌到 2-5 token/s,只适合"能跑就行"的非交互任务(批量离线处理、测试)。

# llama.cpp:40 层模型中前 30 层上 GPU,其余跑 CPU
llama-server -m qwen2.5-14b-q4_k_m.gguf -ngl 30

# ollama 方式:为单个模型定制加载策略
cat > Modelfile <<EOF
FROM qwen2.5:14b
PARAMETER num_gpu 30
EOF
ollama create qwen2.5-14b-offload -f Modelfile

8.5 显存不足时的决策顺序

模型放不下显存时,按"成本从低到高"依次尝试,不要一上来就换小模型:

顺序手段效果代价
KV cache 量化(--cache-type-k q8_0)并收紧上下文长度省 30-60% KV 显存长上下文精度略降
降量化位宽(FP16 → INT8 → INT4)权重显存减半再减半INT4 复杂任务质量降级
限制并发(--max-num-seqs 减半)省多份 KV cache吞吐下降
CPU offload 部分层(--n-gpu-layers)能跑但慢(2-5 token/s)交互体验差,仅批处理
换小模型或减上下文彻底解决能力下降,需重新验证

判断顺序的价值:大多数情况做到 ①③ 就够——先看 nvidia-smi 确认到底是权重占满还是 KV cache 占满,再对症下药。

推荐起点 个人 24G 卡:7B/14B INT4 + 8K 上下文 + KV cache q8_0,是性价比与体验的最佳平衡点。

9. OpenAI 兼容 API 详解

ollama、vLLM、LocalAI 都实现了 OpenAI 的 /v1/chat/completions 接口,应用层只需改 base_url 即可切换后端,这是自托管生态能互通的关键。

9.1 三个后端端点对比

后端默认端点流式输出function callingembedding
ollama/v1/chat/completions支持支持(tools 参数)/v1/embeddings 支持
vLLM/v1/chat/completions支持支持(受模型能力限制)--task embed 启动
LocalAI/v1/chat/completions支持支持/v1/embeddings 支持

9.2 流式输出

# curl 流式请求:stream=true,模型逐字返回 SSE 事件
curl http://localhost:11434/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{"model":"llama3.1:8b","stream":true,
       "messages":[{"role":"user","content":"写一首五言绝句"}]}' \
  --no-buffer | head -30

# Python 客户端:openai SDK 只需改 base_url 与 api_key
from openai import OpenAI
client = OpenAI(base_url="http://localhost:11434/v1", api_key="ollama")
stream = client.chat.completions.create(
    model="llama3.1:8b",
    messages=[{"role": "user", "content": "你好"}],
    stream=True)
for chunk in stream:
    print(chunk.choices[0].delta.content or "", end="", flush=True)

9.3 function calling

# 声明工具,模型返回 tool_calls 而不是直接回答
resp = client.chat.completions.create(model="llama3.1:8b", messages=[
    {"role": "user", "content": "北京现在温度多少?"}
], tools=[{
    "type": "function",
    "function": {
        "name": "get_weather",
        "description": "查询城市当前温度",
        "parameters": {"type": "object",
                       "properties": {"city": {"type": "string"}},
                       "required": ["city"]}
    }}])
# 模型返回:tool_calls=[{function:{name:"get_weather",
#                         arguments:{"city":"北京"}}}]
# 应用执行函数后,把结果以 role="tool" 消息发回,模型给出最终回答
小模型的 function calling 不可靠 7B 以下模型经常漏参数、返回非法 JSON。生产环境选 14B+ 或 Qwen 系列(工具调用训练充分),代码里必须做 JSON 解析兜底与重试,解析失败回退为普通回答。

9.4 embedding 模型部署

# 拉取嵌入模型(RAG 向量检索用)
ollama pull nomic-embed-text
ollama pull qwen3-embedding:0.6b    # 中文场景可选

# 调用:返回 768/1024 维向量,与 chat 接口完全同构
curl http://localhost:11434/v1/embeddings \
  -H "Content-Type: application/json" \
  -d '{"model":"nomic-embed-text","input":"Kafka 与 RabbitMQ 的区别"}'

10. 推理优化——vLLM 生产部署

追求吞吐的 API 服务应使用 vLLM 而不是 ollama(同卡吞吐高 3-5 倍)。三大特性让它成为生产标准:

  • PagedAttention:KV cache 按页管理,消除显存碎片,是吞吐翻倍的根源
  • Continuous Batching:请求到达即插入批次,GPU 持续满载,不再等"凑满一批"
  • 前缀缓存:相同 system prompt 的计算结果复用,多轮对话与 Agent 场景命中率极高
# 安装并启动(需 NVIDIA GPU + CUDA)
pip install vllm==0.6.0
vllm serve Qwen/Qwen2.5-7B-Instruct \
  --gpu-memory-utilization 0.9 \
  --max-model-len 8192 \
  --max-num-seqs 32 \
  --enable-prefix-caching \
  --served-model-name qwen25 \
  --port 8000

# 验证(与 ollama 同一套 OpenAI 接口)
curl http://localhost:8000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{"model":"qwen25","messages":[{"role":"user","content":"你好"}]}'

10.1 关键调优参数

参数作用建议
--gpu-memory-utilization显存可用比例(权重之外余量全给 KV cache)0.85-0.95,留 5-10% 给 CUDA 上下文
--max-num-seqs单 batch 最大并发序列数8-64,越大吞吐越高但首 token 延迟上升
--max-model-len最大上下文长度按业务需要,过长会浪费 KV cache 显存
--enable-prefix-caching前缀缓存复用有固定 system prompt 必开
--served-model-name对外暴露的模型名固定别名,避免应用随权重路径变动
# 压测验证(wrk 打 60 秒,观察 TPS 与 P95)
wrk -t8 -c32 -d60s -s post.lua http://localhost:8000/v1/chat/completions
# 关注指标:吞吐 token/s、排队时间、P95 首 token 延迟
# 报错 "CUDA out of memory":调低 --max-num-seqs 或 --max-model-len
# vLLM 自带 /metrics 端点(Prometheus 格式),直接接入 Grafana

10.2 常见瓶颈与排查

症状原因排查与解决
GPU 利用率低(< 40%)请求太少,batch 不满看 vllm:num_requests_running;低并发场景本就不该用 vLLM,回退 ollama
首 token 延迟高prefill 阶段处理长提示词缩短 system prompt;开启前缀缓存命中固定开头;长文档用 RAG 摘要代替全量塞入
CUDA OOMKV cache 超限调低 --max-num-seqs / --max-model-len;确认 --gpu-memory-utilization 留了余量
吞吐上不去但显存有剩余连续批处理被长序列阻塞长请求改流式分块;提高 --max-num-seqs 让更多短请求并行

排查口诀:先看 vllm 自带 /metrics(gpu_cache_usage_perc、num_requests_running、prompt/completion token 吞吐),再动参数——凭感觉调参是最贵的排障方式。

11. 安全与成本评估

11.1 本地 vs API 成本对比

维度本地自托管云 API(豆包/OpenAI 等)
前期成本GPU 服务器 2-8 万元(24G 单卡约 1-1.5 万)0
运行成本电费+折旧:24G 卡满载约 0.5-1 元/小时按 token:7B 级模型约 0.5-2 元/百万 token
计费模型无论用不用都在烧钱用多少付多少
盈亏平衡点日用量约 500 万-2000 万 token 时与 API 打平低用量(<100 万 token/天)更便宜

11.2 数据隐私场景

  • 必须本地:病历、代码仓库、客户 PII、涉密文档——数据不出内网是合规硬要求
  • 可选本地:内部知识库(可脱敏后走 API,成本更低、模型能力更强)
  • 建议 API:个人玩具项目、一次性实验、需要最强模型能力的业务

11.3 模型许可证速查

模型许可证商用限制
Llama 3.x(Meta)Llama Community License月活 7 亿以下可商用
Mistral 7B / 8x7BApache 2.0无限制
Qwen 2.5(阿里)Apache 2.0无限制
DeepSeek V3 / R1MIT无限制
GLM-4(智谱)GLM 许可(需报备)月活过亿需书面授权

11.4 内容安全过滤

自托管模型没有云厂商的内容审核管线,对外服务必须自建过滤层:

# 最低要求组合:
# 1. Nginx/网关层关键词与正则过滤(OpenResty lua 脚本或 lua-resty-waf)
# 2. 按用户限流(令牌桶),防止服务被批量滥用
# 3. 全量对话日志审计,保留 180 天,供合规排查
# 4. 敏感场景可在网关后串一个开源审核模型做二次过滤

12. 生产案例——从下载到上线

以"给公司内网做一个代码问答助手"为例,完整走一遍:下载 -> 验证 -> 量化 -> vLLM 部署 -> 接入应用 -> 监控。

# ① 选型与下载:Qwen2.5-7B(Apache 2.0 可商用、代码能力好),先拉 GGUF 试效果
ollama pull qwen2.5:7b
ollama run qwen2.5:7b "用 Python 写一个协程池下载器"

# ② 质量确认后,换 AWQ 量化版跑 vLLM(吞吐比 ollama 高 3-5 倍)
git clone https://huggingface.co/Qwen/Qwen2.5-7B-Instruct-AWQ
pip install vllm==0.6.0

# ③ vLLM 部署(systemd 托管,开机自启 + 崩溃重启)
cat > /etc/systemd/system/vllm.service <<EOF
[Unit]
Description=vLLM Inference Server
After=nvidia-persistenced.service

[Service]
ExecStart=/opt/venv/bin/vllm serve /data/models/Qwen2.5-7B-Instruct-AWQ \
  --gpu-memory-utilization 0.9 --max-num-seqs 16 \
  --enable-prefix-caching --served-model-name qwen-coder
Restart=always
Environment=CUDA_VISIBLE_DEVICES=0,1

[Install]
WantedBy=multi-user.target
EOF
systemctl enable --now vllm

# ④ 应用接入:内部工具统一指向 OpenAI 兼容端点
OPENAI_BASE_URL=http://10.0.0.5:8000/v1
OPENAI_API_KEY=local-only-key

# ⑤ 监控:vLLM 自带 /metrics(Prometheus 格式)
curl -s http://10.0.0.5:8000/metrics | grep vllm:gpu_cache_usage_perc
# 告警规则:gpu_cache_usage_perc > 0.9 时降并发或扩容
# 配合 node_exporter 监控 GPU 温度、显存、功耗

上线后观察一周:GPU 利用率、显存占用、P95 时延三张图稳定后,再决定是否加 Redis 缓存层(缓存重复问题)或扩容第二台。整个链路中模型选型与量化级别决定了 80% 的效果,部署本身只占 20%。

常见错误

  • ollama 启动失败:端口 11434 已被占用——使用 lsof -i :11434 查看占用进程并终止,或修改 OLLAMA_HOST 指定其他端口。
  • 模型下载卡住/超时——国内网络环境下从 ollama.com 下载速度慢,可配置代理(HTTPS_PROXY)或使用国内镜像源拉取。
  • Open WebUI 无法连接 ollama——Docker 容器内访问宿主机需使用 host.docker.internal(Linux 需添加 --add-host=host.docker.internal:host-gateway),不要用 127.0.0.1
  • GPU 显存不足导致推理报错——减小模型参数量(如用 8B 替代 14B),或降低 OLLAMA_NUM_PARALLEL 减少并发加载。使用 nvidia-smi 监控显存占用。
  • 模型输出乱码/中文质量差——优先选择中文优化模型(qwen2.5 系列),确保模型下载完整(ollama show 检查),避免使用过低量化格式(Q4 以下)。
  • 显存规划错误导致 OOM——只算了权重没算 KV cache,长上下文场景直接 CUDA out of memory。用第 8 节公式估算总量,并设置 OLLAMA_NUM_PARALLEL--max-num-seqs 限制并发。
  • vLLM 启动失败/显存利用率异常——多卡环境未设 CUDA_VISIBLE_DEVICES 导致卡冲突;或 --gpu-memory-utilization 设置过高(>0.95)挤占 CUDA 上下文空间。
  • function calling 返回非法 JSON——小模型工具调用不可靠,解析失败应重试或回退为普通回答,不要直接抛 500 给用户。
  • 并发调太高导致逐个请求都慢——OLLAMA_NUM_PARALLEL / --max-num-seqs 过大时,单请求被批量排队拖慢。低延迟优先的业务调小并发,高吞吐优先的业务调大。
  • 切换模型前忘记清显存——同一 GPU 上换模型前先 ollama stop 或重启 vLLM,否则旧模型权重残留导致新模型 OOM。

最佳实践

  • 模型存储路径独立挂载——将 OLLAMA_MODELS 指向独立磁盘分区,模型文件动辄数十 GB,避免占用系统盘空间。
  • 生产环境务必加认证——ollama API 本身无任何认证机制,必须通过 Open WebUI、Nginx 反向代理 + mTLS 或 API Key 网关暴露服务。
  • 使用 systemd 托管 ollama——避免手动 ollama serve 后台运行不可靠的问题,systemd 自动重启、日志管理、开机启动一并解决。
  • 按需加载模型,及时卸载——OLLAMA_MAX_LOADED_MODELS 控制常驻内存的模型数量,避免多模型同时加载耗尽 GPU 显存。
  • 定期清理旧版本模型——ollama pull 更新模型后旧版本仍占用磁盘,用 ollama list 检查并 ollama rm 删除不再使用的版本。
  • 先 GGUF 验证效果,再上 vLLM 生产——用 ollama 快速验证模型质量与量化位宽,确认后再用 AWQ/GPTQ 部署 vLLM,避免在错误选型上浪费调优时间。
  • 固定 system prompt 并开启前缀缓存——vLLM 的 --enable-prefix-caching 在 Agent/固定提示词场景可省 30-50% 算力。
  • 许可证合规先行——商用前核对模型许可证(Llama 月活限制、GLM 报备要求),并把许可证声明写进项目 README。
  • 用 nvidia-smi 观测而非估算——显存规划表只是起点,上线后以 nvidia-smi 实测为准,把实测值回填到文档形成团队基线。
  • 显存不足按 ①⑤ 顺序决策——先量化与限并发,再 offload,最后才换小模型,每一步都用压测数据验证。

练习题

  1. 在本地安装 ollama 并运行 qwen2.5:7b,通过 curl 调用 OpenAI 兼容 API 发送一个中文问题,记录响应内容和延迟时间。
  2. 使用 Docker 部署 Open WebUI 并连接到本机 ollama,配置 Nginx 反向代理实现 HTTPS 访问,截图展示多模型切换功能。
  3. 编写一个 systemd override 文件,限制 ollama 进程最多使用 8GB 内存和 2 个 CPU 核心,并在 ollama 运行大模型时用 systemd-cgtop 观察资源消耗。
  4. 用第 8 节公式为"14B 模型、INT4、8K 上下文、batch=16"计算总显存,据此判断 RTX 3090 24G 单卡能否部署,并用 nvidia-smi 实测验证。
  5. 分别用 ollama 与 vLLM 部署同一个 7B 模型,用 wrk 压测对比吞吐(token/s)与 P95 延迟,解释 vLLM 高吞吐的来源(continuous batching、PagedAttention)。
  6. 用 nvidia-smi 记录同一模型在 2K/8K/16K 上下文下的显存占用,画出"上下文长度 vs KV cache 显存"曲线,验证第 8 节公式。
  7. 模拟一次显存 OOM:把 vLLM 的 --max-num-seqs 调到显存放不下,观察报错信息,按 10.2 排查表给出处置方案。

学习检查点

学完本章后,请检验自己是否掌握以下内容:

检查项自测问题验证方法
概念理解能用自己的话解释 LLM 推理引擎的架构和模型量化原理尝试向他人讲解
命令操作能不查文档完成 vLLM/Ollama 部署和模型加载在终端实际执行
原理掌握能说出 LLM 推理的 KV Cache 和批处理优化原理画出流程图
故障排查能独立排查 LLM 服务 GPU 显存不足或推理延迟高的问题模拟故障并修复
最佳实践能说明为什么需要为 LLM 服务配置请求限流和超时对比不同方案

本章总结

自托管 LLM 的门槛比想象中低:ollama 一行命令即可运行中小模型,Open WebUI 提供企业级界面,配合 systemd 与 Nginx 就能变成可对外服务的应用。但选型要清醒:本地推理适合隐私敏感、成本敏感、离线场景;追求模型天花板性能与规模化时,云 API 仍是最优解。量化级别与显存的匹配是性能的关键杠杆,先测再调。

延伸阅读

↑ 回到顶部