不包含LLM系统加速背景的版本:
现有一个计算流程,包含三个串行执行的矩阵乘:
输入 X: [M, H]
算子1 (降维): Y = X @ A 其中 A: [H, r], Y: [M, r]
算子2 (升维): Z = Y @ B 其中 B: [r, H'], Z: [M, H']
算子3 (主干): W = X @ C 其中 C: [H, H'], W: [M, H']
最终输出: O = W + Z 即 O: [M, H']
其中 r 远小于 H 和 H'(例如 r=8, H=4096, H'=4096, M=64)。
由于 r 很小,算子1和算子2的计算量非常小,无法充分利用GPU的计算资源。三个算子串行执行时,算子1和算子2各自都只能用到GPU的一小部分算力,但它们仍然各自占用一次kernel launch和一次完整的显存读写。
将算子1(降维矩阵乘)与算子3(主干矩阵乘)融合成一个Triton kernel,使得:
本质上,就是把算子1和算子3融合成一个算子。可以自己设置几个参数,先用Triton生成三个算子,完成算子1和算子3的正确融合,再往下做
假设一个GPU上有80个SM,是否可以支持发射160个block,block 1 - 40完成计算部分1,block 41-80完成计算部分2,block 81-120完成计算部分1,block 121-160完成计算部分2;然后每个block内进行persistent thread block编程。通过这样的形式,是否可以支持两个block完成相应SM划分调度?
Concise answer: 思路是对的,但不完全可靠。你假设的是调度器按 pid 顺序做 round-robin 填充(pid 0→SM0, pid 1→SM1, ..., pid 79→SM79, pid 80→SM0, pid 81→SM1, ...)。如果这个假设成立,那你的方案确实能让每个 SM 上同时驻留一个 Part1 block 和一个 Part2 block。问题在于:NVIDIA 不保证这个调度顺序,但在实践中它大致成立。
方案图解
Launch 160 blocks, GPU 有 80 SMs, 每个 SM occupancy = 2 blocks
假设 round-robin 调度:
第一轮 (pid 0-79):
SM0 ← pid 0 (Part1)
SM1 ← pid 1 (Part1)
...
SM39 ← pid 39 (Part1)
SM40 ← pid 40 (Part2)
SM41 ← pid 41 (Part2)
...
SM79 ← pid 79 (Part2)
第二轮 (pid 80-159):
SM0 ← pid 80 (Part1)
...
SM39 ← pid 119 (Part1)
SM40 ← pid 120 (Part2)
...
SM79 ← pid 159 (Part2)
Step 1:确定目标矩阵维度并Profile
以Llama3-8B模型、batch size=64为参考场景,确定各矩阵的具体维度。仅仅关注以下线性层的M/N/K:gateup_proj。降维秩 r=8。