Kapitsa 源码拆解 04:GPU 与 ANE 如何同步、并行与回滚?
沿 ready/done、两半 wavefront 和失败重跑,理解“同时工作”背后的依赖关系。
沿 ready/done、两半 wavefront 和失败重跑,理解“同时工作”背后的依赖关系。
先分清 token 行、隐藏维度和 FFN 中间通道,再看分工公式、W8A8 与 IOSurface。
用明确的矩阵形状和字节算例,理解量化权重、Buffer 视图,以及统一内存为什么仍需要同步。
固定 0.2.17 / 919b1b2,从请求、prefill、decode 到会话状态,建立阅读这套原生推理引擎的地图。
从四维布局、1×1 卷积、多头注意力到权重复用,用四张图理解 Apple 2022 年的 ANE 优化思路。
最近看 Kapitsa 的 ANE 实现时,我想先弄明白一个很小的问题:如果只计算两个矩阵相乘,数据究竟怎样进入 Apple Neural Engine,答案又从哪里回来? 于是把例子收进一个 main.mm 文件:输入是两个 2×2 矩阵,计算图内嵌在文件里,乘法交给 ANE,最后打印结果。本文先把硬件和内存关系画清楚,再顺着这个例子读代码。 1. ANE 是什么,它和 GPU 有什么区别? ANE(Apple Neural Engine)是苹果的神经网络加速器,可以归入 NPU。它与 GPU 是并列的计算单元,不是 GPU 内部的一种核心。 它们都能做大量乘加运算,但面向的软件接口和硬件取舍不同: 计算单元 在这里怎样理解 常见工作
用一个能手算的小模型,跟着第 3 行数字走完 Attention、残差连接和 FFN。每一步都能点击播放,看看数字怎样沿着连线流动。 这里的矩阵只有 3 个 token、每个 2 个特征,权重是为了演示而设置的,并非千问的真实参数。重点是看清:Attention 在不同行之间汇合信息,FFN 则分别加工每一行。 在新窗口打开交互演示 ↗ · 手机横屏观看更清楚
Sleep 没啥难度,主要调用系统调用 sleep #include "kernel/types.h" #include "kernel/stat.h" #include "user/user.h" int main(int argc, char *argv[]) { char *err1 = "not right\0"; char *err2 = "sleep wrong\0"; if (argc != 2) { write(2, err1, strlen(err1)
准备 需要三个部分 1. RISC-V 工具链 2. 虚拟机 3. xv6源码 1. 工具链 RISC-V工具链 RISC-V 建议采用手动编译的方式,brew install riscv-tools相对于来说比较卡 git clone --recursive https://github.com/riscv/riscv-gnu-toolchain 代码下载时间比较久 问题: a. 如果下载sub module下载失败了,需要进入 riscv-gnu-toolchain目录下,重新执行 git submodule update --init --recursive 下载 b. 遇到错误/bin/
golang 异步抢占例子,继上篇文章《golang 非协作式抢占》添加一些手操事例 一定要go1.14以后的版本,本文版本 go version go1.15.1 linux/amd64 源码cat main.go package main import ( "fmt" "golang.org/x/sys/unix" "runtime" "time" ) func main() { runtime.GOMAXPROCS(1) for { time.Sleep(time.Second * 5) go
近一年,严格来说可能是11个月,我时常反思关于沟通的问题。一直到近几个月的沉默。我理解都是沟通是原罪。以下言论都是我抹去了大多性格上的短板因素,刚好也是去年这个时候开始想这个因素变量(令自己恐怖的是这个件事我竟然想了一年,老是觉得是上周的事情),这么做是为了减少计算量,我需要计算自己这点上的影响数值。 1. 首先要把自己的位置放正,其次要把态度放正。位置是要明白自己需要产生多大的影响,而且能产生多大的影响,这是一种base,目的与能力的一种权衡;其次态度可以使自己更加客观看自己,不容易受情绪影响,下的结论会更贴近真实客观。 2. 需要明白沟通是需要载体,我们将 model 简化,单对单场景,载体是人。沟通方式,无非是语言、文字、可视化资料。但是往往令人忽略的是沟通载体的差异性,也就是所谓的共识。排除掉所有性格(情绪)的外界因素,剩下影响共识的是经历和学识。或者说“共识”是 “经历和学识”的一种高度抽象,然而“经历和学识”还是太过于抽象,于是在我的认知范畴内将其转化为可计算的。难点在于如何作为简化计算公式和输
总结一下碰到的一些range问题,尤其是边loop边delete的骚操作,我一直以为是人家开源库的bug,直到我看到golang官方也这么用。 首先是比较经典的问题,我们团队之前确实有人写这样代码出事了。 v是数据复制 1. 代码本意是为了获取每个slice每个元素的指针,构造成新的slice type P struct { Name string Age int } func main() { o := []P{ P{"chain1", 20}, P{"chain2", 21}, P{"chain3", 22}, } oPointer := make([]*P, 0, 3) for _, v := range o { oPointer = append(oPointer, &v)