From 5612d9f80ef693c997877d02f271cb089f2a823e Mon Sep 17 00:00:00 2001 From: "test@example.com" <26772842+jeniag@users.noreply.github.com> Date: Mon, 7 Sep 2026 11:57:06 -0700 Subject: [PATCH 1/2] Add flash_attention_triton wrapper that passes checks to the flash-attention-triton question solution notebook --- .../flash-attention-triton_SOLN.ipynb | 253 +++++++++++++----- 1 file changed, 184 insertions(+), 69 deletions(-) diff --git a/v3/gpu-systems/flash-attention-triton/flash-attention-triton_SOLN.ipynb b/v3/gpu-systems/flash-attention-triton/flash-attention-triton_SOLN.ipynb index ba0e100..054fc39 100644 --- a/v3/gpu-systems/flash-attention-triton/flash-attention-triton_SOLN.ipynb +++ b/v3/gpu-systems/flash-attention-triton/flash-attention-triton_SOLN.ipynb @@ -2,6 +2,7 @@ "cells": [ { "cell_type": "markdown", + "id": "a14a63c5", "metadata": {}, "source": [ "# Implement FlashAttention-2 in Triton — Solution\n", @@ -79,9 +80,19 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, + "id": "e1ce38d2", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Triton is available!\n", + "CUDA available: True\n" + ] + } + ], "source": [ "import torch\n", "import torch.nn.functional as F\n", @@ -102,9 +113,23 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, + "id": "cdf6b637", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Q shape: torch.Size([2, 4, 128, 64])\n", + "K shape: torch.Size([2, 4, 128, 64])\n", + "V shape: torch.Size([2, 4, 128, 64])\n", + "\n", + "Full attention matrix would be: 2 x 4 x 128 x 128\n", + "= 512.0 KB\n" + ] + } + ], "source": [ "# Test data\n", "torch.manual_seed(42)\n", @@ -129,7 +154,8 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, + "id": "bdb3477a", "metadata": {}, "outputs": [], "source": [ @@ -152,7 +178,8 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, + "id": "072c33a3", "metadata": {}, "outputs": [], "source": [ @@ -232,82 +259,126 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, + "id": "422ab2cd", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Triton flash attention kernel defined.\n" + ] + } + ], "source": [ - "# Triton kernel reference (requires GPU to actually run)\n", - "# This shows what the GPU kernel would look like\n", - "\n", "if TRITON_AVAILABLE:\n", + " DEVICE = triton.runtime.driver.active.get_active_torch_device()\n", + " \n", " @triton.jit\n", " def flash_attention_kernel(\n", - " Q_ptr, K_ptr, V_ptr, O_ptr,\n", - " stride_qb, stride_qh, stride_qn, stride_qd,\n", - " stride_kb, stride_kh, stride_kn, stride_kd,\n", - " stride_vb, stride_vh, stride_vn, stride_vd,\n", - " stride_ob, stride_oh, stride_on, stride_od,\n", - " N, D: tl.constexpr,\n", - " BLOCK_Q: tl.constexpr, BLOCK_KV: tl.constexpr,\n", - " ):\n", - " \"\"\"\n", - " FlashAttention-2 Triton kernel.\n", - " Each program processes one (batch, head, q_block) tile.\n", - " \"\"\"\n", - " # Program IDs\n", + " Q_block_ptr,\n", + " K_block_ptr,\n", + " V_block_ptr,\n", + " output_ptr,\n", + " Q_strideBH, Q_strideN, Q_strideD,\n", + " K_strideBH, K_strideN, K_strideD,\n", + " V_strideBH, V_strideN, V_strideD,\n", + " output_strideBH, output_strideN, output_strideD,\n", + " N:tl.constexpr, \n", + " D:tl.constexpr, \n", + " BLOCK_Q: tl.constexpr,\n", + " BLOCK_KV: tl.constexpr,\n", + " ): \n", + " scale = 1.0 / tl.sqrt(float(D)) \n", + " n_blocks = tl.cdiv(N , BLOCK_KV) \n", + " running_max = tl.full((BLOCK_Q,1), float('-inf'), dtype=tl.float32)\n", + " running_sum = tl.zeros((BLOCK_Q,1),dtype=tl.float32)\n", + " running_output = tl.zeros((BLOCK_Q,D),dtype=tl.float32)\n", + "\n", " q_block_idx = tl.program_id(0)\n", - " bh_idx = tl.program_id(1) # combined batch*head index\n", - " \n", - " scale = 1.0 / tl.sqrt(float(D))\n", - " \n", - " # Offsets for this Q block\n", - " q_offset = q_block_idx * BLOCK_Q\n", - " q_range = q_offset + tl.arange(0, BLOCK_Q)\n", + " bh_idx = tl.program_id(1)\n", + " \n", + " q_start = Q_block_ptr + Q_strideBH * bh_idx\n", + " q_range = q_block_idx * BLOCK_Q + tl.arange(0, BLOCK_Q)\n", " d_range = tl.arange(0, D)\n", - " q_mask = q_range[:, None] < N\n", + " q_offsets = q_range[:,None]*Q_strideN+d_range[None,:]*Q_strideD\n", + " q_mask = q_range[:,None] Date: Mon, 7 Sep 2026 12:01:03 -0700 Subject: [PATCH 2/2] Add flash_attention_triton wrapper that passes checks to the flash-attention-triton question solution notebook --- .../flash-attention-triton_SOLN.ipynb | 31 ++++++++++--------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/v3/gpu-systems/flash-attention-triton/flash-attention-triton_SOLN.ipynb b/v3/gpu-systems/flash-attention-triton/flash-attention-triton_SOLN.ipynb index 054fc39..daa867d 100644 --- a/v3/gpu-systems/flash-attention-triton/flash-attention-triton_SOLN.ipynb +++ b/v3/gpu-systems/flash-attention-triton/flash-attention-triton_SOLN.ipynb @@ -80,7 +80,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 2, "id": "e1ce38d2", "metadata": {}, "outputs": [ @@ -113,7 +113,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 3, "id": "cdf6b637", "metadata": {}, "outputs": [ @@ -154,7 +154,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 4, "id": "bdb3477a", "metadata": {}, "outputs": [], @@ -178,7 +178,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 5, "id": "072c33a3", "metadata": {}, "outputs": [], @@ -259,7 +259,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 6, "id": "422ab2cd", "metadata": {}, "outputs": [ @@ -329,16 +329,11 @@ " correction = tl.exp(running_max - new_max)\n", " P = tl.exp(S - new_max)\n", " \n", - " running_sum = running_sum * correction + P.sum(axis=1, keep_dims=True)\n", - " #tl.static_print(str((running_output.shape, correction.shape, P.shape, V_block.shape)))\n", - " running_output = running_output * correction + tl.dot(P.to(V_block.dtype), V_block) \n", - " # if bh_idx==7 and q_block_idx==3 and kv_block_idx==1:\n", - " # tl.device_print(\"running_sum\",running_sum.sum())\n", + " running_sum = running_sum * correction + P.sum(axis=1, keep_dims=True) \n", + " running_output = running_output * correction + tl.dot(P.to(V_block.dtype), V_block) \n", " running_max = new_max\n", " \n", - " result = running_output / running_sum\n", - " # if bh_idx==7 and q_block_idx==3:\n", - " # tl.device_print(\"result\",result.sum(axis=None,keep_dims=False))\n", + " result = running_output / running_sum \n", " output_start = output_ptr + output_strideBH * bh_idx \n", " output_offsets = q_range[:,None]*output_strideN+d_range[None,:]*output_strideD\n", " \n", @@ -387,7 +382,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 7, "id": "45628148", "metadata": {}, "outputs": [ @@ -484,6 +479,14 @@ "\n", "print(\"\\nAll tests passed!\")" ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "59e24d81-2de9-4f9b-8896-cb7095ea8604", + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": {