1. vLLM与K8s初识:vLLM是什么、为什么需要K8s、vLLM+K8s的典型架构
大家好,我是你们的老朋友,一个在AI运维和K8s圈子里摸爬滚打了好几年的工程师。今天咱们开始聊一个很有意思的话题——vLLM和K8s的结合。
说实话,我第一次接触vLLM的时候,心里想的是:“又一个推理框架?”但用了一段时间后,我发现这东西确实有两把刷子。咱们今天就从最基础的东西开始,把vLLM是什么、为什么需要K8s、以及它们俩怎么搭伙过日子,掰扯清楚。
1.1 vLLM是什么?
vLLM,全称是Virtual Large Language Model,说白了就是一个专门为LLM推理加速而生的框架。它的核心目标就一个:让你用更少的GPU,跑更多的请求。
我个人的理解是,vLLM就像是一个聪明的调度员。它不会傻傻地等一个请求处理完再处理下一个,而是把请求拆成小块,穿插着处理。这个技术叫PagedAttention,是vLLM的杀手锏。
核心要点:vLLM通过PagedAttention技术,实现了高效的KV Cache管理,显存利用率能提升2-4倍。我在项目中遇到过,同样的模型,用vLLM部署后,QPS直接翻了一倍多。
vLLM的几个关键特性,我列一下:
- PagedAttention:把KV Cache分页管理,像操作系统的虚拟内存一样,按需分配
- 连续批处理:请求不用排队等,可以动态插入和退出
- 高性能推理:支持多种量化方式,比如FP16、INT8、INT4
- 兼容OpenAI API:接口和OpenAI一致,迁移成本极低
嗯,这里要注意一点。vLLM虽然快,但它不是万能的。它主要针对的是在线推理场景,也就是那种需要低延迟、高吞吐的服务。如果你做的是离线批量处理,那可能用别的工具更合适。
1.2 为什么需要K8s?
好,vLLM咱们大概了解了。那问题来了:我本地跑得好好的,为啥非要上K8s?
你想想看,一个LLM服务上线后,会遇到什么情况?
- 流量忽高忽低,白天人多,晚上人少
- GPU节点偶尔会挂,需要自动恢复
- 模型版本要更新,不能停服
- 多个模型要共享GPU资源
这些场景,单机部署根本搞不定。K8s就是来解决这些问题的。
我曾经在一个项目里,用裸机部署了三个vLLM服务。结果半夜一台机器宕机了,第二天早上才发现,用户投诉了一堆。后来上了K8s,Pod挂了自动重启,节点挂了自动调度到其他机器上,省心多了。
K8s给vLLM带来的核心价值,我总结为三点:
| 能力 | 说明 | 我的经验 |
|---|---|---|
| 弹性伸缩 | 根据CPU/GPU利用率或请求数,自动扩缩Pod | 我习惯用HPA配合自定义指标,效果比默认的好 |
| 自愈能力 | Pod挂了自动重启,节点挂了自动迁移 | 记得配置好readiness probe,不然流量会打到未就绪的Pod |
| 资源管理 | 精细控制GPU、内存、CPU的分配 | GPU一定要设置requests和limits一致,避免资源争抢 |
避坑指南:我曾经犯过一个错误,没给vLLM的Pod设置GPU的limits,结果两个Pod抢同一块GPU,推理速度直接掉到原来的三分之一。记住,GPU资源一定要显式声明。
1.3 vLLM+K8s的典型架构
好了,两个主角都介绍完了。咱们来看看它们怎么配合。我画了一张架构图,帮你理解整个流程。
这个架构图,说白了就是三层结构:
- 入口层:用户请求先打到Ingress,做负载均衡和域名路由
- 服务层:K8s Service负责把请求分发到后端的vLLM Pod
- 计算层:每个Pod里跑一个vLLM实例,挂载不同的模型
我个人的习惯是,每个Pod只部署一个模型。这样方便做独立的扩缩容和版本管理。比如llama-7b流量大了,我只扩这个Pod,不影响其他模型。
小技巧:如果你有多个模型,建议用不同的Deployment来管理。每个Deployment对应一个模型,配上独立的HPA策略。这样运维起来清晰很多。
1.4 一个简单的部署示例
光说不练假把式。我给大家看一个最基础的vLLM部署YAML,咱们感受一下。
apiVersion: apps/v1
kind: Deployment
metadata:
name: vllm-llama7b
spec:
replicas: 2
selector:
matchLabels:
app: vllm
model: llama7b
template:
metadata:
labels:
app: vllm
model: llama7b
spec:
containers:
- name: vllm
image: vllm/vllm-openai:latest
args: ["--model", "meta-llama/Llama-2-7b-chat-hf"]
ports:
- containerPort: 8000
resources:
requests:
nvidia.com/gpu: 1
memory: "16Gi"
cpu: "4"
limits:
nvidia.com/gpu: 1
memory: "16Gi"
cpu: "4"
env:
- name: CUDA_VISIBLE_DEVICES
value: "0"
这个YAML里,我特别强调两点:
- GPU资源:requests和limits必须一致,避免多个Pod抢GPU
- 模型路径:可以用HuggingFace的模型名,也可以挂载本地路径
嗯,这里要注意。如果你用的是本地模型,记得用PVC或者hostPath把模型文件挂载进去。不然每次Pod重启都要重新下载,那可就慢了。
1.5 本章小结
咱们今天聊了vLLM和K8s的初识。vLLM是个高效的推理框架,K8s是个强大的编排平台。它们俩结合,能解决LLM服务部署中的很多实际问题。
我个人觉得,vLLM+K8s这套组合,是目前LLM在线推理的最佳实践之一。当然,它也有自己的坑,比如GPU调度、显存管理这些,咱们后面会慢慢聊。
好,今天就到这里。记住一句话:vLLM负责快,K8s负责稳。两者结合,才能让LLM服务真正跑起来。