Skip to content

本地大模型完全指南

不想把数据发给 OpenAI?想在自己的机器上跑大模型?本教程从零开始——选模型、选框架、跑推理、做量化、上生产,让你在本地/私有环境中高效运行开源大模型。


1. 为什么要在本地跑大模型

调 OpenAI API 很方便,但总有些场景你不得不或者更值得在本地跑模型。

1.1 四大驱动力:隐私、成本、延迟、自由

本地部署的四大驱动力:

1️⃣ 数据隐私(Privacy)
   医疗病历、金融交易、政务文档、客户 PII
   → 数据不能出内网,更不能发给第三方 API
   → 本地部署 = 数据零泄露

2️⃣ 成本控制(Cost)
   每天调用 10,000 次 GPT-4o = ~$250/天 = $7,500/月
   本地跑 Qwen-14B = 一张 4090 ($1,600) + 电费
   → 高频场景 2-3 个月回本

3️⃣ 低延迟(Latency)
   API 调用:网络往返 200ms + 排队 + 生成
   本地推理:直接生成,首 Token < 50ms
   → 对实时场景(语音助手/代码补全)至关重要

4️⃣ 定制自由(Freedom)
   想微调?想量化?想改采样策略?想控制上下文窗口?
   → API 给你的只是参数,本地给你的是完全控制权

1.2 本地 vs API:成本交叉点计算

python
def cost_comparison(daily_calls: int, tokens_per_call: int = 1000):
    """计算本地部署 vs API 的成本交叉点"""
    
    # API 成本(GPT-4o-mini)
    api_cost_per_token = 0.6 / 1_000_000  # $0.6/M output tokens
    api_monthly = daily_calls * tokens_per_call * api_cost_per_token * 30
    
    # 本地成本(RTX 4090 + Qwen-14B)
    gpu_cost = 1600           # 一次性购买
    monthly_power = 50        # 电费 ~$50/月
    monthly_maintain = 20     # 维护成本
    local_monthly = monthly_power + monthly_maintain
    
    # 回本月数
    breakeven = gpu_cost / max(api_monthly - local_monthly, 1)
    
    print(f"日调用量: {daily_calls:,}")
    print(f"API 月费: ${api_monthly:,.0f}")
    print(f"本地月费: ${local_monthly:,.0f}(硬件已摊销)")
    print(f"回本周期: {breakeven:.1f} 个月")

cost_comparison(1000)   # → 回本 ~24 个月(不值得)
cost_comparison(10000)  # → 回本 ~3 个月(值得考虑)
cost_comparison(50000)  # → 回本 ~1 个月(必须本地)

1.3 什么场景适合本地部署,什么不适合

场景推荐方案原因
医疗/金融数据处理✅ 本地数据合规硬需求
日调用 > 10,000 次✅ 本地成本优势明显
代码补全/IDE 助手✅ 本地延迟敏感,代码隐私
离线/弱网环境✅ 本地无网络可用
需要最强模型能力❌ APIGPT-4o/Claude 仍是最强
日调用 < 1,000 次❌ API硬件投入不划算
多模态(视频/图像生成)❌ API本地算力不够
快速原型验证❌ API不值得花时间部署

💡 务实建议:不要为了"本地"而本地。先算清成本、评估能力差距,再决定。很多团队的最优解是混合方案——敏感数据走本地,通用任务走 API。


2. 开源模型全景:2026 年选型指南

开源模型爆发式增长——光 HuggingFace 上就有上万个。本章帮你理清主流模型家族,按需选型。

2.1 六大模型家族深度对比

模型家族开发者参数范围亮点许可证
Llama 3.xMeta1B-405B社区最大、工具链最成熟Llama License
Qwen 2.5/3阿里0.5B-72B中文最强、多模态版本丰富Apache 2.0
Mistral/MixtralMistral AI7B-8x22BMoE 架构、效率极高Apache 2.0
Gemma 2/3Google2B-27B小模型质量极高Gemma License
DeepSeek V3/R1DeepSeek7B-671B推理能力强、MoE 架构MIT
Phi-4Microsoft3B-14B小模型之王、数学/推理强MIT

