欢迎光临
我们一直在努力

27天、3000元token费:我用 Trae 从零开发了一个 0.8MB 纯 C11 推理引擎,让 16GB 开发板跑起 30B 大模型

摘要:2026-08-17 ~ 09-12,我用 Trae(Agent 模式 + DeepSeek)从零开发了一个纯 C11、零第三方运行时的 ARM 边缘 LLM 推理引擎。27 天里完成 29 次提交、11 页 Wiki、5 篇技术文档、90 篇教程,并让一块 15.6 GiB 内存的 RK3588 开发板跑起 17.66 GB 的 Qwen3-30B-A3B,服务峰值内存 14.23 GB → 1.11 GB。本文是完整开发实录:时间线、工作流、三个技术转折点、4 个被 AI 坑进文档的错误结论,以及一份可直接复用的规则模板。

关键词:Trae、AI 编程、结对开发、RK3588、ARM、大模型推理、C11、边缘计算、mmap、量化推理

适合读者:正在用 AI 写正经工程的开发者 / 做边缘 AI 部署的工程师 / 对推理引擎感兴趣的同学

目录

  • 一、先说结论:这 27 天我做成了什么
  • 二、为什么我要手搓一个引擎
  • 三、27 天时间线复盘(真实日期)
  • 四、我具体是怎么用 Trae 的(工作流)
  • 五、三个技术转折点
  • 六、4 个被 AI 坑进文档的错误结论
  • 七、成果数据(全部标注口径)
  • 八、反思:AI 结对把瓶颈搬到了哪里
  • 九、可直接复制的规则模板
  • 十、诚实边界

一、先说结论:这 27 天我做成了什么

项结果
周期 27 天(2026-08-17 ~ 09-12,其中 23 天有文件改动)
成本 约 3000 元 token 费(一个月)
产物 纯 C11 引擎,单文件约 0.8 MB(818,872 字节,v0 测点)、28 个 C 文件、零第三方运行时
看家本事 逐层推理:30B-A3B 服务峰值 14.23 GB → 1.11 GB(12.8×),输出与全层档逐位一致
落地 RK3588(Orange Pi 5 Plus,15.6 GiB 内存)纯 CPU 跑起 17.66 GB 的 Qwen3-30B-A3B
配套 29 次提交 | 11 页 Wiki | 5 篇技术文档 | 90 篇教程 | 一键复现脚本

但今天我想讲的不是这些数字,是过程。因为如果只看结果,你会以为“AI 帮我把代码写了,所以我很快”。真实的体感完全不是这样。

二、为什么我要手搓一个引擎

起因很简单:我想在一块几百块的开发板上跑大模型。试过现成方案后,撞上三堵墙:

第一堵是内存墙。主流 ARM 开发板只有 15.6 GiB 可用内存,而一个 q4 量化的 30B MoE 模型权重文件就是 17.66 GB——权重比内存还大。常规“全量加载常驻”路线直接出局(实测全层档服务峰值 14.23 GB,几乎顶满整块板)。

第二堵是体积墙。主流框架型方案(Python + 推理框架 + 加速栈)动辄几 GB,边缘设备的存储和内存都吃紧,而且依赖链条长得没法审计。

第三堵是成本墙。云端 API 按 token 计费,账单随用量持续发生;而我想做的场景(产线问答、离线文档处理)既高频又敏感,既贵又不合规。

想清楚之后我发现:真正要破的不是“把权重压得更小”,而是“取消权重必须同时驻留这个前提”。这个想法,就是我后面 27 天全部工作的主线。

三、27 天时间线复盘(真实日期)

下面的日期来自我本地的 Trae 会话记录与 Git 提交记录,两条线可以互相印证。

日期做了什么
08-17 项目启动。定下三件事:纯 C11、零第三方运行时、目标板 RK3588
08-18 ~ 08-28 内核层攻坚:手写 NEON 量化 GEMM/GEMV、VQF 权重格式、KV 缓存分页、连续批处理
08-31 服务层改造:改为手动加载模式(/admin/api/model/load),解决边缘场景下模型切换的痛点
09-01 并发模型改造:把 vllm_batch.c 里的轮询睡眠换成 pthread_cond_t 事件驱动
09-05 首次开源发布(v0),同时补上模型支持范围声明与口径说明
09-06 ~ 09-10 v1 大重构:纯 VQF 运行时、逐层推理、KV v2 惰性分配、独立转换工具、attestation
09-11 v1.0 测试版发布
09-12 板端实测矩阵:14 个 serve 配置点 + 一键复现脚本 + Wiki 收口

一个细节,能说明 AI 结对最大的价值:9 月 1 日那条改造——我在会话里只写了一句“把轮询睡眠换成事件驱动机制”,它给出的是 pthread_cond_wait(&b->cv, &b->cv_mu) 的完整实现,到今天我文档里记的还是这句话,而代码在 src/serve/vllm_batch.c:209 原样躺着。

这种“当时的记录 → 现在还在的代码”的一致性,是 AI 结对最被低估的好处:它让“我当时的想法”和“最后落地的实现”之间,几乎没有损耗。

四、我具体是怎么用 Trae 的(工作流)

这一段是本文最实用的部分。我不是“打开对话问它怎么写代码”,而是把它当成一个需要被约束的工程师。

4.1 第一步:把它当项目,不是当搜索框

在 Trae 里以独立项目打开工作目录(我的项目目录名会出现在 Trae 的 MCP 配置目录里,这说明它是以项目为单位管理的,而不是临时会话)。好处:项目记忆会累积。我后面定的口径规则、踩坑记录,它会一直带着。

