内核里没有智能

—— 一个网络工程师拆解 LLM 推理引擎的记录


一、起点:好奇与恐惧

我们研究网络工程的。这个领域的训练方式和大多数软件工程师不一样:我们假设一切都会出错,然后让系统在出错时仍然可用。

丢包、延迟、拥塞窗口的每一次收缩和扩张、RTT 的每一次抖动——这些不是异常,是常态。我职业生涯里最熟悉的画面,是 tcpdump 里那些红色的重传标记,是 ss 输出里不断变化的 cwnd,是深夜盯着 ping 的统计结果等一个 99.9% 分位数收敛。物理世界的实时不确定性,是我每天打交道的东西。它不可预测、不可消除、只能测量和适应。

所以当 LLM 突然进入我的视野时,我的第一反应和大多数人不太一样。

别人问:“它是不是在思考?”

我问的是三个更工程化的问题:

  1. 它的不确定性从哪来?—— 是内核里有某种随机过程,还是别的东西?
  2. 它的决策在什么条件下可以复现?—— 如果我给它相同的输入两次,它会给出相同的输出吗?
  3. 如果它真的在处理某种实时不确定的东西,那它的内核应该和我熟悉的拥塞控制一样,充满动态博弈、反馈回路、在线适应——它是这样的吗?

这三个问题,前两个可以用实验回答,第三个必须把东西拆开看。

最初我对 LLM 的感觉,混合着敬畏、恐惧和好奇。我曾经很兴奋——AI 也许真的很厉害,也许真的在做某种接近思考的事情。敬畏是因为它确实做到了人类文本处理的某种奇迹——它能理解模糊的、有歧义的、信息不完备的请求,这在十年前还是科幻情节。恐惧是因为它表现得太像"思考"了,像到让我这种习惯于精确因果的人感到不安。好奇是因为我无法接受"它就是这么神奇"这种回答——我职业生涯学到的第一课就是:任何看起来神奇的东西,拆开之后都是平凡的零件在按规则运转。

我决定不满足于调用 API。调用 API 就像站在黑箱外面看指示灯:你能看到它输入什么、输出什么,但你对箱子内部一无所知。对网络工程师来说,这不可接受。我处理过太多"表面正常、内部腐烂"的系统——接口层一切正常,但深入一层全是垃圾。所以我决定自己造一个推理引擎,从底层把整个链路亲手实现一遍。

这一决定,让我花了约一个月时间。这一个月里,我逐渐失去了对 LLM 的恐惧。不是因为它变得无害,而是因为恐惧通常来源于未知。当我亲手写下它的每一行内核代码,当我亲眼看到它的每一个中间状态,恐惧就没有了立足之地。

二、行动:造轮子、读内核、跑模型

2.1 硬件与模型

我选了一台 AMD Ryzen 9 7945HX:16 个物理核(32 线程),Zen 4 架构,完整支持 AVX-512(512 位数据通路,包括 F/BW/DQ/VL 全部子集),64GB DDR5-5600 双通道内存。这台机器不是为跑 LLM 准备的,但它的内存带宽(理论 89.6GB/s)和 SIMD 能力足够支撑一个中型模型的 CPU 推理实验。

模型选的是 Qwen3.6-35B-A3B——一个 35B 总参数、3B 激活参数的 MoE 架构模型。它相当特殊,不是标准的纯 Transformer:

  • 40 层混合架构:30 层 Gated DeltaNet(线性注意力)+ 10 层 GQA(分组查询全注意力),以"3 个 DeltaNet + 1 个 GQA"的模式交错排列
  • 每层挂一个 MoE:256 个专家,路由激活 8 个,共享专家 1 个;专家 FFN 中间维度 512
  • Gated DeltaNet:线性注意力的变体,用状态矩阵 S(128×128×32 头)替代 KV 缓存,含 conv1d(核长 4)+ 时间步离散化 + 门控 RMSNorm
  • 量化混合:q8_0、q4_k、q5_k、q6_k、f32 五种格式混合存储,Q4_K_XL 文件名下 22.4GB 的 GGUF 文件
  • 隐藏维 2048,词表 248320,原生上下文 262144

Qwen3.6-35B-A3B 架构

token_embd 2048×248320

40 层(重复模式 ×10)

