DeepSeek-V4-Flash-0731 本地 CPU 推理:纯 C 引擎让 284B-A13B 模型在 8 GB 内存笔记本运行
2026/8/25 23:01:31 网站建设 项目流程

项目简介

如何在没有 GPU 的笔记本上运行一个总参数量 284B 的大模型?

开源项目deepseek-v4-flash-0731-in-c给出了一条纯 CPU 路径:使用 C99 和 OpenMP 编写推理引擎,直接读取 DeepSeek-V4-Flash-0731 原生权重,不依赖 CUDA、PyTorch,也不要求把权重转换成其他模型格式。

GitHub:

https://github.com/shyringo/deepseek-v4-flash-0731-in-c

DeepSeek-V4-Flash-0731 是一个 284B-A13B MoE 模型:总参数量 284B,每个 token 激活约 13B。完整权重约 166.9 GB,但由于每个 token 只使用部分专家,引擎可以把冷专家留在磁盘上,仅把当前工作集放入内存。

环境要求

运行项目需要:

  • 主流 64 位 CPU,例如 x86-64 或 ARM64
  • 支持 POSIXmmappread和 pthread 的系统环境
  • 最低 8 GB CPU 内存
  • 约 172 GB 可用磁盘空间
  • C99 编译器、make、OpenMP、Git、curl 和 Bash
  • Windows 用户使用 WSL2

8 GB 是可运行下限,不代表最佳性能。更多内存可以缓存更多 MoE 专家,但内存预算过高导致系统换页时反而会变慢。

编译并启动推理

以 Ubuntu 22.04 或 Windows WSL2 为例,先安装构建工具:

sudoapt-getupdatesudoapt-getinstall-ybuild-essentialgitcurl

拉取并编译项目:

gitclone https://github.com/shyringo/deepseek-v4-flash-0731-in-c.gitcddeepseek-v4-flash-0731-in-cmake-j

从 ModelScope 下载并校验固定版本的原生权重,下载支持断点续传:

scripts/download-dsv4.sh"$HOME/model/DeepSeek-V4-Flash-0731"

启动常驻聊天:

scripts/try-dsv4.sh

启动后直接输入问题即可。输入/reset开始新会话,按Ctrl-C可以停止当前回答但不卸载模型,输入/exit退出。

单次提问也可以直接写在命令行:

scripts/try-dsv4.sh"科技的边界在哪里?"

实测性能:同时公开最佳场景和普通场景

参考环境如下:

项目配置
操作系统Windows 11 + WSL2 Ubuntu 22.04.5 LTS
CPUIntel Core i5-1340P,12 核 / 16 逻辑处理器
内存安装 31.65 GiB,WSL2 可见 23.47 GiB
磁盘Samsung MZVL41T0HBLB NVMe,权重位于 ext4
编译器GCC 11.4.0 + OpenMP
推理配置18 GiB 内存预算,12 线程,65536 上下文

完整有效测试记录:

场景输入/输出TTFTTPOT吞吐专家读取峰值 RSS
普通回答,无可复用文本5 / 64 token20.203 s1.705 s/token0.59 token/s70.67 GiB21.95 GiB
Prompt Lookup 完整命中10 / 60 token26.748 s0.892 s/token1.12 token/s53.64 GiB22.19 GiB

最佳 TPOT 0.892 s/token 来自有重复上下文可复用的 Prompt Lookup 场景。它不是普通问答的固定速度。该测试共完成 60 个输出 token,4 轮完整主模型验证接受 50/51 个 draft token,所有展示内容都经过主模型确认。

同条件关闭 Prompt Lookup 时,总耗时为 124.2 秒、TTFT 为 27.932 秒、TPOT 为 1.594 秒/token;开启后分别为 79.1 秒、22.875 秒和 0.939 秒/token,60 个输出 token 完全一致。

核心实现一:MoE 专家流式读取

普通的模型加载方式会尝试让大量权重常驻内存,而 166.9 GB 显然超出了多数笔记本的物理内存。

本项目把每层真正激活的 MoE 专家作为流式工作集:

  1. Router 确定当前 token 需要的专家。
  2. 命中缓存的专家立即进入计算。
  3. 未命中的专家从 NVMe 读取。
  4. 每读完一个专家就开始计算,不等待本层全部 I/O 完成。
  5. 每层使用独立的 LRU 缓存份额,减少跨层相互驱逐。

内存越多,能够保留的专家越多;内存较少时则增加磁盘读取,但仍可完成正确推理。

核心实现二:磁盘 I/O 与 CPU 计算流水线

专家权重采用双缓冲:一个缓冲区参与计算时,另一个缓冲区读取下一批专家。非专家层权重使用内存映射;计算第 L 层期间,内核 read-ahead 和后台读取线程加载第 L+1 层。

读取线程池在模型生命周期内复用,默认最多四个 worker,避免每层重复创建线程,也避免过多 I/O 线程与 OpenMP 计算线程争抢 CPU。

核心实现三:多 token 批处理

Prefill 和投机验证采用 layer-major 组织:加载一层权重后,连续处理 batch 中的所有 token,再进入下一层。同一份 FP8、FP4、BF16 权重读取和解码结果可以服务多个位置。

这类批处理对 MoE 尤其重要,因为多个 token 可能路由到相同专家。专家只需读取一次,就能处理所有相关 token。

核心实现四:低比特融合算子

FP4 和 FP8 权重不会预先展开成完整浮点矩阵。反量化直接在 GEMV 内核中完成:

  • FP4 使用寄存器内查表
  • FP8 快速路径使用 SIMD 位域转换
  • Gate 和 Up 投影共享量化输入与一次 OpenMP 调度
  • AVX2 路径并行处理八个输出行,同时保持每行原有浮点累加顺序
  • MoE、Attention 和路由工作区在模型打开时预分配并循环使用

这样可以减少中间内存、重复量化和热路径内存分配。

核心实现五:常驻聊天与自动资源规划

交互模式会跨轮次保留模型映射、KV/compressor 状态、专家缓存和热权重。停止当前回答、开始下一轮聊天或执行/reset时,不需要重新加载 167 GB 权重。

启动脚本会根据物理内存、当前可用内存和 CPU 能力,自动决定上下文长度、热权重预算、专家缓存、OpenMP 线程和读取线程。需要手动控制时,只需设置一个总内存预算:

DSV4_MEMORY_GIB=18scripts/try-dsv4.sh

推理正确性验证

不下载完整权重也可以运行测试:

maketest

仓库内置四层 tiny 模型,连续执行 130 个位置,并与独立 Python 实现逐项比较,要求maxdiff=0.000000。完整模型另有固定 16-token oracle。GitHub Actions 同时使用 GCC 与 Clang 构建和测试。

总结

这个项目的目标不是把 284B 模型描述成“小模型”,而是让完整原生权重在笔记本的真实内存和磁盘条件下可运行、可聊天、可继续优化。

项目采用 Apache License 2.0,并基于 kimi-k3-in-c 的专家流式读取思路继续开发。复用代码、适配工作和原创优化在 NOTICE 与优化文档中有清晰边界。

GitHub 项目地址:

https://github.com/shyringo/deepseek-v4-flash-0731-in-c

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询