2.2 参数规模 vs 能力:1B / 7B / 14B / 70B 的边界

参数规模能力边界(经验法则):

  1B-3B(轻量级)
  ├── 适合:分类、提取、简单问答、嵌入
  ├── 不适合:复杂推理、长文写作
  └── 硬件:4GB 内存即可,手机可跑

  7B-14B(甜蜜点)
  ├── 适合:通用对话、代码生成、RAG、Agent 工具调用
  ├── 不适合:超复杂推理(数学竞赛级)
  └── 硬件:8-16GB 显存 / 16-32GB 统一内存

  30B-72B(高性能)
  ├── 适合:接近 GPT-4 的通用能力
  ├── 不适合:成本敏感场景
  └── 硬件:48-80GB 显存 / 64GB+ 统一内存

  > 100B(旗舰级)
  ├── 适合:追求极致质量
  └── 硬件:多卡并行 / 集群

2.3 中文模型专项:Qwen vs DeepSeek vs Yi

维度Qwen 2.5DeepSeek V3Yi-1.5
中文理解⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
代码能力⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
数学推理⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
多模态⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
小模型质量⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
许可证Apache 2.0MITApache 2.0
推荐🥇 中文首选🥈 推理/代码🥉

2.4 按任务选模型:通用 / 代码 / 数学 / 多模态

按任务类型选模型(2026 推荐):

  通用对话 → Qwen2.5-14B / Llama-3.3-70B
  中文对话 → Qwen2.5-14B / Qwen2.5-7B
  代码生成 → DeepSeek-Coder-V2 / Qwen2.5-Coder-14B
  数学推理 → DeepSeek-R1 / Qwen2.5-Math
  多模态   → Qwen2-VL / Llama-3.2-Vision
  嵌入模型 → BGE-M3 / GTE-Qwen2 / Nomic-embed
  小模型   → Phi-4-mini / Gemma-2-2B / Qwen2.5-3B

2.5 许可证避坑:商用限制一览

许可证商用修改限制代表模型
Apache 2.0✅ 自由Qwen, Mistral
MIT✅ 自由DeepSeek, Phi
Llama License⚠️ 有条件MAU>7亿需申请Llama 3
Gemma License⚠️ 有条件不可生成训练数据Gemma 2

💡 商用首选 Apache 2.0 / MIT。Llama License 对绝大多数企业无影响(你的 MAU 不太可能超过 7 亿),但法务可能会纠结。


3. 推理框架对比:Ollama / vLLM / llama.cpp

选完模型,下一步是选"怎么跑"。三大框架各有定位,选错了要么性能浪费,要么能力不足。

3.1 Ollama:5 分钟跑起大模型

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

# 拉取模型(自动下载量化版本)
ollama pull qwen2.5:14b

# 对话
ollama run qwen2.5:14b
>>> 你好,解释一下什么是 RAG?

# 启动 API 服务(OpenAI 兼容)
ollama serve  # 默认端口 11434

# API 调用
curl http://localhost:11434/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{"model": "qwen2.5:14b", "messages": [{"role": "user", "content": "Hello"}]}'

3.2 llama.cpp:极致轻量的 C++ 推理

bash
# 从源码编译(Metal 加速)
git clone https://github.com/ggerganov/llama.cpp
cd llama.cpp
cmake -B build -DLLAMA_METAL=ON
cmake --build build --config Release -j

# 下载 GGUF 模型(HuggingFace)
# 推荐从 TheBloke 或官方获取量化版本

# 运行推理
./build/bin/llama-cli \
  -m models/qwen2.5-14b-q4_k_m.gguf \
  -p "解释什么是向量数据库" \
  -n 256 \
  --gpu-layers 99  # 尽可能多地放到 GPU