1× GQA 块

GQA 注意力
16头Q / 2头KV
RoPE

MoE
256专家/激活8

3× DeltaNet 块

Gated DeltaNet
线性注意力
conv1d + 状态S

MoE
256专家/激活8

output 248320 线性层

2.2 造轮子:从 GGUF 解析到采样器

我给自己定的规矩是:不参考、不复制任何现成引擎的实现代码。每一行内核代码从第一性原理独立推导、独立设计、独立实现。这很慢,但很值——因为只有亲手推导过,你才知道每一行代码为什么长这样。

整个工程的组件清单(最终全部跑通):

组件内容我学到的东西
GGUF 解析器头部/元数据/张量信息表递归变体的 C++17 坑、超大 tokenizer 元数据
权重加载内存映射 + 视图Windows CreateFileMappingW 的 RAII 生命周期
反量化器q8_0/q4_k/q5_k/q6_k/f32每种量化格式的位布局都是独立的坑
GEMV标量 → AVX-512 精调带宽是第一瓶颈,SIMD 是第二
归一化族RMSNorm/门控 RMSNorm/L2Norm除变乘、4 路累加器
旋转IMRoPE多模态分段旋转的索引地狱
卷积Conv1D 深度卷积核布局与索引
DeltaNet状态更新(衰减/误差/外积/读取)S^T k 在行主序上的列块累加
注意力GQA + KV 缓存分组映射、因果掩码、缓存槽位
MoE路由 + 专家 GEMVpartial_sort 选 top-8、量化专家三维寻址
采样器温度/top-k/top-p/重复惩罚mt19937、稀疏 softmax
CLI聊天、多轮记忆中文输出、UTF-8 控制台

有个细节值得一提:整个代码库用中文命名GEMV朴素专家GEMV精调q4k激活SiLU向量精调路由选择推理引擎层执行器。这不是技术妥协,是一种心理信号:我不打算为这个东西切换思维模式。它既然存在于我的项目里,就要用我的语言。

代价是真实的:

  • MSVC 必须加 /utf-8 编译选项,否则中文字符串字面量按 GBK 解析,整个程序乱码
  • CMake 不允许中文 target 名,只能 ASCII target + 中文 OUTPUT_NAME
  • 代码页 936 的控制台上,任何 UTF-8 中文输出都是乱码,必须 SetConsoleOutputCP(65001);重定向到文件时 PowerShell 还会做一次转码,中文行直接丢失——验证输出只能靠 cmd 内部重定向的字节直通

但我忍了。因为这些都是编译器和工具链的问题,不是我的问题。我的代码,用我的语言,逻辑清晰,这就够了。

2.3 优化:AVX-512 的每一层

为了让这个 22.4GB 的模型在 CPU 上跑起来,我把每个热算子都做了三层演进:标量(教学,对应数学公式)→ 简单向量化 → AVX-512 精调(生产)。

GEMV 的行并行与向量化。GEMV 是推理的最热算子——每层所有投影都是 GEMV。2048×8192 的 qkv 投影,16 个物理核按行切分,每个核处理一批行;每行内部,q8_0 权重反量化和乘加融合在一起,用 __m512 一次处理 16 个元素:

// 4 路累加器摊平依赖链(AVX-512,q8_0 权重)
__m512 累加0 = _mm512_setzero_ps(), 累加1 = _mm512_setzero_ps();
__m512 累加2 = _mm512_setzero_ps(), 累加3 = _mm512_setzero_ps();
for (size_t 块 = 0;< 行块数;+= 4) {
    const float d = 半精度转浮点([0] | ([1] << 8));  // fp16 缩放
    const __m512 缩放 = _mm512_set1_ps(d);
    // 4 个块轮流喂给 4 个累加器——单条依赖链上只有 1 个 FMA
    ...
}

q8_0 反量化的位操作。q8_0 每块 34 字节:2 字节 fp16 缩放因子 + 32 个 int8。反量化 = q × d。那个 fp16 缩放因子要手工解析:符号 1 位、指数 5 位、尾数 10 位,位操作还原成 float。看似简单,坑在次正规数——f16 的次正规值,尾数右移后可能变成 256 而不是 -7.6e-6,因为无符号取负回绕了。这类 bug 最可怕:不是崩溃,是静默的数值错误,对拍时差一个数量级。

