本地大模型完全指南
不想把数据发给 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:成本交叉点计算
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 助手 | ✅ 本地 | 延迟敏感,代码隐私 |
| 离线/弱网环境 | ✅ 本地 | 无网络可用 |
| 需要最强模型能力 | ❌ API | GPT-4o/Claude 仍是最强 |
| 日调用 < 1,000 次 | ❌ API | 硬件投入不划算 |
| 多模态(视频/图像生成) | ❌ API | 本地算力不够 |
| 快速原型验证 | ❌ API | 不值得花时间部署 |
💡 务实建议:不要为了"本地"而本地。先算清成本、评估能力差距,再决定。很多团队的最优解是混合方案——敏感数据走本地,通用任务走 API。
2. 开源模型全景:2026 年选型指南
开源模型爆发式增长——光 HuggingFace 上就有上万个。本章帮你理清主流模型家族,按需选型。
2.1 六大模型家族深度对比
| 模型家族 | 开发者 | 参数范围 | 亮点 | 许可证 |
|---|---|---|---|---|
| Llama 3.x | Meta | 1B-405B | 社区最大、工具链最成熟 | Llama License |
| Qwen 2.5/3 | 阿里 | 0.5B-72B | 中文最强、多模态版本丰富 | Apache 2.0 |
| Mistral/Mixtral | Mistral AI | 7B-8x22B | MoE 架构、效率极高 | Apache 2.0 |
| Gemma 2/3 | 2B-27B | 小模型质量极高 | Gemma License | |
| DeepSeek V3/R1 | DeepSeek | 7B-671B | 推理能力强、MoE 架构 | MIT |
| Phi-4 | Microsoft | 3B-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.5 | DeepSeek V3 | Yi-1.5 |
|---|---|---|---|
| 中文理解 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ |
| 代码能力 | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ |
| 数学推理 | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ |
| 多模态 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐ |
| 小模型质量 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐ |
| 许可证 | Apache 2.0 | MIT | Apache 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-3B2.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 分钟跑起大模型
# 安装(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++ 推理
# 从源码编译(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 993.3 vLLM:生产级高吞吐推理引擎
# 安装(需要 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# 代码调用
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、极致吞吐 |
| ExLlamaV2 | GPTQ 推理 | GPTQ 量化模型最快 |
| MLC LLM | 跨平台 | 手机/浏览器/边缘设备 |
3.5 框架选型决策树
你需要什么?
│
├── 快速实验/个人使用
│ → Ollama(最简单)
│
├── 极致轻量/边缘设备/Apple Silicon
│ → llama.cpp(最小依赖)
│
├── 生产高并发服务
│ → vLLM(最高吞吐)
│
├── HuggingFace 生态集成
│ → TGI
│
└── 手机/浏览器运行
→ MLC LLM| 维度 | Ollama | llama.cpp | vLLM |
|---|---|---|---|
| 上手难度 | ⭐ 最简单 | ⭐⭐ 需编译 | ⭐⭐⭐ 需 CUDA |
| 吞吐量 | 中 | 中 | 高(PagedAttention) |
| Apple Silicon | ✅ Metal | ✅ Metal | ❌ 仅 CUDA |
| 多 GPU | ❌ | ✅ | ✅ Tensor Parallel |
| 量化格式 | GGUF | GGUF | GPTQ/AWQ/FP16 |
| API 兼容 | OpenAI | OpenAI | OpenAI |
| 适用 | 开发/个人 | 边缘/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:三大量化格式
| 格式 | 原理 | 推理框架 | 适用 |
|---|---|---|---|
| GGUF | llama.cpp 原生格式,CPU+GPU 混合 | Ollama, llama.cpp | Mac / CPU / 通用 |
| GPTQ | 基于 Hessian 的逐层量化 | vLLM, ExLlama | NVIDIA GPU 生产 |
| AWQ | 激活感知量化,保护重要权重 | vLLM, TGI | NVIDIA 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 实操:自己动手量化一个模型
# 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 1004.5 量化质量评估:Perplexity 测试
# 用 llama.cpp 计算 Perplexity(越低越好)
./build/bin/llama-perplexity \
-m qwen2.5-14b-q4_k_m.gguf \
-f wiki.test.raw \
--chunks 100| 量化等级 | Perplexity | 相对 FP16 |
|---|---|---|
| FP16 | 6.52 | 基准 |
| Q8_0 | 6.53 | +0.2% |
| Q5_K_M | 6.58 | +0.9% |
| Q4_K_M | 6.72 | +3.1% |
| Q3_K_M | 7.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、FlashAttention5.2 MLX 框架:Apple 的原生 AI 引擎
# 安装 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 80805.3 Ollama + Metal:macOS 最佳实践
# 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 8GB | 8GB | ~15 tok/s | ❌ 放不下 | 7B Q4 |
| M1 Pro 16GB | 16GB | ~20 tok/s | ~10 tok/s | 14B Q4 |
| M2 Max 32GB | 32GB | ~25 tok/s | ~15 tok/s | 30B Q4 |
| M3 Max 64GB | 64GB | ~30 tok/s | ~20 tok/s | 70B Q4 |
| M4 Max 128GB | 128GB | ~35 tok/s | ~25 tok/s | 70B 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 环境与驱动配置
# 检查 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 3060 | 12GB | 7B | 3B | $300 |
| RTX 4060 Ti | 16GB | 14B | 7B | $400 |
| RTX 4090 | 24GB | 30B | 14B | $1,600 |
| A100 | 80GB | 70B | 30B | $15,000 |
| H100 | 80GB | 70B | 30B | $30,000 |
6.3 vLLM PagedAttention 原理与调优
PagedAttention 核心思想:
传统方式:为每个请求预分配连续 KV Cache 显存
→ 显存碎片化严重,利用率 < 50%
PagedAttention:像操作系统的虚拟内存一样管理 KV Cache
→ 按需分配,显存利用率 > 95%
→ 同样显存可以服务 2-3 倍的并发请求# 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 实战
# 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 46.5 推理加速技巧:FlashAttention / KV Cache
推理加速清单:
✅ FlashAttention 2 → 注意力计算速度 2-3x
✅ KV Cache 量化 → INT8 KV Cache 省 50% 显存
✅ Continuous Batching → 动态批处理,不等最长请求
✅ Speculative Decoding → 用小模型猜测,大模型验证
✅ Prefix Caching → 相同前缀的请求复用 KV Cache7. 本地模型的 API 服务化
模型跑起来了,怎么让其他应用调用它?答案是包装成 OpenAI 兼容 API。
7.1 OpenAI 兼容 API:无缝替换
# 所有框架都支持 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:统一多模型网关
# 安装
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 40007.3 流式输出与 Function Calling
# 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 集成
# 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-M3 | 1024 | 2.2GB | ⭐⭐⭐⭐⭐ | 🥇 中文首选 |
| GTE-Qwen2 | 1536 | 1.5GB | ⭐⭐⭐⭐⭐ | 🥇 质量最高 |
| Nomic-embed-text | 768 | 550MB | ⭐⭐⭐ | 轻量英文 |
| all-MiniLM-L6 | 384 | 80MB | ⭐⭐ | 极致轻量 |
# 用 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 | 独立服务 | 高 | 生产/大规模 |
| pgvector | PostgreSQL 插件 | 中 | 已有 PG 的团队 |
8.3 完全离线 RAG 管线搭建
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 实战
# 更简洁的方式:直接用 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(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"]# 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# 前提:安装 NVIDIA Container Toolkit
sudo apt install nvidia-container-toolkit
sudo systemctl restart docker
# 启动
docker compose up -d9.2 生产级部署架构
生产部署架构:
客户端
↓
Nginx(反向代理 + SSL + 限流)
↓
LiteLLM(多模型路由 + 认证 + 日志)
↓
┌──────────────┬──────────────┐
│ vLLM #1 │ vLLM #2 │
│ GPU 0 │ GPU 1 │
│ Qwen-14B │ Qwen-14B │
└──────────────┴──────────────┘9.3 监控:GPU 利用率 / 推理延迟 / 吞吐量
# 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)
混合路由:
高峰期本地处理不过来 → 溢出到云 API9.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 + 量化模型
# 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 list10.3 Web UI:Open WebUI 搭建
# 方式 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 知识库集成
# Open WebUI 内置 RAG 功能:
# 1. 进入设置 → Documents
# 2. 上传文档(PDF/TXT/MD)
# 3. 选择嵌入模型:nomic-embed-text
# 4. 在对话中使用 #文档名 引用知识库
# 或者用代码搭建独立 RAG 服务# 独立 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 提供商绑定。