Day 1·1 RK3588上2秒启动:818KB纯C推理引擎是怎么炼成的

简介: 这是一套为边缘设备(如RK3588)深度定制的纯C推理引擎:仅28个C文件,零依赖、800KB单文件、冷启动2秒。手写矩阵乘、线程池与国密SM2,非为炫技,而是被内存受限、频繁重启、可信审计等硬约束倒逼出的工程必然。

如果只是为了"把大模型跑起来",现在的答案多到溢出来:装个 vLLM、llama.cpp、Ollama,几行命令就能出结果。那为什么还有人(对,就是我们)会从 28 个 C 文件开始,手写矩阵乘法、线程池、HTTP 服务器,甚至自己实现 SM2 椭圆曲线签名?答案要先看一个反差的数字:我们的推理引擎,RK3588 板端 Release 产物是 818,872 字节(约 0.8 MB),冷启动 2.01 秒。而常规做法要带多大的环境、预热多久,跑过的人都懂。

1. 知识点:需求把方案逼出来的三条因果链

手搓不是情怀,是被场景逼出来的工程决策。三个因果链:

链一:设备决定"尺寸"。 RK3588 是开发板,不是服务器。内存 4–16GB、eMMC 存储、还可能断网、会重启。在这种设备上,"引擎 = Python 解释器 + PyTorch + CUDA 栈"动辄几 GB 的方案天生不成立——能省的每一字节都是收益,于是你开始在意"我的可执行文件多大"。

链二:边缘决定"启动"。 边缘盒子经常要重启(断电、升级、看门狗拉起)。重启一次服务要 30 秒和要 2 秒,是"能忍"和"无感"的区别。于是你开始在意"加载流程里有没有一秒都没法省的浪费"——这正是后面我们要读的 mmap 权重格式的由来。

链三:可信决定"自研"。 医疗、法务场景要回答"这个结果是不是这台机器用这套权重算的"。这需要把密码学原语(SM3/SM4/SM2)编进引擎。引入 OpenSSL?还是自己写并用国密标准向量逐字节验证? 我们选了后者(第 23–27 天专题),这也是"零依赖"的另一个动机。

所以请记住这个结论:"800KB、零依赖"不是起点,是被场景逼出来的结果;本系列 30 天,就是把这条因果链反着走一遍,逐环还原给你看。

2. 对应代码:先在仓库里找到这三个证据

打开 https://gitee.com/pei-xiaoguang/kestrel-llm ,做三件事:

  1. 读 README.md 顶部的「核心亮点」表——里面的每个数字后面都会被拆成文章;
  2. 看根目录 CMakeLists.txt 第二行 project(vllm_kestrel C)——一个 target、纯 C,没有第三方库声明;
  3. 数一下源码规模:构建清单里是 28 个 .c 文件(main + core 11 + common 2 + serve 6 + model 6 + npu 2,即 CMakeLists.txt 里 VLLM_SOURCES 的完整列表)。注意磁盘上 src/ 实际有 30 个 .c:src/media/ 下另有 h264_dec.c、vllm_mp4.c 两个解码器是独立模块,默认不参与构建(这也呼应了 README 里"H.264 模块独立且默认不启用"的口径)。

2.4 关键代码:CMakeLists 骨架,第一次读

把 CMakeLists.txt 从头扫一遍,你会发现整个构建文件就是"八个决定"(编号是我加的,源码无此编号):