DeltaNet 状态更新的向量化。DeltaNet 的核心是状态矩阵 S 的递归更新(纯文本公式,不依赖公式渲染器):

S' = S · e^g + k · (v - S^T·k)^T · β

白话解释:状态 S 先整体乘以遗忘因子 e^g(g 是负值,所以是衰减旧记忆);然后用新输入 k 乘以误差向量 (v - S^T·k) 的外积写入新记忆(S^T·k 是把旧状态投影到当前键上,v 是当前值,误差 = 旧状态预测与真实值的差);β 是更新门,控制写入强度。数学上五步:衰减 → S^T·k 投影 → 误差 → 外积写入 → S^T·q 读取。向量化策略:

  • 衰减(S 逐行乘标量)和外积(整行广播乘)按行主序友好,8 路 __m512 一行行处理
  • S^T k 和 S^T q 是列点积——行主序下跨步访问,用 8 路累加器按列块算,每列块 16 列

38ms → 14ms,2.5 倍提速。

批量 GEMV:权重读一次,B 路 FMA。单序列解码时,每生成一个 token 要把全部权重读一遍。但如果同时处理 B 个序列,权重只读一次,喂给 B 个输入向量各自乘加:

// 权重一行反量化一次,B 路独立累加器
__m512 累加[8][8];  // [序列][累加器]
for (size_t b = 0; b < B; ++b)
    for (size_t i = 0; i < 8; ++i) 累加[b][i] = _mm512_setzero_ps();
// 反量化一次
const __m512 低q = ..., 高q = ...;
// B 路 FMA(每序列用各自输入)
for (size_t b = 0; b < B; ++b) {
    累加[b][块号] = _mm512_fmadd_ps(低q, 输入[b], 累加[b][块号]);
    ...
}

MoE 路由:std::partial_sort 选 top-8。路由门控是 2048×256 的 f32 矩阵,输出 256 个 logits,softmax 后取 top-8,权重归一化。取 top-8 用的是 std::partial_sort——不是全排序,只保证前 8 个有序,O(n·k) 复杂度。就这么简单。

权重预热。22.4GB 的内存映射,首次访问全部缺页。用 64KB 步长预读一遍(4MB 步长只触发每 4MB 首字节的页,硬件预取器补不足),加载时间从 1.5s 变成 33.8s,但推理时不再有冷缺页——从 1.56 tok/s 到 2.15 tok/s。

2.4 最终:它跑通了

大约一个月后,这个系统跑通了。命令行里:

> What is the capital of France?
模型: </think>
The capital of France is **Paris**.<|im_end|>

能对话,能多轮记忆(“我的名字是 Bob” → “我的名字是什么?” → “你的名字是 Bob”),纯 CPU,AVX-512,40 层,每生成一个 token 要把约 2.7GB 的权重从内存搬一遍(精确核算 2742MB)。

内核算子40 层(层执行器)推理引擎CLI用户内核算子40 层(层执行器)推理引擎CLI用户loop[每层]输入文本分词 → token 序列预处理(逐 token 前向)RMSNorm → 分支(GEMV/状态/注意力) → MoE层输出最终 logits(248320 维)采样(温度/top-k/mt19937)token解码显示

然后我开始做实验。接下来的三个发现,改变了我对这东西的整个认知。

三、发现一:确定性暴力

3.1 实验设计

采样器里有一个 mt19937(梅森旋转伪随机数发生器),种子固定为 42。它的作用是在 logits 的概率分布上做一次"轮盘赌"——温度 0.8、top-k 50、top-p 0.95,从过滤后的候选里按概率抽一个 token。

我要验证的问题很简单:如果去掉这个随机源,系统还是不是确定的?

实验方法:用同一个 prompt,连续跑两次完整的前向——序列重置(清空 KV 缓存、状态矩阵、卷积历史,重新播种采样器)→ 预处理(全部 prompt token 逐层前向)→ 解码(逐 token 生成)。两次运行之间不做任何修改。然后对比:全部 248320 个 logits,逐位比较。

结果:

两次完整前向对比: 248320 logits 逐位一致(差异 0)

