【大模型Wiki】07 · 开源模型与本地部署
开源模型与本地部署
整理自博客园旧笔记《搭建ChatGLM2-6B CPU版本》《使用kaggle白嫖GPU搭建chatglm-6B/Qwen-7B等大模型》(2024-04),2026-09 补充现代部署方案。
一、本地部署的三条路线
把大模型跑在自己机器上,动机通常有三:数据不出内网(隐私/合规)、不想为每次调用付 API 费、要做微调或二次开发。2026 年的开源生态已经把这件事的难度降到了"一条命令"。但不同工具解决的是不同层面的问题,先想清楚自己要什么,再选路线。
| 路线 | 工具 | 适合人群 |
|---|---|---|
| 开箱即用 | Ollama、LM Studio | 只想跑起来聊天,一条命令 |
| 极致性能 | vLLM、SGLang、TensorRT-LLM | 自己提供 API 服务、高并发 |
| 原始 transformers | AutoModel.from_pretrained |
学习/实验/微调开发 |
这三条路线本质上是从"上层封装"到"底层原生"的光谱:
- Ollama / LM Studio 把模型下载、量化、推理引擎全部打包好,你只管选模型名。底层其实也是调用 llama.cpp(GGUF 引擎),只是替你屏蔽了细节。优点是省心,缺点是定制自由度低。
- vLLM / SGLang 面向"服务化"。它们把模型加载成进程常驻的 HTTP 服务,对外暴露 OpenAI 兼容接口,重点解决吞吐、并发、显存利用率。适合做产品后端。
- transformers 原生 是最贴近论文/源码的方式,每个张量怎么加载、怎么 forward 你都能改。适合学习原理、改结构、做微调。
显存估算经验值(推理,FP16):

