1. vLLM与K8s基础:vLLM是什么、为什么选择K8s部署、vLLM在K8s中的典型架构
大家好,我是你们的老朋友。今天咱们正式开讲《vLLM显存溢出K8s报错解决实战》的第一章。说实话,这个系列我准备了很久,因为在实际项目中,vLLM和K8s的搭配确实坑不少。尤其是显存溢出(OOM)的问题,我当年第一次遇到时,差点把服务器重启了三遍才找到原因。
好,废话不多说。咱们先打好地基,搞清楚vLLM是什么,为什么非要用K8s来部署它,以及它们在K8s里到底长什么样。
1.1 vLLM是什么?
vLLM,全称是「Virtual Large Language Model」。说白了,它是一个专门为LLM推理加速而生的开源库。你想想看,大模型跑推理时,最头疼的是什么?显存!显存!还是显存!
vLLM的核心技术叫PagedAttention。嗯,这个名字你可能听过。它借鉴了操作系统的虚拟内存分页思想——把KV Cache切成小块,按需分配。这样一来,显存利用率能提升好几倍。
我在项目中遇到过这样一个场景:用HuggingFace的原生推理,一个13B模型要占40GB显存。换成vLLM后,同样的模型只用了18GB。你想想看,这差距有多大?
核心优势总结:
- 高吞吐:连续批处理(Continuous Batching),请求来了不排队,直接塞进当前批次
- 低显存:PagedAttention,KV Cache按需分配,不浪费一丁点
- 易用性:兼容OpenAI API格式,一行代码就能切换
1.2 为什么选择K8s部署?
好,问题来了。vLLM这么好用,为什么非要上K8s?直接在单机上跑不行吗?
行,当然行。但你要考虑几个现实问题:
- 资源弹性:大模型推理的负载波动很大。白天高峰期,可能同时有几百个请求;半夜低谷期,可能就几个人在用。K8s可以自动扩缩容,省成本。
- 故障恢复:我遇到过GPU卡突然掉线的情况。单机部署的话,服务直接挂了。K8s有自愈能力,Pod挂了自动重启,或者调度到其他节点。
- 多模型管理:你可能同时部署了7B、13B、70B好几个模型。K8s的命名空间和标签机制,能帮你把不同模型的服务隔离开。
- GPU共享:K8s支持GPU的MPS(多进程服务)和MIG(多实例GPU),一块A100可以切成多个小GPU,跑多个小模型。
我的个人习惯: 只要模型推理服务需要对外提供API,我第一反应就是上K8s。单机部署只适合开发调试阶段。
1.3 vLLM在K8s中的典型架构
接下来,咱们看看vLLM在K8s里到底是怎么组织的。我画了一张架构图,你一看就明白。
这张图展示了最标准的部署模式。我来拆解一下每一层的作用:
1.3.1 用户层
用户通过HTTP请求访问你的模型API。请求格式兼容OpenAI的Chat Completions接口。说白了,你原来怎么调GPT,现在就怎么调vLLM。
1.3.2 Ingress层
Ingress负责外部流量接入。我建议用Nginx Ingress Controller或者Traefik。它们可以帮你做SSL终止、限流、路径转发。我曾经踩过一个坑——没配Ingress的请求超时时间,结果长文本生成请求被截断了。嗯,后来加了nginx.ingress.kubernetes.io/proxy-read-timeout: "600"才解决。
1.3.3 Service层
Service是K8s内部的负载均衡器。vLLM的Pod可能会动态扩缩容,Service能自动发现新Pod,把请求分发过去。这里要注意,vLLM的API是长连接(SSE流式输出),所以Service的sessionAffinity最好设置为ClientIP,避免请求被转发到不同Pod导致流中断。
1.3.4 Deployment层
Deployment管理Pod的副本数。你可以设置replicas: 3,K8s会保证始终有3个vLLM实例在运行。如果某个Pod挂了,它会自动拉起一个新的。
避坑指南: 我曾经把replicas设得太大,结果集群GPU不够用,Pod一直处于Pending状态。后来我加了resources.limits.nvidia.com/gpu: 1,确保每个Pod只占1块GPU。
1.3.5 Pod内部
每个Pod里跑一个vLLM容器。容器启动命令大概是这样的:
python -m vllm.entrypoints.openai.api_server \
--model /models/llama-13b \
--tensor-parallel-size 1 \
--gpu-memory-utilization 0.9 \
--max-model-len 4096
这里有几个关键参数:
--tensor-parallel-size:如果你的Pod分配了多块GPU,可以设置这个参数做张量并行--gpu-memory-utilization:控制显存利用率。我一般设0.9,留10%给系统和其他进程--max-model-len:最大序列长度。设太大容易OOM,设太小又限制业务
1.4 典型部署场景对比
| 场景 | 推荐架构 | 说明 |
|---|---|---|
| 单模型单GPU | Deployment + Service + Ingress | 最简单,适合7B以下模型 |
| 单模型多GPU | Deployment + StatefulSet + Headless Service | 需要张量并行,Pod间通信用RDMA |
| 多模型混合部署 | 多个Deployment + 统一Ingress + 路由规则 | 用Ingress的路径转发区分模型 |
| 高并发场景 | HPA + Cluster Autoscaler | 根据CPU/GPU利用率自动扩缩容 |
我的建议: 刚开始别搞太复杂。先跑一个Deployment + Service + Ingress的经典组合。等业务稳定了,再考虑HPA和Cluster Autoscaler。步子迈大了容易扯着蛋。
1.5 本章小结
好,咱们把第一章的内容捋一捋:
- vLLM是一个高效的LLM推理引擎,核心是PagedAttention
- K8s部署能解决资源弹性、故障恢复、多模型管理等问题
- 典型架构是:用户 → Ingress → Service → Deployment → Pod (vLLM + GPU)
- Pod启动时要注意显存利用率、模型长度等参数
下一章,咱们会深入分析vLLM在K8s中常见的显存溢出报错。说实话,那才是真正的硬仗。不过别担心,我会把每个坑的解法都掰开揉碎了讲给你听。