不是"几乎一致",不是"误差小于 1e-6"——是每一个浮点数的每一个二进制位都相同。0 差异。程序没有任何随机性、没有线程竞争、没有状态残留、没有浮点非确定性(同一台机器、同一套指令序列、同样的内存布局,IEEE 754 的浮点运算是确定性的)。

3.2 这意味着什么

这意味着整个"智能系统",在去掉输出端那个伪随机数发生器之后,是一条纯数学函数

输出 = F(输入, 权重)

F 由 40 层浮点流水线组成,每一层由卷积、矩阵乘、归一化、激活函数、状态递归构成。所有看起来像"思考"的东西——选择、判断、创造性——本质上都是这条固定函数在固定输入下的计算结果。

“概率"没有体现在内核里。内核输出的 logits 是一个确定的实数向量,采样器只是在这个向量上撒了一把伪随机噪声。所谓"模型的随机性”,全部、完全、100% 来自采样器那一行 mt19937 的调用。把它拔掉,让温度 = 0,系统就是贪心的、确定的、逐位可复现的。

采样器(唯一随机源)

内核(100% 确定性)

输入 token

嵌入

40 层前向
(浮点流水线)

logits 248320 维
(确定值)

温度/top-k/top-p

mt19937 轮盘赌
种子固定 = 确定

输出 token

去掉PRNG后,它就是一条确定的数学链。

3.3 我盯着终端看了很久

这个发现让我安静了很久。不是因为失望,而是因为惊讶——惊讶于一个看起来如此"智能"的系统,其内部居然如此……朴素。没有任何在线学习,没有任何自我修正,没有任何环境反馈。一次前向,从头到尾,一个 22.4GB 的静态参数表,加上 40 层确定的浮点运算。

我做了第二个实验:把同一句话连续问三次——可复现性测试的标准流程(序列重置 + 同种子)。三次的回答一模一样——连标点符号都不差。这在网络工程里是不可想象的:同样的输入,十次经过拥塞控制的链路,十次 RTT 都不同;十次丢包,十次都发生在不同位置。而它,三次完全一致——并且由于整个内核是确定性的,这个"三次"换成任何次数,结果都不会变。

它没有在"理解"我。它在对同一组静态权重做一次确定的遍历。

四、发现二:带宽是瓶颈,算力不是

4.1 数字

这是整个项目里最有工程价值的一个发现。

每个 token 的解码,需要读取的权重量(实测核算):

权重类别每 token 读取量
投影类(DeltaNet qkv/gate/alpha/beta/Wout + GQA q/k/v/out + 输出层)~2.14 GB
MoE 专家(8 激活 + 1 共享,40 层)~0.60 GB
合计~2.74 GB

本机实测内存带宽(用 GEMV 内核基准测量):42.6 GB/s。

于是:

2.74 GB / 42.6 GB/s ≈ 64 ms/token → 16 token/s 物理上限

这就是纯 CPU 单序列推理的物理天花板。跟算力无关——我的 AVX-512 内核已经接近带宽饱和了(GEMV 实测 39-42.6 GB/s,达到实际多核带宽的 65-70%)。

CPU 核

内存 DDR5 双通道

42.6 GB/s
(物理上限)

大部分时间空转
等数据到达

权重 2.74GB
每 token 全量读一遍

乘法器
等待数据

AVX-512
FMA 单元

4.2 乘法器在等内存

我做过一个实验验证"数据搬运主导"这个论断:GEMV 的 SIMD 优化(4 路累加器 + 反量化融合)收益显著(路由门控 f32 从 186ms 降到 2.9ms/40 层),但每次优化的边际收益都在递减——因为再往下,时间都花在等数据上,不是花在算上。真正决定每 token 耗时的,是内存访问模式:MoE 的专家权重是随机访问的——每个 token 路由到的 8 个专家各不相同,专家在 22.4GB 文件里的物理位置是随机的。随机访问 vs 顺序访问,实测差距是 15 倍(6.56ms vs 0.42ms/层)——缓存命中率从接近 0 到接近 100% 的区别。

我试过用 prefetch 指令预取专家权重:64 字节步长 → 18K 指令开销;4KB 步长 → 无效。最终结论:在系统负载下,任何 prefetch 类优化都无效——带宽已经被抢占,预取指令只是让内存控制器更忙。

