遇到CUDA OOM时,优先检查的不是单条命令,而是SGLang对显存的预分配方式。DeepSeek-V3作为大规模MoE,权重加载与KV Cache预分配是占满显存的两个常见起点,临时激活值通常只在请求处理中瞬时抬升;如果启动阶段未出错,那么运行期OOM更可能与KV Cache预留比例或请求长度有关。
先分清启动期OOM和运行期OOM
启动阶段直接报CUDA OOM,通常发生在模型权重加载、张量并行初始化或KV Cache池创建时。运行阶段OOM则多出现在第一个请求或长文本请求到达后,因为此时激活值、临时张量和KV Cache实际用量同时上涨。判断方法是观察命令执行后多久报错,以及报错前后进程状态。
- 启动期OOM:先看tp/pp设置是否匹配模型并行度,再看权重加载是否完整;降低静态显存占用比例(如mem-fraction-static)优先于调KV Cache。
- 运行期OOM:先看单请求最大token数是否过大,再看并发请求是否超过KV Cache池;调低KV Cache预分配比例或并发上限。
检查当前显存占用与启动参数
执行下面命令,确认每张卡在被SGLang退出前的显存余量。需要结合启动日志一起看,日志中会打印KV Cache预留量或内存池大小。
nvidia-smi `--query-gpu`=memory.used,memory.total,memory.free `--format`=csv启动日志常见关键字段包括cache size、memory pool、KV cache等。如果日志显示权重加载已占用大部分显存,那么KV Cache比例设置得再高也只会OOM;如果日志显示预留值远大于实际可分配空间,就应降低KV Cache预留比例。
调整KV Cache预分配设置
SGLang用启动参数或环境变量控制显存分配比例。不同版本参数名称不同,先运行帮助命令核对:
python -m sglang.launch_server `--help` | grep -iE 'cache|memory|fraction'一个可尝试的启动骨架如下,参数名以你当前版本的帮助输出为准:
python -m sglang.launch_server `--model` deepseek-ai/DeepSeek-V3 `--tp` 8 `--mem-fraction-static` 0.75 `--kv-cache-mem-fraction` 0.4 `--max-num-tokens` 4096调低`--mem-fraction-static`会减少启动时预留的缓存,给激活值腾出空间;调低`--kv-cache-mem-fraction`会限制KV Cache池大小。两者都直接影响可并发处理的请求数量,调低后如果请求并发很高,可能触发缓存不足或重复配额,体现为日志中的排队或性能下降,因此需要结合预期请求长度与并发度逐步调整。
验证信号与后续分支
调整后,不能只看进程是否启动成功,还要观察连续请求的显存波动。验证信号包括:启动日志无CUDA OOM;nvidia-smi看到的显存峰值低于总限;每个batch都能完成prefill和decode。如果仍有OOM,下一步检查两层:一是是否超过KV Cache池容量(日志通常会记录请求被截断或排队),二是上下文长度是否超过单请求上限。
- 日志关键词:OutOfMemory、CUDA error、cache capacity
- 观察命令:watch -n 1 nvidia-smi
- 调整原则:每次只改一个参数,重启后对比日志。