# 启动 API 服务
./build/bin/llama-server \
  -m models/qwen2.5-14b-q4_k_m.gguf \
  --host 0.0.0.0 --port 8080 \
  --gpu-layers 99

3.3 vLLM:生产级高吞吐推理引擎

bash
# 安装(需要 CUDA)
pip install vllm

# 启动 API 服务
python -m vllm.entrypoints.openai.api_server \
  --model Qwen/Qwen2.5-14B-Instruct \
  --port 8000 \
  --tensor-parallel-size 1 \
  --max-model-len 8192 \
  --gpu-memory-utilization 0.9
python
# 代码调用
from openai import OpenAI

client = OpenAI(base_url="http://localhost:8000/v1", api_key="dummy")
response = client.chat.completions.create(
    model="Qwen/Qwen2.5-14B-Instruct",
    messages=[{"role": "user", "content": "什么是 PagedAttention?"}],
)
print(response.choices[0].message.content)

3.4 其他框架速览:TGI / SGLang / ExLlama

框架定位亮点
TGI (HuggingFace)生产部署HF 生态集成、Flash Decoding
SGLang高性能研究RadixAttention、极致吞吐
ExLlamaV2GPTQ 推理GPTQ 量化模型最快
MLC LLM跨平台手机/浏览器/边缘设备

3.5 框架选型决策树

你需要什么?

├── 快速实验/个人使用
│     → Ollama(最简单)

├── 极致轻量/边缘设备/Apple Silicon
│     → llama.cpp(最小依赖)

├── 生产高并发服务
│     → vLLM(最高吞吐)

├── HuggingFace 生态集成
│     → TGI

└── 手机/浏览器运行
      → MLC LLM
维度Ollamallama.cppvLLM
上手难度⭐ 最简单⭐⭐ 需编译⭐⭐⭐ 需 CUDA
吞吐量高(PagedAttention)
Apple Silicon✅ Metal✅ Metal❌ 仅 CUDA
多 GPU✅ Tensor Parallel
量化格式GGUFGGUFGPTQ/AWQ/FP16
API 兼容OpenAIOpenAIOpenAI
适用开发/个人边缘/Mac生产/服务

4. 量化技术:用更少内存跑更大模型

14B 模型原始权重 28GB,量化到 INT4 只要 8GB——这就是量化的魔力。

4.1 量化基础:从 FP32 到 INT4

精度层级与内存占用(以 14B 模型为例):

  FP32(32位浮点)  → 56 GB   ← 训练用,推理太浪费
  FP16(16位浮点)  → 28 GB   ← 标准推理精度
  INT8(8位整数)   → 14 GB   ← 几乎无质量损失
  INT4(4位整数)   →  8 GB   ← 轻微质量损失,性价比最高
  INT2(2位整数)   →  4 GB   ← 质量明显下降,不推荐

  经验法则:
  模型显存 ≈ 参数量(B) × 精度(字节) × 1.2(KV Cache 开销)

4.2 GGUF / GPTQ / AWQ:三大量化格式

格式原理推理框架适用
GGUFllama.cpp 原生格式,CPU+GPU 混合Ollama, llama.cppMac / CPU / 通用
GPTQ基于 Hessian 的逐层量化vLLM, ExLlamaNVIDIA GPU 生产
AWQ激活感知量化,保护重要权重vLLM, TGINVIDIA GPU 生产

4.3 量化等级选择:精度 vs 内存 vs 速度

GGUF 量化等级推荐(以 Qwen2.5-14B 为例):

  等级      │ 大小    │ 质量保持 │ 推荐场景
  ─────────┼────────┼────────┼──────────
  Q2_K     │ ~5.5GB │ 75%    │ ❌ 不推荐,质量太差
  Q3_K_M   │ ~6.5GB │ 85%    │ 内存极限时的妥协
  Q4_K_M   │ ~8.0GB │ 92%    │ ⭐ 性价比最优
  Q5_K_M   │ ~9.5GB │ 95%    │ ⭐ 质量优先推荐
  Q6_K     │ ~11GB  │ 98%    │ 质量几乎无损
  Q8_0     │ ~14GB  │ 99%    │ 追求极致质量
  FP16     │ ~28GB  │ 100%   │ 基准(不量化)