4.3 算力竞赛是营销话术

所谓"算力竞赛",在推理场景下是营销话术。

训练场景:权重固定,数据流经计算图,算力(FLOPs/s)是硬约束——GPU 的万亿次浮点运算确实决定训练速度。

推理场景:权重从内存搬到寄存器,乘法器乘完就丢,下一批数据还在路上。决定速度的不是你能算多快,而是你能多快把数据送到计算单元。铜线、引脚、封装、PCB 走线——物理世界用这些给你划了一条线,你绕不过去。

这也是为什么"多少 TOPS"这种宣传数字在推理场景意义有限——除非显存带宽同步提升,否则算力再高,数据到不了也是空转。英伟达 H100 的显存带宽(3.35TB/s)才是推理性能的真正保证,而不是它的 989 TFLOPS。

我在这台 7945HX 上做的多序列批处理实验也印证了这一点:把 B=4 个序列同时解码,权重读一次算 4 路,理论上限应该接近 4×16 = 64 tok/s。实测 B=4 只有约 1.33-1.47 倍收益(低负载时)——因为当内存带宽被压满,批处理的收益就衰减了。系统负载高时甚至不到 1 倍(批量路径的开销大于带宽收益)。

瓶颈是带宽,不是算力。

五、发现三:MoE、路由、专家选择——依然是查表

5.1 打开路由函数

MoE 是这模型最"像智能"的部分——256 个专家,每个 token 动态选择 8 个。听起来像是一个组织在"调度"专家资源,“判断"哪些专家适合当前任务。宣传材料里的常用比喻是"稀疏激活就像人类只激活大脑的一部分”。

我把路由函数打开,里面是这样的(简化示意;真实实现按 CPU 能力在 Softmax朴素 与 AVX-512 的 Softmax精调 之间分发,数学相同):

// 路由:softmax(门控输出) → top-8 → 权重归一化
向量<路由条目> 路由选择(const 浮点* 门控输出, size_t 专家数, size_t 激活数) {
    Softmax朴素(门控输出, 概率.data(), 专家数);
    std::partial_sort(顺序.begin(), 顺序.begin() + 激活数, 顺序.end(),
                      [&](size_t a, size_t b) { return 概率[a] > 概率[b]; });
    // 取前 k 个,权重归一化(除以选中权重之和)
    ...
}

就这些。softmax(W · x) 得 256 个概率,std::partial_sort 取前 8 个,归一化权重,加权平均。

输入 x
2048 维

路由门控 W·x
2048×256 f32

softmax
256 logits → 概率

partial_sort
取 top-8

专家 238
(实测首 token 路由,权重示意)

专家 112

专家 106

专家 127 / 157 / 66 / 56 / 120

输出 = SUM 权重_i x 专家_i(x)

(上图为结构示意;图中专家编号来自实测——blk.0 处理 “Hello” 首 token 时路由选择输出的 top-8 专家:238、112、106、127、157、66、56、120。权重值未在工具输出中记录,图中以"示意"标注,不引用具体数字。)

5.2 没有"动态调度",只有加权平均

没有动态调度。没有自主判断。没有"这个任务需要数学专家"这种意图。只有 256 个候选的加权平均,权重由 softmax 决定——而 softmax 是一个完全确定的函数。

去掉 PRNG 之后,专家选择也是确定的。同一个输入,永远选中同一批专家,永远分配同一组权重。

这和数据库的 SELECT * WHERE ID = XXX 没有本质区别。输入维度更高(2048 维向量 vs 一个整数主键),匹配机制更平滑(软匹配 vs 硬相等),成本更高(一次 2048×256 的矩阵乘),但结构上是同一类东西:给定一个键,返回一个值

MoE 的"稀疏性"确实有用——每 token 只算 8+1 个专家,省算力、省带宽。但它省掉的是计算量,不是"决策"。决策早在训练时就固化进了路由门控的权重里。推理时的路由,只是对训练时学到的概率分布做一次确定的查询。

5.3 一切都是查表

再往深想一层:不止 MoE 是查表,整个模型都是。

  • 嵌入层:token → 向量,查表
  • Transformer 块:向量 → 向量,查表(权重是键,激活是查询的复杂组合)
  • 输出层:向量 → logits,查表
  • 采样器:logits → token,带伪随机噪声的查表