- 7B ≈ 14GB;14B ≈ 28GB;32B ≈ 64GB;70B ≈ 140GB(多卡或量化)
- 量化(INT4/Q4_K_M)可以再砍一半以上:7B Q4 约 4-5GB,一台 16G 内存的笔记本也能跑
经验值的来历:一个参数为 FP16(半精度浮点)时占 2 字节。7B 模型 = 70 亿参数 × 2 字节 ≈ 14GB。这个"裸权重"数字还没算 KV Cache(见第四节),所以实际显存占用会更高;下面第四节给出完整公式。
二、路线一:Ollama(2026 年的"默认答案")
当年在 ChatGLM2-6B 上手动改 .cuda()→.float()、克隆 12GB 模型文件的日子,如今被一条命令取代:
# 安装后(官网下载),直接拉模型运行
ollama run qwen3:8b # 通义千问 8B,自动下载 GGUF 量化版
ollama run deepseek-r1:7b # DeepSeek-R1 蒸馏 7B(带思考链)
ollama run glm4:9b # 智谱 GLM-4
# 自带 OpenAI 兼容 API
curl http://localhost:11434/v1/chat/completions -d '{
"model": "qwen3:8b",
"messages": [{"role": "user", "content": "你好"}]
}'
要点:模型以 GGUF 格式分发;/v1 端点与 OpenAI API 兼容,所以 Next-Web、Dify 等前端可以直接接。
2.1、Ollama 的工作机制与常用命令
Ollama 本质上是一个"模型运行时 + 守护进程":
- 安装后
ollama命令通过本地 11434 端口与一个常驻的ollama serve守护进程通信。 - 模型以 GGUF 文件形式存于
~/.ollama/models(Windows 在C:\Users\<你>\.ollama\models)。 ollama run <name>第一次会先pull再加载进内存,之后常驻,便于多轮对话复用。
# 查看已拉取的模型
ollama list
# 删除某个模型(释放磁盘)
ollama rm qwen3:8b
# 只拉取不运行(常用于预先准备)
ollama pull deepseek-r1:7b
# 手动指定量化等级 / 上下文长度(通过临时 Modelfile)
ollama run qwen3:8b # 默认上下文 8192,可在对话中用 /set parameter num_ctx 16384 调整
# 用 Modelfile 固化配置:新建一个文件 myqwen,内容:
# FROM qwen3:8b
# PARAMETER num_ctx 16384
# PARAMETER num_gpu 41 # 用多少层放 GPU(CPU 卸载时为层数)
# SYSTEM "你是一个严谨的中文助手"
# 然后:
ollama create myqwen -f myqwen
ollama run myqwen
2.2、Ollama 关键参数讲解
| 参数 | 含义 | 默认值/建议 |
|---|---|---|
num_ctx |
上下文窗口 token 数 | 2048/4096;长文档问答调到 8192~32768 |
num_gpu |
加载到 GPU 的层数 | 自动;CPU 跑时设 0 |
num_thread |
CPU 推理线程数 | 物理核数 |
temperature / top_p |
采样参数(见 API 篇) | 0.7 / 0.9 |
repeat_penalty |
重复惩罚(类似 frequency_penalty) | 1.1 |
踩坑:把
num_ctx调得很大但显存不够时,Ollama 会默默降级或 OOM。先ollama ps看常驻占用,再决定能开多大上下文。
2.3、Ollama 的边界
Ollama 适合"单用户 / 小团队自托管聊天"。它默认是单并发顺序推理(一次只算一个请求),高并发场景吞吐远不如 vLLM。如果你要做对外服务、要连续 batching、要多卡张量并行,请直接看第三节的 vLLM。
三、路线二:vLLM(自建服务)
pip install vllm
vllm serve Qwen/Qwen3-8B --max-model-len 32768 \
--gpu-memory-utilization 0.9 --port 8000
- PagedAttention 管理 KV Cache(显存利用率提升数倍)
- Continuous Batching 动态拼批,吞吐远高于 transformers 原生
- 原生 OpenAI 兼容 API,可配 tensor-parallel-size 多卡跑大模型
生产部署事实标准;单机高并发场景同样可用 SGLang(结构化生成/多轮更快)。
3.1、vLLM 为什么快:PagedAttention 与 Continuous Batching
传统 transformers 推理每个请求都要预留一整块连续 KV Cache(最坏情况长度),导致显存碎片严重、利用率低。vLLM 借鉴操作系统"分页"思想:
- KV Cache 被切成固定大小的 block 存到非连续显存,像虚拟内存一样按需分配,碎片大幅减少——同样显存能多塞 2~4 倍的并发请求。
- Continuous Batching(连续批处理):不等一个 batch 里所有请求都生成完,而是哪个请求生成完就立刻把新请求补进来,GPU 利用率接近打满。这是吞吐翻倍的真正原因。
3.2、vLLM 启动参数详解
vllm serve Qwen/Qwen3-8B \
--host 0.0.0.0 --port 8000 \
--max-model-len 32768 \ # 最大上下文长度(token),影响 KV Cache 显存
--gpu-memory-utilization 0.90 \ # GPU 显存占用上限比例,留点余量给碎片
--tensor-parallel-size 2 \ # 多卡张量并行(模型切到 2 张卡),70B 必备
--dtype auto \ # 权重精度 auto/half/bfloat16
--quantization awq \ # 若加载 AWQ 量化权重,需显式声明
--enable-prefix-caching \ # 复用相同 system prompt 的 KV(多用户同提示词省显存)
--max-num-seqs 256 # 最大并发序列数
启动成功后访问 http://localhost:8000/docs 能看到 Swagger 文档;OpenAI 兼容端点就是 /v1/chat/completions。
# 用 OpenAI SDK 直接对接 vLLM 起的服务(改 base_url 即可)
from openai import OpenAI
client = OpenAI(base_url="http://localhost:8000/v1", api_key="EMPTY")
resp = client.chat.completions.create(
model="Qwen/Qwen3-8B",
messages=[{"role": "user", "content": "用一句话解释 PagedAttention"}],
max_tokens=256,
)
print(resp.choices[0].message.content)
3.3、SGLang 简介(何时选它)
SGLang 在"结构化输出 / 多轮 agent"场景更快:它用 RadixAttention 缓存可复用前缀,并通过 DSL 让"先抽取再判断"这类多步调用减少重复计算。若你的业务是大量 JSON 抽取、工具调用链路,可优先试 SGLang;纯聊天高并发两者接近。
四、显存到底怎么算:完整估算公式
只记"7B≈14GB"不够用。真实部署要算两部分:权重本体 + 推理时的 KV Cache。
4.1、权重显存公式
权重显存(GB) ≈ 参数量(B) × 每参数字节数
| 精度 | 每参数字节 | 7B 权重 | 说明 |
|---|---|---|---|
| FP32 | 4 | 28 GB | 基本不用,除非 CPU int 推理 |
| FP16 / BF16 | 2 | 14 GB | transformers 默认 |
| INT8 | 1 | 7 GB | 权重量化 |
| INT4 (Q4_K_M) | 0.5 | ~3.5–4.5 GB | GGUF 常用,含开销 |
之所以 INT4 实际略高于 0.5×参数量,是因为量化权重还附带少量缩放因子(scales/zeros)元数据,约占 5%~10%。
4.2、KV Cache 显存公式(决定你能开多长上下文)
Transformer 每生成一个 token,都要把历史所有 token 的 Key/Value 缓存下来。KV Cache 随上下文长度和并发数线性增长:
KV Cache(GB) ≈
2 # K 和 V 两份
× 层数 L
× 隐藏维度 H
× 序列长 S(token)
× 批大小 B(并发)
× 每元素字节(精度)
/ (1024^3)
简化写法(以 FP16 为例,2 字节/元素):
KV Cache(GB) ≈ 2 × L × H × S × B × 2 / 1e9
以 Qwen3-8B 为例(约 36 层、隐藏维 4096):
单层每 token KV = 2 × 4096 × 2 字节 ≈ 16 KB
一个 8192 长、并发 1 的请求 ≈ 16KB × 8192 ≈ 131 MB
并发 32、上下文 8192 ≈ 4.2 GB
关键结论:
- 上下文从 4k 翻倍到 32k,KV Cache 翻 8 倍;这是
--max-model-len一调大显存就爆的根因。 - 并发 B 直接线性放大 KV Cache,所以"高并发 + 长上下文"最吃显存。
- vLLM 的 PagedAttention 不改变 KV Cache 的"总量公式",但把"预留浪费"压到最低,等效提升了可承载并发。
4.3、一条机器能不能跑的总判据
总显存需求 ≈ 权重显存 + KV Cache + 约 1~2GB 运行时开销
决策例子:
- 笔记本 16GB 内存、无独显 → 只能 CPU + INT4(GGUF),
num_ctx控制在 4096 内。 - 单卡 24GB(RTX 4090)→ 可 FP16 跑 7B~14B,或 INT4 跑 32B。
- 单卡 80GB(A100)→ FP16 跑 70B,或 INT4 跑更大的 MoE。
五、量化格式对比:GGUF / GPTQ / AWQ
量化是把高精度的权重"压缩",用更少比特表示,从而省显存、提速,代价是少量精度损失。三种主流格式针对的引擎和场景不同:
| 维度 | GGUF (GGML) | GPTQ | AWQ |
|---|---|---|---|
| 提出/代表 | llama.cpp / Georgi Gerganov | GPTQ 论文 | MIT Han Lab (AWQ) |
| 典型比特 | Q4_K_M / Q5_K_M 等 | 4-bit / 3-bit | 4-bit / 2-bit |
| 主要推理引擎 | llama.cpp、Ollama、LM Studio(CPU/GPU 通吃) | AutoGPTQ、vLLM、TGI | AutoAWQ、vLLM、LM Studio |
| 是否依赖校准集 | 否(训练后直接量化) | 是(用 128~256 条样本校准) | 是(用少量样本估算"重要权重") |
| 精度保持 | 好(k-quant 混合量化优秀) | 好 | 优(保护 1% 显著权重) |
| CPU 跑 | 原生支持,最快 | 基本不支持 | 基本不支持 |
| 适用场景 | 个人本地/边缘/CPU | GPU 服务化 | GPU 服务化、保精度优先 |
5.1、三者的原理差异(一句话版)
- GGUF:llama.cpp 的容器格式,内部是 k-quant 混合量化——对"重要的"权重用高精度、不重要的用低精度,且把模型结构/分词器/元数据打包进一个文件,便于分发。它不依赖校准集,开箱即用。
- GPTQ:基于"近似二阶信息"的训练后量化,用校准数据做逐层补偿,使 4-bit 下重建误差最小。需要校准集,量化过程较慢。
- AWQ(Activation-aware Weight Quantization):观察到"只有约 1% 的权重对激活输出影响巨大",量化时不碰这些重要权重(只做缩放保留),其余正常低位量化。因此对精度更友好,常作为 vLLM 上保精度首选。
5.2、怎么选
- 想在笔记本/树莓派/纯 CPU 跑 → 只选 GGUF(Ollama 默认)。
- 有 GPU、要部署成服务且最省显存 → GPTQ 或 AWQ 皆可,vLLM 都支持;追求极限保精度选 AWQ。
- 想一个文件到处跑 → GGUF 是单文件,GPTQ/AWQ 通常是一组 safetensors + 配置。
# 在 HuggingFace 上常见命名规律
Qwen3-8B-GGUF/Qwen3-8B-Q4_K_M.gguf # GGUF 量化版(llama.cpp/Ollama)
Qwen/Qwen3-8B-GPTQ-Int4 # GPTQ 版
Qwen/Qwen3-8B-AWQ # AWQ 版
# Ollama 拉的就是 GGUF;vLLM 拉 GPTQ/AWQ 时需加 --quantization
vllm serve Qwen/Qwen3-8B-AWQ --quantization awq
六、路线三:transformers 原始方式(学习用)
保留当年笔记的核心代码,这是所有框架底下最原生的样子:
from transformers import AutoModelForCausalLM, AutoTokenizer
model = AutoModelForCausalLM.from_pretrained(
"Qwen/Qwen3-8B", torch_dtype="auto", device_map="auto",
)
tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen3-8B")
messages = [{"role": "user", "content": "你是谁?"}]
text = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
model_inputs = tokenizer([text], return_tensors="pt").to(model.device)
generated_ids = model.generate(**model_inputs, max_new_tokens=512)
response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]
print(response)
这段原生代码每一步的含义:
AutoModelForCausalLM—— 因果语言模型(Causal LM,只能"从左往右"生成),适配 Qwen/Llama 等。torch_dtype="auto"—— 用模型卡里声明的精度(通常 BF16)加载,省显存且数值稳。device_map="auto"—— 自动把层分布到可用 GPU,多卡时自动切分;无 GPU 则全 CPU。apply_chat_template—— 把 messages 按模型规定的聊天模板拼成带特殊标记的纯文本(这一步最容易漏,漏了模型就不"聊天"而像续写)。model.generate—— 自回归生成,max_new_tokens控制最多新生成多少 token(注意是"新增"而非总长度)。
6.1、当年的 CPU 方案回顾(ChatGLM2-6B)
无 GPU 时把 .cuda() 改为 .float()(FP32 加载进内存),32G 内存可跑,启动慢、占用约 22G。三种入口脚本:
cli_demo.py:命令行对话web_demo.py:Gradio Web UI(launch(server_name='0.0.0.0', auth=fn)可对外)api.py:uvicorn 暴露 POST API
这套"改代码适配硬件"的思路如今由量化(GGUF/GPTQ/AWQ)+ 推理框架(llama.cpp/Ollama)接管——CPU 跑 7B 模型在 2026 年已是普通操作。
6.2、模型下载
# HuggingFace(国内镜像)
export HF_ENDPOINT=https://hf-mirror.com
huggingface-cli download Qwen/Qwen3-8B
# ModelScope(魔搭,国内直连)
modelscope download --model deepseek-ai/DeepSeek-R1-0528
下载量注意:FP16 的 7B 约 14GB;GGUF Q4 约 4-5GB;70B FP16 约 140GB(建议直接拉量化版)。
七、白嫖 GPU:Kaggle / Colab / AutoDL
当年用 Kaggle 免费 GPU(P100/T4×2,每周 30h)跑 7B 模型的方法依然有效:
- 登录 Kaggle → 手机验证(不验证不能用 GPU)
- Notebook 设置里切换 Accelerator 为 GPU
- Settings → Internet 打开(下载模型需要联网)
# Kaggle/Colab 里跑一个 7B
!pip install -q transformers accelerate
from transformers import AutoModelForCausalLM, AutoTokenizer
tok = AutoTokenizer.from_pretrained("Qwen/Qwen3-8B")
model = AutoModelForCausalLM.from_pretrained(
"Qwen/Qwen3-8B", torch_dtype="auto", device_map="auto")
2026 年的补充选项:
| 平台 | 免费额度 | 说明 |
|---|---|---|
| Kaggle | T4×2,30h/周 | 最稳的免费双卡 |
| Google Colab | T4(免费版) | 挂代理可用 |
| AutoDL / 仙宫云 | 按小时计费(约 ¥1-3/h) | 国内租 4090/A100,跑 70B 微调性价比高 |
7.1、Kaggle 跑模型的完整最小示例
# 1) 安装依赖(Kaggle 镜像已含 torch,但 transformers 版本可能旧)
!pip install -q transformers accelerate sentencepiece
# 2) 用镜像加速下载(Kaggle 机房连 HF 有时慢)
import os
os.environ["HF_ENDPOINT"] = "https://hf-mirror.com"
# 3) 加载(device_map="auto" 自动用免费 GPU)
from transformers import AutoModelForCausalLM, AutoTokenizer
tok = AutoTokenizer.from_pretrained("Qwen/Qwen3-8B")
model = AutoModelForCausalLM.from_pretrained(
"Qwen/Qwen3-8B", torch_dtype="auto", device_map="auto").eval()
# 4) 推理
prompt = tok.apply_chat_template(
[{"role": "user", "content": "用一句话介绍你自己"}],
tokenize=False, add_generation_prompt=True)
out = model.generate(**tok([prompt], return_tensors="pt").to(model.device),
max_new_tokens=256)
print(tok.decode(out[0], skip_special_tokens=True))
Kaggle 注意:免费 GPU 单次会话有断连风险(闲置 60 分钟或总时长到 30h 会被回收);不要把微调后的大模型权重只存在
/kaggle/working之外,关掉就没了。要持久化请挂 Kaggle Dataset 或传 ModelScope。
八、常见报错排查
本地部署 90% 的坑集中在显存、依赖版本、编码、网络四类。
8.1、显存不足(CUDA out of memory)
RuntimeError: CUDA out of memory. Tried to allocate ...
- 换更小量化:FP16→INT4(GGUF Q4_K_M / vLLM
--quantization awq)。 - 减小
--max-model-len/num_ctx,KV Cache 立刻下降。 - 降并发:单用户先跑通再谈性能。
- 多卡:
vllm serve ... --tensor-parallel-size 2;或 transformersdevice_map="auto"自动拆分。 - CPU 兜底:Ollama
num_gpu 0或 transformers 不指定 cuda。
8.2、依赖版本冲突
ImportError: cannot import name 'xxx' from 'transformers'
- 锁定版本:
pip install transformers==4.44.0 accelerate==0.33.0。 - 新模型往往要求新版 transformers,旧模型用新库可能报错——以模型卡
requirements为准。 - torch 与 CUDA 版本要匹配(如 CUDA 12.1 配 torch 2.3+),否则报
CUDA error。
8.3、trust_remote_code 相关
ValueError: Loading THUDM/chatglm2-6b requires you to execute the modeling file...
- 老模型(ChatGLM2/早期 Qwen)需要
trust_remote_code=True,新版 Qwen2+ 已无需。 - 远程代码有安全风险,只对自己信任的仓库开启。
8.4、网络/下载失败
- HF 连不上:设
HF_ENDPOINT=https://hf-mirror.com或用modelscope download。 - GGUF 下载中断:用
huggingface-cli download支持断点续传,比浏览器稳。
8.5、CPU 推理极慢 / 卡死
- 确认不是误把 14GB FP16 模型放 CPU 了(会swap到磁盘,慢到像死机)。应换 GGUF Q4。
num_thread设成物理核数,别超线程翻倍导致争抢。- 关闭其他吃内存程序,避免 22G+ 占用触发系统 OOM Killer。
8.6、中文乱码 / 输出退格
- Windows 终端编码设为 UTF-8:
chcp 65001;或在 Python 文件头加# -*- coding: utf-8 -*-。 - 确认 tokenizer 加载成功,没退化成按字切分。
九、2026 年开源模型选型速查
| 需求 | 推荐 | 理由 |
|---|---|---|
| 个人电脑聊天 | Qwen3-8B、GLM-4-9B | Ollama 一条命令,中文好 |
| 推理/数学 | DeepSeek-R1-Distill、Qwen3-Thinking | 思考链蒸馏小模型 |
| 代码 | Qwen3-Coder、DeepSeek-V3 | 补全与 Agent 式改码 |
| 长上下文/知识库 | Qwen3-32B、GLM-4.5 | 128k 窗口 |
| 边缘设备 | Qwen3-1.7B/4B、Llama-3.2-3B | 手机/树莓派可跑 |
选型原则:先看显存预算,再看中文/代码/推理的侧重点;中文场景 Qwen/GLM/DeepSeek 基本全面优于 Llama 同级。
十、小结
- 想"立刻用"选 Ollama;想"对外服务"选 vLLM/SGLang;想"学原理/微调"用 transformers 原生。
- 量化是本地部署的命门:CPU 只能跑 GGUF,GPU 服务化 GPTQ/AWQ。
- 显存 = 权重 + KV Cache,上下文和并发是显存黑洞,调参前先套第四节公式算一遍。
- 报错先怀疑显存和版本,九成问题能在这两处定位。
下一篇(08)会展开 OpenAI 兼容 API 的全参数与函数调用,本地起的服务也能直接对接这些代码。

浙公网安备 33010602011771号