Text Generation WebUI 跑小模型总爆显存 / 是量化没选对还是上下文开太大?

文章导读
小模型爆显存,先要分清是“加载就爆”还是“聊着聊着才爆”。加载瞬间就 OOM,通常说明权重本身的精度和量化方式已经超出这张卡的容量;加载成功、空闲时不爆,一发长 prompt 或连续聊几轮才爆,多半是上下文长度和输出长度把 KV cache 撑起来了。量化方式、ctx 长度、GPU 层数这三项里,建议按“先看监控 → 再减 ctx → 再换量化 → 最后调 GPU 层数”的顺序逐项排除,每次只改一
📋 目录
  1. A 在任务管理器或 nvidia-smi 里确认是显存峰值还是持续占用
  2. B 把上下文长度先减半再跑同一段对话
  3. C 切换量化加载方式重载同一模型
  4. D 检查 GPU 层数和 CPU 卸载是否把压力留在内存
  5. E 用同一提示词做前后对照并记录可复现配置
A A

小模型爆显存,先要分清是“加载就爆”还是“聊着聊着才爆”。加载瞬间就 OOM,通常说明权重本身的精度和量化方式已经超出这张卡的容量;加载成功、空闲时不爆,一发长 prompt 或连续聊几轮才爆,多半是上下文长度和输出长度把 KV cache 撑起来了。量化方式、ctx 长度、GPU 层数这三项里,建议按“先看监控 → 再减 ctx → 再换量化 → 最后调 GPU 层数”的顺序逐项排除,每次只改一个变量,否则你无法知道是哪一项在起作用。

小模型爆显存,多数情况不是量化选错,而是加载后空闲已接近上限,再被上下文和输出长度顶穿。建议先用 nvidia-smi 分别记录“加载后空闲”和“多轮生成后”两个显存值,再把 ctx 减半跑同一段对话,然后才切换到更低的量化重载。显存占用只在你自己的模型文件、量化格式、显卡容量和 WebUI 版本下才有意义,别人的参数表不能直接照搬。

在任务管理器或 nvidia-smi 里确认是显存峰值还是持续占用

先建立基线:在点击 Load 之前记一次显存,加载过程中记一次,加载完成后空闲再记一次,发完 prompt 并生成结束后记一次。这四个点能把“权重占用”和“推理增长”分开。Linux 和 Windows 命令行都可以用:

# 每秒刷新,观察加载与生成阶段的变化
nvidia-smi -l 1

# 只输出数值,方便抄进记录表
nvidia-smi `--query-gpu`=memory.used,memory.total,utilization.gpu `--format`=csv -l 1

Windows 下还可以开任务管理器 → 性能 → GPU,看“专用 GPU 内存”和“共享 GPU 内存”。专用内存是显卡板载显存,共享内存是驱动在系统内存里划的。如果专用内存没满但共享内存一直涨、速度明显变慢,说明部分内容被挪到了系统内存,这属于降级运行,不是显存够用。

日志侧要认几个关键字:CUDA out of memorytorch.cuda.OutOfMemoryErrorTried to allocate ... GiB,以及 llama.cpp 类后端可能出现的分配失败提示(例如 failed to allocate buffer 或 GGML 断言类报错)。如果这些字样出现在“加载模型”那几行日志中间,属于加载期 OOM;如果出现在你发送 prompt 之后的日志里,属于推理期 OOM。两者的处理方向完全不同,别混着改参数。

把上下文长度先减半再跑同一段对话

在 Parameters 或生成参数区域,找这两个字段:一是“Truncate the prompt up to this length”(界面里常被当成 ctx 上限使用,默认值通常在 1024~2048 之间,按你实际看到的数字来),二是 max_new_tokens。如果用的是 llama.cpp 类 Loader,参数区通常还有 n_ctxn_batch,需要结合当前界面确认字段名。

操作动作:把截断长度或 n_ctx 改成原来的一半,max_new_tokens 暂时不动,重载模型,然后跑完全相同的对话。观察点只有一个——生成结束后的显存峰值有没有明显下降。如果减半后不再 OOM,说明上下文窗口是主因,可以先把 ctx 定在这个档位,再考虑其他优化;如果减半后照样 OOM,说明瓶颈在权重加载阶段,直接跳到下一节看量化。

