vLLM 是目前本地部署大语言模型最常用的推理框架之一,很多团队在部署 Qwen、DeepSeek、Llama 系列模型时都会优先选它。但有一个非常容易踩、又非常难发现的坑:KV cache 泄漏。更麻烦的是,传统的显存观测工具根本看不到它。Kvcachescope 这个项目,就是专门为解决这个问题出现的。
先给你三个结论:
- nvidia-smi 显示的是驱动视角下进程占用的总显存,它看不到进程内部 KV cache 池的分配、释放和复用情况,所以当 vLLM 出现 KV cache 泄漏时,nvidia-smi 很可能是“盲”的。
- KV cache 泄漏的典型表现不是“某张显卡 OOM”,而是服务吞吐逐步下降、延迟持续拉高,重启后恢复,过一段时间又劣化,极其隐蔽。
- 要定位这类问题,需要深入 vLLM 进程内部拿指标。Kvcachescope 这类工具的价值就在这——它把 KV cache 的分配与释放情况暴露出来,让你能判断当前瓶颈到底是正常的长上下文消耗,还是真的在泄漏。
这篇文章会从原理、使用场景、环境准备、部署流程、功能验证、接口调用、批量任务、资源占用、常见排错等角度完整展开,尽量让你看完能自己跑一遍,并且知道怎么验证结果。
1. 核心能力速览
先给一张总表,快速判断这个项目值不值得看。
| 能力项 | 说明 |
|---|---|
| 项目类型 | KV cache 可视化与泄漏检测工具 |
| 来源 | Show HN 社区项目,具体仓库、维护团队以官方页面为准 |
| 核心功能 | 观察 vLLM 进程内的 KV cache block 分配、释放、缓存命中率,辅助定位显存泄漏 |
| 解决问题 | nvidia-smi 只能看进程级显存占用,无法区分 KV cache 池内部的分配状况 |
| 显存需求 | 观测组件本身占用很低;被观测的 vLLM 实例按模型规模配置 |
| 依赖环境 | Linux + NVIDIA GPU,需要 GPU 驱动、CUDA 环境和 vLLM 推理服务 |
| 启动方式 | 作为 vLLM 的辅助观测组件启动,具体命令需按项目 README 配置 |
| 接口能力 | 通常以 Web 面板或 CLI 方式提供观测入口,具体以项目版本为准 |
| 批量任务 | 可配合 vLLM 批量推理的压测场景做持续观测 |
| 适合场景 | vLLM 长稳运行、批量推理集群、显存优化、缓存命中率调优 |
| 不适合场景 | 单次短时推理、临时测试小模型、无持续显存压力的场景 |
这个项目本身不会替代 vLLM。它的位置是:把 vLLM 推理引擎里“看不见的那部分显存”用可读的方式展示出来。
2. 为什么 nvidia-smi 看不到 vLLM 的 KV cache 泄漏
这是整个问题最核心的地方。
vLLM 为了高性能,并不是“用多少显存就临时申请多少”,而是在加载模型后,根据参数一次性预留一大块显存,专门给 KV cache 使用。这块空间由 vLLM 内部的 PagedAttention 机制管理,按 block 分配、释放和复用。
从操作系统和 NVIDIA 驱动的角度看,显存已经被 vLLM 进程吃掉了。nvidia-smi 汇报的进程显存占用是“这个进程总共拿了多少显存”,而不是“这些显存当前被哪个模块用着、是否真的在用”。
所以会出现这种情况:
- nvidia-smi 看到显存占用一直很稳定,没有涨到接近 OOM;
- 但 vLLM 服务越来越慢,单请求延迟从 200ms 慢慢涨到 700ms;
- 并发稍微一高,大量请求排队;
- 重启 vLLM 进程之后一切恢复,几个小时后再次劣化。
这种劣化,很多并不是“显存总量不足”,而是 KV cache 池内部出现了问题:已经分配出去的 block 没有被正确回收到空闲池,缓存无法命中,导致每次请求都重新计算历史 token 的 KV cache。单位请求的显存消耗增加,有效处理并发量下降,服务变慢。
你用 nvidia-smi 盯一整天的显存曲线,可能都看不出来问题。如果只关注“显存占用率”一个指标,你甚至会觉得服务非常健康。这就是标题里说的“blind”——不是 nvidia-smi 坏了,而是它的观测粒度根本不在 KV cache 这一层。
vLLM 在显存管理和缓存策略上做得很复杂,这本身是设计取舍,不是缺陷。但对使用者来说,如果缺少进程内观测手段,出了缓存泄漏和利用率下降问题,就只能靠盲猜。Kvcachescope 想补上的,正是这一层观测缺口。
3. 适用场景与使用边界
适合用这个工具的场景,大体有三类。
3.1 适合长期运行的 vLLM 服务
部署完一个模型,开了 24 小时在线 API,这种服务最容易积累 KV cache 管理问题。短期重启看不出,跑一天两天后性能逐步劣化。Kvcachescope 可以持续观察 KV cache 相关指标,判断是否有缓慢泄漏。
3.2 批量推理与高并发压测
批量任务场景下,请求类型多样,有的 prompt 很长,有的生成文本很长。KV cache 的分配伸缩很频繁,一旦 block 回收逻辑触发不及时,就会出现问题。批量任务跑得越久,问题越明显。
3.3 显存利用率和吞吐调优
vLLM 的gpu_memory_utilization参数决定了 KV cache 最大可用空间,但模型也不一定用满。KV cache 池的利用率需要实际观测。如果你只想把单卡吞吐压到极限,这个项目的观测粒度是很有用的。
3.4 使用边界与合规提醒
KV cache 观测本身不涉及模型权重修改,也不涉及用户输入内容的修改,但仍然要注意几类问题:
- 如果观测面板需要对外访问,要限制到内网或加鉴权,避免推理服务接口和观测页面暴露在公网。
- 被观测的模型可能是商用模型或有许可证要求的开源模型,不要因为做性能观测就忽略模型本身的授权范围。
- 推理服务里如果包含用户数据,日志和指标不要记录 prompt 原文,避免隐私风险。
4. 环境准备与前置条件
要跑通整个链路,建议按以下清单准备环境。
4.1 硬件与系统
| 项目 | 最低建议 |
|---|---|
| 操作系统 | Linux 优先,Ubuntu 22.04 是常见选择 |
| GPU | NVIDIA GPU,建议显存 8GB 以上 |
| 驱动 | 需要和 CUDA 版本匹配的 NVIDIA 驱动 |
| 磁盘 | 模型文件按规模准备,7B 模型通常需要 15GB 以上空间 |
| 内存 | 建议 32GB 以上,取决于模型大小 |
Windows 环境也能跑 vLLM,但兼容性问题较多。如果你在 Windows 上部署,优先考虑 WSL2 或 Docker Desktop 方案,不要指望原生 Windows 环境能和 Linux 环境完全一样。从热词来看,也有“windows vllm modelscope”这类组合场景,说明还是有不少人尝试在 Windows 上配合 ModelScope 做模型下载和 vLLM 部署,这时候更建议用 Linux 容器统一环境,减少模型路径、显存调用上的差异。
4.2 软件依赖
| 依赖 | 作用 |
|---|---|
| Python | vLLM 和观测工具的运行环境 |
| CUDA Toolkit | 部分版本需要编译 vLLM 算子,不同版本对 CUDA 版本有要求 |
| vLLM | 被观测的推理框架 |
| nvidia-ml-py | Python 环境下读取 nvidia-smi 信息 |
4.3 模型准备
用 vLLM 部署需要先准备 Hugging Face 格式的模型权重。以 Qwen 系列为例,可以提前在 ModelScope 或 Hugging Face 下载权重,也可以让 vLLM 启动时自动拉取。为了部署稳定,更推荐先把权重下载到本地指定目录,再通过--model参数指定路径。这样避免了启动时下载失败、磁盘占满等问题。
4.4 检查端口占用
vLLM 默认的 API 服务端口是 8000,观测工具一般会占用一个独立端口。启动前检查一下:
sudo lsof -i :8000如果有残留进程占用,先终止它,避免服务启动失败。
5. 安装部署与启动方式
本节分两部分:先启动 vLLM 推理服务,再挂载 Kvcachescope 这类观测组件。vLLM 是整个链路的基础,必须确保推理服务健康。
5.1 vLLM 推理服务启动
vLLM 有 Python API 和 Docker 两种常见启动方式。先看 Python 方式。
# 创建虚拟环境(建议独立 venv,避免污染全局环境) python -m venv vllm-env source vllm-env/bin/activate # 安装 vLLM,具体命令以官方文档为准 pip install vllm安装完成后,启动 OpenAI 兼容的 API 服务:
python -m vllm.entrypoints.openai.api_server \ --model /data/models/Qwen/Qwen2.5-7B-Instruct \ --gpu-memory-utilization 0.9 \ --max-model-len 32768 \ --host 127.0.0.1 \ --port 8000说明一下参数:
--model:模型路径或 Hugging Face 模型名。--gpu-memory-utilization:允许 vLLM 使用的显存比例,0.9 表示最多使用单卡显存的 90%。实际值需要根据你的显卡确定。--max-model-len:模型最大上下文长度。设得越大,KV cache 预留空间越多,单请求能占用的显存越多。--host和--port:服务监听地址和端口。
如果走 Docker 路线,命令模板如下:
docker run --rm --gpus all \ -p 8000:8000 \ -v /data/models:/data/models \ vllm/vllm-openai:latest \ --model /data/models/Qwen/Qwen2.5-7B-Instruct \ --gpu-memory-utilization 0.9 \ --max-model-len 32768这里-v把宿主机模型目录挂载进容器,模型路径以容器内路径为准。
5.2 安装并启动 Kvcachescope
Kvcachescope 是辅助观测工具,具体的安装命令需要以项目 README 为准。从项目定位推测,它的启动流程大概率是做三件事:连接 vLLM 实例、读取 KV cache 状态、在某个端口展示结果。
通用启动思路如下:
# 示例:按实际项目 README 调整 git clone https://github.com/Kvcachescope/kvcachescope.git cd kvcachescope pip install -r requirements.txt # 连接到已经在 127.0.0.1:8000 启动的 vLLM 服务 python run.py --vllm-url http://127.0.0.1:8000 --port 8080如果你用的是发行版一键包,一般会提供一个start.sh或者start.bat。我建议第一次不要直接双击,而是先在终端里运行,把输出日志看清楚。终端里如果出现类似 “Connected to vLLM” 的提示,说明连接成功;如果卡在连接超时,优先检查 vLLM 服务是否真的在运行、URL 端口是否写对。
5.3 启动后的验证
启动完成后,可以先做一个最小检查:
curl http://127.0.0.1:8000/health如果输出"OK",说明 vLLM 推理服务可用。然后打开浏览器访问 Kvcachescope 的观测页面,确认页面上能读取到 vLLM 的基本信息。
6. 功能测试与效果验证
光能启动还不够,关键是验证工具真的能看到“nvidia-smi 看不到的问题”。下面给出一套通用验证流程。
6.1 基线记录
先记录一张基准表:
- 用 nvidia-smi 记录当前 GPU 显存占用。
- 用观测工具记录 KV cache 空闲 block 数量、已分配 block 数量、缓存命中率。
- 记录一个固定请求的响应延迟。
这些数据作为“健康状态”的标准。以后任何调优或排错都拿这组数据对比。
nvidia-smi --query-gpu=index,memory.used,memory.total --format=csv6.2 连续请求压力测试
连续向 vLLM 发送同一组请求,观察指标变化。这里推荐用 Python 脚本做持续压力请求:
import json import time import requests url = "http://127.0.0.1:8000/v1/chat/completions" headers = {"Content-Type": "application/json"} payload = { "model": "Qwen/Qwen2.5-7B-Instruct", "messages": [ {"role": "user", "content": "给我写一篇关于城市交通的五百字介绍。"} ], "max_tokens": 512, "temperature": 0.7 } for i in range(50): start = time.time() try: resp = requests.post(url, headers=headers, json=payload, timeout=180) cost = time.time() - start print(f"request={i} status={resp.status_code} cost={cost:.2f}s") except Exception as exc: print(f"request={i} error={exc}") time.sleep(0.5)跑完这 50 个请求后,分别看三个层面的现象:
第一层,进程显存占用。如果 nvidia-smi 显示的占用没有明显变化,说明显存总量层面没出问题。
第二层,KV cache 可用量。如果观测工具显示可用 block 数量持续下降,并且没有回升迹象,就说明有 block 被分配出去但没有正常释放。这是 KV cache 泄漏最直接的信号。
第三层,请求延迟。如果第 1 个请求耗时 300ms,跑到第 40 个请求时耗时到了 800ms,但显存总量、模型参数量都没有变化,就要高度怀疑 KV cache 池复用出现了异常。
6.3 变长上下文测试
KV cache 泄漏与上下文长度关系很大。建议准备三组测试:
- 短 prompt,短生成:验证基础性能。
- 长 prompt,短生成:观察预填充阶段对 KV cache 的占用。
- 短 prompt,长生成:观察解码阶段 KV cache 的持续分配。
三类请求混合发送,更容易暴露缓存回收问题。
6.4 判断成功与失败的标准
判断观测工具有没有“真正起作用”,可以看三个标准:
- 能展示 vLLM 进程内 KV cache block 级别的统计数据,而不是 GPU 总显存曲线。
- 在持续请求压力下,指标有真实变化,能看出分配、释放、命中率的波动。
- 当 KV cache 到达上限时,指标能反映出缓存淘汰或请求排队,而不是等到 OOM 才暴露。
如果观测页面只能显示 nvidia-smi 已有的信息,那就没有解决原来的盲区问题。
6.5 失败排查
柯场景下最容易遇到的失败是“能打开观测页面,但页面没有数据”。这时候依次检查:
- vLLM 服务是否确实运行在指定端口;
- 观测工具和 vLLM 是否在同一台机器,如果不在同一台,网络策略是否放开;
- vLLM 日志里是否有输出 KV cache 相关的统计信息供观测工具抓取;
- 观测工具和 vLLM 版本是否兼容。
7. 接口 API 与批量任务
vLLM 本身提供了 OpenAI 兼容接口,这是最稳定的接入方式。下面的接口功能都基于 vLLM 的标准接口说明,如果你的模型通过 vLLM 启动,这些接口默认可用。
7.1 基础调用示例
curl http://127.0.0.1:8000/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{ "model": "Qwen/Qwen2.5-7B-Instruct", "messages": [ {"role": "user", "content": "用一句话介绍 KV cache 是什么"} ], "max_tokens": 128 }'返回结果中会包含usage字段,这里可以看到prompt_tokens和completion_tokens。这两个值是判断 KV cache 压力的基础数据。
7.2 批量任务设计
批量任务场景里,不适合用“每个请求都建新连接、每次都不复用 KV cache”的方式。更好的模式是:
- 固定一个长上下文作为背景知识;
- 在这个上下文基础上多次追加问题;
- 观察这些请求是否命中了已缓存的 KV cache。
如果命中了,虽然prompt_tokens每次都很大,但实际耗时应该很低。如果耗时一直很高,说明缓存没有生效,每次请求都在重复计算前文 KV cache。
一个简单的批量脚本模板:
import json import time import requests from concurrent.futures import ThreadPoolExecutor url = "http://127.0.0.1:8000/v1/chat/completions" headers = {"Content-Type": "application/json"} def send(prompt, idx): payload = { "model": "Qwen/Qwen2.5-7B-Instruct", "messages": [{"role": "user", "content": prompt}], "max_tokens": 256 } start = time.time() resp = requests.post(url, headers=headers, json=payload, timeout=300) data = resp.json() usage = data.get("usage", {}) print(f"task={idx} cost={time.time()-start:.2f}s " f"prompt_tokens={usage.get('prompt_tokens')} " f"completion_tokens={usage.get('completion_tokens')}") return data prompts = [f"第 {i} 题:请解释城市公共交通系统的优化方向。" for i in range(20)] with ThreadPoolExecutor(max_workers=4) as executor: futures = [executor.submit(send, prompts[i], i) for i in range(len(prompts))] for f in futures: f.result()批量任务的重点是长时间跑、观察趋势,而不是只看单次结果。建议任务结束后,对比观测工具里的 KV cache 状态和任务开始前是否一致。如果可用 block 大幅下降且长时间不恢复,基本可以认定存在泄漏。
7.3 失败重试与日志
批量任务建议加三样东西:
- 每一条请求的耗时和状态码都记录到本地日志;
- 失败的请求单独重试,不要混在正常任务里继续发;
- 任务结束后的快照式观测数据,用来判断是否存在泄漏。
日志文件建议至少包含时间戳、请求 ID、状态码、耗时、返回 token 数。这些数据在做性能对比时非常有用。
8. 资源占用与性能观察
8.1 显存占用怎么观察
在 vLLM 场景下,显存观察不能只看 nvidia-smi。要给出一套组合观察方式:
- nvidia-smi 负责看“进程总显存”和“GPU 总显存”是否达到边界;
- 观测工具(Kvcachescope 所属这类工具)负责看 KV cache 池内部状态;
- vLLM 日志负责看每次请求的 token 数和耗时。
这里提供一个用 Python 读取 nvidia-smi 信息的简单脚本,让显存数据和观测页面时间轴对上:
import time import pynvml pynvml.nvmlInit() handle = pynvml.nvmlDeviceGetHandleByIndex(0) print("time_sec,gpu_mem_used_mib,gpu_mem_total_mib") for i in range(60): meminfo = pynvml.nvmlDeviceGetMemoryInfo(handle) used_mib = meminfo.used / 1024 / 1024 total_mib = meminfo.total / 1024 / 1024 print(f"{i * 5},{used_mib:.1f},{total_mib:.1f}", flush=True) time.sleep(5)这个脚本需要先安装依赖:
pip install nvidia-ml-py把输出结果拿到 Excel 或任何表格工具里画一条曲线,就能看出来 nvidia-smi 视角下显存占用是否一直平缓。如果平缓而服务变慢,问题基本可以锁定在 KV cache 层。
8.2 CPU 推理和 GPU 推理的差异
vLLM 主要面向 GPU 推理。CPU 推理一般用 llama.cpp 或其他专用方案。如果你是在一台没有 NVIDIA GPU 的机器上做验证,可以先跑 CPU 环境的小模型熟悉 vLLM 的 API 流程,但显存和 KV cache 观测的意义会大打折扣。原因很简单:CPU 环境下没有 GPU 显存池,KV cache 分配在普通内存上,nvidia-smi 完全派不上用场。
8.3 关键参数对性能的影响
几个最重要的参数,建议按实际模型调整:
| 参数 | 影响 |
|---|---|
--gpu-memory-utilization | 决定 KV cache 池上限,设太大会挤占模型和计算剩余量,设太小缓存命中率上不去 |
--max-model-len | 决定单请求最长可用 KV cache 空间,越大单请求风险越高,但长上下文适配更好 |
--max-num-seqs | 决定并发序列数,设置过大会增加 KV cache 池的压力 |
--enable-prefix-caching | 开启前缀缓存优化,对批量任务很有帮助,但需要 vLLM 版本支持 |
如果你不确定改哪个参数,优先控制并发数,再调gpu_memory_utilization。这两个参数对 KV cache 池的压力影响最直接。
8.4 如何降低 KV cache 压力
- 缩小
max-model-len,不让请求无限使用长上下文; - 开启前缀缓存或自动前缀缓存机制,减少重复计算;
- 控制并发请求数,避免短时间内大量请求同时创建新的 KV cache block;
- 长任务拆成多个小任务,减少单个序列对缓存池的长期占用。
9. 常见问题与排查方法
下面这张表覆盖 vLLM 部署 + KV cache 观测过程中最常遇到的问题。
| 问题现象 | 可能原因 | 排查方式 | 解决方案 |
|---|---|---|---|
| 观测页面打不开 | 观测工具端口未启动或端口被占用 | 查看工具启动日志,确认监听端口 | 换端口或重启观测服务 |
| 观测页面打开但没有数据 | 连不上 vLLM 实例或版本不兼容 | 从观测工具配置项检查 vLLM URL | 核对 URL、检查网络策略、升级或降级 vLLM |
nvidia-smi has failed because it couldn't communicate with the nvidia driver | 显卡驱动异常、驱动与 CUDA 版本不匹配、容器没有挂载驱动 | 先执行nvidia-smi看报错,检查驱动状态,查看内核模块日志 | 重装匹配版本的驱动,容器内要挂载/usr/bin/nvidia-smi和/proc/driver/nvidia |
| nvidia-smi 显示显存很高但服务性能反而一般 | 显存被预留但 KV cache 利用率低,模型并发吞吐受限 | 看观测工具的 KV cache 利用率指标 | 调低gpu_memory_utilization,或增大max-num-seqs逻辑,按实际观察结果调整 |
| 服务刚启动快,跑几小时后越来越慢 | 疑似 KV cache 泄漏或缓存命中率下降 | 对比启动初期和当前的 KV cache 可用 block 和请求延迟 | 开启前缀缓存、控制并发、必要时重启服务恢复健康状态 |
| 大批量任务跑到一半开始大量超时 | 请求并发超过 KV cache 池或带宽上限,也可能是磁盘或日志阻塞 | 看观测工具的 block 分配曲线和 vLLM 日志 | 降低并发数,增加失败重试,给批量任务加队列 |
| 启动 vLLM 时显存不足 OOM | gpu-memory-utilization设置过高,或模型权重本身占用超过显卡显存 | 查看显卡剩余显存,确认模型权重大小 | 调低gpu-memory-utilization,换更大显存的卡,或使用量化模型 |
| 观测指标没有 KV cache 相关的值 | vLLM 版本不支持对应指标,或没有开启相关启动参数 | 打开 vLLM 的 metrics 端口,检查指标名 | 升级 vLLM,更新观测工具,或按项目要求的 vLLM 版本对齐 |
| 缓存命中率很低,每次请求都慢 | 前缀缓存未开启,或请求前缀不一致 | 检查请求前缀是否相同,查看缓存命中指标 | 开启前缀缓存,批量任务尽量复用相同前缀 |
遇到nvidia-smi报错时,第一反应不要觉得是工具坏了。这个报错在实际部署中出现频率很高,核心问题是驱动和 CUDA 环境不匹配。先执行nvidia-smi确认裸机驱动没问题,再进 Python 环境执行import torch; print(torch.cuda.is_available())确认 PyTorch 能看到 GPU,最后再启动 vLLM。这样能把问题快速分层。
10. 最佳实践与使用建议
10.1 第一次先小参数测试
不要一上来就开gpu_memory_utilization=0.98加超大 max-model-len。第一次测试用一个小模型、限制并发、限制 max-tokens,把所有流程跑通,确认观测面板能正常看到数据,再做压力测试。
10.2 保留一套最小可运行配置
把能稳定运行 vLLM + 观测工具的命令写到脚本里,包括 Python 虚拟环境、模型路径、端口、观测工具连接地址。遇到环境被破坏时可以快速恢复。
10.3 模型和输出分目录管理
建议用以下目录结构:
/data/ models/ # 模型权重 inputs/ # 测试输入 outputs/ # 推理输出 logs/ # vLLM 日志和观测数据这样模型目录、测试素材、运行日志互不干扰,重装环境时只需要备份 logs 和 inputs。
10.4 批量任务要加日志和失败重试
批量任务不要裸跑,至少加日志和重试。耗时数据要能和观测面板的 KV cache 数据对齐,这样才能定位是哪一类请求触发了缓存压力。
10.5 接口服务要限制访问范围
vLLM 的服务端口如果暴露到公网,很容易被刷流量。建议:
- vLLM 服务只监听内网地址;
- 对外开放走 API 网关加鉴权;
- 观测工具的 Web 页面更敏感,不要暴露到公网。
10.6 涉及模型权重和数据合规
使用模型前确认模型许可协议。如果推理服务涉及业务数据,观测工具内部尽量不要记录用户输入原文,只记录 token 数、耗时、命中率这类结构化指标。
10.7 上线前做稳定性预演
社区或公司内部如果要上线 vLLM 服务,建议上线前用批量任务连续压测 3 到 6 个小时,观察:
- 显存占用长时间是否稳定;
- KV cache 可用量是否出现持续下降;
- 高延迟请求占比是否逐步上升。
如果三项里有两项异常,不要急着上线,先调参数或换版本。
11. 总结与下一步
这个项目最值得尝试的点,就是它补上了 vLLM 在 KV cache 层面的观测盲区。nvidia-smi 看显存总量,Kvcachescope 看显存内部的 KV cache 状态。前者回答“显存够不够”,后者回答“KV cache 池是不是真的在高效工作”。
建议你拿到项目后,先做以下三个动作:
第一,部署一个小模型 vLLM 服务并确认 API 可用。这一步过不去,后面所有观测都无从谈起。
第二,连接 Kvcachescope,确保面板有数据。先不发压力请求,就看空闲状态的 KV cache 分配情况。
第三,连续发一批长上下文请求,观察 KV cache 可用量和请求延迟的变化。这是最快复现泄漏问题的路径。
最容易踩的坑是版本不匹配:vLLM 版本和观测工具版本相差太远,或者观测指标名对不上。排错顺序永远是从底向上:驱动、CUDA、vLLM、观测工具。
后续可以扩展的方向也很多。你可以把这个观测思路接到 Prometheus + Grafana 上,做成持续监控面板;也可以在多卡环境下对比不同模型并行策略下的 KV cache 利用率;还可以结合批量任务,做一个自动告警,一旦 KV cache 可用量连续下降超过阈值就通知运维。
如果你正在长期维护 vLLM 服务,建议先把这个项目跑起来,把 KV cache 的基线数据留好,后面调参数、换显卡、升级 vLLM 都能有据可依。