4.4 实操:自己动手量化一个模型

bash
# 1. 下载原始模型
pip install huggingface-hub
huggingface-cli download Qwen/Qwen2.5-14B-Instruct --local-dir ./qwen2.5-14b

# 2. 转换为 GGUF(需要 llama.cpp 的 convert 脚本)
cd llama.cpp
python convert_hf_to_gguf.py ../qwen2.5-14b --outfile qwen2.5-14b-f16.gguf

# 3. 量化
./build/bin/llama-quantize \
  qwen2.5-14b-f16.gguf \
  qwen2.5-14b-q4_k_m.gguf \
  Q4_K_M

# 4. 验证
./build/bin/llama-cli -m qwen2.5-14b-q4_k_m.gguf -p "你好" -n 100

4.5 量化质量评估:Perplexity 测试

bash
# 用 llama.cpp 计算 Perplexity(越低越好)
./build/bin/llama-perplexity \
  -m qwen2.5-14b-q4_k_m.gguf \
  -f wiki.test.raw \
  --chunks 100
量化等级Perplexity相对 FP16
FP166.52基准
Q8_06.53+0.2%
Q5_K_M6.58+0.9%
Q4_K_M6.72+3.1%
Q3_K_M7.15+9.7%

💡 Q4_K_M 是黄金标准。Perplexity 只增加 3%,但内存节省 70%。除非你的任务对质量极度敏感,否则 Q4_K_M 就是最优选择。


5. Apple Silicon 深度优化

Mac 用户的福音——M 系列芯片的统一内存架构天然适合跑大模型。

5.1 M 系列芯片的 AI 推理优势

为什么 M 系列芯片适合跑 LLM:

  统一内存架构(Unified Memory)
  ├── CPU 和 GPU 共享同一块内存
  ├── 无需 PCIe 数据搬运(省掉 GPU 显存瓶颈)
  └── 64GB Mac = 64GB 全部可用于模型

  对比 NVIDIA:
    RTX 4090 = 24GB 显存(模型必须放进 24GB)
    Mac M2 Ultra = 192GB 统一内存(可以跑 70B+ 模型)
    
  劣势:
    内存带宽 < NVIDIA HBM → 推理速度较慢
    无 CUDA → 不能用 vLLM、FlashAttention

5.2 MLX 框架:Apple 的原生 AI 引擎

bash
# 安装 MLX
pip install mlx mlx-lm

# 下载并运行模型
python -m mlx_lm.generate \
  --model mlx-community/Qwen2.5-14B-Instruct-4bit \
  --prompt "解释什么是向量数据库" \
  --max-tokens 500

# 启动 API 服务
python -m mlx_lm.server \
  --model mlx-community/Qwen2.5-14B-Instruct-4bit \
  --port 8080

5.3 Ollama + Metal:macOS 最佳实践

bash
# Ollama 在 Mac 上默认启用 Metal GPU 加速
ollama run qwen2.5:14b

# 查看 GPU 使用情况
# 活动监视器 → GPU 历史记录 → 可以看到 Metal 使用率

# 性能调优环境变量
export OLLAMA_NUM_PARALLEL=2    # 并行请求数
export OLLAMA_MAX_LOADED_MODELS=1  # 同时加载模型数(省内存)

5.4 M1 到 M4 性能实测对比

芯片内存Qwen2.5-7B Q4 速度Qwen2.5-14B Q4 速度可跑最大模型
M1 8GB8GB~15 tok/s❌ 放不下7B Q4
M1 Pro 16GB16GB~20 tok/s~10 tok/s14B Q4
M2 Max 32GB32GB~25 tok/s~15 tok/s30B Q4
M3 Max 64GB64GB~30 tok/s~20 tok/s70B Q4
M4 Max 128GB128GB~35 tok/s~25 tok/s70B Q8

