在服务器上跑大模型这件事,说实话,两年前还是极客圈里少数人的玩具,到了今天已经变成了不少团队的基础设施。但正因为人人都能拉个镜像把模型跑起来,"部署"这个词的门槛反而被严重低估了。我见过太多团队在演示环境里跑得飞起,一上生产就各种崩:显存溢出、并发一高就超时、莫名其妙的 OOM、Docker 里看不到 GPU、多卡权重切分错误——这些坑我全踩过。这篇文章不聊算法,只聊部署,从需求拆解、框架选型、云资源对比,到生产级流程和问题排查,把我这两年摸爬滚打攒下的经验一次性整理出来,给正准备入手大模型服务器部署的团队和个人一个可以照着抄的作业。
1. 部署前先算账:模型需求与硬件预算怎么拆解
很多人一上来就问"哪个框架最快""买哪家云服务器",这个顺序是错的。部署的起点不是选工具,而是算清楚你到底要跑什么模型、跑多少并发、承受多高的延迟。这笔账算不明白,后面所有选型都是拍脑袋。
1.1 从参数量到显存:推理和微调的资源估算逻辑
算显存这件事,底层逻辑其实很简单:模型权重要占多少,KV Cache 要占多少,激活值和中间张量要留多少。权重部分,FP16 精度下每个参数占 2 字节,所以一个 7B 模型的权重大约是 14GB,13B 约 26GB,70B 约 140GB。如果是 INT4/INT8 量化,权重除以 2 或 4,对应地给推理留出更大余量。
KV Cache 是很多人容易忽略的部分。它的大小和上下文长度、并发请求数直接挂钩。以 7B 模型为例,假设 32 层 Transformer、32 个注意力头、每个头维度 128,FP16 精度下每个 token 的 KV Cache 大概是 512KB。如果 max-model-len 设为 4096,单个请求最多吃掉约 2GB,那么 8 个并发请求就可能额外占用 16GB 显存。这个数字在推理框架里可以通过参数动态分配,但如果你用的是比较底层的方案,就得自己把这部分算进预算里。
微调场景则完全不同。微调不光有权重和 KV Cache,还有优化器状态、梯度、激活值。单看 Adam 优化器,FP16 混合精度下每个参数要额外占 12 字节左右(FP32 的主权重+动量+方差),所以 7B 模型做 LoRA 微调虽然只训练少量低秩矩阵,全量微调却往往需要 70GB 以上显存。我的建议是:先确定你的场景是纯推理、LoRA 微调还是全量微调,再按不同的公式估算显存,最后再加 20% 的余量,别把显存卡得太死。
1.2 场景决定形态:在线推理、批量推理与私有化部署
同样一个模型,跑在线对话和跑离线批量打标,对硬件和框架的要求差异极大。在线推理要求低首 token 延迟、稳定的吞吐,所以框架要在 PagedAttention、Continuous Batching 这类调度机制上做得够好,硬件上也倾向于单卡或双卡能扛住的目标模型,减少跨节点通信。
批量推理场景(比如给几万条文本打标签、批量做内容分类)更关心吞吐,不在乎单次延迟。这时候你可以把 batch size 拉得很大,甚至可以考虑用抢占式实例降低成本,因为任务可重试、可断点续跑。
私有化部署则还要多考虑一层:内网可用、权限管理、模型文件的安全存放、是否支持离线安装。很多政企客户要求模型权重不能出内网,连带推理框架都得在内网环境下装好,这就要求你选型的时候尽量选依赖少、便于离线打包的方案。所以我做部署规划的第一步永远是画一个简单的决策表:场景、模型规模、并发量、延迟要求、部署环境,五项对一遍,第一版方案基本就出来了。
1.3 成本模型的初步测算:按量、包月、竞价实例怎么选
云 GPU 的计费模式,本质上是拿不确定性换价格。按量付费最灵活,用完即走,适合实验和不可预测的流量;包月适合长期稳定的在线服务,综合成本比按量低不少;竞价/抢占式实例最便宜,通常只有按量价格的 3 到 5 折,但实例可能随时被回收,只能跑批处理任务。
我见过不少团队犯同一个错误:生产环境的在线推理服务去买竞价实例,结果凌晨流量高峰实例被回收,整个服务宕机,省下的钱还不够赔。正确做法是在线服务至少选包月,或者用按量+自动重启脚本做兜底;竞价实例留给数据清洗、模型评估、批量评测这类任务。
这里还有一个常被忽略的隐性成本:带宽和数据传输费。大模型部署在云端,模型权重的下载、镜像拉取、日志传输都走公网带宽,部分云厂商对出网流量单独计费。如果模型动不动几十 GB,初始化部署时流量费可能比你一个月的主机费还高。所以选云服务商时,要意识到它不仅是"买 GPU",更是在买一套包含存储、带宽、镜像分发在内的完整基础设施。
2. 2026 框架选型:主流推理引擎的横向对比与实战体会
框架选型是部署决策里最核心的一环。到了 2026 年,推理框架的格局已经比两年前清晰很多:vLLM 是事实标准,SGLang 在某些场景反超,TensorRT-LLM 和 MindIE 走厂商深度适配路线,轻量场景里 Ollama 和 llama.cpp 依然有生存空间。下面挨个说我的真实体会。
2.1 vLLM:还是生产环境最稳妥的默认项
vLLM 的核心优势在于 PagedAttention,它把显存管理做得像操作系统的虚拟内存一样,按需分页,大幅提升了 KV Cache 的利用率。配合 Continuous Batching,高并发下吞吐优势非常明显。而且它直接提供 OpenAI 兼容的 API,接入现有应用几乎零改造,这是它成为生产环境默认项的最大理由。
我在生产上大量使用 vLLM,最常用的启动参数大致是这样:
docker run --runtime nvidia --gpus all \ -v /data/models:/models \ -p 8000:8000 \ vllm/vllm-openai:latest \ --model /models/Qwen2.5-72B-Instruct \ --tensor-parallel-size 4 \ --gpu-memory-utilization 0.9 \ --max-model-len 32768 \ --served-model-name qwen72b \ --enable-prefix-caching实测下来,vLLM 在多卡张量并行的场景里挺省心,--tensor-parallel-size 一设,权重自动切分,不需要手工干预。它最让我满意的一点是 --enable-prefix-caching,对重复前缀(比如系统提示词、多轮对话的历史)的缓存效果显著,实际场景能省 30% 以上的算力。
vLLM 的短板也不是没有。对于某些冷门模型架构,它支持得不够及时;多模态模型的兼容性也在追赶中。如果你的模型是很新的架构,部署前先去 vLLM 的官方文档确认一下支持矩阵,别等跑起来才发现算子不支持。
2.2 SGLang:结构化输出和高并发场景下的强对手
SGLang 这两年追得很猛,它最大的亮点是 RadixAttention,用树形结构复用 KV Cache,在有多轮对话、多请求共享前缀的场景下表现非常好。另外一个实用特性是结构化输出,可以直接约束模型输出符合 JSON Schema,不用像以前那样靠提示词"求着"模型输出合法 JSON,对需要稳定解析结果的业务场景价值很大。
我在一个需要大量抽取结构化信息的项目里做过 vLLM 和 SGLang 的对比,同样一批数据、同样的模型,SGLang 的端到端吞吐高出大概 20%,而且 JSON 输出的格式错误率明显更低。如果你的业务偏信息抽取、智能体工具调用这类结构化输出场景,SGLang 值得认真考虑。
SGLang 也提供 OpenAI 兼容 API,从 vLLM 迁移成本不高。它的生态迭代更快,但反过来说也意味着稳定性偶尔不如 vLLM。生产环境我一般建议:非结构化对话为主选 vLLM,结构化输出和高前缀复用场景选 SGLang。
2.3 TensorRT-LLM 与 MindIE:厂商深度优化的适配之路
TensorRT-LLM 是 NVIDIA 官方出品,底层走 TensorRT 引擎,把算子融合、显存管理、内核自动调优做到极致。同一张 H 系列卡上,TensorRT-LLM 的吞吐通常比 vLLM 再高 20% 到 40%,代价是使用复杂度高不少:需要先转换模型格式、构建 TensorRT 引擎,构建时间长,而且不同 GPU 型号出的引擎不通用。
MindIE 则是昇腾生态的推理引擎,对标的就是 TensorRT-LLM,专门跑在昇腾 910B 这类国产加速卡上。国内做信创适配、国产算力平台的项目,MindIE 基本是绕不开的选择。我自己在昇腾环境里跑过 Qwen 系列模型,整体流程已经相当顺畅,但网上资料、社区案例数量确实不如 CUDA 生态丰富,遇到问题经常要翻官方文档甚至提工单。
这两类框架适合什么团队?我的判断是:如果你的流量大到需要压榨每一分硬件性能,且团队有专门做模型优化的人,可以上 TensorRT-LLM;如果是国产算力合规需求,没得选,MindIE 是当前最实际的路。中小团队流量没那么大的话,vLLM 的性价比已经足够,把省下来的时间花在业务上更划算。
2.4 Ollama / llama.cpp / TGI:轻量场景的补充选项
Ollama 最大的价值是"傻瓜式部署"。一条命令下载模型、一条命令起服务,特别适合个人本机调试、小团队内网试用、快速 Demo 演示。它底层调 llama.cpp,CPU 上也能跑,但并发能力弱,API 也不完全兼容 OpenAI 格式,所以生产环境我基本不用它,但它做前置验证很好用。
llama.cpp 的优势是极致轻量和跨平台,树莓派上都能跑,适合边缘计算、离线单机、低配环境。它的 GGUF 量化格式生态也很成熟,很多模型发布时直接就带 GGUF 版本。缺点同样明显:高并发场景性能拉胯,多卡支持比较弱。
TGI 是 Hugging Face 出品的推理框架,和 HuggingFace 生态衔接最好,Text Generation Inference 处理大模型文本生成很稳,但性能优化力度比 vLLM 保守。它的存在价值更多是"官方默认解决方案"——如果你是 HF 生态的深度用户,TGI 天然兼容,但让我选的话,生产环境还是优先 vLLM。
2.5 我的框架选型决策清单
整理一下我这几年沉淀出的选型清单,照着这个走基本不会出错:
| 场景 | 首选框架 | 备选 | 理由 |
|---|---|---|---|
| 标准在线对话服务 | vLLM | SGLang | 生态最稳,OpenAI 兼容,PagedAttention 成熟 |
| 高并发结构化输出 | SGLang | vLLM | RadixAttention 和 JSON 约束更强 |
| NVIDIA 显卡极致性能 | TensorRT-LLM | vLLM | 吞吐上限最高,但工程复杂度也最高 |
| 昇腾/国产卡 | MindIE | - | 昇腾生态唯一成熟路线 |
| 个人调试/内网试用 | Ollama | llama.cpp | 零配置启动,够用就好 |
| 边缘/CPU 低配 | llama.cpp | - | 资源占用极小,GGUF 格式友好 |
这表格即使放到 2026 年,我觉得大方向也依然适用。选型这件事别追求"最先进",要追求"最匹配"。
3. 云服务对比:GPU 实例选择与网络架构设计
框架选完,下一步是选"床"。云服务商的选择直接影响成本、稳定性和运维体验。大模型部署对云资源的要求集中在三块:GPU 型号、内网带宽与存储、网络暴露方式。
3.1 主流云厂商的 GPU 实例横向对比
坦率讲,国内主流云厂商的 GPU 实例同质化已经比较严重,每家的主流款都是 NVIDIA A100/H800/L20/L40S 这些卡,性价比差异不算悬殊,真正的差异在配套服务和运维体验上。
阿里云在 GPU 实例的覆盖面上很全,从入门级的 T4 到高端的 H 系列都有,竞价实例的供给也比较充足,抢不到 H 800 竞价资源的概率比其他家低一些。它的 nvidia 驱动镜像、GPU 监控组件做得比较顺手,出错时工单响应速度也说得过去。腾讯云的 GPU 实例在游戏、社交场景打磨得多,如果业务涉及大量实时音视频处理,混合部署会更方便。AWS 和 Azure 的优势是全球节点多,海外业务部署方便,但对国内客户来说访问延迟、数据出境的合规成本是要额外考虑的。
我的建议是:国内业务为主、合规要求明确的,优先阿里云或腾讯云这类国内厂商,拉镜像快、备案省心、带宽便宜;海外业务或有全球部署需求的,再看 AWS/Azure。另外千万别只看 GPU 型号,实例所在可用区的库存深度、抢占式实例是否充足、数据传输是否收额外费用,这些往往才是账单上差距最大的地方。
3.2 实例存储、镜像与模型权重的预加载
模型权重动辄几十 GB,甚至一个 70B 模型 FP16 就要 140GB。如果在每次扩容新实例时都现场从公网下载,光是带宽和时间成本就够受的。生产环境的正确思路是:把模型权重放在共享存储(比如 NAS / 对象存储挂载)里,实例启动时直接挂载加载,镜像里只放推理框架,不打包权重。这样扩容秒级拉起,也方便多副本共享同一份权重。
镜像这块,我的经验是尽量自己维护一份基础镜像,把 CUDA 版本、推理框架版本、依赖库都固定住。别小看这个步骤,我有一次线上服务挂了要紧急扩容,结果拉下来的最新镜像和旧镜像 Python 版本不一致,关键依赖冲突,折腾了快半小时才恢复。固定的版本化镜像配合滚动发布,是生产环境的基本素养。
还有一个经验:预热很重要。新实例启动后,模型从共享存储加载到显存需要一定时间,冷启动期间进来的请求会失败。要在这段时间把实例从负载均衡摘掉,等预热完成再挂回流量,这个动作可以在启动脚本里做健康检查,自动化处理。
3.3 生产网元:公网暴露、安全组与访问链路设计
线上推理服务对公网暴露是常见需求,但直接把 8000 端口裸奔到公网绝对是给自己找麻烦。我自己经历过的教训是:有人扫描端口后疯狂调用你的接口,账单直接爆炸。所以生产部署一定要有访问控制意识。
第一层是安全组/防火墙,只放行必要端口,最好限定来源 IP。第二层是在服务前面加一层网关,做 API Key 鉴权、限流、访问日志。vLLM 本身就支持 API Key 校验,但更完整的方案是再套一层 Nginx 或者 API 网关,把统一鉴权、单请求超时控制、并发限制都放在网关层实现。第三层是留意公网 IP 的架构设计:如果客户端和服务器都在同一个云 VPC 内,优先走内网地址调用,既安全又不产生公网流量费用。不同云厂商之间互通,则要提前规划好专线或公网回源方案,别等到告警了才想起网络链路有问题。
这里多说一句:我见过不少教程教人用各种内网穿透工具把本地服务暴露到公网,这种方案在开发调试时提提效率还行,拿来跑生产业务是在走钢丝。生产环境该买公网 IP 就买,该走负载均衡就走负载均衡,安全性和稳定性这些钱不能省。
4. 生产级部署全流程:从零到可对外服务的实操记录
纸上谈兵聊完了,现在走一遍完整的生产部署流程。我以一台 4×H800(80GB)的云主机为例,部署一个 72B 参数的模型,用 vLLM 做推理引擎,把这套流程一步步拆开。
4.1 环境初始化:驱动、容器运行时与依赖
拿到裸机后第一步不是装 Python,而是确认 GPU 驱动和容器运行时。命令如下:
nvidia-smi # 查看 GPU 是否被识别、驱动版本 nvcc --version # 查看 CUDA 版本(非必须,容器内独立)如果是刚买的高端卡,系统自带的驱动版本可能偏旧,建议先安装对应型号的最新驱动。然后安装 NVIDIA Container Toolkit,否则 Docker 容器里根本看不到 GPU:
distribution=$(. /etc/os-release; echo $ID$VERSION_ID) curl -s -L https://nvidia.github.io/libnvidia-container/gpgkey | sudo apt-key add - curl -s -L https://nvidia.github.io/libnvidia-container/$distribution/libnvidia-container.list | sudo tee /etc/apt/sources.list.d/libnvidia-container.list sudo apt-get update && sudo apt-get install -y nvidia-container-toolkit sudo nvidia-ctk runtime configure --runtime=docker sudo systemctl restart docker这套装完,跑一个docker run --gpus all nvidia/cuda:12.4-base nvidia-smi看到 GPU 信息,环境就算通了。我之前踩过一个坑:容器内显示 GPU 正常,但 nvidia-smi 的进程列表里看不到容器内的进程,原因是 NVIDIA_DRIVER_CAPABILITIES 没设置完整,需要在运行时加-e NVIDIA_DRIVER_CAPABILITIES=compute,utility解决。
4.2 模型权重获取与目录规划
模型权重的获取渠道,国内首选 ModelScope,下载速度快且不需要特殊网络条件。我通常这样规划目录:
/data/models/qwen2.5-72b-instruct/ ├── config.json ├── model-00001-of-00041.safetensors ├── ... └── tokenizer.json权重直接用 safetensors 格式,不用 pickle 格式,一方面是安全(防止恶意代码注入),另一方面是加载速度更快。下载完成后重点确认 config.json 里的关键字段:max_position_embeddings决定你 max-model-len 的上限,num_hidden_layers、num_attention_heads、head_dim这些决定 KV Cache 估算,rope_scaling决定超长上下文的旋转位置编码设置,部署前必须逐一核对。
4.3 以 vLLM 为例的启动配置解析
72B 模型在 4 张 H800 上做张量并行,启动命令是:
docker run --runtime nvidia --gpus all \ -v /data/models:/models \ -p 8000:8000 \ --ipc=host \ --name vllm-qwen72b \ vllm/vllm-openai:latest \ --model /models/qwen2.5-72b-instruct \ --tensor-parallel-size 4 \ --gpu-memory-utilization 0.93 \ --max-model-len 65536 \ --served-model-name qwen72b \ --trust-remote-code \ --enforce-eager说几个关键参数的含义。--tensor-parallel-size 4表示把模型切到 4 张卡并行,72B 权重约 140GB,平均每张卡 35GB,加上 KV Cache 和激活值,80GB 的卡完全够用。--gpu-memory-utilization 0.93告诉 vLLM 可以占用单卡 93% 的显存,剩下 7% 留给 CUDA context 和其他开销,这个值别拉满,否则有概率显存溢出。--max-model-len 65536要结合显卡余量算,KV Cache 如果不够,vLLM 会启动时就报错,而不是等请求进来才爆。
--enforce-eager这个参数要注意:它强制不使用 CUDA Graph,启动变快但性能略降。调试期可以先开着,性能测试过了再关掉上正式配置。--trust-remote-code只在模型代码确实需要时才加,有些小众模型的 custom code 本身有安全风险,得看好来源。
4.4 服务验证与基础压测
服务起来后,先用 curl 验证接口:
curl http://localhost:8000/v1/models curl http://localhost:8000/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{"model":"qwen72b","messages":[{"role":"user","content":"你好,请简单介绍一下自己"}]}'能正常返回,说明基础链路通了。但我建议别急着接业务,先做一轮压测。压测工具不一定要上复杂的 Load Testing 平台,vLLM 自带的 benchmark 脚本就够用:
python benchmark/benchmark_serving.py \ --model qwen72b \ --tokenizer /models/qwen2.5-72b-instruct/ \ --endpoint /v1/completions \ --num-prompts 1000 \ --request-rate 20关键看三个指标:首 token 延迟(TTFT)、吞吐(tokens/s)、TPOT(每个输出 token 的时间)。如果压测时出现超时或显存错误,优先调--max-model-len和--gpu-memory-utilization,这俩是部署参数里最影响稳定性的两个旋钮。
4.5 GPU 监控与日志体系
生产环境没有监控就等于盲飞。GPU 层面的监控我推荐 dcgm-exporter 配合 Prometheus + Grafana,一套标准组合。dcgm-exporter 直接暴露 GPU 利用率、显存使用、温度、功耗、SM 时钟等指标,Grafana 里导入现成的 NVIDIA DCGM 面板就能用。
应用层的监控也别落下:vLLM 本身暴露了一些 Prometheus 指标,包括生成 token 数、请求队列长度、cache 命中率,这些指标能帮你判断什么时候该扩容。日志方面,至少做好三类:access log(谁调了什么接口)、error log(服务异常堆栈)、system log(容器和宿主机层面的问题)。日志的保留和轮转要在部署脚本里提前配好,不要等日志把磁盘撑满了才想起来处理。
5. 常见问题与排查技巧实录
这部分是实打实的踩坑汇总。我把过去两年被问得最多、自己也折过跟头的问题整理成了一个速查表,并附上排查思路。
5.1 显存溢出与并发抖动
现象:启动时一切正常,请求并发一上来就报 CUDA out of memory。
排查思路:先看是不是模型权重加 KV Cache 的估算出了问题。vLLM 启动日志里会打印显存分配情况,重点看 "Maximum concurrency for 65536 tokens" 这个信息,它会告诉你当前配置下最多能支持多少并发。如果并发数太低,说明--max-model-len设置过长,吃掉大量 KV Cache 空间,需要缩短上下文长度或降低--gpu-memory-utilization的预留。
还有一个常见原因:--max-num-seqs设置过大。这个参数控制一次最多同时处理的序列数,如果单卡显存本来就不宽裕,尝试把它从默认值调小到 16 或 8,能明显降低显存峰值的压力。
5.2 首 token 延迟高、吞吐上不去
现象:总延迟还行,但首 token 迟迟不吐,或者吞吐和网上测的数字差一大截。
排查思路:首 token 延迟高,优先检查是不是没有开 prefix caching。多轮对话场景里如果每次请求都重新计算公共前缀,TTFT 会高得离谱,开--enable-prefix-caching立竿见影。吞吐上不去,先看 GPU 利用率是不是拉满了。如果一堆请求进来但 GPU 只有 30% 利用,多半是--max-num-seqs太小,模型在等 batch 填满的过程中空转。
另外检查--enforce-eager是否还开着,这个参数禁用 CUDA Graph 后吞吐损失明显,性能调优阶段要关掉。
5.3 Docker 里看不到 GPU 的经典坑
现象:宿主机 nvidia-smi 正常,容器里执行 nvidia-smi 报错,或者程序直接检测不到 CUDA 设备。
排查思路:90% 是 nvidia-container-toolkit 没装或没配置好。装完后必须执行sudo nvidia-ctk runtime configure --runtime=docker并重启 Docker。还有一类问题是 Docker 版本太老,不支持--gpus参数,这种情况要么升级 Docker,要么改用旧的--runtime=nvidia方式。
如果容器里能看到 GPU 但报 CUDA 驱动版本错,一般是宿主机驱动版本太老,和容器内 CUDA 版本不匹配,把宿主机驱动升到支撑该 CUDA 版本的最低要求即可。
5.4 多卡并行与权重加载的 IO 瓶颈
现象:4 卡张量并行启动时,单卡显存占用不均匀,或者启动时间异常漫长。
排查思路:显存不均匀先看权重切分是否生效。vLLM 在--tensor-parallel-size 4下理论上每卡显存占用应该基本均衡,如果差异大,检查是否有别的进程占用了某张卡。启动时间漫长的原因通常是权重从机械硬盘或网络存储加载,瓶颈在 IO。70B 模型动辄 130GB+ 权重,机械硬盘顺序读顶多 200MB/s,光加载就要十几分钟。
解决方法是把权重放到 NVMe SSD 或者内存缓存层,网络存储的话确认带宽够。另一个提升技巧是开启--load-format sharded_state,按分片加载可以并行读多个文件,速度提升明显。模型结构越复杂,这个 IO 优化带来的收益越大。
| 问题现象 | 大概率原因 | 快速处理 |
|---|---|---|
| 显存溢出 | KV Cache 预留不足 | 调小 max-model-len 或 max-num-seqs |
| 首 token 延迟高 | 未开启 prefix caching | 启动参数加 --enable-prefix-caching |
| 吞吐偏低 | CUDA Graph 被禁用 | 去掉 --enforce-eager |
| Docker 无 GPU | nvidia-container-toolkit 未配置 | 执行 nvidia-ctk runtime configure |
| 启动超慢 | 权重加载 IO 瓶颈 | 权重放 NVMe/共享高速存储 |
最后再分享一个我自己的习惯吧。每次部署完一个新的模型服务,我不会急着庆祝,而是先做一轮"破坏性测试":故意把并发拉到预估峰值的 3 倍,把上下文长度拉到接近上限,看服务会不会崩、监控告警能不能及时触发。这套测试做过之后,心里才算真正有底。大模型服务部署的坑是踩不完的,但每踩一次,把这些经验固化到部署脚本和检查清单里,下一次就会省下大量时间。希望你读完这篇之后,能少走一些我走过的弯路。