CS149 (2023): Assignment 4
由于 2024 Assignment 4 需要服务器,转做 2023 的了。
封面来源:@hiyualice240
相关文章:CS149 Programming Assignment 4 - Chat149 - A Flash Attention Transformer DNN | MizukiCry's Blog
原始实验材料仓库:stanford-cs149/cs149gpt
任务推荐资料:
环境问题:
ImportError: cs149gpt/module_ref.so: undefined symbol · Issue #2 · stanford-cs149/cs149gpt
我想要请教下此项目环境配置问题是如何解决的呢? · Issue #1 · BienBoy/cs149gpt
Transformer 的产生动机:
环境
一开始想在 Mac 上做,但环境存在的不太行,转回 wsl2 了。
- OS: Windows11 - wsl2 (6.6.87.2-microsoft-standard-WSL2) - Ubuntu 22.04.5 LTS
- CPU: AMD Ryzen 7 6800H (8 cores, 16 logical processors, AVX2 256-bit)
- Python 3.10.12
这个任务,using CPU only,不需要 GPU。
官方是服务器,没有给环境,需要自己配一下。
参考 ImportError: cs149gpt/module_ref.so: undefined symbol · Issue #2 · stanford-cs149/cs149gpt
|
|
Warm-Up: Accessing Tensors
参照 2D Accessor
,实现 4D Accessor
,4D-tensor 转 1D vector 访问。
这里我直接模仿的写法没什么问题,加乘嵌套的写法 tensor[((x * sizeX + y) * sizeY + z) * sizeZ + b]
,看 MizukiCry 的结果是会影响到编译器的优化。
|
|
测试结果:
|
|
Part 1: A Simple (But Not So Efficient) Implementation of Attention
简单实现 Attention 模块。
原注释中还给出了写入 0 的例子,难度很友好了。
|
|
测试结果:
|
|
Part 2: Blocked Matrix Multiply and Unfused Softmax
参照 lecture ,分块优化 cache 的命中率。
先查询本机的 cacheline,为 64
|
|
N 固定 1024 时,在本机上的最佳的 tile size 是多少?
Part 1, 2 的 DRAM 访问差别(缓存命中情况)
使用 Perf
|
|
测试结果:
|
|
Part 3: Fused Attention
由于 Q, K 矩阵乘、Softmax、注意力得分,遍历参数类似,但要重复三轮,并且整块占用,对 cache 表现和内存占用都不友好。
观察到 QK矩阵 的每一行之间的计算是独立的,我们考虑把矩阵乘和 Softmax 操作融合 fused 起来。
使用 OpenMP,来简单地实现并行,如 #pragma omp parallel for collapse(2)
,omp_get_thread_num()
来使用必要的子数组。
- 为什么 Part 3 的内存占用和 Part 1 & 2 相比骤降?
- 把 OpenMP 注释掉,比较 cpu 耗时,为什么融合让多线程利用更加轻松且充分了?
|
|
测试结果:
|
|
Part 4 : Putting it all Together - Flash Attention
为了更好的融合分块与 Softmax,Flash Attnetion 诞生了。
对着伪代码实现即可,注意变量名不要打错,找了半天 QnQ。
B H 多轮,应该只有 l 是需要重新初始化的。(当然根据写法不同有不同)
实验只要求正确性,不过超过得也比较轻松。挺多可以做融合 fused 的地方,不过为了和伪代码对应,就没去做。
也就不去进一步优化了。
|
|
测试结果:
|
|
Extra Credit: Optimize Further
用 ISPC 进一步优化上面每一个 Part。
感觉意义一般,也跑路了。
结语
总的来说,这个是做下来目前感觉最简单的。