5.5 内存规划:多大内存跑多大模型

Mac 内存 → 可跑模型(Q4_K_M 量化):

  8GB  → 最大 7B(紧凑,留给系统 2GB)
  16GB → 最大 14B(推荐 7B,留余量给 KV Cache)
  32GB → 舒适跑 14B,勉强跑 30B
  64GB → 舒适跑 30B,勉强跑 70B
  96GB → 舒适跑 70B
  192GB → 可以跑 100B+

  公式:所需内存 ≈ 模型文件大小 × 1.3
  (额外 30% 用于 KV Cache + 系统开销)

💡 买 Mac 跑模型,内存比 CPU 重要。M3 Pro 36GB > M3 Max 32GB(对 LLM 来说)。能加内存就加到最大。


6. NVIDIA GPU 推理优化

有 NVIDIA GPU?那你拥有本地推理的最强武器。本章教你榨干每一分算力。

6.1 CUDA 环境与驱动配置

bash
# 检查 GPU 和驱动
nvidia-smi

# 安装 CUDA Toolkit(推荐 12.x)
# 参考 https://developer.nvidia.com/cuda-downloads

# 验证 PyTorch GPU 支持
python -c "import torch; print(torch.cuda.is_available(), torch.cuda.get_device_name(0))"

6.2 显存规划:模型大小 vs GPU 选型

GPU显存可跑模型(Q4)可跑模型(FP16)价格参考
RTX 306012GB7B3B$300
RTX 4060 Ti16GB14B7B$400
RTX 409024GB30B14B$1,600
A10080GB70B30B$15,000
H10080GB70B30B$30,000

6.3 vLLM PagedAttention 原理与调优

PagedAttention 核心思想:

  传统方式:为每个请求预分配连续 KV Cache 显存
  → 显存碎片化严重,利用率 < 50%

  PagedAttention:像操作系统的虚拟内存一样管理 KV Cache
  → 按需分配,显存利用率 > 95%
  → 同样显存可以服务 2-3 倍的并发请求
bash
# vLLM 关键调优参数
python -m vllm.entrypoints.openai.api_server \
  --model Qwen/Qwen2.5-14B-Instruct \
  --gpu-memory-utilization 0.90 \  # GPU 显存使用率
  --max-model-len 8192 \           # 最大上下文长度
  --max-num-seqs 32 \              # 最大并发序列数
  --enable-chunked-prefill          # 分块预填充(减少首 Token 延迟)

6.4 多 GPU 推理:Tensor Parallel 实战

bash
# 2 卡 Tensor Parallel(模型切成 2 半,各放一张卡)
python -m vllm.entrypoints.openai.api_server \
  --model Qwen/Qwen2.5-72B-Instruct \
  --tensor-parallel-size 2 \
  --port 8000

# 4 卡(跑 Llama-3-405B)
python -m vllm.entrypoints.openai.api_server \
  --model meta-llama/Llama-3-405B-Instruct \
  --tensor-parallel-size 4

6.5 推理加速技巧:FlashAttention / KV Cache

推理加速清单:

  ✅ FlashAttention 2  → 注意力计算速度 2-3x
  ✅ KV Cache 量化     → INT8 KV Cache 省 50% 显存
  ✅ Continuous Batching → 动态批处理,不等最长请求
  ✅ Speculative Decoding → 用小模型猜测,大模型验证
  ✅ Prefix Caching    → 相同前缀的请求复用 KV Cache

7. 本地模型的 API 服务化

模型跑起来了,怎么让其他应用调用它?答案是包装成 OpenAI 兼容 API。

7.1 OpenAI 兼容 API:无缝替换

python
# 所有框架都支持 OpenAI 格式,只需改 base_url
from openai import OpenAI

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

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

# 用 llama.cpp
client = OpenAI(base_url="http://localhost:8080/v1", api_key="dummy")

