FLUX.2-dev GGUF Q4_K_M 在 Apple Silicon 上为何占用 29GB 显存
理论上,量化后的 FLUX.2-dev 模型(GGUF Q4_K_M 格式)应仅需约 19GB 内存,但在搭载 M3 Pro 芯片的 Apple Silicon 设备上,其显存峰值高达 28.92GB。深入分析发现,额外消耗的内存主要来自 MPS 开销、权重反量化过程,以及统一内存中 CPU 与 GPU 之间的数据传输。
加载架构与逐级卸载机制
FLUX.2-dev 使用 Mistral-Small-3.2-24B 文本编码器,全精度下需 45GB 显存。针对 Apple Silicon,采用 MLX 提供的 4 位版本,占用 16GB。整个流程遵循逐级卸载模式:
- 加载 MLX 编码器(约 13GB)。
- 在 CPU 上将提示词编码为嵌入向量。
- 卸载编码器并清空缓存。
- 从磁盘加载 DiT 模型(GGUF Q4_K_M,约 19GB)。
- 在 CPU 上初始化 VAE 和调度器。
- 将完整推理管线迁移至 MPS。
理论峰值是各组件最大值的总和,但实际表现受统一内存机制影响而不同。
测试环境
- macOS: 26.3.1 (Tahoe)
- 芯片: Apple M3 Pro,36GB 统一内存
- Python: 3.14.3
- PyTorch: 2.11.0
- diffusers: 0.38.0.dev
- mlx-lm: 0.31.1
使用 phys_footprint(类似活动监视器)和 PyTorch 的 MPS 指标进行性能分析。psutil.rss 不计入 MPS 分配的内存。
详细内存使用拆解
分阶段测量结果
| 阶段 | phys_footprint | MPS 驱动 | MPS 当前 |
|-------|----------------|------------|-------------|
| 基线 | 0.27 GB | 0 | 0 |
| MLX 编码器加载后 | 13.22 GB | 0 | 0 |
| GGUF 在 CPU 上 | 19.23 GB | 0 | 0 |
| pipe.to(mps) | 23.79 GB | 20.06 GB | 18.75 GB |
| 推理中段 | 26.50 GB | 25.62 GB | 18.78 GB |
峰值 28.92GB 出现在 pipe.to("mps") 阶段,原因是 CPU 和 MPS 同时存在数据副本。
28GB 峰值构成解析
- DiT Q4_K_M(uint8):18.59 GB
- VAE(bf16):0.16 GB
- MPS 池开销:+1.31 GB
- IOKit/Metal graphCache:~3.73 GB(着色器、页表、待处理缓冲区)
GGUF 权重在 MPS 上保持 uint8 格式;反量化为 bf16 在前向传播过程中逐层完成。临时 bf16 张量(最高达 6.92GB)在缓存中累积。
降低峰值内存的优化策略
- 增量式 MPS 迁移:逐个参数迁移,并每 30 个参数执行一次
gc.collect()。
def _move_to_device_incremental(pipe, device):
n = 0
for attr in list(vars(pipe)):
comp = getattr(pipe, attr, None)
if not isinstance(comp, torch.nn.Module):
continue
for param in comp.parameters():
param.data = param.data.to(device)
n += 1
if n % 30 == 0:
gc.collect()
for buf in comp.buffers():
buf.data = buf.data.to(device)
gc.collect()
torch.mps.synchronize()
torch.mps.empty_cache()
- 步骤间清空缓存:在推理步骤中加入回调,使用
torch.mps.empty_cache()清除反量化缓存。
- 生成后清理:推理完成后,执行
gc.collect()再调用torch.mps.empty_cache()。
优化效果对比
| 指标 | 优化前 | 优化后 | 变化 |
|--------|--------|-------|-------|
| 峰值 phys_footprint | 28.92 GB | 27.36 GB | -1.56 GB |
| 推理后稳定状态 | 26.25 GB | 21.76 GB | -4.49 GB |
| 生成耗时(1 步) | 2:04 | 2:11 | +7秒 |
峰值下降源于加载阶段的增量垃圾回收;稳定状态改善来自缓存清理。无法优化的 MPS/IOKit 开销仍维持在约 3.5GB。
核心结论:
- 稳定状态最低约 24GB,推理峰值约 27GB。
- 主要成本:18.59GB 的 uint8 DiT 权重 + 3.5GB MPS 开销。
- 反量化至 bf16 增加 3–5GB 临时缓冲区。
- CPU→MPS 传输因统一内存机制使峰值翻倍。
- 优化后峰值减少 1.5GB,稳定状态减少 4.5GB,且无质量损失。
FLUX.2-dev GGUF 在 M3 Pro 上的实际最小需求为 24GB 以上统一内存。对于更小配置,需采用更激进的量化或 CPU 卸载方案。
— Editorial Team
暂无评论。