Text Generation WebUI 跑小模型总爆显存 / 是量化没选对还是上下文开太大?

每次只改 ctx,量化、GPU 层数、提示词都保持不变,并把两次的显存数值各记一遍,不要凭印象判断。这里不预设具体降幅,不同模型和显卡上的结果差别很大。

切换量化加载方式重载同一模型

Text Generation WebUI 的 Loader 下拉里常见的选项包括 Transformers、llama.cpp、ExLlamaV2、AutoGPTQ、GPTQ-for-LLaMa 等,具体有哪些取决于你的版本和已装扩展,以实际界面为准。它们对量化的控制方式并不一样:

  • llama.cpp 类 Loader:量化精度由你下载的模型文件本身决定(如 Q4_K_M、Q5_K_M、Q8_0 这类命名),Loader 只控制 n_gpu_layersn_ctx、缓存类型等运行参数。
  • Transformers 类 Loader:通过界面勾选项启用 4bit / 8bit 加载,并可选量化类型和计算精度。
  • ExLlama / GPTQ 类:通常要求模型目录里已有对应量化格式的权重文件,换 Loader 前要先确认模型是不是这个格式。

Transformers 路径下的配置骨架大致是这样,字段名以你界面上的实际写法为准:

load_in_4bit = true
bnb_4bit_quant_type = "nf4"      # 常见可选 nf4 / fp4
bnb_4bit_compute_dtype = "bfloat16"
bnb_4bit_use_double_quant = true

对比原则:同一个模型、同一个 ctx、同一段提示词,只改量化方式重载一次,记录加载后空闲显存和生成后显存。更低的位宽一般会降低显存占用,但可能换来输出质量下降或速度变化,需要你自己权衡,不要只看显存数字。

检查 GPU 层数和 CPU 卸载是否把压力留在内存

n-gpu-layers(在部分 Loader 里写作 n_gpu_layers 或 GPU layers 滑杆)表示有多少层模型权重放到显卡上,剩下的层留在系统内存、由 CPU 计算。不把它设满,显存占用会下降,但代价是推理变慢、系统内存占用上升——这是取舍,不是免费的优化。

Text Generation WebUI 跑小模型总爆显存 / 是量化没选对还是上下文开太大?

做法:先记下当前值,然后每次减少若干层,重载模型,观察显存是否降到目标区间以内,同时留意生成速度能不能接受。如果显存始终降不下来,说明降层没生效或其它部分(KV cache、批处理缓冲)才是大头,需要回到前两节重新定位。

验证方式看加载日志:llama.cpp 类后端加载时一般会打印 offload 相关行,例如把多少层放到 GPU、模型缓冲区和 KV cache 各占多少 MiB;Transformers 类 Loader 通常会给出设备分布信息。把日志里这几行连同 nvidia-smi 数值一起记下来,比只看任务管理器可靠。

用同一提示词做前后对照并记录可复现配置

复测的关键是提示词固定。建议自己准备一段长度稳定的中文段落(比如几百字,每次粘贴同一份),再配一句固定指令,例如:

请用 200 字总结下面这段文字,不要分点。
<此处粘贴每次完全相同的固定段落>

然后按下面这张表逐次记录。每行只允许一个变量变化,其它列保持一致,否则结果无法对比。“是否成功”只写成功 / OOM / 明显变慢,“显存峰值”填生成结束那一刻 nvidia-smi 的数值,不要填估算值。

序号Loader量化方式ctx / n_ctxmax_new_tokensn-gpu-layers加载后空闲显存生成后显存峰值是否成功备注
1原配置原量化原值原值原值基线
2同 1同 1减半同 1同 1只改 ctx
3同 1 或更低精度 Loader换量化同 2同 1同 1只改量化
4同 3同 3同 2同 1减少若干层只改层数

四行跑完,你基本就能判断爆显存的主因是加载期的量化选择,还是推理期的上下文长度。把这张表和当时的加载日志一起留着,下次换模型时可以照着同一套流程复测,而不必再从头猜。