# 调用方式完全一样!
response = client.chat.completions.create(
    model="qwen2.5:14b",
    messages=[{"role": "user", "content": "你好"}],
    temperature=0.7,
    stream=True,
)
for chunk in response:
    print(chunk.choices[0].delta.content, end="")

7.2 LiteLLM:统一多模型网关

bash
# 安装
pip install litellm

# 配置多模型(config.yaml)
# model_list:
#   - model_name: local-qwen
#     litellm_params:
#       model: ollama/qwen2.5:14b
#       api_base: http://localhost:11434
#   - model_name: gpt-4o
#     litellm_params:
#       model: gpt-4o
#       api_key: sk-xxx

# 启动代理
litellm --config config.yaml --port 4000

7.3 流式输出与 Function Calling

python
# Ollama 支持 Function Calling
response = client.chat.completions.create(
    model="qwen2.5:14b",
    messages=[{"role": "user", "content": "北京明天天气如何?"}],
    tools=[{
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "查询天气",
            "parameters": {
                "type": "object",
                "properties": {
                    "city": {"type": "string"},
                    "date": {"type": "string"}
                },
                "required": ["city"]
            }
        }
    }],
)

7.4 与 LangChain / LlamaIndex 集成

python
# LangChain + Ollama
from langchain_ollama import ChatOllama

llm = ChatOllama(model="qwen2.5:14b", base_url="http://localhost:11434")
response = llm.invoke("什么是 RAG?")

# LlamaIndex + Ollama
from llama_index.llms.ollama import Ollama

llm = Ollama(model="qwen2.5:14b", request_timeout=120)

7.5 多模型路由与负载均衡

多模型路由策略:

  简单任务(分类/提取)→ Qwen2.5-3B(快、便宜)
  通用对话            → Qwen2.5-14B(均衡)
  复杂推理            → Qwen2.5-72B / API fallback

  路由判断:
    输入长度 < 100 字 → 小模型
    包含 "分析" "对比" "推理" → 大模型
    用户指定 → 尊重用户选择

8. 本地 RAG 全栈:私有知识库

模型有了,API 有了,下一步是让它理解你的数据——搭建完全私有的 RAG 系统。

8.1 本地嵌入模型:BGE / GTE / Nomic

模型维度大小中文支持推荐
BGE-M310242.2GB⭐⭐⭐⭐⭐🥇 中文首选
GTE-Qwen215361.5GB⭐⭐⭐⭐⭐🥇 质量最高
Nomic-embed-text768550MB⭐⭐⭐轻量英文
all-MiniLM-L638480MB⭐⭐极致轻量
bash
# 用 Ollama 运行嵌入模型
ollama pull nomic-embed-text

# API 调用
curl http://localhost:11434/api/embeddings \
  -d '{"model": "nomic-embed-text", "prompt": "什么是 RAG?"}'

8.2 本地向量数据库:Chroma vs Qdrant

数据库部署性能适用
Chroma嵌入式(无需启动)原型/小规模
Qdrant独立服务生产/大规模
pgvectorPostgreSQL 插件已有 PG 的团队

8.3 完全离线 RAG 管线搭建

python
from langchain_ollama import ChatOllama, OllamaEmbeddings
from langchain_chroma import Chroma
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.chains import RetrievalQA

# 所有组件都是本地的,零网络依赖
embeddings = OllamaEmbeddings(model="nomic-embed-text")
llm = ChatOllama(model="qwen2.5:14b")

# 1. 文档切分
splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50)
docs = splitter.split_documents(load_documents("./my_docs/"))

# 2. 向量化存储
vectorstore = Chroma.from_documents(docs, embeddings, persist_directory="./chroma_db")

# 3. 检索问答
qa = RetrievalQA.from_chain_type(
    llm=llm,
    retriever=vectorstore.as_retriever(search_kwargs={"k": 5}),
)

# 完全离线运行!
answer = qa.invoke("公司报销流程是什么?")

8.4 与 Ollama 集成的 RAG 实战

python
# 更简洁的方式:直接用 Ollama + Chroma
import chromadb
import ollama

