Safetensors 模型的结构解析:Checkpoint 与 Diffusers 的差异
你是否遇到过下载的Stable Diffusion Safetensors模型缺少VAE和CLIP模型?
你是否想知道下载的几十GB的模型文件是否损坏?
本文给出解答!
在 Stable Diffusion 的生态里,模型有两种常见的封装形式:Checkpoint 格式 与 Diffusers 格式
一、Checkpoint 格式(传统 SD 封装)
在 CompVis 原版 Stable Diffusion 中,所有组件(UNet、CLIP、VAE)通常打包在一个 .ckpt 或 .safetensors 文件里。键名的命名习惯如下:
- UNet :
model.diffusion_model.* - CLIP/Text Encoder :
cond_stage_model.* - VAE :
first_stage_model.*
这种命名方式直接对应论文里的"阶段"概念:
- 第一阶段(first stage):VAE,负责图像 ↔ 潜空间转换
- 第二阶段(diffusion model):UNet,负责潜空间去噪
- 条件阶段(cond stage):CLIP,负责文本条件编码
优点是下载即用,缺点是难以替换单个模块。
二、Diffusers 格式(工程化封装)
Hugging Face 的 Diffusers 库采用模块化设计,将各组件拆分到不同目录中,并用 model_index.json 描述组合关系。常见目录结构:
├── unet/
├── vae/
├── text_encoder/
├── scheduler/
├── model_index.json
实例:

UNET模型在unet目录里,CLIP和VAE在text_encoder 和 vae目录里。
这种方式更透明,方便替换和扩展,但文件较多。要下载全部文件才能使用。
三、如何验证 safetensors 文件结构
你可以用 Python 代码快速查看 safetensors 文件的键和模块前缀,来判断你下载的是一个checkpoint模型还是单独的Unet模型:
from safetensors import safe_open
model_path = "E:\\xxx_ckptsafetensors"
with safe_open(model_path, framework="pt", device="cpu") as f:
keys = f.keys()
print("键数量:", len(keys))
rs = []
for k in list(keys):
nn = str(k).split(".")
nm_prefix = ""
if len(nn) >= 2:
nm_prefix = nn[0] + "." + nn[1]
else:
nm_prefix = str(k)
if nm_prefix not in rs:
rs.append(nm_prefix)
print(rs)
如果是 Checkpoint 格式,你会看到 model.diffusion_model.*, first_stage 等前缀。
比如:
键数量: 2515
['conditioner.embedders', 'first_stage_model.decoder', 'first_stage_model.encoder', 'first_stage_model.post_quant_conv', 'first_stage_model.quant_conv', 'model.diffusion_model']
如果是 Diffusers 格式的UNET模型,你只会看到 down_blocks.*、up_blocks.* 等模块化命名的前缀。
具体前缀和模块对应如下
| 模块 | Checkpoint 格式 | Diffusers 格式 |
|---|---|---|
| UNet | model.diffusion_model.* |
down_blocks.*, up_blocks.*, mid_block.* |
| VAE | first_stage_model.* |
vae.* |
| CLIP | cond_stage_model.* |
text_encoder.* |
| 调度器 | 无单独存储 | scheduler.* |
总结
- Checkpoint 格式:单文件打包,命名体现"阶段"概念,下载即用但不透明。
- Diffusers 格式:模块化目录,命名直观,方便替换与扩展,更适合工程化和社区共享。
- 命名差异 :Checkpoint 用
first_stage_model表示 VAE,而 Diffusers 直接用vae。UNet 在 Checkpoint 中是model.diffusion_model,在 Diffusers 中则拆分为down_blocks、up_blocks、mid_block。