【模型架构篇01】大模型部署:从vLLM到ollama
大模型部署技术解析 本文系统介绍大模型部署的核心挑战与解决方案。主要内容包括: 部署挑战:大模型部署面临显存不足、推理速度慢等难题,以70B模型为例,FP16精度下需要148GB显存,远超单卡GPU容量。 量化技术:通过降低参数精度减少显存占用,包括FP8、INT8、4-bit等方案。量化后70B模型可压缩至35GB(4-bit),适配消费级GPU。 推理框架对比: vLLM:生产级高并发API服
·
【模型架构篇01】大模型部署:从vLLM到ollama
前言:训练好的大模型锁在实验室里毫无价值,真正产生价值的是部署到线上服务千万用户。但大模型部署不是启动一个Python程序那么简单——显存不够怎么办?推理太慢怎么办?多用户同时请求怎么调度?本文从全量精度部署到4-bit量化,从vLLM生产级部署到ollama个人玩法,带着大家一次搞懂大模型部署的全链路。
📋 目录
- 一、部署的核心挑战
- 二、量化:让大模型"瘦下来"
- 三、推理框架对比:vLLM vs ollama vs SGLang vs TensorRT-LLM
- 四、vLLM:生产级部署首选
- 五、ollama:一行命令本地运行
- 六、SGLang:结构化生成与高性能推理
- 七、TensorRT-LLM:NVIDIA专属极致优化
- 八、KV Cache优化:支持长上下文
- 九、多卡部署与分布式推理
- 十、实战:从模型下载到API上线完整流程
一、部署的核心挑战
1.1 为什么大模型部署这么难?
传统软件部署 vs 大模型部署:
传统Web服务:
代码:几MB
内存:几百MB
CPU:够用
启动:秒级
大模型推理服务:
模型:几十GB ~ 几百GB
显存:至少需要模型的两倍大小
GPU:必须,且显存越大越好
启动:分钟级
推理速度:受显存带宽限制
核心矛盾:模型太大,显存太少
1.2 显存去哪了?
以LLaMA-2 70B为例,一次推理需要的显存:
1️⃣ 模型参数(FP16精度)
70B × 2 bytes = 140GB
2️⃣ KV Cache(每生成一个token)
32层 × 64头 × 128维 × 2(K+V) × 4bytes = 每token约2MB
生成2048个token:2MB × 2048 ≈ 4GB
3️⃣ 激活值(中间计算结果)
模型推理过程中的临时变量
取决于batch size和序列长度
大约2-8GB
总需求(70B模型,FP16,2048 tokens):
≈ 140GB(参数) + 4GB(KV Cache) + 4GB(激活值)
= 148GB显存
而一张H100只有80GB,A100只有80GB/40GB
→ 必须用多张GPU或量化
1.3 推理速度瓶颈
影响推理速度的三个核心因素:
1️⃣ 显存带宽(Memory Bandwidth)
大模型推理是"显存带宽密集型"任务
计算本身很快,但把数据从显存搬到计算单元很慢
H100:3.35 TB/s
A100:2.0 TB/s
RTX 4090:1.0 TB/s
RTX 3090:0.94 TB/s
以H100部署70B模型为例:
每生成一个token需要读取140GB参数
理论最小延迟 = 140GB / 3.35TB/s ≈ 42ms/token
→ 每秒最多生成约24个token
2️⃣ 计算能力(Compute Capability)
Attention计算中的矩阵乘法
当batch size增大时,计算成为瓶颈
3️⃣ 内存容量(Memory Capacity)
显存放不下模型 → 用多卡或CPU offloading
CPU offloading → 速度下降10-100倍
2026年旗舰硬件的推理能力:
H200(141GB显存):可单卡跑70B FP16
B200(192GB显存):可单卡跑70B FP16+大batch
单卡推理速度:70B模型约30-50 tokens/s
二、量化:让大模型"瘦下来"
2.1 量化原理
量化 = 用更低精度的数据类型存储模型参数
精度对比:
FP32(32位浮点):每个参数4字节 → 精度最高
FP16(16位浮点):每个参数2字节 → 主流训练精度
INT8(8位整数): 每个参数1字节 → 质量损失小
INT4(4位整数): 每个参数0.5字节 → 质量损失可接受
NF4(4位规范化浮点):每个参数0.5字节 → 比INT4略好
量化效果(以70B模型为例):
FP16:140GB → 需要2张H100
INT8:70GB → 1张H100刚好放下
INT4:35GB → 1张H100甚至还有富裕做KV Cache
量化损失:
INT8:质量损失约1-2%
INT4:质量损失约3-5%
NF4: 质量损失约2-4%
2.2 主流量化技术
2026年主流量化方法:
1️⃣ GPTQ(2023)
基于二阶优化的后训练量化
需要少量校准数据
支持INT4/INT3/INT2
特点:质量好,但量化过程较慢
2️⃣ AWQ(2024)
基于激活值感知的量化
识别"重要"和"不重要"的权重通道
重要通道保留更高精度
特点:量化速度快,质量接近GPTQ
3️⃣ GGUF / GGML(持续更新)
llama.cpp生态的量化格式
社区支持最好的量化格式
从Q2_K到Q8_0多种选择
特点:兼容性最好,ollama原生支持
4️⃣ BitsAndBytes(4-bit/8-bit)
HuggingFace生态的量化库
支持QLoRA训练时直接量化
特点:最简单,一行代码加载4-bit模型
5️⃣ FP8(2024-2026新趋势)
H100原生支持FP8计算
不需要"量化",直接在FP8精度推理
速度比FP16快2倍
质量损失极小
→ 2026年部署的首选精度
量化方式对比:
┌──────────┬──────────┬──────────┬──────────┐
│ 方法 │ 质量 │ 速度 │ 兼容性 │
├──────────┼──────────┼──────────┼──────────┤
│ FP16 │ 最佳 │ 基准 │ 最好 │
│ FP8 │ 极佳 │ 2倍↑ │ H100+专用 │
│ INT8 │ 优秀 │ 1.5倍↑ │ 好 │
│ AWQ-4bit │ 良好 │ 3-4倍↓ │ vLLM支持 │
│ GPTQ-4bit│ 良好 │ 3-4倍↓ │ 广泛 │
│ GGUF-Q4 │ 良好 │ 3-4倍↓ │ ollama │
│ NF4 │ 可接受 │ 4倍↓ │ bitsandbytes│
└──────────┴──────────┴──────────┴──────────┘
2.3 量化选择指南
根据硬件选择量化方案:
场景1:你有一张H100(80GB)
目标模型:70B
推荐方案:FP8(原生支持,质量好速度快)
或:INT8(vLLM支持良好)
场景2:你有一张A100(80GB)
目标模型:70B
推荐方案:INT8(65-70GB,刚好放下)
或:AWQ-4bit(35GB,有富裕做KV Cache)
场景3:你有一张RTX 4090(24GB)
目标模型:7B
推荐方案:FP16(14GB,足够)
目标模型:13B
推荐方案:INT8(13GB,刚好)
场景4:你有一张RTX 3060(12GB)
目标模型:7B
推荐方案:AWQ-4bit / GGUF-Q4_K_M
注意:7B模型INT4大约4-5GB,有富裕
场景5:只有CPU(无GPU)
目标模型:7B
推荐方案:GGUF-Q4_K_M + llama.cpp
速度:约1-3 tokens/s(取决于CPU)
一句话总结:
有H100 → FP8
有A100/H100 → INT8
显存不够 → 4-bit量化
只有CPU → GGUF+llama.cpp
三、推理框架对比:vLLM vs ollama vs SGLang vs TensorRT-LLM
3.1 四款框架概览
2026年主流推理框架:
┌──────────┬──────────┬──────────┬──────────┬──────────────┐
│ 框架 │ 定位 │ 部署方式 │ 性能 │ 适用场景 │
├──────────┼──────────┼──────────┼──────────┼──────────────┤
│ vLLM │ 生产级 │ Docker/ │ ⭐⭐⭐⭐⭐ │ 高并发API服务 │
│ │ 推理引擎 │ Python │ 吞吐极强 │ │
│ ollama │ 个人本地 │ 安装包 │ ⭐⭐⭐ │ 本地开发/体验 │
│ │ 轻量工具 │ 一行命令 │ 够用 │ │
│ SGLang │ 高性能 │ Python │ ⭐⭐⭐⭐⭐ │ 结构化生成 │
│ │ 推理引擎 │ │ 极快 │ 复杂推理场景 │
│ TensorRT │ NVIDIA │ Docker │ ⭐⭐⭐⭐⭐ │ 极致优化 │
│ -LLM │ 专属优化 │ 编译部署 │ 最高性能 │ NVIDIA专属 │
│ XInference│ 分布式 │ Docker │ ⭐⭐⭐⭐ │ 企业多模型管理 │
└──────────┴──────────┴──────────┴──────────┴──────────────┘
3.2 性能实测对比
各框架在相同条件下的吞吐量对比(A100 80GB, LLaMA-2 7B):
测试条件:
- 模型:LLaMA-2 7B FP16
- 输入:512 tokens
- 输出:128 tokens
- Batch size:动态(框架自适应)
吞吐量(tokens/s):
┌──────────┬────────────┬────────────┬────────────┐
│ 框架 │ batch=1 │ batch=16 │ batch=64 │
├──────────┼────────────┼────────────┼────────────┤
│ vLLM │ 45 t/s │ 320 t/s │ 780 t/s │ ← 高并发最强
│ SGLang │ 52 t/s │ 350 t/s │ 820 t/s │ ← 略有优势
│ TensoRT │ 48 t/s │ 340 t/s │ 800 t/s │ ← 编译优化
│ -LLM │ │ │ │
│ ollama │ 38 t/s │ 150 t/s │ 300 t/s │ ← 不适合高并发
└──────────┴────────────┴────────────┴────────────┘
关键结论:
ollama方便,但vLLM/SGLang吞吐量是它的2-3倍
生产环境不要用ollama做高并发API
个人使用ollama,生产用vLLM
四、vLLM:生产级部署首选
4.1 为什么是vLLM
vLLM是2024-2026年最流行的大模型推理引擎。
核心优势:
1️⃣ PagedAttention(核心创新)
这是vLLM的看家本领
类似操作系统的"虚拟内存"
KV Cache不再连续存储
而是分页管理,消除显存碎片
效果:KV Cache利用率从20-40%提升到95%+
同样显存可以服务更多并发请求
2️⃣ Continuous Batching(连续批处理)
传统方法:等一批请求都完成再处理下一批
vLLM:随时有新请求随时加入
一个请求生成完了,立刻插入新的
效果:GPU利用率大幅提升
吞吐量是HuggingFace Transformers的10-20倍
3️⃣ 量化原生支持
AWQ、GPTQ、FP8开箱即用
不需要额外转换
4️⃣ OpenAI兼容API
一行代码切换
从OpenAI迁移到自部署:改base_url就行
4.2 vLLM部署示例
# 安装
pip install vllm
# 启动API服务(最简单的用法)
python -m vllm.entrypoints.openai.api_server \
--model Qwen/Qwen2.5-7B-Instruct \
--tensor-parallel-size 1 \
--gpu-memory-utilization 0.9 \
--max-model-len 4096
# 客户端调用(和OpenAI API完全兼容)
from openai import OpenAI
client = OpenAI(
base_url="http://localhost:8000/v1",
api_key="not-needed" # vLLM默认不验证API Key
)
response = client.chat.completions.create(
model="Qwen/Qwen2.5-7B-Instruct",
messages=[
{"role": "user", "content": "用Python实现二分查找"}
],
temperature=0.1
)
print(response.choices[0].message.content)
4.3 vLLM生产配置
# 生产环境推荐配置
# 1. 基本配置
python -m vllm.entrypoints.openai.api_server \
--model Qwen/Qwen2.5-7B-Instruct \
--tensor-parallel-size 1 \ # 单卡1,多卡用GPU数量
--gpu-memory-utilization 0.9 \ # 显存利用率(0.9为90%)
--max-model-len 8192 \ # 最大上下文长度
--dtype auto \ # 自动选择精度
--enforce-eager \ # 不使用图编译(调试用)
--max-num-seqs 256 \ # 最大并行序列数
# 2. 量化配置(显存不够时)
--quantization awq \ # AWQ量化
--quantization-param-path /path/to/quant_config.json \
# 3. 多卡配置
--tensor-parallel-size 4 \ # 4卡并行
# 4. 性能配置
--block-size 16 \ # PagedAttention块大小
--swap-space 16 \ # CPU交换空间(GB)
--disable-log-stats # 关闭日志(生产环境)
4.4 vLLM的高级功能
# 流式输出(SSE)
response = client.chat.completions.create(
model="Qwen/Qwen2.5-7B-Instruct",
messages=[{"role": "user", "content": "写一首诗"}],
stream=True # 启用流式输出
)
for chunk in response:
if chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="")
# 结构化输出(JSON模式)
import json
response = client.chat.completions.create(
model="Qwen/Qwen2.5-7B-Instruct",
messages=[{"role": "user", "content": "提取信息:张三,28岁,北京"}],
response_format={"type": "json_object"}, # JSON模式
temperature=0.1
)
data = json.loads(response.choices[0].message.content)
# {"name": "张三", "age": 28, "city": "北京"}
五、ollama:一行命令本地运行
5.1 ollama是什么
ollama = 大模型界的"Docker"
一行命令拉取模型
一行命令启动服务
自动处理量化、依赖、配置
安装:
macOS/Linux: curl -fsSL https://ollama.ai/install.sh | sh
Windows: 下载安装包
常用命令:
ollama pull qwen2.5 # 拉取模型
ollama run qwen2.5 # 运行模型(交互式)
ollama serve # 启动API服务
ollama list # 列出已下载的模型
ollama rm qwen2.5 # 删除模型
ollama ps # 查看运行中的模型
5.2 ollama支持的模型
2026年ollama模型仓库(部分):
对话模型:
llama3.3:70b ← Meta最新
qwen2.5:72b ← 阿里旗舰
deepseek-r1:70b ← DeepSeek推理模型
mistral:7b ← 轻量首选
gemma3:27b ← Google
代码模型:
codellama:34b ← 代码专用
deepseek-coder:33b ← DeepSeek代码模型
qwen2.5-coder:32b ← 阿里代码模型
中文模型:
qwen2.5:7b/32b/72b ← 中文最强
glm4:9b ← 智谱
yi:34b ← 零一万物
Embedding模型:
nomic-embed-text ← 通用Embedding
mxbai-embed-large ← 英文Embedding
bge-m3 ← 多语言Embedding
视觉模型:
llava:13b ← 多模态
llama3.2-vision:11b ← Meta多模态
5.3 ollama部署示例
# 启动API服务
ollama serve
# 默认监听 http://localhost:11434
# 或:直接交互式运行
ollama run qwen2.5:7b
>>> 用Python实现快速排序
# Python调用ollama(兼容OpenAI格式)
from openai import OpenAI
client = OpenAI(
base_url="http://localhost:11434/v1",
api_key="ollama"
)
response = client.chat.completions.create(
model="qwen2.5:7b",
messages=[{"role": "user", "content": "什么是RAG?"}],
stream=True
)
for chunk in response:
print(chunk.choices[0].delta.content or "", end="")
5.4 Modelfile:自定义配置
ollama支持通过Modelfile自定义模型配置:
FROM qwen2.5:7b # 基础模型
# 修改System Prompt
SYSTEM """你是一个专业的AI助手。
请用中文回答,保持简洁准确。"""
# 调整参数
PARAMETER temperature 0.3
PARAMETER top_p 0.9
PARAMETER num_ctx 8192 # 上下文长度
PARAMETER num_gpu 1 # GPU层数(-1为CPU)
PARAMETER num_thread 8 # CPU线程数
# 使用
# ollama create my-custom-model -f Modelfile
# ollama run my-custom-model
5.5 ollama的局限性
ollama很方便,但也有明显的局限:
❌ 不适合生产环境高并发
单请求时速度不错
并发请求时吞吐量急剧下降
没有Continuous Batching
❌ 不支持分布式推理
不能跨多台机器部署
70B模型只能在单台机器上跑
❌ 量化格式有限
主要支持GGUF格式
AWQ/GPTQ支持不如vLLM完善
❌ 监控和运维功能弱
没有健康检查
没有自动扩缩容
没有请求排队
✅ ollama适合的场景:
个人开发测试
本地知识库
小团队内部使用(<10个并发)
快速原型验证
❌ ollama不适合的场景:
面向外部用户的API服务
需要高QPS的生产环境
大规模分布式部署
六、SGLang:结构化生成与高性能推理
6.1 SGLang的核心优势
SGLang是2024年崛起的高性能推理框架,在某些场景下甚至超过vLLM。
核心创新:
1️⃣ RadixAttention
类似vLLM的PagedAttention
但进一步优化了前缀缓存
如果多个请求共享相同的前缀(如相同的system prompt)
前缀的KV Cache可以复用
效果:共享前缀场景下吞吐量提升1.5-3倍
2️⃣ Structured Generation(结构化生成)
不只是生成文本
可以约束生成的格式:
- JSON Schema约束
- 正则表达式约束
- 上下文无关文法约束
效果:结构化数据提取速度提升5-10倍
3️⃣ 高效的Function Calling
原生支持工具调用
比vLLM的Function Calling更高效
场景优势:
Agent系统:大量共享system prompt → RadixAttention优势明显
数据提取:需要JSON输出 → Structured Generation优势
工具调用:Function Calling场景
6.2 SGLang部署示例
# 安装
pip install sglang
# 启动API服务
python -m sglang.launch_server \
--model-path Qwen/Qwen2.5-7B-Instruct \
--port 30000 \
--tp-size 1
# SGLang的结构化生成示例
import sglang as sgl
@sgl.function
def extract_info(s, text):
s += sgl.user(f"从以下文本中提取结构化信息:{text}")
s += sgl.assistant(
sgl.gen(
"output",
max_tokens=256,
# 指定JSON Schema约束
json_schema={
"type": "object",
"properties": {
"name": {"type": "string"},
"age": {"type": "integer"},
"city": {"type": "string"}
},
"required": ["name", "age", "city"]
}
)
)
# 运行
state = extract_info.run(text="张三,28岁,居住在北京")
print(state["output"])
# {"name": "张三", "age": 28, "city": "北京"}
七、TensorRT-LLM:NVIDIA专属极致优化
7.1 什么是TensorRT-LLM
TensorRT-LLM = NVIDIA官方的大模型推理优化框架
它不是"即插即用"的
而是需要"编译"模型的
工作流程:
1. 加载原始模型(HuggingFace格式)
2. 编译优化模型(TensorRT格式)
3. 部署编译后的模型
编译做了哪些优化:
✅ 算子融合:合并多个小算子为一个
✅ 内核自动调优:选择最快的CUDA kernel
✅ 内存优化:减少中间变量
✅ 量化集成:INT4/INT8/FP8原生优化
✅ 多卡优化:跨GPU通信优化
效果(在NVIDIA GPU上):
比原始PyTorch实现快2-4倍
比vLLM快10-20%(在NVIDIA GPU上)
但在非NVIDIA硬件上无法运行
7.2 什么时候用TensorRT-LLM
✅ 推荐使用场景:
你的基础设施全是NVIDIA GPU
追求极致性能(低于10%的差异也重要)
模型已经确定,不需要频繁更换
有专门的运维团队
❌ 不推荐使用场景:
使用AMD/Intel GPU
需要频繁切换模型
团队没有NVIDIA优化经验
只是做快速原型验证
选型建议:
90%的情况用vLLM就够了
需要极致性能用TensorRT-LLM
个人/小团队用ollama
Agent场景用SGLang
八、KV Cache优化:支持长上下文
8.1 KV Cache为什么重要
KV Cache = 推理时缓存下来的Key和Value矩阵
没有KV Cache:
生成第100个token时
需要重新计算前99个token的K和V
每次生成的计算量 = O(n²)
→ 速度极慢
有KV Cache:
生成第100个token时
前99个token的K和V已经缓存好了
只需要计算第100个token的K和V
每次生成的计算量 = O(n)
→ 快了一个数量级
KV Cache的代价:
显存占用随序列长度线性增长
70B模型,32层,128头,128维
每token ≈ 2MB
4096 tokens ≈ 8GB
32768 tokens ≈ 64GB
→ 长上下文的显存开销非常大
8.2 各框架的KV Cache技术
各框架的KV Cache优化:
vLLM → PagedAttention
分页管理KV Cache,消除碎片
利用率从20-40%提升到95%+
支持CPU Swap(显存不够时换出到内存)
SGLang → RadixAttention
在PagedAttention基础上
增加了前缀共享(Prefix Caching)
相同前缀的KV Cache可以复用
ollama → 基本缓存
使用llama.cpp的KV Cache管理
支持缓存到CPU(offloading)
没有分页管理
TensorRT-LLM → 编译优化
KV Cache的in-flight计算优化
减少K和V的搬运次数
KV Cache量化(2026年趋势):
把KV Cache从FP16量化到INT8
显存占用减少50%
质量损失可以忽略
vLLM v0.6+ 和 TensorRT-LLM 都支持
8.3 长上下文部署配置
部署长上下文模型的关键配置:
显存估算公式:
总显存 = 模型参数 + KV Cache + 激活值
模型参数 = param_count × bytes_per_param
KV Cache = 2 × n_layers × n_heads × head_dim × seq_len × bytes_per_value
激活值 = 约2-8GB
示例:32K上下文场景
模型:LLaMA-3 70B INT8(70GB)
KV Cache(32K):2×80×64×128×32768×2 ≈ 67GB
激活值:4GB
总计:70+67+4 = 141GB → 需要2张H100
优化方案:
1. KV Cache量化到INT8 → 减少50%
2. 使用更小的模型(如7B)
3. 减少上下文窗口(8K而非32K)
4. 多卡分摊(TP=2)
九、多卡部署与分布式推理
9.1 张量并行(Tensor Parallelism)
张量并行 = 把一个矩阵乘法拆到多张GPU上算
直观理解:
一个巨大的矩阵(70000×70000)
单卡H100放不下 → 切成两块
GPU 0:前35000行
GPU 1:后35000行
计算时:
输入同时发给两张卡
各自算自己的部分
结果合并
好处:
可以跑单卡放不下的模型
推理速度几乎线性提升(2卡≈2倍速度)
代价:
卡间通信开销(NVLink/NVSwitch)
每生成一个token都需要一次通信
配置方式(vLLM):
--tensor-parallel-size 4 # 4卡张量并行
注意:
TP=2需要单节点2卡
TP=8需要单节点8卡(DGX标准配置)
跨节点TP性能下降明显
9.2 流水线并行(Pipeline Parallelism)
流水线并行 = 把模型按层切分到多张GPU
直观理解:
LLaMA-3 70B有80层Transformer
GPU 0:第1-20层
GPU 1:第21-40层
GPU 2:第41-60层
GPU 3:第61-80层
计算时:
输入 → GPU0 → GPU1 → GPU2 → GPU3 → 输出
像工厂流水线一样
好处:
可以跑更大的模型
卡间通信较少(只传中间激活值)
代价:
GPU利用率不均匀(前段卡在等后段)
延迟稍高(串行通过4个阶段)
9.3 部署配置示例
# vLLM多卡部署(4卡H100,70B模型)
# 方式1:张量并行(推荐)
python -m vllm.entrypoints.openai.api_server \
--model /path/to/llama-70b \
--tensor-parallel-size 4 \ # 4卡TP
--dtype bfloat16 \
--max-model-len 8192 \
--gpu-memory-utilization 0.9
# 方式2:流水线并行
python -m vllm.entrypoints.openai.api_server \
--model /path/to/llama-70b \
--pipeline-parallel-size 4 \ # 4卡PP
--dtype bfloat16 \
--max-model-len 8192
# 方式3:TP+PP混合
python -m vllm.entrypoints.openai.api_server \
--model /path/to/llama-70b \
--tensor-parallel-size 2 \ # 2卡TP
--pipeline-parallel-size 2 \ # 2卡PP
--dtype bfloat16 \
--max-model-len 8192
# 总卡数:2×2=4卡
十、实战:从模型下载到API上线完整流程
10.1 选择模型和框架决策树
你的场景是?
│
├─ 个人/小团队本地用
│ └─ ollama:ollama pull qwen2.5:7b
│
├─ 生产环境API服务
│ ├─ 单模型高并发
│ │ └─ vLLM
│ ├─ Agent/工具调用场景
│ │ └─ SGLang(RadixAttention优势)
│ └─ 极致性能+全NVIDIA
│ └─ TensorRT-LLM
│
└─ 边缘设备/手机
├─ MLC-LLM(手机端)
└─ llama.cpp + GGUF(CPU/小GPU)
10.2 完整部署脚本(vLLM)
#!/bin/bash
# deploy.sh - 完整部署脚本
# === 1. 环境准备 ===
echo "=== 环境准备 ==="
# 创建虚拟环境
python -m venv venv
source venv/bin/activate
# 安装依赖
pip install vllm==0.6.0
pip install openai # 客户端库
pip install prometheus-client # 监控
# === 2. 模型下载 ===
echo "=== 下载模型 ==="
# vLLM会自动从HuggingFace下载
export HF_TOKEN="your_hf_token"
# === 3. 启动服务 ===
echo "=== 启动API服务 ==="
# 生产配置
MODEL="Qwen/Qwen2.5-7B-Instruct"
NUM_GPU=$(nvidia-smi --list-gpus | wc -l)
python -m vllm.entrypoints.openai.api_server \
--model $MODEL \
--tensor-parallel-size $NUM_GPU \
--gpu-memory-utilization 0.9 \
--max-model-len 8192 \
--dtype bfloat16 \
--port 8000 \
--host 0.0.0.0 \
--max-num-seqs 256 \
--enable-prefix-caching &
# 等待服务启动
sleep 30
# === 4. 健康检查 ===
echo "=== 健康检查 ==="
curl http://localhost:8000/health
# 返回 {"status": "healthy"}
# === 5. 测试调用 ===
echo "=== 测试API ==="
python -c "
from openai import OpenAI
client = OpenAI(base_url='http://localhost:8000/v1', api_key='test')
resp = client.chat.completions.create(
model='$MODEL',
messages=[{'role': 'user', 'content': '你好'}]
)
print(resp.choices[0].message.content)
"
echo "=== 部署完成!API地址: http://localhost:8000/v1 ==="
10.3 客户端SDK封装
# rag_client.py - 对接部署好的API
from openai import OpenAI
from typing import List, Dict, Optional
import time
class LLMClient:
"""大模型API客户端"""
def __init__(self, base_url: str = "http://localhost:8000/v1",
api_key: str = "not-needed",
model: str = "Qwen/Qwen2.5-7B-Instruct"):
self.client = OpenAI(base_url=base_url, api_key=api_key)
self.model = model
def chat(self, messages: List[Dict],
temperature: float = 0.1,
max_tokens: int = 1024,
stream: bool = False) -> str:
"""普通对话"""
response = self.client.chat.completions.create(
model=self.model,
messages=messages,
temperature=temperature,
max_tokens=max_tokens,
stream=stream
)
if stream:
return self._handle_stream(response)
return response.choices[0].message.content
def _handle_stream(self, response) -> str:
"""处理流式输出"""
full_response = ""
for chunk in response:
if chunk.choices[0].delta.content:
content = chunk.choices[0].delta.content
full_response += content
print(content, end="", flush=True)
print()
return full_response
def structured_extract(self, text: str, schema: Dict) -> Dict:
"""结构化数据提取"""
import json
response = self.client.chat.completions.create(
model=self.model,
messages=[
{"role": "system", "content": "提取信息并以JSON格式输出。"},
{"role": "user", "content": text}
],
response_format={"type": "json_object"},
temperature=0.1
)
return json.loads(response.choices[0].message.content)
def benchmark(self, test_prompts: List[str],
output_len: int = 128) -> Dict:
"""性能基准测试"""
total_tokens = 0
total_time = 0
for prompt in test_prompts:
start = time.time()
response = self.client.chat.completions.create(
model=self.model,
messages=[{"role": "user", "content": prompt}],
max_tokens=output_len,
temperature=0.1
)
elapsed = time.time() - start
total_time += elapsed
total_tokens += response.usage.completion_tokens
return {
"avg_latency": total_time / len(test_prompts),
"avg_throughput": total_tokens / total_time,
"total_requests": len(test_prompts),
"total_tokens": total_tokens
}
# 使用
client = LLMClient()
# 普通对话
response = client.chat([
{"role": "system", "content": "你是AI助手"},
{"role": "user", "content": "用Python实现快速排序"}
], stream=True)
# 运行基准测试
results = client.benchmark([
"解释量子计算",
"写一首关于秋天的诗",
"Python装饰器是什么"
], output_len=128)
print(f"平均延迟: {results['avg_latency']:.2f}s")
print(f"平均吞吐: {results['avg_throughput']:.1f} tokens/s")
10.4 部署检查清单
部署上线前的检查清单:
✅ 显存检查
□ 模型能装下(需预留20%显存给KV Cache)
□ 实际测试峰值显存占用
□ 设置了gpu-memory-utilization
✅ 性能验证
□ 单请求延迟 < 3秒(用户体验要求)
□ 并发请求吞吐达到业务要求
□ 长文本场景下KVCache不爆显存
✅ 可用性保障
□ 健康检查接口可用
□ 服务崩溃能自动重启
□ 有请求超时设置(避免死等)
✅ 安全加固
□ 添加API Key认证
□ 限制请求频率(Rate Limit)
□ 敏感内容过滤
□ Prompt注入防护
✅ 监控告警
□ GPU利用率监控
□ 显存使用率监控
□ 请求延迟监控(P50/P95/P99)
□ 错误率监控
✅ 运维准备
□ 模型更新策略
□ 日志收集
□ 扩容方案(水平/垂直)
□ 降级方案(大模型不可用时回退规则)
📌 总结
大模型部署核心要点:
1️⃣ 部署的三大挑战
显存:模型太大,放不下
速度:带宽限制,推理慢
并发:多用户时吞吐量下降
2️⃣ 量化选择
H100+ → FP8(原生支持,质量好)
显存够 → INT8(70B单卡)
显存不够 → AWQ-4bit
只有CPU → GGUF+llama.cpp
3️⃣ 框架选型
生产高并发 → vLLM
个人本地玩 → ollama
Agent场景 → SGLang
极致性能(NVIDIA全栈) → TensorRT-LLM
4️⃣ KV Cache优化
长上下文的核心瓶颈
PagedAttention(vLLM)解决碎片
RadixAttention(SGLang)共享前缀
KV Cache量化减少50%显存
5️⃣ 多卡部署
张量并行:矩阵切分到多卡
流水线并行:层切分到多卡
推荐TP,除非模型超大
🔗 延伸阅读
- 【模型架构篇02】模型压缩:知识蒸馏与剪枝(下一篇)
- 【模型架构篇03】MoE混合专家模型详解
- 【AI基础篇03】大模型参数、算力、数据:Scaling Law的本质
觉得有帮助?点赞收藏!下一篇我们讲模型压缩技术——知识蒸馏与剪枝,让大模型变得更小、更快、更便宜! 🚀
标签:人工智能、大模型部署、vLLM、ollama、SGLang、TensorRT-LLM、量化、推理优化、KV Cache
更多推荐


所有评论(0)