# 初始化
chroma = chromadb.PersistentClient(path="./chroma_db")
collection = chroma.get_or_create_collection("my_docs")

# 检索
results = collection.query(query_texts=["报销流程"], n_results=3)
context = "\n".join(results["documents"][0])

# 生成
response = ollama.chat(
    model="qwen2.5:14b",
    messages=[{
        "role": "user",
        "content": f"根据以下资料回答问题:\n{context}\n\n问题:公司报销流程是什么?"
    }]
)

8.5 检索质量优化

RAG 质量优化清单:

  Chunk 策略:
  ├── 按语义分段(不要硬切 500 字符)
  ├── chunk_overlap = 10-20%(避免上下文断裂)
  └── 对表格/代码用专门的 Splitter

  检索优化:
  ├── 混合检索(向量 + BM25 关键词)
  ├── 重排序(Reranker:BGE-reranker-v2)
  └── 多路召回 → Top-K 融合

  Prompt 优化:
  ├── 明确指示"仅根据给定资料回答"
  └── 加入"如果资料中没有,请说不知道"

9. 生产部署:从单机到集群

本地跑通了,怎么上生产?本章给出从 Docker 化到集群部署的完整路径。

9.1 Docker 容器化:GPU 透传配置

dockerfile
# Dockerfile(vLLM 生产镜像)
FROM vllm/vllm-openai:latest

COPY ./models /models
ENV MODEL_PATH=/models/Qwen2.5-14B-Instruct

CMD ["python", "-m", "vllm.entrypoints.openai.api_server", \
     "--model", "/models/Qwen2.5-14B-Instruct", \
     "--port", "8000", \
     "--gpu-memory-utilization", "0.9"]
yaml
# docker-compose.yml
services:
  llm:
    image: vllm/vllm-openai:latest
    ports:
      - "8000:8000"
    volumes:
      - ./models:/models
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: 1
              capabilities: [gpu]
    command: >
      python -m vllm.entrypoints.openai.api_server
      --model /models/Qwen2.5-14B-Instruct
      --port 8000
bash
# 前提:安装 NVIDIA Container Toolkit
sudo apt install nvidia-container-toolkit
sudo systemctl restart docker

# 启动
docker compose up -d

9.2 生产级部署架构

生产部署架构:

  客户端

  Nginx(反向代理 + SSL + 限流)

  LiteLLM(多模型路由 + 认证 + 日志)

  ┌──────────────┬──────────────┐
  │  vLLM #1     │  vLLM #2     │
  │  GPU 0       │  GPU 1       │
  │  Qwen-14B    │  Qwen-14B    │
  └──────────────┴──────────────┘

9.3 监控:GPU 利用率 / 推理延迟 / 吞吐量

bash
# GPU 监控(实时)
watch -n 1 nvidia-smi

# Prometheus + Grafana(vLLM 内置 metrics 端点)
# vLLM 自动暴露 /metrics
# 关键指标:
#   vllm:num_requests_running    → 正在处理的请求数
#   vllm:avg_generation_throughput → 平均生成吞吐
#   vllm:gpu_cache_usage_perc    → KV Cache 使用率

9.4 自动扩缩容与成本优化

成本优化策略:

  时段调度:
    工作时间(9:00-18:00)→ 2 个 GPU 实例
    非工作时间           → 1 个 GPU 实例
    
  模型卸载:
    空闲 10 分钟 → 自动卸载模型释放显存
    新请求到来   → 自动加载(冷启动 ~30s)

  混合路由:
    高峰期本地处理不过来 → 溢出到云 API

9.5 高可用与故障恢复

高可用清单:

  ✅ 健康检查:每 30s 检查 /health 端点
  ✅ 自动重启:Docker restart: always
  ✅ 多实例:至少 2 个 GPU 实例互为备份
  ✅ 降级策略:GPU 故障 → 切到 CPU 推理(慢但可用)
  ✅ 告警:延迟 > 30s / 错误率 > 5% → 立即通知

