全景
这一部分先回答「candle 在张量运算和硬件之间放了几层」,再把算子主线和推理主线各从头到尾走一遍,后面各章都从这里出发。实验在 CPU(开与不开 accelerate)和 Metal 上各跑一遍,Metal 的计时都注明 macOS 的 Metal 库缓存是冷是热。
- candle 解决什么问题:README 的「make serverless inference possible」落在哪:
Tensor和Storage两层、枚举后端、内建的自动微分、立即执行、手写内核;README 的 Backends 一段没写 Metal;一个 CPU matmul 的二进制 0.92 MB,开metal多出的一大半是嵌进去的.metal源码;和 burn、tch-rs、PyTorch 只对照能核实的部分。 - 一次 matmul:算子主线逐层走:lldb 看到 CPU 上四个 candle 函数之后就是
gemm或 Accelerate 的SGEMM;Metal 上matmul十几微秒返回,唯一一次提交和等待发生在to_vec2里;1024² f32 上 Accelerate 0.9 ms、gemmcrate 3.8 ms、Metal 1.4 ms;冷缓存时第一次 matmul 要等 3.8 s 编译 gemm 库。 - 生成一个 token:推理主线逐步走:SmolLM2-135M Q8_0 分阶段计时;热缓存下 Metal 每个 decode 步 2.5 ms、CPU 8 ms;冷缓存时建模型、prefill、第一个 decode 步各编译一批
.metal库,合计约 12 s,这就是「Metal 比 CPU 慢」的全部原因;读 GGUF 头部换成BufReader快 4 倍。
flowchart TB why["candle 解决什么问题"] --> mm["一次 matmul"] why --> tok["生成一个 token"] mm --> tensor["02 张量"] mm --> backend["03 后端"] mm --> ad["04 自动微分"] tok --> nn["05 神经网络层"] tok --> quant["06 量化"] tok --> models["07 模型"]
💬 关联讨论
发起讨论加载中...