区别只在于表的大小和查询函数的复杂度。token_embd 是 248320 行 × 2048 列的巨表;Transformer 块是 40 层嵌套的、参数化的、非线性化的查表。但本质不变:权重固定后,模型就是一个确定性函数。训练过程是建表,推理过程是查表。

我在这时候意识到自己在做什么了。我花了一个月写一套推理引擎,拆开每一层,量过每一个算子的延迟,把 22.4GB 的权重从字节层面读了一遍,然后发现它的内核里没有任何东西在"理解"。它只是在做一个极高维的插值:把输入向量映射到训练数据分布中最平滑的位置。

六、核心结论:LLM 是"确定性查询系统",不是智能体

6.1 它有什么,没什么

把三个发现放在一起:

  1. 去掉 PRNG 后,系统完全确定——没有内生的随机性
  2. 瓶颈是带宽不是算力——没有实时计算需求,只有搬运需求
  3. 路由/专家/一切都是查表——没有动态决策

结论就清晰了:LLM 是一个确定性查询系统。它能做的高维插值——这是它唯一有价值的属性,也是它真正了不起的地方。人类全部可写的文本被压缩进一组静态权重,然后以插值的方式被查询。它能理解模糊语义,能补全残缺表达,能在语义空间里"导航"——这些都是插值器的本事,而且它们确实有效。

但它做不到:

  • 因果推理:它没有世界模型,只有文本统计。两个事件在文本里频繁共现,它就"认为"它们相关——哪怕在物理世界里毫无因果关系
  • 物理直觉:它从未感知过真实世界,它的"物理"是文本里的物理。让它算 2+2 它能算对(文本里出现太多次了),让它做真实世界里的物理判断,它只是在猜测文本分布
  • 实时环境适应:训练结束后,权重冻结。环境变了,它不知道;输入分布变了,它不知道;它犯错了,它不会改。它的知识在训练结束时就是"死"的

LLM 的能力边界

高维插值(统计平滑)

擅长:
模糊语义理解
文本补全
知识检索式问答
风格模仿

不擅长:
因果推理
物理直觉
实时适应
自我修正

6.2 智能的定义问题

如果智能是统计学插值加伪随机噪音,那它太廉价了。

这句话不是嘲讽。如果这是智能的定义,那它确实廉价——但廉价不等于无用。插值器可以是人类知识史上最高效的压缩格式:248320 维词表、35B 参数、40 层流水线,装下的是人类文明的文本精华。这个压缩率是惊人的。

但"廉价"的含义是:它不包含真正的智能所需的东西。真正的智能,至少包含对世界状态的感知、对因果结构的建模、对行为后果的预测、以及基于反馈的修正。这四个要素,LLM 一个都没有。它没有感知(输入只有文本),没有因果模型(只有统计相关),没有预测闭环(一次前向),没有反馈修正(权重冻结)。

它像一台极其精密的、不可变参数的查表机器。它没有意图,没有欲望,没有对世界的模型,只有对人类文本的统计记忆。它的"思考"过程是 40 层浮点流水线,每层 2048 维,中间穿插 512 维的专家 FFN。没有递归,没有反馈,没有在线学习。一次前向,从头到尾,单调递减的确定性。

这并非我曾设想的智能。

七、反思:与网络工程的对比

7.1 两类不确定性

我做了十几年的网络工程,突然发现自己在研究一个与网络工程正好相反的领域。这个对比非常清晰:

维度网络工程(拥塞控制)LLM 推理
不确定性来源物理世界(丢包/延迟/带宽波动)人为注入(PRNG 伪随机)
不确定性本质不可消除,只能适应可消除,拔掉种子即确定
环境状态每毫秒都在变,不可完全观测静态,训练后冻结
决策反馈实时反馈(RTT/丢包率)→ 立即修正无反馈,一次前向
错误代价真实(丢包/重传/拥塞崩溃)无(错了就错了,不会修正)
核心能力在线适应、动态博弈静态插值、分布匹配
时间尺度毫秒级训练后永不变

