前 15 篇我们走过了认知 → 训练 → 推理优化的完整路径。从这一篇开始我们进入整个系列的重头戏——部署服务化篇第 16-20 篇。为什么这是重头戏回到系列规划的初衷——这个专栏叫「大模型系列」定位是后端工程师视角的 AI 工程化**。前面 15 篇打基础从这一篇开始才是真正干活的内容拿到一个模型权重怎么把它变成稳定可用的 API 服务单卡跑不下大模型怎么办要几张卡怎么上 Docker / Kubernetes 怎么做监控、告警、滚动升级长尾延迟怎么治OOM 怎么排查这一篇我们就从最具代表性的推理框架——vLLM——开始。读完之后你应该能从零部署一个生产级的大模型 API 服务。如果你做过相关工作下面这些问题应该不陌生装了 vLLM 但启动报错为什么不同 GPU 配置要不同启动参数TP4 和 PP2 应该选哪个怎么混合vLLM 跑着跑着 OOM 了是哪里设置错了想多副本部署前面要不要加 nginx还是用 K8s怎么平滑升级模型权重老连接怎么处理读完本文你将能用 vLLM 部署单卡 多卡的生产级推理服务写出完整的 Dockerfile 和 Kubernetes YAML配置监控Prometheus Grafana和告警设计高可用架构多副本、滚动升级、健康检查排查最常见的 5 类 vLLM 部署问题我们开始。一、vLLM 为什么是首选1.1 推理框架四强回顾第 1 篇我们做过的对比框架来源特点当下地位vLLMUC Berkeley易用、社区活跃通用首选⭐SGLangLMSYSAgent / 结构化输出强增长最快TensorRT-LLMNVIDIA极致性能生产追求极限TGIHuggingFaceHF 生态融合HF 用户lmdeployOpenMMLab国产、轻量中文场景为什么本系列重点讲 vLLM生态最广HuggingFace 模型几乎全支持OpenAI 兼容 API客户端无缝迁移社区活跃每周都有新特性文档完善踩坑成本最低生产就绪大量公司在用1.2 vLLM 当下能力清单2026.05vLLM已经把第 11-15 篇讲的所有优化集成了✅ PagedAttention Continuous Batching核心✅ Flash Attention v2 / v3✅ Tensor Parallel Pipeline Parallel Context Parallel✅ AWQ / GPTQ / FP8 / INT8 量化✅ Prefix Caching Chunked Prefill✅ EAGLE / Medusa 投机解码✅ YaRN 长上下文✅ Multi-LoRA 热加载✅ OpenAI 兼容 API✅ Prometheus metrics✅ 流式输出SSE意思是第 11-15 篇讲过的所有优化vLLM 默认就帮你做了或者一个参数就能开启。二、从零起步单卡部署2.1 环境准备2.1.1 硬件要求模型规模推荐显卡7B (FP16)A10 24GB / 4090 24GB7B (INT4)任何 12GB GPU14B (FP16)A100 40GB / L40 48GB32B (INT4)A100 40GB / 4090 24GB紧张70B (INT4)A100 80GB / H100 80GB70B (FP16)2 × H100 80GB2.1.2 软件要求# CUDA 12.xPython 3.10 # 推荐用 conda 环境 conda create -n vllm python3.10 conda activate vllm # 安装 vLLM pip install vllm0.6.4 # 验证安装 python -c import vllm; print(vllm.__version__)2.2 最简启动最快上手的命令vllm serve Qwen/Qwen3-7B-Instruct就这一句话——vLLM 会自动从 HuggingFace 下载模型启动 OpenAI 兼容 API默认端口 8000启用所有默认优化PagedAttention、Continuous Batching 等测试curl http://localhost:8000/v1/chat/completions \ -H Content-Type: application/json \ -d { model: Qwen/Qwen3-7B-Instruct, messages: [{role: user, content: 你好}] }输出{ id:chat-xxx, object:chat.completion, choices:[{ message:{role:assistant,content:你好有什么可以帮您的吗}, ... }] }完全 OpenAI 兼容——前端的 OpenAI SDK 客户端代码不用改一行就能切换过来。2.3 用 Python SDK 调用from openai import OpenAI client OpenAI( base_urlhttp://localhost:8000/v1, api_keydummy # vLLM 默认不验证 ) response client.chat.completions.create( modelQwen/Qwen3-7B-Instruct, messages[{role: user, content: 解释一下 KV Cache}], streamTrue, # 流式输出 ) for chunk in response: print(chunk.choices[0].delta.content or , end, flushTrue)三、生产级配置所有最优参数最简启动只是 demo。生产部署要把所有优化开关打开。3.1 完整生产级启动命令vllm serve Qwen/Qwen3-32B-Instruct \ \ # 模型相关 \ --model Qwen/Qwen3-32B-Instruct \ --served-model-name qwen3-32b \ --tokenizer Qwen/Qwen3-32B-Instruct \ --trust-remote-code \ --dtype bfloat16 \ \ # 上下文与精度 \ --max-model-len 32768 \ --quantization fp8 \ --kv-cache-dtype fp8 \ \ # 并行配置单机 4 卡 \ --tensor-parallel-size 4 \ --pipeline-parallel-size 1 \ \ # 推理优化 \ --enable-prefix-caching \ --enable-chunked-prefill \ --max-num-batched-tokens 16384 \ --max-num-seqs 256 \ \ # 显存管理 \ --gpu-memory-utilization 0.92 \ --swap-space 16 \ \ # 服务相关 \ --host 0.0.0.0 \ --port 8000 \ --api-key sk-your-secret-key \ --uvicorn-log-level info \ \ # 监控 \ --disable-log-requests3.2 关键参数详解参数含义推荐值--served-model-nameAPI 返回的 model 字段短名如qwen3-32b--dtype计算精度bfloat16A100/H100/float16V100--max-model-len最大上下文长度看模型能力 显存--quantization模型权重量化fp8/awq/gptq--kv-cache-dtypeKV Cache 精度fp8/int8--tensor-parallel-sizeTP 数通常 GPU 数单机--pipeline-parallel-sizePP 数通常 1多机才用--enable-prefix-cachingKV Cache 复用生产强烈推荐--enable-chunked-prefill分块 prefill生产推荐--max-num-batched-tokens单次 batch 总 token长上下文场景 8192-16384--max-num-seqs并发上限看显存--gpu-memory-utilization显存上限比例0.85-0.95--swap-spaceCPU swap16GB--api-key鉴权 key必须设置3.3 调优 Checklist部署后必须验证的指标# 1. 服务健康 curl http://localhost:8000/health # 应返回 200 OK # 2. 模型列表 curl http://localhost:8000/v1/models -H Authorization: Bearer sk-xxx # 3. 实际推理 curl http://localhost:8000/v1/chat/completions \ -H Content-Type: application/json \ -H Authorization: Bearer sk-xxx \ -d {model:qwen3-32b,messages:[{role:user,content:hi}]} # 4. Metrics curl http://localhost:8000/metrics四、多卡部署TP / PP / 数据并行模型一大单卡装不下。这时候要上多卡。4.1 三种并行策略选择并行方式切分目标适用场景通信开销Tensor Parallel (TP)单层算子单机多卡高要 NVLinkPipeline Parallel (PP)模型层多机部署中跨机Data Parallel (DP)不同请求高并发低独立核心规则TP 用于装下模型DP 用于扩大并发PP 用于跨机部署。4.2 单机多卡纯 TP最常见8 卡 H100 部署 Llama-3-70Bvllm serve meta-llama/Llama-3-70B-Instruct \ --tensor-parallel-size 8 \ --dtype bfloat16 \ --max-model-len 32768 \ --enable-prefix-caching \ --enable-chunked-prefill \ --gpu-memory-utilization 0.92 \ --port 8000TP 的注意事项TP 数必须是模型num_attention_heads的因子如 64 → TP 可以是 1/2/4/8/16TP 通常 ≤ 一个节点的 GPU 数跨机 TP 通信开销大单机 8 卡 H100 用 TP8 是常见配置4.3 多机多卡TP PP跨 2 台机器 × 8 卡 16 卡# Master 节点 vllm serve meta-llama/Llama-3-405B-Instruct \ --tensor-parallel-size 8 \ --pipeline-parallel-size 2 \ --distributed-executor-backend ray \ --num-nodes 2 \ --node-rank 0 \ ... # Worker 节点 ray start --addressmaster_ip:6379 # 然后等 master 调度实战提示单机优先 TP跨机才用 PP跨机互联要 100Gbps InfiniBand用 Ray 作为分布式执行器4.4 多副本DP业务层如果想提高吞吐 / 高可用部署多个独立 vLLM 副本前面加负载均衡┌─ vLLM 副本 1 (GPU 0-3) nginx / nginx-LB ─┼─ vLLM 副本 2 (GPU 4-7) └─ vLLM 副本 3 (其他机器)nginx 配置示例upstream vllm_backend { least_conn; server vllm-1:8000 max_fails3 fail_timeout30s; server vllm-2:8000 max_fails3 fail_timeout30s; server vllm-3:8000 max_fails3 fail_timeout30s; } server { listen80; location / { proxy_pass http://vllm_backend; proxy_http_version1.1; proxy_set_header Connection ; proxy_bufferingoff; # 重要流式输出需要 proxy_read_timeout600s; } }关键参数least_conn选连接最少的副本不要用默认 round_robinproxy_buffering off流式输出必须关闭缓冲proxy_read_timeout 600s长输出场景要够长五、Docker / Kubernetes 部署5.1 Dockerfile# 基于 NVIDIA 官方 CUDA 镜像 FROM nvidia/cuda:12.4.1-cudnn-runtime-ubuntu22.04 # 安装 Python 和系统依赖 RUN apt-get update apt-get install -y \ python3.10 python3-pip git curl \ rm -rf /var/lib/apt/lists/* # 安装 vLLM RUN pip install --no-cache-dir vllm0.6.4 # 设置工作目录 WORKDIR /app # 模型缓存目录用 volume 挂载 ENV HF_HOME/models VOLUME [/models] # 暴露端口 EXPOSE8000 # 健康检查 HEALTHCHECK --interval30s --timeout10s --retries3 \ CMD curl -f http://localhost:8000/health || exit 1 # 启动命令通过环境变量传入 CMD [sh, -c, vllm serve $MODEL_NAME --host 0.0.0.0 --port 8000 $EXTRA_ARGS]Build Rundocker build -t my-vllm:0.6.4 . # 启动单卡 docker run -d --name vllm \ --gpus all \ -p 8000:8000 \ -v /data/models:/models \ -e MODEL_NAMEQwen/Qwen3-7B-Instruct \ -e EXTRA_ARGS--enable-prefix-caching --gpu-memory-utilization 0.9 \ --shm-size 8g \ my-vllm:0.6.4⚠️关键点--gpus all必须否则容器看不到 GPU--shm-size 8g必须PyTorch 多进程通信需要模型 volume 挂载避免每次启动重新下载5.2 docker-compose.yml开发环境version: 3.8 services: vllm: image:my-vllm:0.6.4 container_name:vllm-qwen3 runtime:nvidia environment: -MODEL_NAMEQwen/Qwen3-32B-Instruct -EXTRA_ARGS--tensor-parallel-size4--quantizationfp8--max-model-len32768 -HF_TOKEN${HF_TOKEN} deploy: resources: reservations: devices: -driver:nvidia count:4 capabilities: [gpu] ports: -8000:8000 volumes: -/data/models:/models shm_size:16g healthcheck: test: [CMD, curl, -f, http://localhost:8000/health] interval:30s timeout:10s retries:3 restart: unless-stopped5.3 Kubernetes 部署DeploymentapiVersion: apps/v1 kind:Deployment metadata: name:vllm-qwen3 namespace:ai spec: replicas:3 # 3 个副本 selector: matchLabels: app:vllm-qwen3 template: metadata: labels: app:vllm-qwen3 spec: containers: -name:vllm image:my-vllm:0.6.4 env: -name:MODEL_NAME value:Qwen/Qwen3-32B-Instruct -name:EXTRA_ARGS value:--tensor-parallel-size 4 --quantization fp8 --max-model-len 32768 --enable-prefix-caching resources: limits: nvidia.com/gpu:4 # 每个 Pod 4 张 GPU memory:128Gi requests: nvidia.com/gpu:4 memory:96Gi ports: -containerPort:8000 volumeMounts: -name:models mountPath:/models -name:dshm mountPath:/dev/shm livenessProbe: httpGet: path:/health port:8000 initialDelaySeconds:300 # 模型加载慢给足时间 periodSeconds:30 failureThreshold:3 readinessProbe: httpGet: path:/health port:8000 initialDelaySeconds:180 periodSeconds:10 volumes: -name:models persistentVolumeClaim: claimName:model-pvc -name:dshm emptyDir: medium:Memory sizeLimit:16Gi nodeSelector: gpu-type: h100Service IngressapiVersion: v1 kind:Service metadata: name:vllm-qwen3 namespace:ai spec: selector: app:vllm-qwen3 ports: -port:80 targetPort:8000 sessionAffinity:ClientIP # ⚠ Prefix Caching 场景建议会话粘性 --- apiVersion:networking.k8s.io/v1 kind:Ingress metadata: name:vllm-qwen3 namespace:ai annotations: nginx.ingress.kubernetes.io/proxy-buffering:off nginx.ingress.kubernetes.io/proxy-read-timeout:600 spec: rules: -host:llm-api.internal http: paths: -path:/ pathType:Prefix backend: service: name:vllm-qwen3 port: number: 80滚动升级策略spec: strategy: type: RollingUpdate rollingUpdate: maxUnavailable: 0 # 不允许同时下线 maxSurge: 1 # 只能多创建 1 个滚动升级的关键考虑模型加载慢70B 加载需 3-5 分钟不能太激进maxUnavailable: 0保证总有可用副本配合健康检查确保新副本完全就绪后才下旧的六、监控、告警、日志6.1 Prometheus 监控vLLM 内置 Prometheus metrics 端点curl http://localhost:8000/metrics核心 metricsMetric含义告警阈值vllm:time_to_first_token_seconds_histogramTTFTp99 2svllm:time_per_output_token_seconds_histogramTPOTp99 100msvllm:request_success_total成功请求-vllm:num_requests_running运行中请求-vllm:num_requests_waiting等待中请求 max_num_seqs × 80%vllm:gpu_cache_usage_percKV Cache 使用率 95%vllm:e2e_request_latency_seconds_histogram端到端延迟p99 30sPrometheus 配置scrape_configs: - job_name: vllm static_configs: - targets: [vllm-1:8000, vllm-2:8000, vllm-3:8000] metrics_path: /metrics scrape_interval: 15s6.2 Grafana 面板推荐核心面板请求量每秒成功 / 失败 / 排队请求延迟分布TTFT / TPOT / E2Ep50/p90/p99GPU 利用率与 vLLM 中的请求并发关联KV Cache使用率随时间变化错误率5xx 错误 / OOM6.3 告警规则groups: -name:vllm rules: # TTFT 过高 -alert:HighTTFT expr:histogram_quantile(0.99,rate(vllm:time_to_first_token_seconds_histogram_bucket[5m]))2 for:5m annotations: summary:TTFT p99 2s # KV Cache 接近满 -alert:KVCacheFull expr:vllm:gpu_cache_usage_perc0.95 for:2m annotations: summary:KV Cache 使用率 95% # 排队请求堆积 -alert:HighQueueDepth expr:vllm:num_requests_waiting50 for:3m annotations: summary:排队请求 50 # 服务 down -alert:VLLMDown expr:up{jobvllm}0 for:1m annotations: summary: vLLM 副本下线6.4 日志聚合vLLM 的日志输出到 stdout。在 K8s 中kubectl logs -f deployment/vllm-qwen3 -n ai生产建议接到ELK / Loki# Pod 注解 annotations: fluentd.io/include: true fluentd.io/parser: json七、常见问题排查7.1 OOM最常见症状启动时报CUDA out of memory。排查# 启动时打印显存使用情况 vllm serve ... --enforce-eager # 关闭 cuda graph更易看到真实占用对策按优先级降低--gpu-memory-utilization到 0.85降低--max-num-seqs启用--kv-cache-dtype fp8或int8启用--quantization fp8或awq降低--max-model-len增加 TP7.2 TTFT 飙升症状偶尔 TTFT 从 200ms 跳到 5s。原因长 prompt 阻塞了短请求。对策--enable-chunked-prefill \ --max-num-batched-tokens 81927.3 服务卡死症状请求一直 pending但 GPU 利用率低。可能原因死锁早期 vLLM bug升级版本网络问题kubelet 重启显存碎片少见重启服务应急方案配合 K8s liveness probe 自动重启。7.4 流式输出中断症状客户端流式输出中途断开。原因通常是 nginx / ingress 的 buffering 或 timeout。对策proxy_buffering off; proxy_read_timeout 600s; proxy_send_timeout 600s;7.5 模型加载慢症状每次启动 70B 模型要 5-10 分钟。对策模型存放在本地 SSD不要用 NFS启用--load-format autovLLM 会选最快的格式用safetensors格式比.bin快 2-3×K8s 中给 livenessProbe 设initialDelaySeconds: 300八、扩展话题与下一篇预告8.1 vLLM 的豪华套餐把前 15 篇所有优化打包到一个 vLLM 启动命令vllm serve Qwen/Qwen3-32B-Instruct \ --tensor-parallel-size 4 \ --max-model-len 131072 \ \ # 量化优化第 12 篇 \ --quantization fp8 \ --kv-cache-dtype fp8 \ \ # Flash Attention第 13 篇 \ # 默认已启用 v3 (H100) \ \ # 投机解码第 14 篇 \ --speculative-model yuhuili/EAGLE-LLaMA3-8B \ --num-speculative-tokens 5 \ \ # 长上下文第 15 篇 \ --rope-scaling {type:yarn,factor:4.0} \ \ # 推理三板斧第 11 篇 \ --enable-prefix-caching \ --enable-chunked-prefill \ \ --gpu-memory-utilization 0.92 \ --max-num-seqs 256 \ --port 8000这就是 2026 年 vLLM 的生产 SOTA 配置。8.2 不推荐 vLLM 的场景虽然 vLLM 强但有些场景不太合适需要复杂控制流 / JSON 严格输出→ SGLang追求极致单卡性能→ TensorRT-LLM嵌入式 / 端侧→ llama.cpp / Ollama轻量本地开发→ OllamaHF 生态深度绑定→ TGI下一篇我们会做完整的横向对比。8.3 下一篇预告第 17 篇推理框架横评 - vLLM / TGI / TensorRT-LLM / SGLang—— 同样的硬件、同样的模型4 个主流推理框架的性能、易用性、生态对比。看完这一篇你会知道每种场景选哪个框架。之后是本地化部署18 篇、OpenAI 兼容 API 设计19 篇、分布式推理20 篇。九、结语vLLM 是大模型部署的「事实标准」读完本文你应该明白vLLM 是大多数场景的首选——生态、易用性、性能三优单卡部署 → 多卡 TP → 多机 TPPP → 多副本 DP按业务规模选配生产部署的关键是「全套优化 完整监控 高可用」Docker / K8s 部署有特殊注意事项shm_size、健康检查、滚动升级5 类常见问题OOM、TTFT 飙升、卡死、流式中断、加载慢都有套路化排查参考文献16.vLLM 部署实战从单卡到多卡的高性能推理服务