WeLM 本地私有化部署的显存规划,核心是先确认模型原始精度和参数量,再按量化位数重算权重占用,最后通过增量加载测试逼近真实上限。量化选择不是先买卡,而是先用公式算出权重占用,再用实际推理日志验证生成质量。下面按五步处理,每一步都有可执行命令或代码。
WeLM 私有化部署的显存规划应以“原始权重精度+参数量”为起点,而不是模型文件夹大小。先读取 config.json 中的参数量和数据类型,按“参数量×每参数字节数”估算权重占用,再叠加 KV Cache 和 CUDA context 开销。量化能降低权重占用,但生成质量需用本地推理日志验证。部署前用 nvidia-smi 和 torch.cuda.get_device_properties 核对真实显存,通过增量加载观察峰值,最终固定量化级别与最大序列长度。
先确认模型原始精度与参数量
在计算显存前,需要先拿到两个值:参数量(通常是 1B、10B、100B 这类数值)和权重保存精度(FP32、FP16、BF16 或 INT8)。模型文件大小不能直接作为依据,因为分片权重、打包格式和优化器状态会干扰判断。先查看模型目录里的 config.json 或 README。
# 查看 config.json 中的参数字段和精度字段
cat ./welm-model/config.json | python3 -m json.tool | grep -E 'params|dtype|precision'
# 或者直接看 README 前 30 行
head -30 ./welm-model/README.mdconfig.json 中影响显存估算的字段主要是这些:n_params 或 parameter_count(参数量),torch_dtype 或 dtype(权重保存精度),max_position_embeddings(最大序列长度,影响 KV Cache),num_hidden_layers、num_attention_heads 和 head_dim(用于计算注意力中间缓存)。如果 config.json 里没有参数字段,去 README 或模型卡片里找,通常会有“Model Parameters”说明。
按量化位数重算权重占用
参数量和精度确认后,用下面这个公式计算权重显存占用:
权重显存(GiB) = 参数量 × 每参数字节数 ÷ 1024^3
每参数字节数:FP32 = 4,FP16/BF16 = 2,INT8 = 1,INT4 = 0.5举例(占位参数,请替换为实际值):假设模型参数量为 100B,FP16 精度下权重显存约为 100e9 × 2 ÷ 1024^3 ≈ 186.3 GiB,INT8 量化后约为 93.2 GiB,INT4 约为 46.6 GiB。这个数字只是权重部分,不能直接作为显卡显存需求。实际部署时还需要叠加三类额外开销:
- KV Cache:与最大序列长度和批大小相关,序列越长占用越大,通常每词元的缓存大小等于 2 × 层数 × 头数 × 头维 × 2 字节(FP16)。
- CUDA context 和激活值:即使不推理,CUDA 环境也会占用几百 MB 到 1 GiB 不等的显存;推理时的中间激活值取决于 batch size 和序列长度。
- 框架和优化器状态:如果使用训练工具加载推理,还会多出优化器缓存,但纯推理一般没有。
因此,建议把权重占用控制在显卡总显存的 60% 到 70% 以内,剩余空间留给 KV Cache 和激活值。这个比例是保守经验值,不是固定结论,具体需要结合推理时的序列长度验证。
实际可用显存与核显内存的校验方法
不要只看显卡命名或系统设置里的“共享 GPU 内存”,那些数值不代表单独可用的显存。先用 nvidia-smi 读取实际专用显存:
nvidia-smi `--query-gpu`=name,memory.total,memory.used,memory.free `--format`=csv在 Python 里可以用 PyTorch 读取设备属性,并检查当前可用显存:
import torch
if torch.cuda.is_available():
props = torch.cuda.get_device_properties(0)
print(f"设备名称: {props.name}")
print(f"总显存: {props.total_memory / 1024**3:.2f} GiB")
free_before = torch.cuda.mem_get_info(0)[0] / 1024**3
print(f"当前可用显存: {free_before:.2f} GiB")
else:
print("CUDA 不可用,请检查驱动和 PyTorch 版本")如果你的部署机没有独立显卡,而是使用核显或 CPU 内存,那么需要看的是物理内存和 swap 可用量,此时不能用 nvidia-smi。可以用 free -h 查看总内存和可用内存,但纯 CPU 推理的速度和延迟需要单独评估,不建议把 CPU 内存当作“显存”来规划。核显共享内存的实际可用大小取决于 BIOS 设置,不要想当然认为系统里显示的共享内存就是可用的。
用增量加载测试逼近真实上限
公式只能给出理论下限,真实显存峰值必须通过加载模型并跑一次生成来确认。建议用增量加载方式(例如 device_map="auto" 或逐层加载)先加载最小片段,再逐步生成文本,同时监控显存峰值。下面是一个最小推理骨架,使用时替换 YOUR_FRAMEWORK 为实际加载方式:
# inference_test.py
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer # 按实际框架替换
model_path = "/data/models/welm" # 替换为实际路径
tokenizer = AutoTokenizer.from_pretrained(model_path)
model = AutoModelForCausalLM.from_pretrained(
model_path,
torch_dtype=torch.float16, # 按量化方案替换
device_map="auto", # 增量加载,观察各设备显存
)
prompt = "写一个关于显存规划的短句"
inputs = tokenizer(prompt, return_tensors="pt").to("cuda")
outputs = model.generate(**inputs, max_new_tokens=64)
print(tokenizer.decode(outputs[0]))用下面的命令运行并监控显存峰值:
/usr/bin/time -v python inference_test.py 2>& | tee inference_log.txt
nvidia-smi `--query-gpu`=memory.used,memory.free `--format`=csv -l 1 > gpu_mem.csv &
# 运行结束后查看日志中的 Maximum resident set size,以及 gpu_mem.csv 中的最大显存值记录生成前后 2-3 分钟的显存变化。如果显存占用在生成后没有回落到基线,说明存在缓存泄漏,需要调整 batch size 或序列长度;如果生成时显存峰值接近总显存,就降低最大序列长度或改用更高压缩比的量化。
确定最终部署形态并固化参数
根据测试结果,把量化级别、最大序列长度、最大并发数写入配置文件。下面是一个 YAML 配置示例,实际字段以你的部署脚本为准:
# config.yaml
model:
path: /data/models/welm
quantize: int8 # fp16/bf16/int8/int4,根据测试结果选择
max_seq_len: 2048 # 测试中未爆显存时使用的最大序列长度
batch_size: 1 # 服务化时同时处理的请求数
generation:
max_new_tokens: 512
temperature: 0.7启动服务的命令需要经过验证后再固定,例如 python serve.py `--config` config.yaml。服务启动后,先做一次短请求验证,再连续跑 20 次以上不同长度的请求,观察显存峰值是否稳定、生成的文本是否与原模型输出趋势一致。如果显存持续增长或生成质量明显变差,就需要退回更保守的量化级别或缩短最大序列长度。只有在长时间运行中显存曲线平稳、输出结果符合预期,这套参数才算固化下来。