4.2 第二步:先给规则,再给任务

这是最关键的一步。我不会直接说“帮我写个 KV 缓存”,我会先把规则文件摆好(见第九节模板)。规则里最重要的三类:

  • 数字口径规则(什么数字必须标什么口径、不许跨口径混表)
  • 自证日志规则(任何优化必须打印一行能证明它生效的日志)
  • 汇报格式规则(说“改完了”必须给文件路径 + 行号)
  • 4.3 第三步:给它一条“上板”的通道

    这是我做得最对的一个决定。我给项目加了 tools/rk_remote.py——一个 SSH 执行/上传工具。它就能自己完成“写脚本 → 传到板子 → 执行 → 读日志 → 改代码”的闭环。一句提醒:Windows 侧写的 .sh 传到 Linux 后要先去 CR(sed -i "s/\\r$//"),否则报 not found——这个坑我踩过。

    4.4 第四步:让它自己证明自己

    我要求每个功能都要有自证日志。比如启用逐层推理时,引擎会打印:

    [VQF-STREAM] enabled keep=1 nl=48 segs=11 per-layer=334.1MB data=16847.2MB resident~808.4MB rss=988kB

    data=16847.2MB 是权重总量,resident~808.4MB 是实际常驻。有了这行日志,“AI 说它生效了”这个问题,就从信任问题变成了读日志问题。

    五、三个技术转折点

    转折点一:把“量化 + 布局重排”从推理期挪到转换期

    最初的做法是常规流程:启动时读权重 → 逐层量化 → 重排布局。结果 2B 模型在板端光加载就要 20 多秒。后来我把量化与 8×8/4×4 布局重排全部固化到转换期,推理时只需 mmap + 指针直挂。意外收获:转换与推理共用同一套量化代码,这直接消灭了“两套实现漂移”的风险,也是后来“逐层档与全层档输出逐位一致”能成立的前提。

    转折点二:发现“驱逐是免费的”

    逐层推理的核心是:每层权重算完就 madvise(MADV_DONTNEED) 释放,只留 keep 层常驻。为什么这个设计能成立?因为映射是只读的,页面是干净页——驱逐不需要回写。下次用到再从文件重建。所以它是时间换内存,不是有损近似。这个认识一旦成立,后面的一切就顺了:权重常驻内存不再随模型体积线性增长。

    转折点三:发现“最贵的优化”是一个环境变量

    我的 30B 多轮追问 prefill 原来是 722 秒 / 822 秒——基本等于不可用。后来发现引擎里 L3 驱逐与前缀复用默认是互斥的,置上 VLLM_L3_PREFIX_REUSE=1 让二者共存后,同样的请求变成 4.7 秒 / 3.2 秒。一个环境变量,150 倍。这个坑的教训是:“优化不生效”往往不是优化没用,而是它被另一个机制静默关掉了。

    六、4 个被 AI 坑进文档的错误结论

    这一段是我写这篇文章的真正原因。AI 从没对我撒过谎。它只是特别擅长把错的结论,写得像对的一样自信、一样完整、一样有条理。下面 4 个错误结论,每一个都进过我的文档。

    坑一:同一个数字,我写了三遍,三遍都对,但都不一样

    我要写“逐层推理的 decode 代价”。AI 给了我 +37%,我信了,写进文档。后来自己核对,发现同一指标在不同口径下是:

    口径decode 代价
    冷页缓存 + –threads 4 +86%(207 → 385 ms/tok)
    冷页缓存 + –threads 8 +37%(429 → 586 ms/tok)
    serve 稳态热档 +34.6%(458.4 → 617.2 ms/tok)

    三个数字都是真的。 +37% 没错,+86% 也没错——它们只是问的不是同一个问题。如果我当初只写 +37% 发出去,我就是在用最漂亮的那个口径,去描述一个跨口径的事实。这不是撒谎,但比撒谎更糟——因为它看起来严谨,还有数据支撑。

    七、成果数据(全部标注口径)

    本节所有数字均标注测量口径,避免跨口径混用。

    指标数值口径
    引擎体积 0.8 MB(818,872 字节) v0 测点,单文件
    服务峰值内存 14.23 GB → 1.11 GB 30B-A3B,全层档 vs 逐层档
    内存降幅 12.8× 同上
    decode 代价 +34.6% serve 稳态热档(458.4 → 617.2 ms/tok)
    prefill 耗时 722 s → 4.7 s 30B 多轮追问,置 VLLM_L3_PREFIX_REUSE=1

    八、反思:AI 结对把瓶颈搬到了哪里

    这 27 天下来,我最大的感受是:AI 结对并没有让“写代码”消失,它只是把瓶颈从“写”搬到了“审”。以前我花时间写,现在我花时间验证它写的是不是我要的。数字口径、日志自证、跨口径核对——这些原本是工程素养,现在成了 AI 结对时代的核心技能。AI 负责把想法变成代码,我负责把代码变成事实。

    九、可直接复制的规则模板

    下面是我在 Trae 项目里实际使用的规则模板,可直接复制使用。

    # 项目规则
    ## 1. 数字口径规则
    – 任何数字必须标注测量口径(环境、线程数、冷/热缓存、模型档位)
    – 禁止跨口径混表;同一

    赞(0)
    未经允许不得转载:171主机测评 » 27天、3000元token费:我用 Trae 从零开发了一个 0.8MB 纯 C11 推理引擎,让 16GB 开发板跑起 30B 大模型
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址