project(vllm_kestrel C)                              # (1) 纯 C 工程,没有 C++
set(CMAKE_C_STANDARD 11)                             # (2) 强制 C11,编译器必须支持
set(CMAKE_C_STANDARD_REQUIRED ON)
if(NOT CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64|arm64|ARM64")
    if(NOT VLLM_MARCH)
        message(FATAL_ERROR
          "vllm_kestrel targets aarch64 (RK3588) only; found ...")   # (3) 构建层单平台守卫
    endif()
endif()
if(NOT VLLM_MARCH)
    set(VLLM_MARCH "armv8.2-a+dotprod+fp16")         # (4) march 旋钮:不传参就用默认值
endif()
option(VLLM_STATIC "Build a fully static (zero .so dependency) binary" OFF)  # (5)
set(CMAKE_C_FLAGS_RELEASE "-O2 -mcpu=cortex-a76 -march=${VLLM_MARCH} -ffast-math -fopenmp -D_GNU_SOURCE")  # (6)
set(VLLM_SOURCES src/main.c src/core/vllm_l3.c ... ) # (7) 28 个 .c,功能布局排列
add_executable(vllm_kestrel ${VLLM_SOURCES} ${VLLM_HEADERS})  # (8) 单 target、单产物

逐点看懂:

  • (2) CMAKE_C_STANDARD 11:从构建系统层面锁死"C11",配合代码里大量 _Static_assert、for (int i...) 等 C11 特性。这解释了为什么 README 敢写"纯 C11"——不是口头约定,是构建系统强制。
  • (3) 构建层也有一道平台守卫:1-2 你会在 vllm_platform.h 里看到 #error(编译 C 代码时的守卫),这里 message(FATAL_ERROR) 是更早一层的守卫——cmake 配置阶段就拒绝。两道守卫 = "错误前移"做了两次。
  • (4) VLLM_MARCH 旋钮:这就是为什么 1-2 能用一个 cmake -DVLLM_MARCH=... 就复现翻车——架构串是变量,不是写死的。
  • (5) VLLM_STATIC:默认 OFF;打开后走 -static 链接(CMakeLists 第 39–44 行),产物 ldd 报 not a dynamic executable。
  • (7) 源文件清单:这就是 1-1 开头数的"28 个 C 文件"的官方出处。留意排列是按功能布局(main / core 推理内核 / common / serve / model / npu),且 vllm_l3.c(1-3 的对拍主角)和 vllm_ckks.c / vllm_fhe.c / vllm_ntt.c(同态加密研究内核)都在同一个 target 里编译——一个二进制里既有明文引擎也有 FHE 研究代码,是刻意的共存设计。
  • (8) 单 add_executable:全工程只有一个产物。这行决定了"800KB 单文件"不是靠打包,而是真的只链出一个可执行文件。

小结:读懂 CMakeLists 的顺序 = 读懂引擎"边界"的顺序:语言(C11)→ 平台(aarch64)→ 指令集(march 旋钮)→ 依赖(静态/动态)→ 组成(28 个文件谁是谁)。第 2–3 天会沿着这条线逐层深入。

3. 改动后果:一个真实的教训——"不用心维护运行产物"会怎样

这一篇先讲一个不改代码也会踩的坑。看 build_rk3588.sh 第 75–79 行的注释,它记录了仓库的真实事故:

# Keep the repo-root ./vllm_kestrel in lockstep with the build artifact. Every
# ./vllm_kestrel invocation on the board then runs the LATEST kernel code -
# without this, stale binaries silently invalidate perf/quality runs
# (2026-08-22: a 00:05 M4b binary at the repo root invalidated all M4c runs).

意思是:构建脚本特意把产物同步到仓库根 ./vllm_kestrel,就是为了防止你手滑运行了旧的二进制。某次实验里,根目录躺着一个旧版本二进制,导致一整天性能数据全部作废。后果是:代码没改错,但"跑错了东西",结果比不跑还糟。这是贯穿整个系列的第一条工程纪律:实验前先确认你在跑哪个二进制。build_rk3588.sh 的"根同步"正是为此而存在。

4. 学员调试任务(本篇为观察任务)

  • A 档:git clone 仓库到你的板子,执行 ls src、ls include,用 file 查看 README 里提到的产物(若还没有可先跳过),并把 CMakeLists.txt 第 37 行那串编译旗标抄下来——下一篇要逐字拆它。
  • B 档:同上 clone + 数文件 + 读 CMakeLists.txt,记录你对"零第三方依赖"的疑问清单,后面每天会逐条回答。

预期输出:能说出"引擎由哪几层组成、构建入口在哪、为什么脚本要 root-sync 二进制"。

收尾

本篇源码点名:CMakeLists.txt、build_rk3588.sh、README「核心亮点」表。

下篇预告: ARM交叉编译踩坑实录带你看一个真实的 -march 翻车现场——编译期报错,是引擎在救你。

上一篇:课程介绍与大纲(《30 天手搓推理引擎》系列总介绍)

下一篇:Day 1·2 ARM交叉编译踩坑实录:-march=armv8.2-a+dotprod+fp16写错会怎样

相关文章
|
9天前
|
人工智能 JSON API
全网刷屏的 Jev 模型正式开放!一手实战测评 + 保姆级教程
全网爆火的 Jev 模型是什么?有什么用?怎么使用?怎么接入 AI 编程工具?效果真的好么?傻子可懂的 Jev 保姆级实战教程 + 项目实战测评来啦
7684 13
|
7天前
|
人工智能 测试技术 API
最近全网爆火的 Jev 到底是什么?适合干什么、怎么用,一篇讲透!
Jev是TypeSafe AI推出的“系统一模型”,不生成文本,专做毫秒级结构化决策:Choice(多选)、Score(打分)、Noul(是非概率)。响应快193倍、成本低444倍,适合工单路由、内容审核、测试定级等高频判断场景。
1642 4
最近全网爆火的 Jev 到底是什么?适合干什么、怎么用,一篇讲透!
|
4天前
|
人工智能 JavaScript 芯片
DeepSeek 官方偷偷上传 Harness 桌面端安装包,我已经用上了。。附最新下载地址
DeepSeek Harness 官方的桌面端安装包被网友扒出来了,2 分钟讲明白如何使用,体验如何,适合作为 AI 编程工具么?附最新 Windows 和 Mac 双端的下载地址
1407 1
|
8天前
|
人工智能 并行计算 PyTorch
秋叶 ComfyUI 2026 整合包 v3.2 完整部署教程:Python 3.13 + Torch 2.13 全栈升级
秋叶aaaki ComfyUI 2026年8月整合包v3.2正式发布!全面升级Python 3.13.11、PyTorch 2.13.0+cu130及ComfyUI v0.30.2,原生支持MiniMax H3、Wan 2.2、Qwen-Image-2.1等2026主流音视频/图像模型,解压即用,无需环境配置。
1187 9
|
21天前
|
人工智能 自然语言处理 安全
阿里云千问办公 QwenWork详细介绍:产品核心能力、典型场景、价格及常见问题解答
千问办公是阿里云推出的一站式AI办公平台,主打"不止于对话,更注重交付",依托通义千问旗舰大模型,用户一句话即可完成数据分析、PPT生成、视频剪辑等复杂任务,直接输出可用成果。产品深度打通钉钉生态与企业OA,覆盖桌面端、网页端,提供企业标准版198元/人/月等多档订阅方案,新用户注册即赠2000积分,适配工程师、HR、财务等多职业办公场景,成为能动手干活的"全能AI同事"。
3670 10
|
5天前
|
编解码 缓存 PyTorch
16G 显卡能跑 Qwen-Image 2.1 吗?
9月20日,阿里Qwen开源Qwen-Image-2.1:7B DiT图像模型+8B文本编码器+VAE,单模型支持文生图与图像编辑,原生输出2K PNG(含Alpha通道),支持10张参考图。在自建Qwen-Image-Bench达60.28分(开源模型第一),GenAI Showdown文生图排名7/15。16G显存可跑1024×1024(需INT8量化+ComfyUI优化),但2K需24G以上。注意其Qwen Research License限非商业用途。
609 1
|
6天前
|
人工智能 编解码 并行计算
MiniMax-H3 一键整合包技术文档:8G 显存运行 AI 漫剧制作 —— 角色替换 / 动作迁移 / 文图生视频部署与调参指南
MiniMax H3 是 MiniMax 开源的全模态视频生成模型,支持文/图/音/视多条件输入,输出最高2K、15秒带双声道音频视频。本文档详述其Int8量化版在8GB显存下的本地一键部署、三段式工作流(EDIT/REPLACE/CONTINUE)、参数调优及常见问题排查。(239字)
|
16天前
|
缓存 IDE Java
【保姆级】Android Studio下载、安装和汉化教程(2026最新)
Android Studio 是 Google 官方推出的免费 Android 应用开发集成环境,基于 IntelliJ IDEA,内置模拟器、调试器、性能分析及 Compose 界面工具,功能全面,文档丰富,是安卓开发首选工具。(239字)
1720 1

热门文章

最新文章