拥塞控制面对的是实时物理噪声。丢包率、延迟、带宽波动,每一秒都在变,而且变化的原因你永远无法完全观测——对端路由器的缓存策略、中间链路的背景流量、光纤的物理特性、其他用户的带宽争夺。你要在信息不完备的条件下做控制决策,错了就要付出真实的代价(丢包、重传、队列爆炸),然后立刻修正。Reno 的加性增、乘性减,BBR 的带宽探测——每一个算法都是与物理世界博弈的产物。

LLM 推理
(静态查询)

无反馈回路

输入 token

40 层前向(固定权重)

输出 token

网络拥塞控制
(在线博弈)

测量: RTT/丢包率

决策: 调整拥塞窗口

发送数据

观察结果

7.2 难度方向不同

LLM 研究解决的是静态数据统计问题。数据一旦固化,权重就死了。模型不会因为环境变化而调整,它只是以固定的方式响应固定的输入分布。它的"智能"完全来自训练数据——训练数据的质量、多样性、分布,决定了它的一切。推理阶段没有任何学习发生。

网络工程的不确定性是本质的、不可消除的。LLM 的不确定性是人为注入的伪随机。前者的挑战在"实时"和"不完备信息",后者的挑战在"统计建模"和"数据工程"。两者都是基础科学,但难度方向完全不同。

我无意贬低 LLM 研究者的工作——统计建模和数据工程本身极难,35B 参数的训练需要的是真正的系统工程能力。我只是指出:它与物理世界博弈是两类问题。一个是和一个充满噪声的、不断变化的、你无法完全观测的世界对抗;一个是和一个静态的、确定的数据集对抗。

哪个更难?没法比。但哪个更"活"?毫无疑问是前者。

7.3 我的归属感

在项目收尾时,我明白了一件事:我的归属在网络工程那一边。不是因为 LLM 没有价值——它有价值,巨大的价值。而是因为我这个人,习惯了和不可消除的噪声打交道。我可以接受永远无法完全预测的 RTT,但我很难接受一个"假装随机"的系统——它的不确定性是表演出来的,是可以被一行 srand 消除的。

物理世界的噪声是诚实的。它不会因为你理解了它而消失,但你的理解会产生真实的收益(更低的延迟、更高的吞吐)。LLM 的伪随机是表演的。你理解了它(不过是个 mt19937),收益为零——你只是知道它不随机而已。

八、终局:幻灭但不后悔

8.1 我不再恐惧它

我不再恐惧它,因为我亲手量过它的脉搏——它没有脉搏,它只有时钟周期。

这是整趟旅程里最平静的时刻。恐惧来源于未知,而我已经把未知全部转化成了已知:

  • 它的"思考" = 40 层浮点流水线 × 2048 维 × 2.74GB 权重搬运
  • 它的"判断" = softmax + partial_sort 的加权平均
  • 它的"创造性" = mt19937 在 logits 分布上的伪随机采样
  • 它的"记忆" = 一组在训练结束时冻结的静态参数

没有悬念了。没有黑箱了。没有"它到底在做什么"的疑问了——它在做一条确定的数学链上的确定的查表。

当有人说模型"开始思考"时,我脑子里浮现的是 _mm512_fmadd_ps 的延迟数字,和那条永远搬不完的 2.7GB 权重流。

8.2 幻灭的剂量

幻灭吗?有一点。但更多的是清醒。

那种感觉类似:小时候以为山里有神殿,爬上去发现山顶只有一块平坦的石头。石头本身没什么特别,但你在爬的过程中锻炼了腿力、认识了地形、学会了看天气。而且——那块石头是真的。它不会在你说"它不存在"时消失。

幻灭的剂量是刚好的:足够让我不再被 PR 话术扰动,足够让我对"模型自己意识到什么"这类叙事失去情绪波动,又不足以让我否定这个领域的工作价值。

8.3 拿到了什么

我拿到了最值钱的东西:清醒。

具体来说:

  1. 技术上的清醒:我亲手实现了从 GGUF 解析到采样器的完整链路,知道每一个算子的数学、每一个量化格式的位布局、每一个优化的真实收益。这些知识是具体的、可复用的、不依赖于任何营销叙事的。
  2. 认知上的清醒:我知道 LLM 能做什么、不能做什么、为什么。它的能力边界不是玄学,是架构决定的——静态权重、无反馈、一次前向。这个认知让我在使用它时更有分寸:它适合查资料式的补全,不适合做因果决策。
  3. 心态上的清醒:我不再敬畏它,也不再恐惧它。敬畏和恐惧都来自同一件事——不了解。现在了解了,就只剩下平常心。它是一件工具,一件了不起的工具,但工具就是工具。