10. 实战:搭建你的私有 AI 助手

把前 9 章串起来——用 Ollama + Open WebUI + RAG,搭建一个完整的私有 AI 助手。

10.1 方案选型与硬件规划

推荐方案(个人/小团队):

  硬件:Mac M3 Pro 36GB / RTX 4090 24GB
  模型:Qwen2.5-14B-Instruct(Q4_K_M 量化,~8GB)
  框架:Ollama(简单可靠)
  UI:  Open WebUI(功能丰富、类 ChatGPT 界面)
  RAG: Chroma + Nomic-embed(本地嵌入)
  
  预算:
    Mac 方案:已有 Mac → $0 额外成本
    GPU 方案:RTX 4090 ~$1,600 + 电费 ~$50/月

10.2 模型部署:Ollama + 量化模型

bash
# 1. 安装 Ollama
curl -fsSL https://ollama.com/install.sh | sh

# 2. 拉取模型
ollama pull qwen2.5:14b          # 对话模型
ollama pull nomic-embed-text     # 嵌入模型
ollama pull qwen2.5-coder:7b     # 代码模型(可选)

# 3. 测试
ollama run qwen2.5:14b "用 Python 写一个快排算法"

# 4. 查看已安装模型
ollama list

10.3 Web UI:Open WebUI 搭建

bash
# 方式 1:Docker 一键部署
docker run -d -p 3000:8080 \
  --add-host=host.docker.internal:host-gateway \
  -e OLLAMA_BASE_URL=http://host.docker.internal:11434 \
  -v open-webui:/app/backend/data \
  --name open-webui \
  ghcr.io/open-webui/open-webui:main

# 方式 2:pip 安装
pip install open-webui
open-webui serve --port 3000

# 打开浏览器
# http://localhost:3000
# 首次访问创建管理员账号

10.4 私有 RAG 知识库集成

bash
# Open WebUI 内置 RAG 功能:
# 1. 进入设置 → Documents
# 2. 上传文档(PDF/TXT/MD)
# 3. 选择嵌入模型:nomic-embed-text
# 4. 在对话中使用 #文档名 引用知识库

# 或者用代码搭建独立 RAG 服务
python
# 独立 RAG 服务(FastAPI)
from fastapi import FastAPI
import ollama
import chromadb

app = FastAPI()
chroma = chromadb.PersistentClient(path="./knowledge_base")
collection = chroma.get_or_create_collection("docs")

@app.post("/chat")
async def chat(question: str):
    # 1. 检索
    results = collection.query(query_texts=[question], n_results=3)
    context = "\n".join(results["documents"][0])
    
    # 2. 生成
    response = ollama.chat(
        model="qwen2.5:14b",
        messages=[{
            "role": "user",
            "content": f"根据以下资料回答:\n{context}\n\n问题:{question}"
        }]
    )
    return {"answer": response["message"]["content"]}

10.5 完整部署清单与运维手册

部署清单:

  ✅ Ollama 安装并运行
  ✅ 模型下载完成(qwen2.5:14b + nomic-embed-text)
  ✅ Open WebUI 部署并可访问
  ✅ RAG 知识库导入文档
  ✅ SSL 证书配置(如果对外暴露)
  ✅ 定时重启脚本(防止内存泄漏)
  ✅ 监控告警(Ollama 进程存活 + 磁盘空间)

  日常运维:
  ├── 更新模型:ollama pull qwen2.5:14b(检查新版本)
  ├── 更新 UI:docker pull ghcr.io/open-webui/open-webui:main
  ├── 备份数据:/app/backend/data + ./knowledge_base
  └── 查看日志:docker logs open-webui --tail 100

💡 最后一句话:本地大模型不是 API 的替代品,而是补充。最优解通常是混合架构——敏感数据和高频任务走本地,复杂推理和低频任务走 API。关键是拥有选择权——本地跑模型的能力,让你不再被任何一家 API 提供商绑定。

坚持是一种品格