本地部署DeepSeek-v4-flash-0731 满血版

前言

这次测试的目标,是在一台普通的本地服务器上运行 DeepSeek-V4-Flash-0731 的 Q8 版本,尽量保留模型能力,同时观察纯 CPU 和 GPU+CPU 混合部署时的实际速度。

测试使用的是 DeepSeek-V4-Flash-0731 GGUF 的 UD-Q8_K_XL 版本。这里所说的“Q8 无损版”,是指本次测试采用的 Q8 量化版本,重点是尽量减少量化对模型效果的影响;它并不等同于原始 BF16 权重完全不变。

测试机器

测试机器配置如下:

  • 内存:256 GB
  • CPU:128 核
  • GPU:2 张 NVIDIA L20
  • GPU 总显存:约 96 GB,每张卡约 46 GB 可用显存
  • 模型:DeepSeek-V4-Flash-0731 UD-Q8_K_XL
  • 推理后端:llama.cpp server CUDA 镜像
  • 上下文长度:128K
  • 测试方式:OpenAI 兼容接口调用

服务器资源

从资源监控可以看到,服务器内存容量足够大,双 L20 的显存也基本被模型推理使用。这个配置的关键并不是把模型强行全部塞进显存,而是让 llama.cpp 根据可用 GPU 显存自动决定 GPU 层和需要留在系统内存中的权重。

第一种方案:纯 CPU 运行

第一种方案是完全使用 CPU 运行模型,不使用 GPU 加速。这样部署最简单,也不依赖 CUDA 或显卡配置,适合先验证模型能否正常加载和输出。

纯 CPU 运行的优点是稳定、兼容性好,显存不足时也能启动;缺点是速度比较慢,而且会占用大量系统内存。实测生成速度大约为:

1
约 5 token/s

对于简单问答和功能验证,5 token/s 仍然可以使用;但如果需要长文本推理、代码生成或连续对话,等待时间会比较明显。

第二种方案:GPU + CPU 混合运行

第二种方案使用两张 L20,同时保留一部分权重在 CPU 内存中,让 GPU 和 CPU 混合运行。由于 Q8 模型体积较大,96 GB 显存并不一定适合把所有内容都强制放进 GPU,因此混合部署反而更实用。

本次测试使用 Docker Compose 启动 llama.cpp server,核心配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
services:
deepseek-v4-flash-0731-q8:
image: ghcr.nju.edu.cn/ggml-org/llama.cpp:server-cuda
ports:
- "8003:8000"
environment:
CUDA_VISIBLE_DEVICES: "0,1"
NVIDIA_VISIBLE_DEVICES: all
NVIDIA_DRIVER_CAPABILITIES: compute,utility
volumes:
- /data/ai/models/DeepSeek-V4-Flash-0731-GGUF/UD-Q8_K_XL:/models:ro
command:
- --model
- /models/DeepSeek-V4-Flash-0731-UD-Q8_K_XL-00001-of-00005.gguf
- --alias
- deepseek-v4-flash-0731-q8
- --host
- 0.0.0.0
- --port
- "8000"
- --ctx-size
- "131072"
- --parallel
- "1"
- --device
- CUDA0,CUDA1
- --split-mode
- layer
- --fit
- on
- --fit-target
- 4096,4096
- --flash-attn
- on
- --cache-type-k
- q8_0
- --cache-type-v
- q8_0
- --threads
- "64"
- --threads-batch
- "96"
- --numa
- distribute

这里有几个比较重要的参数:

  • --device CUDA0,CUDA1:使用两张 L20;
  • --split-mode layer:按照层在两张 GPU 之间切分;
  • --fit on:让 llama.cpp 根据显存情况自动适配;
  • --fit-target 4096,4096:给两张 GPU 预留一定的显存空间,避免把显存全部占满;
  • --ctx-size 131072:启用 128K 上下文;
  • --flash-attn on:开启 Flash Attention;
  • --cache-type-k q8_0--cache-type-v q8_0:降低 KV Cache 的显存占用。

实测 GPU+CPU 混合部署的生成速度大约为:

1
约 18 token/s

在测试日志中,连续生成阶段的速度大约在 18 token/s 左右,单次统计结果达到约 18.6 token/s。相比纯 CPU 的约 5 token/s,速度提升非常明显。

GPU CPU 混合速度

问答测试

通过 OpenAI 兼容接口调用模型,可以直接使用常见的 /v1/chat/completions 接口。测试中使用了中文系统提示词,并让模型解释 MES 中组织权限、角色权限和数据权限的区别,同时给出一个多工厂场景示例。

模型能够正常返回中文回答,接口返回的 usage 信息也能看到 prompt token、completion token 和总 token 数量。截图中的一次测试显示,预测阶段速度约为 18.85 token/s,与命令行日志中的 18 token/s 左右基本一致。

问答测试

两种方案对比

部署方式 GPU 使用 实测速度 特点
纯 CPU 不使用 GPU 约 5 token/s 配置简单,兼容性好,但速度较慢
GPU+CPU 混合 2 张 L20 约 18 token/s 速度明显更快,适合长期运行

从结果来看,双 L20 并不一定要追求“全部 GPU offload”。对于体积较大的 Q8 模型,使用 GPU 加速关键部分,同时让系统内存承载无法放入显存的部分,是更加稳妥的方案。

部署时的注意事项

1. 不要同时手动指定过多 GPU 参数

如果已经使用 --fit on,就不要再同时手工指定 --n-gpu-layers--tensor-split 和大量 --override-tensor 参数。多个参数互相影响时,反而容易导致模型启动失败、显存分配不合理或输出异常。

2. 注意模型分片

本次模型由 5 个 GGUF 分片组成,Docker 容器只读挂载包含这些分片的目录,并把第一个分片作为 --model 参数传给 llama.cpp。挂载前要确认所有分片都已经完整下载到同一目录。

3. 关注 CUDA MoE 输出质量

当前 llama.cpp 的 DeepSeek-V4 CUDA MoE 路径可能存在输出质量问题。如果启动后出现乱码、答非所问或语言漂移,可以尝试启用:

1
- --cpu-moe

这样会把 MoE 专家权重放到 CPU 上,速度可能下降,但输出稳定性可能更好。实际使用时应同时关注速度和回答质量,不能只看 token/s。

4. 先验证,再调大批处理参数

配置中使用了相对稳妥的 --batch-size 2048--ubatch-size 512。建议先确认模型能稳定启动、接口能正常返回,再根据显存和延迟情况逐步调整,不要一开始就把所有参数调到最大。

总结

在 256 GB 内存、双 L20(约 96 GB 显存)的服务器上,DeepSeek-V4-Flash-0731 Q8 版本可以正常本地部署。

  • 纯 CPU 运行速度约 5 token/s;
  • GPU+CPU 混合运行速度约 18 token/s;
  • 双 L20 加上大内存,适合采用自动 fit 的混合部署方式;
  • Q8 版本在模型体积、显存占用和回答质量之间取得了比较好的平衡;
  • 实际部署时还要关注 CUDA MoE 的输出质量,而不是只关注推理速度。

如果目标是本地测试、个人使用或内部知识库问答,这套配置已经能够提供比较实用的 DeepSeek-V4-Flash-0731 服务。