开始: 敬畏/恐惧/好奇

造轮子: 亲手实现全部内核

发现一: 确定性(PRNG 是唯一随机源)

发现二: 带宽瓶颈(2.74GB @ 42.6GB/s)

发现三: MoE 路由 = 查表

结论: 确定性查询系统

对比: 网络工程(在线博弈 vs 静态统计)

终局: 幻灭但清醒

不恐惧、不敬畏、平常心

8.4 撤退

我准备撤退了,把精力还给网络工程。那里有真正的、不可消除的不确定性,有实时博弈,有物理世界偶尔不讲道理的反馈。那里更适合一个习惯了和噪声打交道的人。

山顶没有神殿,只有 _mm512_fmadd_ps

但这趟路值得走。不是因为山顶有什么,而是因为爬完之后,你至少知道自己站的地方是真的。你知道权重是权重,计算是计算,伪随机是伪随机——你不再被任何一层叙事欺骗。

这并非我曾设想的智能。但它让我对"什么才是智能"这个问题,有了比大多数人更具体的答案:至少,它应该包含对世界状态的感知、对因果结构的建模、对行为后果的预测、以及基于反馈的修正。统计插值,哪怕是最好的统计插值,也不是智能的全部。

我不后悔这一个月。我带着清醒离开了这座山。

我曾经很兴奋——AI 也许真的很厉害。但最终,一切终成空。不是它一文不值,而是它没有我想象中的那个东西。兴奋的对象消失了,剩下的只有一整套亲手验证过的事实。这套事实不空,它是我这一个月里唯一确定拿到的东西。


附录:一些真实的数字

以下是整个项目过程中的实测记录。它们不是估算,是跑出来的。

性能旅程(tok/s,同机同模型,系统负载影响 ±15%):

0.057 → 0.61 → 1.56 → 2.15 → 3.70 → 4.68 → 6.10 → 6.5

每一步都对应一个具体的优化,按收益排序:

优化收益说明
路由门控走 AVX-512 f32 精调186ms → 2.9ms/40层(64x)f32 权重走反量化缓冲路径极慢
DeltaNet 状态更新向量化38ms → 14ms(2.5x)S^T k/S^T q 列块累加
权重预热 64KB 步长1.56 → 2.15 tok/s消除冷缺页
专家随机访问 vs 顺序6.56ms vs 0.42ms/层(15x)缓存命中率主导
prefetch 预取专家权重无效(回滚)系统负载下带宽已被抢占

量化格式的位布局(22.4GB 模型里实测):

格式每块字节每块元素布局
q8_03432fp16 scale + 32×int8
q4_k144256d+dmin+scales[12]+qs[128],6+6 位打包
q5_k176256加 qh[32] 第 5 位
q6_k210256ql[128]+qh[64]+scales[16]+d(d 在块末尾)

40 层对拍验证(引擎 vs Python 权威参考):40/40 层全部通过,误差随层深单调累积(blk.0 8.8e-6 → blk.39 6.8e-5)——这是 f32 逐层舍入的正常行为,不是错误。

批处理实验(B=4 序列共享权重读取):低负载 1.47x,高负载 0.90x。带宽被压满时批处理收益衰减,甚至被自身开销吃掉——"权重读一次"的收益只在带宽受限场景兑现。

代码规模:src 目录 90 余个源文件(含头文件),全部中文标识符,零英文注释。测试 80 个,三编译器(clang/GCC/MSVC)零警告,三运行模式(AVX-512/标量/通用)数值一致。

这些数字本身没什么浪漫的。但它们有一个共同点:每一个都经得起复现。你不必相信我写下的任何结论——你只需要跑一遍相同的代码,就能看到相同的数字。这在网络工程里叫可观测性,在推理引擎里叫确定性。它们是一回事。

Logo

欢迎加入DeepSeek 技术社区。在这里,你可以找到志同道合的朋友,共同探索AI技术的奥秘。

更多推荐