mirror of
https://github.com/rasbt/LLMs-from-scratch.git
synced 2025-06-26 23:50:03 +00:00
2799 lines
442 KiB
Plaintext
2799 lines
442 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "e2e65c03-36d4-413f-9b23-5cdd816729ab",
|
|
"metadata": {
|
|
"id": "e2e65c03-36d4-413f-9b23-5cdd816729ab"
|
|
},
|
|
"source": [
|
|
"<table style=\"width:100%\">\n",
|
|
"<tr>\n",
|
|
"<td style=\"vertical-align:middle; text-align:left;\">\n",
|
|
"<font size=\"2\">\n",
|
|
"Supplementary code for the <a href=\"http://mng.bz/orYv\">Build a Large Language Model From Scratch</a> book by <a href=\"https://sebastianraschka.com\">Sebastian Raschka</a><br>\n",
|
|
"<br>Code repository: <a href=\"https://github.com/rasbt/LLMs-from-scratch\">https://github.com/rasbt/LLMs-from-scratch</a>\n",
|
|
"</font>\n",
|
|
"</td>\n",
|
|
"<td style=\"vertical-align:middle; text-align:left;\">\n",
|
|
"<a href=\"http://mng.bz/orYv\"><img src=\"https://sebastianraschka.com/images/LLMs-from-scratch-images/cover-small.webp\" width=\"100px\"></a>\n",
|
|
"</td>\n",
|
|
"</tr>\n",
|
|
"</table>"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "6f678e62-7bcb-4405-86ae-dce94f494303",
|
|
"metadata": {
|
|
"id": "6f678e62-7bcb-4405-86ae-dce94f494303"
|
|
},
|
|
"source": [
|
|
"# Comparing Efficient Multi-Head Attention Implementations"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "b742938a-4bfc-4527-a1f1-d5963508967d",
|
|
"metadata": {
|
|
"id": "b742938a-4bfc-4527-a1f1-d5963508967d"
|
|
},
|
|
"source": [
|
|
"This code notebook compares different ways to implement causal multi-head attention used in decoder-style LLMs like GPT, Llama, etc."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 1,
|
|
"id": "7898551e-f582-48ac-9f66-3632abe2a93f",
|
|
"metadata": {
|
|
"colab": {
|
|
"base_uri": "https://localhost:8080/"
|
|
},
|
|
"id": "7898551e-f582-48ac-9f66-3632abe2a93f",
|
|
"outputId": "1d132538-9d44-4393-c2de-6947fee4c793"
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"PyTorch version: 2.4.0\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"import torch\n",
|
|
"\n",
|
|
"torch.manual_seed(123)\n",
|
|
"device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n",
|
|
"print(f\"PyTorch version: {torch.__version__}\")\n",
|
|
"\n",
|
|
"batch_size = 8\n",
|
|
"context_len = 1024\n",
|
|
"embed_dim = 768\n",
|
|
"embeddings = torch.randn((batch_size, context_len, embed_dim), device=device)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "2f9bb1b6-a1e5-4e0a-884d-0f31b374a8d6",
|
|
"metadata": {
|
|
"id": "2f9bb1b6-a1e5-4e0a-884d-0f31b374a8d6"
|
|
},
|
|
"source": [
|
|
"<br>\n",
|
|
" \n",
|
|
"\n",
|
|
"## 1) CausalAttention MHA wrapper class from chapter 3"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 2,
|
|
"id": "297c93ed-aec0-4896-bb89-42c4b294d3d1",
|
|
"metadata": {
|
|
"colab": {
|
|
"base_uri": "https://localhost:8080/"
|
|
},
|
|
"id": "297c93ed-aec0-4896-bb89-42c4b294d3d1",
|
|
"outputId": "b63ea806-ef0d-4673-c36a-c22f0381e7ad"
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"torch.Size([8, 1024, 768])\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"from ch03 import MultiHeadAttentionWrapper as Ch03_MHA_Wrapper\n",
|
|
"\n",
|
|
"mha_ch03_wrapper = Ch03_MHA_Wrapper(\n",
|
|
" d_in=embed_dim,\n",
|
|
" d_out=embed_dim//12,\n",
|
|
" context_length=context_len,\n",
|
|
" dropout=0.0,\n",
|
|
" num_heads=12,\n",
|
|
" qkv_bias=False\n",
|
|
").to(device)\n",
|
|
"\n",
|
|
"out = mha_ch03_wrapper(embeddings)\n",
|
|
"print(out.shape)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "21930804-b327-40b1-8e63-94dcad39ce7b",
|
|
"metadata": {
|
|
"id": "21930804-b327-40b1-8e63-94dcad39ce7b"
|
|
},
|
|
"source": [
|
|
"<br>\n",
|
|
" \n",
|
|
"\n",
|
|
"## 2) The multi-head attention class from chapter 3"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 3,
|
|
"id": "4ee6a61b-d25c-4a0c-8a59-f285544e3710",
|
|
"metadata": {
|
|
"colab": {
|
|
"base_uri": "https://localhost:8080/"
|
|
},
|
|
"id": "4ee6a61b-d25c-4a0c-8a59-f285544e3710",
|
|
"outputId": "79618eba-bc6f-4247-8d30-14381323a129"
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"torch.Size([8, 1024, 768])\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"from ch03 import MultiHeadAttention as Ch03_MHA\n",
|
|
"\n",
|
|
"mha_ch03 = Ch03_MHA(\n",
|
|
" d_in=embed_dim,\n",
|
|
" d_out=embed_dim,\n",
|
|
" context_length=context_len,\n",
|
|
" dropout=0.0,\n",
|
|
" num_heads=12,\n",
|
|
" qkv_bias=False\n",
|
|
").to(device)\n",
|
|
"\n",
|
|
"out = mha_ch03(embeddings)\n",
|
|
"print(out.shape)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "73cd11da-ea3b-4081-b483-c4965dfefbc4",
|
|
"metadata": {
|
|
"id": "73cd11da-ea3b-4081-b483-c4965dfefbc4"
|
|
},
|
|
"source": [
|
|
"<br>\n",
|
|
" \n",
|
|
"\n",
|
|
"## 3) An alternative multi-head attention with combined weights"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "1fa1a5ea-eaff-4d2d-aaf0-b34cdb6fd4dd",
|
|
"metadata": {
|
|
"id": "1fa1a5ea-eaff-4d2d-aaf0-b34cdb6fd4dd"
|
|
},
|
|
"source": [
|
|
"- The code for the `MultiHeadAttentionAlt` class below is based on code that was kindly shared by [Rayed Bin Wahed](https://github.com/rasbt/LLMs-from-scratch/discussions/51)\n",
|
|
"- The main difference between the `MultiHeadAttentionAlt` class and the `MultiHeadAttention` class used in chapter 3 is that `MultiHeadAttentionAlt` uses a single weight matrix, `self.qkv = nn.Linear(d_in, 3 * d_out, bias=qkv_bias)` instead of separate weight matrices:\n",
|
|
"\n",
|
|
" - `self.W_query = nn.Linear(d_in, d_out, bias=qkv_bias)`\n",
|
|
" - `self.W_key = nn.Linear(d_in, d_out, bias=qkv_bias)`\n",
|
|
" - `self.W_value = nn.Linear(d_in, d_out, bias=qkv_bias)`\n",
|
|
"\n",
|
|
"- Here, `self.qkv` combines all three weight matrices `self.W_query`, `self.W_key`, and `self.W_value` to carry out the query, key, and value computation in a single step\n",
|
|
"- Using `q, k, v = qkv.unbind(0)`, we obtain the individual query, key, and value tensors, which are then used similarly to the query, key, and value tensors in the `MultiHeadAttention` class in chapter 3"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 4,
|
|
"id": "9a6bd0a2-f27c-4602-afa0-c96cd295c1a6",
|
|
"metadata": {
|
|
"colab": {
|
|
"base_uri": "https://localhost:8080/"
|
|
},
|
|
"id": "9a6bd0a2-f27c-4602-afa0-c96cd295c1a6",
|
|
"outputId": "011ba527-4dcb-4909-ffa2-383b92b81c9f"
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"torch.Size([8, 1024, 768])\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"import torch.nn as nn\n",
|
|
"\n",
|
|
"\n",
|
|
"class MultiHeadAttentionCombinedQKV(nn.Module):\n",
|
|
" def __init__(self, d_in, d_out, num_heads, context_length, dropout=0.0, qkv_bias=False):\n",
|
|
" super().__init__()\n",
|
|
"\n",
|
|
" assert d_out % num_heads == 0, \"embed_dim is indivisible by num_heads\"\n",
|
|
"\n",
|
|
" self.num_heads = num_heads\n",
|
|
" self.context_length = context_length\n",
|
|
" self.head_dim = d_out // num_heads\n",
|
|
"\n",
|
|
" self.qkv = nn.Linear(d_in, 3 * d_out, bias=qkv_bias)\n",
|
|
" self.proj = nn.Linear(d_out, d_out)\n",
|
|
" self.dropout = nn.Dropout(dropout)\n",
|
|
"\n",
|
|
" self.register_buffer(\n",
|
|
" \"mask\", torch.triu(torch.ones(context_length, context_length), diagonal=1)\n",
|
|
" )\n",
|
|
"\n",
|
|
" def forward(self, x):\n",
|
|
" batch_size, num_tokens, embed_dim = x.shape\n",
|
|
"\n",
|
|
" # (b, num_tokens, embed_dim) --> (b, num_tokens, 3 * embed_dim)\n",
|
|
" qkv = self.qkv(x)\n",
|
|
"\n",
|
|
" # (b, num_tokens, 3 * embed_dim) --> (b, num_tokens, 3, num_heads, head_dim)\n",
|
|
" qkv = qkv.view(batch_size, num_tokens, 3, self.num_heads, self.head_dim)\n",
|
|
"\n",
|
|
" # (b, num_tokens, 3, num_heads, head_dim) --> (3, b, num_heads, num_tokens, head_dim)\n",
|
|
" qkv = qkv.permute(2, 0, 3, 1, 4)\n",
|
|
"\n",
|
|
" # (3, b, num_heads, num_tokens, head_dim) -> 3 times (b, num_head, num_tokens, head_dim)\n",
|
|
" queries, keys, values = qkv.unbind(0)\n",
|
|
"\n",
|
|
" # (b, num_heads, num_tokens, head_dim) --> (b, num_heads, num_tokens, num_tokens)\n",
|
|
" attn_scores = queries @ keys.transpose(-2, -1)\n",
|
|
" attn_scores = attn_scores.masked_fill(\n",
|
|
" self.mask.bool()[:num_tokens, :num_tokens], -torch.inf\n",
|
|
" )\n",
|
|
"\n",
|
|
" attn_weights = torch.softmax(attn_scores / keys.shape[-1]**-0.5, dim=-1)\n",
|
|
" attn_weights = self.dropout(attn_weights)\n",
|
|
"\n",
|
|
" # (b, num_heads, num_tokens, num_tokens) --> (b, num_heads, num_tokens, head_dim)\n",
|
|
" context_vec = attn_weights @ values\n",
|
|
"\n",
|
|
" # (b, num_heads, num_tokens, head_dim) --> (b, num_tokens, num_heads, head_dim)\n",
|
|
" context_vec = context_vec.transpose(1, 2)\n",
|
|
"\n",
|
|
" # (b, num_tokens, num_heads, head_dim) --> (b, num_tokens, embed_dim)\n",
|
|
" context_vec = context_vec.contiguous().view(batch_size, num_tokens, embed_dim)\n",
|
|
"\n",
|
|
" context_vec = self.proj(context_vec)\n",
|
|
"\n",
|
|
" return context_vec\n",
|
|
"\n",
|
|
"\n",
|
|
"mha_combined_qkv = MultiHeadAttentionCombinedQKV(\n",
|
|
" d_in=embed_dim,\n",
|
|
" d_out=embed_dim,\n",
|
|
" context_length=context_len,\n",
|
|
" dropout=0.0,\n",
|
|
" num_heads=12,\n",
|
|
" qkv_bias=False\n",
|
|
").to(device)\n",
|
|
"\n",
|
|
"out = mha_combined_qkv(embeddings)\n",
|
|
"print(out.shape)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "48a042d3-ee78-4c29-bf63-d92fe6706632",
|
|
"metadata": {
|
|
"id": "48a042d3-ee78-4c29-bf63-d92fe6706632"
|
|
},
|
|
"source": [
|
|
"<br>\n",
|
|
" \n",
|
|
"\n",
|
|
"## 4) Multihead attention with PyTorch's scaled dot product attention and FlashAttention"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "f78e346f-3b85-44e6-9feb-f01131381148",
|
|
"metadata": {
|
|
"id": "f78e346f-3b85-44e6-9feb-f01131381148"
|
|
},
|
|
"source": [
|
|
"- The implementation below uses PyTorch's [`scaled_dot_product_attention`](https://pytorch.org/docs/stable/generated/torch.nn.functional.scaled_dot_product_attention.html) function, which implements a memory-optimized version of self-attention called [FlashAttention](https://arxiv.org/abs/2205.14135)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 5,
|
|
"id": "1b8e5a0d-1f65-4a03-bf6e-723f0cc428f5",
|
|
"metadata": {
|
|
"id": "1b8e5a0d-1f65-4a03-bf6e-723f0cc428f5"
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"class MHAPyTorchScaledDotProduct(nn.Module):\n",
|
|
" def __init__(self, d_in, d_out, num_heads, context_length, dropout=0.0, qkv_bias=False):\n",
|
|
" super().__init__()\n",
|
|
"\n",
|
|
" assert d_out % num_heads == 0, \"embed_dim is indivisible by num_heads\"\n",
|
|
"\n",
|
|
" self.num_heads = num_heads\n",
|
|
" self.context_length = context_length\n",
|
|
" self.head_dim = d_out // num_heads\n",
|
|
" self.d_out = d_out\n",
|
|
"\n",
|
|
" self.qkv = nn.Linear(d_in, 3 * d_out, bias=qkv_bias)\n",
|
|
" self.proj = nn.Linear(d_out, d_out)\n",
|
|
" self.dropout = dropout\n",
|
|
"\n",
|
|
" def forward(self, x):\n",
|
|
" batch_size, num_tokens, embed_dim = x.shape\n",
|
|
"\n",
|
|
" # (b, num_tokens, embed_dim) --> (b, num_tokens, 3 * embed_dim)\n",
|
|
" qkv = self.qkv(x)\n",
|
|
"\n",
|
|
" # (b, num_tokens, 3 * embed_dim) --> (b, num_tokens, 3, num_heads, head_dim)\n",
|
|
" qkv = qkv.view(batch_size, num_tokens, 3, self.num_heads, self.head_dim)\n",
|
|
"\n",
|
|
" # (b, num_tokens, 3, num_heads, head_dim) --> (3, b, num_heads, num_tokens, head_dim)\n",
|
|
" qkv = qkv.permute(2, 0, 3, 1, 4)\n",
|
|
"\n",
|
|
" # (3, b, num_heads, num_tokens, head_dim) -> 3 times (b, num_heads, num_tokens, head_dim)\n",
|
|
" queries, keys, values = qkv\n",
|
|
"\n",
|
|
" use_dropout = 0. if not self.training else self.dropout\n",
|
|
"\n",
|
|
" context_vec = nn.functional.scaled_dot_product_attention(\n",
|
|
" queries, keys, values, attn_mask=None, dropout_p=use_dropout, is_causal=True)\n",
|
|
"\n",
|
|
" # Combine heads, where self.d_out = self.num_heads * self.head_dim\n",
|
|
" context_vec = context_vec.transpose(1, 2).contiguous().view(batch_size, num_tokens, self.d_out)\n",
|
|
"\n",
|
|
" context_vec = self.proj(context_vec)\n",
|
|
"\n",
|
|
" return context_vec"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 6,
|
|
"id": "fbc8ba92-3471-41cb-b1b2-4c0ef5be392b",
|
|
"metadata": {
|
|
"colab": {
|
|
"base_uri": "https://localhost:8080/"
|
|
},
|
|
"id": "fbc8ba92-3471-41cb-b1b2-4c0ef5be392b",
|
|
"outputId": "fcd0508d-f474-4f81-89e5-7e1dbd6305f4"
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"torch.Size([8, 1024, 768])\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"mha_pytorch_scaled = MHAPyTorchScaledDotProduct(\n",
|
|
" d_in=embed_dim,\n",
|
|
" d_out=embed_dim,\n",
|
|
" context_length=context_len,\n",
|
|
" dropout=0.0,\n",
|
|
" num_heads=12,\n",
|
|
" qkv_bias=False\n",
|
|
").to(device)\n",
|
|
"\n",
|
|
"out = mha_pytorch_scaled(embeddings)\n",
|
|
"print(out.shape)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "51492724-6018-49f6-8bf6-ae9e585229c3",
|
|
"metadata": {
|
|
"id": "51492724-6018-49f6-8bf6-ae9e585229c3"
|
|
},
|
|
"source": [
|
|
"<br>\n",
|
|
" \n",
|
|
"\n",
|
|
"## 5) PyTorch's scaled dot product attention without FlashAttention\n",
|
|
"\n",
|
|
"- This is similar to above, except that we disable FlashAttention by passing an explicit causal mask"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 7,
|
|
"id": "bad53538-e905-4065-ba0c-caacdfec5a0b",
|
|
"metadata": {
|
|
"id": "bad53538-e905-4065-ba0c-caacdfec5a0b"
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"class MHAPyTorchSDPAWithoutFlash(nn.Module):\n",
|
|
" def __init__(self, d_in, d_out, num_heads, context_length, dropout=0.0, qkv_bias=False):\n",
|
|
" super().__init__()\n",
|
|
"\n",
|
|
" assert d_out % num_heads == 0, \"embed_dim is indivisible by num_heads\"\n",
|
|
"\n",
|
|
" self.num_heads = num_heads\n",
|
|
" self.context_length = context_length\n",
|
|
" self.head_dim = d_out // num_heads\n",
|
|
" self.d_out = d_out\n",
|
|
"\n",
|
|
" self.qkv = nn.Linear(d_in, 3 * d_out, bias=qkv_bias)\n",
|
|
" self.proj = nn.Linear(d_out, d_out)\n",
|
|
" self.dropout = dropout\n",
|
|
" self.register_buffer(\"mask\", torch.triu(torch.ones(context_length, context_length), diagonal=1).bool())\n",
|
|
"\n",
|
|
" def forward(self, x):\n",
|
|
" batch_size, num_tokens, embed_dim = x.shape\n",
|
|
"\n",
|
|
" # (b, num_tokens, embed_dim) --> (b, num_tokens, 3 * embed_dim)\n",
|
|
" qkv = self.qkv(x)\n",
|
|
"\n",
|
|
" # (b, num_tokens, 3 * embed_dim) --> (b, num_tokens, 3, num_heads, head_dim)\n",
|
|
" qkv = qkv.view(batch_size, num_tokens, 3, self.num_heads, self.head_dim)\n",
|
|
"\n",
|
|
" # (b, num_tokens, 3, num_heads, head_dim) --> (3, b, num_heads, num_tokens, head_dim)\n",
|
|
" qkv = qkv.permute(2, 0, 3, 1, 4)\n",
|
|
"\n",
|
|
" # (3, b, num_heads, num_tokens, head_dim) -> 3 times (b, num_heads, num_tokens, head_dim)\n",
|
|
" queries, keys, values = qkv\n",
|
|
"\n",
|
|
" use_dropout = 0. if not self.training else self.dropout\n",
|
|
"\n",
|
|
" # Ensure attn_mask is compatible with expected shape and `batch_first=True`\n",
|
|
" # No need to manually adjust for num_heads; ensure it's right for the sequence\n",
|
|
" if self.context_length >= num_tokens:\n",
|
|
" attn_mask = self.mask[:num_tokens, :num_tokens]\n",
|
|
" else:\n",
|
|
" attn_mask = self.mask[:self.context_length, :self.context_length]\n",
|
|
"\n",
|
|
" context_vec = nn.functional.scaled_dot_product_attention(\n",
|
|
" queries, keys, values, attn_mask=attn_mask, dropout_p=use_dropout, is_causal=False)\n",
|
|
"\n",
|
|
" # Combine heads, where self.d_out = self.num_heads * self.head_dim\n",
|
|
" context_vec = context_vec.transpose(1, 2).contiguous().view(batch_size, num_tokens, self.d_out)\n",
|
|
"\n",
|
|
" context_vec = self.proj(context_vec)\n",
|
|
"\n",
|
|
" return context_vec"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 8,
|
|
"id": "f3da7850-e772-47d3-bd51-22d077b01412",
|
|
"metadata": {
|
|
"colab": {
|
|
"base_uri": "https://localhost:8080/"
|
|
},
|
|
"id": "f3da7850-e772-47d3-bd51-22d077b01412",
|
|
"outputId": "841ee076-8f71-4223-85e0-9e74fc7ac2f4"
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"torch.Size([8, 1024, 768])\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"mha_pytorch_sdpa_no_flash = MHAPyTorchSDPAWithoutFlash(\n",
|
|
" d_in=embed_dim,\n",
|
|
" d_out=embed_dim,\n",
|
|
" context_length=context_len,\n",
|
|
" dropout=0.0,\n",
|
|
" num_heads=12,\n",
|
|
" qkv_bias=False\n",
|
|
").to(device)\n",
|
|
"\n",
|
|
"out = mha_pytorch_sdpa_no_flash(embeddings)\n",
|
|
"print(out.shape)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "351c318f-4835-4d74-8d58-a070222447c4",
|
|
"metadata": {
|
|
"id": "351c318f-4835-4d74-8d58-a070222447c4"
|
|
},
|
|
"source": [
|
|
"<br>\n",
|
|
" \n",
|
|
"\n",
|
|
"## 6) Using PyTorch's torch.nn.MultiheadAttention"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "74a6d060-6324-48fa-a35c-cb09f2a48965",
|
|
"metadata": {
|
|
"id": "74a6d060-6324-48fa-a35c-cb09f2a48965"
|
|
},
|
|
"source": [
|
|
"- Below, we use PyTorch's [torch.nn.MultiheadAttention](https://pytorch.org/docs/stable/generated/torch.nn.MultiheadAttention.html) implementation"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 9,
|
|
"id": "3799c7ef-3155-42c6-a829-f95656453ae0",
|
|
"metadata": {
|
|
"colab": {
|
|
"base_uri": "https://localhost:8080/"
|
|
},
|
|
"id": "3799c7ef-3155-42c6-a829-f95656453ae0",
|
|
"outputId": "2f001121-6357-4ee2-9ba5-8ec1e687ea23"
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"torch.Size([8, 1024, 768])\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"import torch.nn as nn\n",
|
|
"\n",
|
|
"\n",
|
|
"class MHAPyTorchClass(nn.Module):\n",
|
|
" def __init__(self, d_in, d_out, num_heads, context_length, dropout=0.0, qkv_bias=False, need_weights=True):\n",
|
|
" super().__init__()\n",
|
|
"\n",
|
|
" self.context_length = context_length\n",
|
|
" self.multihead_attn = nn.MultiheadAttention(\n",
|
|
" embed_dim=d_out,\n",
|
|
" num_heads=num_heads,\n",
|
|
" dropout=dropout,\n",
|
|
" bias=qkv_bias,\n",
|
|
" add_bias_kv=qkv_bias,\n",
|
|
" batch_first=True,\n",
|
|
" )\n",
|
|
"\n",
|
|
" self.need_weights = need_weights\n",
|
|
" self.proj = nn.Linear(d_out, d_out)\n",
|
|
" self.register_buffer(\"mask\", torch.triu(torch.ones(context_length, context_length), diagonal=1).bool())\n",
|
|
"\n",
|
|
" def forward(self, x):\n",
|
|
" batch_size, num_tokens, _ = x.shape\n",
|
|
"\n",
|
|
" # Ensure attn_mask is compatible with expected shape and `batch_first=True`\n",
|
|
" # No need to manually adjust for num_heads; ensure it's right for the sequence\n",
|
|
" if self.context_length >= num_tokens:\n",
|
|
" attn_mask = self.mask[:num_tokens, :num_tokens]\n",
|
|
" else:\n",
|
|
" attn_mask = self.mask[:self.context_length, :self.context_length]\n",
|
|
"\n",
|
|
" # attn_mask broadcasting will handle batch_size dimension implicitly\n",
|
|
" attn_output, _ = self.multihead_attn(\n",
|
|
" x, x, x, attn_mask=attn_mask, need_weights=self.need_weights\n",
|
|
" )\n",
|
|
"\n",
|
|
" output = self.proj(attn_output)\n",
|
|
"\n",
|
|
" return output\n",
|
|
"\n",
|
|
"\n",
|
|
"mha_pytorch_class_default = MHAPyTorchClass(\n",
|
|
" d_in=embed_dim,\n",
|
|
" d_out=embed_dim,\n",
|
|
" context_length=context_len,\n",
|
|
" dropout=0.0,\n",
|
|
" num_heads=12,\n",
|
|
" qkv_bias=False\n",
|
|
").to(device)\n",
|
|
"\n",
|
|
"out = mha_pytorch_class_default(embeddings)\n",
|
|
"print(out.shape)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "a3953bff-1056-4de2-bfd1-dfccf659eee4",
|
|
"metadata": {
|
|
"id": "a3953bff-1056-4de2-bfd1-dfccf659eee4"
|
|
},
|
|
"source": [
|
|
"<br>\n",
|
|
" \n",
|
|
"\n",
|
|
"## 7) Using PyTorch's torch.nn.MultiheadAttention with `scaled_dot_product_attention`"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "d2164859-31a0-4537-b4fb-27d57675ba77",
|
|
"metadata": {
|
|
"id": "d2164859-31a0-4537-b4fb-27d57675ba77"
|
|
},
|
|
"source": [
|
|
"- Set `need_weights` (default `True`) to need_weights=False so that MultiheadAttention uses `scaled_dot_product_attention` [according to the documentation](https://github.com/pytorch/pytorch/blob/71d020262793542974cf13b30f2a9099773f015c/torch/nn/modules/activation.py#L1096)\n",
|
|
"\n",
|
|
"> need_weights: If specified, returns ``attn_output_weights`` in addition to ``attn_outputs``.\n",
|
|
" Set ``need_weights=False`` to use the optimized ``scaled_dot_product_attention``\n",
|
|
" and achieve the best performance for MHA.\n",
|
|
" Default: ``True``."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 10,
|
|
"id": "4a4c2afe-5e1f-4bd7-a118-67031176f147",
|
|
"metadata": {
|
|
"colab": {
|
|
"base_uri": "https://localhost:8080/"
|
|
},
|
|
"id": "4a4c2afe-5e1f-4bd7-a118-67031176f147",
|
|
"outputId": "311c1e2b-f437-4c4d-cbdc-1ecb0db3b78c"
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"torch.Size([8, 1024, 768])\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"mha_pytorch_class_noweights = MHAPyTorchClass(\n",
|
|
" d_in=embed_dim,\n",
|
|
" d_out=embed_dim,\n",
|
|
" context_length=context_len,\n",
|
|
" dropout=0.0,\n",
|
|
" num_heads=12,\n",
|
|
" qkv_bias=False,\n",
|
|
" need_weights=False # NEW!\n",
|
|
").to(device)\n",
|
|
"\n",
|
|
"out = mha_pytorch_class_noweights(embeddings)\n",
|
|
"print(out.shape)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "21f4ff35-651c-4e47-bfa1-016f3de01ecc",
|
|
"metadata": {
|
|
"id": "21f4ff35-651c-4e47-bfa1-016f3de01ecc"
|
|
},
|
|
"source": [
|
|
"<br>\n",
|
|
" \n",
|
|
"\n",
|
|
"## 8) Using PyTorch's FlexAttention\n",
|
|
"\n",
|
|
"- See [FlexAttention: The Flexibility of PyTorch with the Performance of FlashAttention](https://pytorch.org/blog/flexattention/) to learn more about FlexAttention\n",
|
|
"- This is currently only supported in PyTorch 2.5 (nightly), which you can install on a CPU machine via\n",
|
|
"\n",
|
|
"```python\n",
|
|
"pip install --pre torch torchvision torchaudio --index-url https://download.pytorch.org/whl/nightly/cpu -U\n",
|
|
"```\n",
|
|
"\n",
|
|
"- To install PyTorch nighly on a GPU machine, use the following (for more information, also see the installation menu on [pytorch.org](https://pytorch.org/))\n",
|
|
"\n",
|
|
"```python\n",
|
|
"pip install --pre torch torchvision torchaudio --index-url https://download.pytorch.org/whl/nightly/cu121 -U\n",
|
|
"```\n",
|
|
"\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 11,
|
|
"id": "834318c8-4748-4902-99f0-70ee02bef63e",
|
|
"metadata": {
|
|
"id": "834318c8-4748-4902-99f0-70ee02bef63e"
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"from packaging.version import parse as parse_version\n",
|
|
"\n",
|
|
"def normalize_version(version):\n",
|
|
" parsed_version = parse_version(version)\n",
|
|
" return parse_version(f\"{parsed_version.major}.{parsed_version.minor}.{parsed_version.micro}\")\n",
|
|
"\n",
|
|
"current_version = normalize_version(torch.__version__)\n",
|
|
"MIN_TORCH_VERSION = \"2.5.0\"\n",
|
|
"required_version = parse_version(MIN_TORCH_VERSION)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 12,
|
|
"id": "WYyFRCXndVH9",
|
|
"metadata": {
|
|
"id": "WYyFRCXndVH9"
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"if current_version >= required_version:\n",
|
|
" from torch.nn.attention.flex_attention import flex_attention\n",
|
|
" from torch.nn.attention.flex_attention import create_block_mask\n",
|
|
"\n",
|
|
"\n",
|
|
"def causal(b, h, q_idx, kv_idx):\n",
|
|
" return q_idx >= kv_idx\n",
|
|
"\n",
|
|
"\n",
|
|
"class MHAPyTorchFlexAttention(nn.Module):\n",
|
|
"\n",
|
|
" def __init__(self, d_in, d_out, num_heads, context_length, dropout=0.0, qkv_bias=False):\n",
|
|
" super().__init__()\n",
|
|
"\n",
|
|
" assert d_out % num_heads == 0, \"embed_dim is indivisible by num_heads\"\n",
|
|
"\n",
|
|
" self.num_heads = num_heads\n",
|
|
" self.context_length = context_length\n",
|
|
" self.head_dim = d_out // num_heads\n",
|
|
" self.d_out = d_out\n",
|
|
"\n",
|
|
" self.qkv = nn.Linear(d_in, 3 * d_out, bias=qkv_bias)\n",
|
|
" self.proj = nn.Linear(d_out, d_out)\n",
|
|
" self.dropout = dropout\n",
|
|
" # self.register_buffer(\"block_mask\", create_block_mask(causal, B=None, H=None, Q_LEN=context_length, KV_LEN=context_length))\n",
|
|
" # `create_block_mask` function doesn not support buffers, yet\n",
|
|
" self.block_mask = create_block_mask(causal, B=None, H=None, Q_LEN=context_length, KV_LEN=context_length)\n",
|
|
"\n",
|
|
"\n",
|
|
" def forward(self, x):\n",
|
|
" batch_size, num_tokens, embed_dim = x.shape\n",
|
|
"\n",
|
|
" # (b, num_tokens, embed_dim) --> (b, num_tokens, 3 * embed_dim)\n",
|
|
" qkv = self.qkv(x)\n",
|
|
"\n",
|
|
" # (b, num_tokens, 3 * embed_dim) --> (b, num_tokens, 3, num_heads, head_dim)\n",
|
|
" qkv = qkv.view(batch_size, num_tokens, 3, self.num_heads, self.head_dim)\n",
|
|
"\n",
|
|
" # (b, num_tokens, 3, num_heads, head_dim) --> (3, b, num_heads, num_tokens, head_dim)\n",
|
|
" qkv = qkv.permute(2, 0, 3, 1, 4)\n",
|
|
"\n",
|
|
" # (3, b, num_heads, num_tokens, head_dim) -> 3 times (b, num_heads, num_tokens, head_dim)\n",
|
|
" queries, keys, values = qkv\n",
|
|
"\n",
|
|
" use_dropout = 0. if not self.training else self.dropout\n",
|
|
"\n",
|
|
" # Ensure attn_mask is compatible with expected shape and `batch_first=True`\n",
|
|
" # No need to manually adjust for num_heads; ensure it's right for the sequence\n",
|
|
" if self.context_length >= num_tokens:\n",
|
|
" attn_mask = self.block_mask[:num_tokens, :num_tokens]\n",
|
|
" else:\n",
|
|
" attn_mask = self.block_mask[:self.context_length, :self.context_length]\n",
|
|
"\n",
|
|
" context_vec = flex_attention(queries, keys, values, block_mask=attn_mask)\n",
|
|
"\n",
|
|
" # Combine heads, where self.d_out = self.num_heads * self.head_dim\n",
|
|
" context_vec = context_vec.transpose(1, 2).contiguous().view(batch_size, num_tokens, self.d_out)\n",
|
|
"\n",
|
|
" context_vec = self.proj(context_vec)\n",
|
|
"\n",
|
|
" return context_vec"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 13,
|
|
"id": "9cdaaf8a-f956-44bc-932f-4d33448e8aaf",
|
|
"metadata": {
|
|
"colab": {
|
|
"base_uri": "https://localhost:8080/"
|
|
},
|
|
"id": "9cdaaf8a-f956-44bc-932f-4d33448e8aaf",
|
|
"outputId": "0888271f-d6ae-4905-fabb-805b70f9e712"
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"if current_version >= required_version:\n",
|
|
"\n",
|
|
" mha_pytorch_flex = MHAPyTorchFlexAttention(\n",
|
|
" d_in=embed_dim,\n",
|
|
" d_out=embed_dim,\n",
|
|
" context_length=context_len,\n",
|
|
" dropout=0.0,\n",
|
|
" num_heads=12,\n",
|
|
" qkv_bias=False\n",
|
|
" ).to(device)\n",
|
|
"\n",
|
|
" out = mha_pytorch_flex(embeddings)\n",
|
|
" print(out.shape)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "8877de71-f84f-4f6d-bc87-7552013b6301",
|
|
"metadata": {
|
|
"id": "8877de71-f84f-4f6d-bc87-7552013b6301"
|
|
},
|
|
"source": [
|
|
"<br>\n",
|
|
" \n",
|
|
"\n",
|
|
"## Quick speed comparison (M3 Macbook Air CPU)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 14,
|
|
"id": "219cf93a-078f-434d-888c-2458d0731285",
|
|
"metadata": {
|
|
"colab": {
|
|
"base_uri": "https://localhost:8080/"
|
|
},
|
|
"id": "219cf93a-078f-434d-888c-2458d0731285",
|
|
"outputId": "2bb41cd4-a152-4754-f361-94f9e17cf498"
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"PyTorch version: 2.4.0\n",
|
|
"Running on cpu\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"torch.manual_seed(123)\n",
|
|
"device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n",
|
|
"print(f\"PyTorch version: {torch.__version__}\")\n",
|
|
"print(f\"Running on {device}\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 15,
|
|
"id": "a97c0b2e-6593-49d8-98bc-2267b3aa610f",
|
|
"metadata": {
|
|
"colab": {
|
|
"base_uri": "https://localhost:8080/"
|
|
},
|
|
"id": "a97c0b2e-6593-49d8-98bc-2267b3aa610f",
|
|
"outputId": "67389a57-945b-42c9-e1a1-1e2a8b8cb710"
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"196 ms ± 3.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"## 1) CausalAttention MHA wrapper class from chapter 3\n",
|
|
"%timeit mha_ch03_wrapper(embeddings)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 16,
|
|
"id": "19db9c2c-8e75-431a-8eef-0b4d8284e6e6",
|
|
"metadata": {
|
|
"colab": {
|
|
"base_uri": "https://localhost:8080/"
|
|
},
|
|
"id": "19db9c2c-8e75-431a-8eef-0b4d8284e6e6",
|
|
"outputId": "930a14ee-36df-4a41-c162-374f9e1ea600"
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"204 ms ± 14.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"## 2) The multi-head attention class from chapter 3\n",
|
|
"%timeit mha_ch03(embeddings)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 17,
|
|
"id": "aa526ee0-7a88-4f34-a49a-f8f97da83779",
|
|
"metadata": {
|
|
"colab": {
|
|
"base_uri": "https://localhost:8080/"
|
|
},
|
|
"id": "aa526ee0-7a88-4f34-a49a-f8f97da83779",
|
|
"outputId": "801cf4e1-4f2a-44d8-e5d7-89fe0c62cee9"
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"214 ms ± 8.1 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"## 3) An alternative multi-head attention with combined weights\n",
|
|
"%timeit mha_combined_qkv(embeddings)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 18,
|
|
"id": "cc2b4256-16d8-4c34-9fd0-d4b4af0e60fa",
|
|
"metadata": {
|
|
"colab": {
|
|
"base_uri": "https://localhost:8080/"
|
|
},
|
|
"id": "cc2b4256-16d8-4c34-9fd0-d4b4af0e60fa",
|
|
"outputId": "b9b43252-8942-46f4-84de-4b2889e3fb7e"
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"81 ms ± 15.9 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"## 4) Multihead attention with PyTorch's scaled dot product attention\n",
|
|
"%timeit mha_pytorch_scaled(embeddings)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 19,
|
|
"id": "c44305ce-9f61-451a-b9ef-30caba222357",
|
|
"metadata": {
|
|
"colab": {
|
|
"base_uri": "https://localhost:8080/"
|
|
},
|
|
"id": "c44305ce-9f61-451a-b9ef-30caba222357",
|
|
"outputId": "a044e5f2-212e-45d5-ea40-4f4611077794"
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"83.7 ms ± 2.32 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"## 5) PyTorch's scaled dot product attention without FlashAttention\n",
|
|
"%timeit mha_pytorch_sdpa_no_flash(embeddings)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 20,
|
|
"id": "0f209e70-ebb6-4a1a-b608-1ff42e41c01d",
|
|
"metadata": {
|
|
"colab": {
|
|
"base_uri": "https://localhost:8080/"
|
|
},
|
|
"id": "0f209e70-ebb6-4a1a-b608-1ff42e41c01d",
|
|
"outputId": "c3f002da-b9b6-42d1-a24b-45789369c9a9"
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"251 ms ± 23.3 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"## 6) Using PyTorch's torch.nn.MultiheadAttention\n",
|
|
"%timeit mha_pytorch_class_default(embeddings)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 21,
|
|
"id": "3f4968c2-8d40-4ab9-8dba-052b4f77d756",
|
|
"metadata": {
|
|
"colab": {
|
|
"base_uri": "https://localhost:8080/"
|
|
},
|
|
"id": "3f4968c2-8d40-4ab9-8dba-052b4f77d756",
|
|
"outputId": "7d85c861-6e77-4d8b-8cb3-b05d8ddd243d"
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"131 ms ± 20.1 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"## 7) Using PyTorch's torch.nn.MultiheadAttention disabling `need_weights`\n",
|
|
"%timeit mha_pytorch_class_noweights(embeddings)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "5d7ee70d-7bdd-48ad-ad7f-af3bf2439609",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"## 8) Using PyTorch's FlexAttention\n",
|
|
"\n",
|
|
"# Requires PyTorch 2.5.0 or newer\n",
|
|
"%timeit mha_pytorch_flex(embeddings)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "a78ff594-6cc2-496d-a302-789fa104c3c9",
|
|
"metadata": {
|
|
"id": "a78ff594-6cc2-496d-a302-789fa104c3c9"
|
|
},
|
|
"source": [
|
|
"<br>\n",
|
|
" \n",
|
|
"\n",
|
|
"## Quick speed comparison (Nvidia A100 GPU)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "RStnI1pEi6Eo",
|
|
"metadata": {
|
|
"id": "RStnI1pEi6Eo"
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Cnable tensor cores\n",
|
|
"torch.set_float32_matmul_precision(\"high\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "e8431d75-e1c9-4d9a-b7da-9a1ff391f2bf",
|
|
"metadata": {
|
|
"colab": {
|
|
"base_uri": "https://localhost:8080/"
|
|
},
|
|
"id": "e8431d75-e1c9-4d9a-b7da-9a1ff391f2bf",
|
|
"outputId": "5176759d-9599-4c8b-90bd-58cf8890ccde"
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"PyTorch version: 2.5.0.dev20240810+cu121\n",
|
|
"Running on cuda\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"torch.manual_seed(123)\n",
|
|
"device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n",
|
|
"print(f\"PyTorch version: {torch.__version__}\")\n",
|
|
"print(f\"Running on {device}\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "707a2a14-a089-48a8-88aa-d328e1e0a9d0",
|
|
"metadata": {
|
|
"colab": {
|
|
"base_uri": "https://localhost:8080/"
|
|
},
|
|
"id": "707a2a14-a089-48a8-88aa-d328e1e0a9d0",
|
|
"outputId": "d0fe060f-058a-43ec-8d23-de23a94ed4cb"
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"4.35 ms ± 30.8 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"## 1) CausalAttention MHA wrapper class from chapter 3\n",
|
|
"%timeit mha_ch03_wrapper(embeddings)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "8686dd69-3655-40e4-a57b-a2c55532a010",
|
|
"metadata": {
|
|
"colab": {
|
|
"base_uri": "https://localhost:8080/"
|
|
},
|
|
"id": "8686dd69-3655-40e4-a57b-a2c55532a010",
|
|
"outputId": "b404c9e6-e0e0-4cb4-921f-fd612beb8668"
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"3.09 ms ± 136 ns per loop (mean ± std. dev. of 7 runs, 1000 loops each)\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"## 2) The multi-head attention class from chapter 3\n",
|
|
"%timeit mha_ch03(embeddings)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "2209d7df-e54b-4910-ae2b-c78cf684d9bf",
|
|
"metadata": {
|
|
"colab": {
|
|
"base_uri": "https://localhost:8080/"
|
|
},
|
|
"id": "2209d7df-e54b-4910-ae2b-c78cf684d9bf",
|
|
"outputId": "ef47787d-65bb-4407-d718-77dadb6f53d2"
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"3.81 ms ± 189 ns per loop (mean ± std. dev. of 7 runs, 100 loops each)\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"## 3) An alternative multi-head attention with combined weights\n",
|
|
"%timeit mha_combined_qkv(embeddings)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "1075abe2-4839-4fd6-af3e-c09bb3651e26",
|
|
"metadata": {
|
|
"colab": {
|
|
"base_uri": "https://localhost:8080/"
|
|
},
|
|
"id": "1075abe2-4839-4fd6-af3e-c09bb3651e26",
|
|
"outputId": "58c8f320-79e2-400f-978c-1983fb810cf3"
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"1.21 ms ± 875 ns per loop (mean ± std. dev. of 7 runs, 1000 loops each)\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"## 4) Multihead attention with PyTorch's scaled dot product attention\n",
|
|
"%timeit mha_pytorch_scaled(embeddings)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "218adbaf-f17f-47d9-81d5-41c758218df7",
|
|
"metadata": {
|
|
"colab": {
|
|
"base_uri": "https://localhost:8080/"
|
|
},
|
|
"id": "218adbaf-f17f-47d9-81d5-41c758218df7",
|
|
"outputId": "4e66760e-516a-43a5-a148-0afef96d23ca"
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"1.96 ms ± 117 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"## 5) PyTorch's scaled dot product attention without FlashAttention\n",
|
|
"%timeit mha_pytorch_sdpa_no_flash(embeddings)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "868e3670-8edc-47bc-9e06-eb505e44dc9d",
|
|
"metadata": {
|
|
"colab": {
|
|
"base_uri": "https://localhost:8080/"
|
|
},
|
|
"id": "868e3670-8edc-47bc-9e06-eb505e44dc9d",
|
|
"outputId": "c17ddc03-0aab-4ef5-d3e3-a3695ec30b62"
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"3.05 ms ± 225 ns per loop (mean ± std. dev. of 7 runs, 100 loops each)\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"## 6) Using PyTorch's torch.nn.MultiheadAttention\n",
|
|
"%timeit mha_pytorch_class_default(embeddings)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "944870e6-de54-4e3b-a455-b8f21f6f92c8",
|
|
"metadata": {
|
|
"colab": {
|
|
"base_uri": "https://localhost:8080/"
|
|
},
|
|
"id": "944870e6-de54-4e3b-a455-b8f21f6f92c8",
|
|
"outputId": "e2781053-e7f4-4d87-99a1-08ca20f92951"
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"2.29 ms ± 5.66 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"## 7) Using PyTorch's torch.nn.MultiheadAttention disabling `need_weights`\n",
|
|
"%timeit mha_pytorch_class_noweights(embeddings)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "evKtpb5QN_2A",
|
|
"metadata": {
|
|
"colab": {
|
|
"base_uri": "https://localhost:8080/"
|
|
},
|
|
"id": "evKtpb5QN_2A",
|
|
"outputId": "a8af4a1c-e1c2-4a41-f454-cd395818a327"
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"12.2 ms ± 587 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"## 8) Using PyTorch's FlexAttention\n",
|
|
"\n",
|
|
"# Requires PyTorch 2.5.0 or newer\n",
|
|
"%timeit mha_pytorch_flex(embeddings)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "dabc6575-0316-4640-a729-e616d5c17b73",
|
|
"metadata": {
|
|
"id": "dabc6575-0316-4640-a729-e616d5c17b73"
|
|
},
|
|
"source": [
|
|
"<br>\n",
|
|
" \n",
|
|
"\n",
|
|
"\n",
|
|
"## Speed comparison (Nvidia A100 GPU) with warmup (forward pass only)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "bbb2f729-d3d8-46d0-b249-9249197ea574",
|
|
"metadata": {
|
|
"colab": {
|
|
"base_uri": "https://localhost:8080/"
|
|
},
|
|
"id": "bbb2f729-d3d8-46d0-b249-9249197ea574",
|
|
"outputId": "09bf4056-d219-4f90-f8f7-f31b62ffa671"
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"PyTorch version: 2.5.0.dev20240810+cu121\n",
|
|
"Running on cuda\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"torch.manual_seed(123)\n",
|
|
"device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n",
|
|
"print(f\"PyTorch version: {torch.__version__}\")\n",
|
|
"print(f\"Running on {device}\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "29b63d3d-6d0b-43bb-9c68-d5514dc81000",
|
|
"metadata": {
|
|
"id": "29b63d3d-6d0b-43bb-9c68-d5514dc81000"
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# CUDA benchmark code shared by Andrei Aksionov\n",
|
|
"# and based on code from\n",
|
|
"# https://github.com/cuda-mode/lectures/blob/main/lecture1/pytorch_square.py\n",
|
|
"\n",
|
|
"def time_pytorch_function(func, *input, num_repeats = 1_000):\n",
|
|
" # CUDA IS ASYNC so can't use python time module\n",
|
|
" start = torch.cuda.Event(enable_timing=True)\n",
|
|
" end = torch.cuda.Event(enable_timing=True)\n",
|
|
"\n",
|
|
" # Warmup\n",
|
|
" for _ in range(5):\n",
|
|
" func(*input)\n",
|
|
" torch.cuda.synchronize()\n",
|
|
"\n",
|
|
" start.record()\n",
|
|
" for _ in range(num_repeats):\n",
|
|
" func(*input)\n",
|
|
" torch.cuda.synchronize()\n",
|
|
" end.record()\n",
|
|
" torch.cuda.synchronize()\n",
|
|
" return start.elapsed_time(end) / num_repeats"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "CDJAPZaszaqx",
|
|
"metadata": {
|
|
"colab": {
|
|
"base_uri": "https://localhost:8080/",
|
|
"height": 488
|
|
},
|
|
"id": "CDJAPZaszaqx",
|
|
"outputId": "86fef2d2-856b-4ae1-beb9-cc04b4ed6aad"
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"image/png": "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\n",
|
|
"text/plain": [
|
|
"<Figure size 640x480 with 1 Axes>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"import matplotlib.pyplot as plt\n",
|
|
"\n",
|
|
"\n",
|
|
"embeddings_cuda = embeddings.to(torch.device(\"cuda\"))\n",
|
|
"\n",
|
|
"\n",
|
|
"functions = {\n",
|
|
" \"1) MHA wrapper class\": mha_ch03_wrapper,\n",
|
|
" \"2) MHA Ch03\": mha_ch03,\n",
|
|
" \"3) MHA with combined QKV weights\": mha_combined_qkv,\n",
|
|
" \"4) MHA with PyTorch scaled_dot_product_attention\": mha_pytorch_scaled,\n",
|
|
" \"5) PyTorch's SDPA, no FlashAttention\": mha_pytorch_sdpa_no_flash,\n",
|
|
" \"6) PyTorch MHA class defaults\": mha_pytorch_class_default,\n",
|
|
" \"7) PyTorch MHA with need_weights=False\": mha_pytorch_class_noweights,\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"if current_version >= required_version:\n",
|
|
" functions[\"8) PyTorch's FlexAttention\"] = mha_pytorch_flex\n",
|
|
"\n",
|
|
"execution_times = [time_pytorch_function(fn, embeddings_cuda) for name,fn in functions.items()]\n",
|
|
"\n",
|
|
"\n",
|
|
"# Plotting\n",
|
|
"\n",
|
|
"# Customize further for dark mode aesthetics\n",
|
|
"plt.rcParams[\"figure.facecolor\"] = \"#121212\" # Dark figure background\n",
|
|
"plt.rcParams[\"axes.facecolor\"] = \"#121212\" # Dark axes background\n",
|
|
"plt.rcParams[\"axes.edgecolor\"] = \"white\" # White axes border\n",
|
|
"plt.rcParams[\"axes.labelcolor\"] = \"white\" # White labels\n",
|
|
"plt.rcParams[\"text.color\"] = \"white\" # White text\n",
|
|
"plt.rcParams[\"xtick.color\"] = \"white\" # White x ticks\n",
|
|
"plt.rcParams[\"ytick.color\"] = \"white\" # White y ticks\n",
|
|
"plt.rcParams[\"grid.color\"] = \"#444444\" # Lighter grid lines for contrast\n",
|
|
"plt.rcParams[\"lines.linewidth\"] = 2 # Thicker plot lines for visibility\n",
|
|
"plt.rcParams[\"lines.markersize\"] = 8 # Larger markers for visibility\n",
|
|
"\n",
|
|
"fig, ax = plt.subplots()\n",
|
|
"bars = plt.bar(functions.keys(), execution_times)\n",
|
|
"\n",
|
|
"plt.ylabel(\"Execution time (ms)\")\n",
|
|
"plt.xticks(rotation=45, ha=\"right\")\n",
|
|
"\n",
|
|
"# Calculate new ylim with a margin\n",
|
|
"max_execution_time = max(execution_times)\n",
|
|
"upper_ylim = max_execution_time + 0.2 * max_execution_time # Adding a 20% margin\n",
|
|
"\n",
|
|
"plt.ylim(0, upper_ylim) # Setting new ylim\n",
|
|
"\n",
|
|
"# Annotate bars with execution times\n",
|
|
"for bar in bars:\n",
|
|
" yval = bar.get_height()\n",
|
|
" plt.text(bar.get_x() + bar.get_width()/2, yval + (0.05 * upper_ylim), round(yval, 2), ha=\"center\", va=\"bottom\")\n",
|
|
"\n",
|
|
"\n",
|
|
"plt.tight_layout()\n",
|
|
"plt.savefig(\"1_forward-only.pdf\")\n",
|
|
"plt.show()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "VQaSerWCOnYB",
|
|
"metadata": {
|
|
"id": "VQaSerWCOnYB"
|
|
},
|
|
"source": [
|
|
"<br>\n",
|
|
" \n",
|
|
"\n",
|
|
"\n",
|
|
"## Speed comparison (Nvidia A100 GPU) with warmup (forward and backward pass)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "ReCmeRhCOpm8",
|
|
"metadata": {
|
|
"colab": {
|
|
"base_uri": "https://localhost:8080/",
|
|
"height": 488
|
|
},
|
|
"id": "ReCmeRhCOpm8",
|
|
"outputId": "79daea84-6ca3-41d2-91c9-ecabb1a035bb"
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"image/png": "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\n",
|
|
"text/plain": [
|
|
"<Figure size 640x480 with 1 Axes>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"def forward_backward(func, embeddings):\n",
|
|
" if embeddings.grad is not None:\n",
|
|
" embeddings.grad.zero_()\n",
|
|
"\n",
|
|
" output = func(embeddings)\n",
|
|
" loss = output.sum()\n",
|
|
" loss.backward()\n",
|
|
"\n",
|
|
"\n",
|
|
"def time_pytorch_function_forward_backward(func, *input, num_repeats = 1_000):\n",
|
|
" # CUDA IS ASYNC so can't use python time module\n",
|
|
" start = torch.cuda.Event(enable_timing=True)\n",
|
|
" end = torch.cuda.Event(enable_timing=True)\n",
|
|
"\n",
|
|
" # Warmup\n",
|
|
" for _ in range(5):\n",
|
|
" forward_backward(func, *input)\n",
|
|
" torch.cuda.synchronize()\n",
|
|
"\n",
|
|
" start.record()\n",
|
|
" for _ in range(num_repeats):\n",
|
|
" forward_backward(func, *input)\n",
|
|
" torch.cuda.synchronize()\n",
|
|
" end.record()\n",
|
|
" torch.cuda.synchronize()\n",
|
|
" return start.elapsed_time(end) / num_repeats\n",
|
|
"\n",
|
|
"\n",
|
|
"execution_times = [time_pytorch_function_forward_backward(fn, embeddings_cuda) for name,fn in functions.items()]\n",
|
|
"\n",
|
|
"\n",
|
|
"# Plotting\n",
|
|
"\n",
|
|
"\n",
|
|
"fig, ax = plt.subplots()\n",
|
|
"bars = plt.bar(functions.keys(), execution_times)\n",
|
|
"\n",
|
|
"plt.ylabel(\"Execution time (ms)\")\n",
|
|
"plt.xticks(rotation=45, ha=\"right\")\n",
|
|
"\n",
|
|
"# Calculate new ylim with a margin\n",
|
|
"max_execution_time = max(execution_times)\n",
|
|
"upper_ylim = max_execution_time + 0.2 * max_execution_time # Adding a 20% margin\n",
|
|
"\n",
|
|
"plt.ylim(0, upper_ylim) # Setting new ylim\n",
|
|
"\n",
|
|
"# Annotate bars with execution times\n",
|
|
"for bar in bars:\n",
|
|
" yval = bar.get_height()\n",
|
|
" plt.text(bar.get_x() + bar.get_width()/2, yval + (0.05 * upper_ylim), round(yval, 2), ha=\"center\", va=\"bottom\")\n",
|
|
"\n",
|
|
"\n",
|
|
"plt.tight_layout()\n",
|
|
"plt.savefig(\"2_forward-and-backward.pdf\")\n",
|
|
"plt.show()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "1gWX-Ayqia1k",
|
|
"metadata": {
|
|
"id": "1gWX-Ayqia1k"
|
|
},
|
|
"source": [
|
|
"<br>\n",
|
|
" \n",
|
|
"\n",
|
|
"\n",
|
|
"## Speed comparison (Nvidia A100 GPU) with warmup and compilation (forward and backward pass)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 38,
|
|
"id": "LQDiAPooiYAz",
|
|
"metadata": {
|
|
"colab": {
|
|
"base_uri": "https://localhost:8080/",
|
|
"height": 1000
|
|
},
|
|
"id": "LQDiAPooiYAz",
|
|
"outputId": "09d66064-0986-480e-ee39-c9a5faf7dcf5"
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stderr",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] WON'T CONVERT forward <ipython-input-12-a390090d40bb> line 30 \n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] due to: \n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] Traceback (most recent call last):\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_dynamo/output_graph.py\", line 1438, in _call_user_compiler\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] compiled_fn = compiler_fn(gm, self.example_inputs())\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_dynamo/repro/after_dynamo.py\", line 129, in __call__\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] compiled_gm = compiler_fn(gm, example_inputs)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/__init__.py\", line 2236, in __call__\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] return compile_fx(model_, inputs_, config_patches=self.config)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_inductor/compile_fx.py\", line 1507, in compile_fx\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] return aot_autograd(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_dynamo/backends/common.py\", line 72, in __call__\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] cg = aot_module_simplified(gm, example_inputs, **self.kwargs)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_functorch/aot_autograd.py\", line 1033, in aot_module_simplified\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] compiled_fn = dispatch_and_compile()\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_functorch/aot_autograd.py\", line 1022, in dispatch_and_compile\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] compiled_fn, _ = create_aot_dispatcher_function(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_functorch/aot_autograd.py\", line 435, in create_aot_dispatcher_function\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] return _create_aot_dispatcher_function(flat_fn, flat_args, aot_config)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_functorch/aot_autograd.py\", line 736, in _create_aot_dispatcher_function\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] compiled_fn, fw_metadata = compiler_fn(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_functorch/_aot_autograd/jit_compile_runtime_wrappers.py\", line 564, in aot_dispatch_autograd\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] compiled_fw_func = aot_config.fw_compiler(fw_module, adjusted_flat_args)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_inductor/compile_fx.py\", line 1336, in fw_compiler_base\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] return _fw_compiler_base(model, example_inputs, is_inference)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_inductor/compile_fx.py\", line 1407, in _fw_compiler_base\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] return inner_compile(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_inductor/compile_fx.py\", line 468, in compile_fx_inner\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] return wrap_compiler_debug(_compile_fx_inner, compiler_name=\"inductor\")(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_dynamo/repro/after_aot.py\", line 85, in debug_wrapper\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] inner_compiled_fn = compiler_fn(gm, example_inputs)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_inductor/compile_fx.py\", line 653, in _compile_fx_inner\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] compiled_graph = FxGraphCache.load(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_inductor/codecache.py\", line 1319, in load\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] compiled_graph = compile_fx_fn(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_inductor/compile_fx.py\", line 563, in codegen_and_compile\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] compiled_graph = fx_codegen_and_compile(gm, example_inputs, **fx_kwargs)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_inductor/compile_fx.py\", line 845, in fx_codegen_and_compile\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] graph.run(*example_inputs)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_inductor/graph.py\", line 772, in run\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] return super().run(*args)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/fx/interpreter.py\", line 147, in run\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] self.env[node] = self.run_node(node)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_inductor/graph.py\", line 1280, in run_node\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] result = super().run_node(n)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/fx/interpreter.py\", line 204, in run_node\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] return getattr(self, n.op)(n.target, args, kwargs)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_inductor/graph.py\", line 1037, in call_function\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] raise LoweringException(e, target, args, kwargs).with_traceback(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_inductor/graph.py\", line 1034, in call_function\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] out = lowerings[target](*args, **kwargs) # type: ignore[index]\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_inductor/lowering.py\", line 323, in wrapped\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] out = decomp_fn(*args, **kwargs)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_inductor/kernel/flex_attention.py\", line 627, in flex_attention\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] query.get_stride(),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_inductor/ir.py\", line 6151, in __getattr__\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] fn = getattr(self.data, name)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] torch._inductor.exc.LoweringException: AttributeError: 'View' object has no attribute 'get_stride'\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] target: flex_attention\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] args[0]: TensorBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] View(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ReinterpretView(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] StorageBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ExternKernelOut(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] python_kernel_name='extern_kernels.mm',\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] name=buf0,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] layout=FixedLayout('cuda', torch.float32, size=[8192, 2304], stride=[2304, 1]),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] inputs=[ReinterpretView(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] StorageBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] InputBuffer(name='primals_1', layout=FixedLayout('cuda', torch.float32, size=[8, 1024, 768], stride=[786432, 768, 1]))\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] FixedLayout('cuda', torch.float32, size=[8192, 768], stride=[768, 1]),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([mm])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ), ReinterpretView(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] StorageBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] InputBuffer(name='primals_2', layout=FixedLayout('cuda', torch.float32, size=[2304, 768], stride=[768, 1]))\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] FixedLayout('cuda', torch.float32, size=[768, 2304], stride=[1, 768]),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([mm])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] constant_args=(),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] kwargs={},\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] output_view=None,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] python_kernel_name=extern_kernels.mm,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] cpp_kernel_name=at::mm_out,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ordered_kwargs_for_cpp_kernel=(),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] op_overload=None,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] arg_properties=[{}, {}],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] kwarg_properties=None,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] unbacked_bindings={},\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] mutation_outputs=[],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origin_node=mm,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([mm])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] FixedLayout('cuda', torch.float32, size=[1, 8, 12, 1024, 64], stride=[768, 2359296, 64, 2304, 1]),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([select])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] size=[8, 12, 1024, 64],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] reindex=lambda i0, i1, i2, i3: [0, i0, i1, i2, i3],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([select])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] args[1]: TensorBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] View(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ReinterpretView(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] StorageBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ExternKernelOut(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] python_kernel_name='extern_kernels.mm',\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] name=buf0,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] layout=FixedLayout('cuda', torch.float32, size=[8192, 2304], stride=[2304, 1]),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] inputs=[ReinterpretView(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] StorageBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] InputBuffer(name='primals_1', layout=FixedLayout('cuda', torch.float32, size=[8, 1024, 768], stride=[786432, 768, 1]))\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] FixedLayout('cuda', torch.float32, size=[8192, 768], stride=[768, 1]),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([mm])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ), ReinterpretView(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] StorageBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] InputBuffer(name='primals_2', layout=FixedLayout('cuda', torch.float32, size=[2304, 768], stride=[768, 1]))\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] FixedLayout('cuda', torch.float32, size=[768, 2304], stride=[1, 768]),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([mm])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] constant_args=(),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] kwargs={},\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] output_view=None,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] python_kernel_name=extern_kernels.mm,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] cpp_kernel_name=at::mm_out,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ordered_kwargs_for_cpp_kernel=(),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] op_overload=None,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] arg_properties=[{}, {}],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] kwarg_properties=None,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] unbacked_bindings={},\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] mutation_outputs=[],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origin_node=mm,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([mm])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] FixedLayout('cuda', torch.float32, size=[1, 8, 12, 1024, 64], stride=[768, 2359296, 64, 2304, 1], offset=768),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([select_1])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] size=[8, 12, 1024, 64],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] reindex=lambda i0, i1, i2, i3: [0, i0, i1, i2, i3],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([select_1])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] args[2]: TensorBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] View(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ReinterpretView(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] StorageBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ExternKernelOut(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] python_kernel_name='extern_kernels.mm',\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] name=buf0,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] layout=FixedLayout('cuda', torch.float32, size=[8192, 2304], stride=[2304, 1]),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] inputs=[ReinterpretView(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] StorageBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] InputBuffer(name='primals_1', layout=FixedLayout('cuda', torch.float32, size=[8, 1024, 768], stride=[786432, 768, 1]))\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] FixedLayout('cuda', torch.float32, size=[8192, 768], stride=[768, 1]),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([mm])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ), ReinterpretView(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] StorageBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] InputBuffer(name='primals_2', layout=FixedLayout('cuda', torch.float32, size=[2304, 768], stride=[768, 1]))\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] FixedLayout('cuda', torch.float32, size=[768, 2304], stride=[1, 768]),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([mm])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] constant_args=(),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] kwargs={},\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] output_view=None,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] python_kernel_name=extern_kernels.mm,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] cpp_kernel_name=at::mm_out,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ordered_kwargs_for_cpp_kernel=(),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] op_overload=None,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] arg_properties=[{}, {}],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] kwarg_properties=None,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] unbacked_bindings={},\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] mutation_outputs=[],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origin_node=mm,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([mm])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] FixedLayout('cuda', torch.float32, size=[1, 8, 12, 1024, 64], stride=[768, 2359296, 64, 2304, 1], offset=1536),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([select_2])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] size=[8, 12, 1024, 64],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] reindex=lambda i0, i1, i2, i3: [0, i0, i1, i2, i3],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([select_2])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] args[3]: Subgraph(name='sdpa_score0', graph_module=<lambda>(), graph=None)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] args[4]: (TensorBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ReinterpretView(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] StorageBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] InputBuffer(name='primals_3', layout=FixedLayout('cuda', torch.int32, size=[1, 1, 8], stride=[8, 8, 1]))\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] FixedLayout('cuda', torch.int32, size=[1, 1, 8], stride=[8, 8, 1]),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([slice_2])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ), TensorBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ReinterpretView(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] StorageBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] InputBuffer(name='primals_4', layout=FixedLayout('cuda', torch.int32, size=[1, 1, 8, 8], stride=[64, 64, 8, 1]))\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] FixedLayout('cuda', torch.int32, size=[1, 1, 8, 8], stride=[64, 64, 8, 1]),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([slice_4])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ), TensorBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ReinterpretView(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] StorageBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] InputBuffer(name='primals_5', layout=FixedLayout('cuda', torch.int32, size=[1, 1, 8], stride=[8, 8, 1]))\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] FixedLayout('cuda', torch.int32, size=[1, 1, 8], stride=[8, 8, 1]),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([slice_6])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ), TensorBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ReinterpretView(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] StorageBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] InputBuffer(name='primals_6', layout=FixedLayout('cuda', torch.int32, size=[1, 1, 8, 8], stride=[64, 64, 8, 1]))\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] FixedLayout('cuda', torch.int32, size=[1, 1, 8, 8], stride=[64, 64, 8, 1]),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([slice_8])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ), TensorBox(StorageBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ComputedBuffer(name='buf6', layout=FixedLayout('cuda', torch.int32, size=[1, 1, 8], stride=[8, 8, 1]), data=Pointwise(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] 'cuda',\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] torch.int32,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] def inner_fn(index):\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] _, _, i2 = index\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] tmp0 = ops.load(buf3, i2)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] tmp1 = ops.to_dtype(tmp0, torch.int32, src_dtype=torch.int64)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] return tmp1\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ranges=[1, 1, 8],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origin_node=convert_element_type,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([convert_element_type])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ))\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )), TensorBox(StorageBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ComputedBuffer(name='buf7', layout=FixedLayout('cuda', torch.int32, size=[1, 1, 8, 8], stride=[64, 64, 8, 1]), data=Pointwise(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] 'cuda',\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] torch.int32,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] def inner_fn(index):\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] _, _, i2, i3 = index\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] tmp0 = ops.load(buf5, i3 + 8 * i2)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] tmp1 = ops.to_dtype(tmp0, torch.int64, src_dtype=torch.int16)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] tmp2 = ops.to_dtype(tmp1, torch.int32, src_dtype=torch.int64)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] return tmp2\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ranges=[1, 1, 8, 8],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origin_node=clone_1,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([convert_element_type_1, clone_1, sort])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ))\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )), TensorBox(StorageBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ComputedBuffer(name='buf13', layout=FixedLayout('cuda', torch.int32, size=[1, 1, 8], stride=[8, 8, 1]), data=Pointwise(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] 'cuda',\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] torch.int32,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] def inner_fn(index):\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] _, _, i2 = index\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] tmp0 = ops.load(buf10, i2)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] tmp1 = ops.to_dtype(tmp0, torch.int32, src_dtype=torch.int64)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] return tmp1\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ranges=[1, 1, 8],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origin_node=convert_element_type_2,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([convert_element_type_2])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ))\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )), TensorBox(StorageBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ComputedBuffer(name='buf14', layout=FixedLayout('cuda', torch.int32, size=[1, 1, 8, 8], stride=[64, 64, 8, 1]), data=Pointwise(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] 'cuda',\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] torch.int32,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] def inner_fn(index):\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] _, _, i2, i3 = index\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] tmp0 = ops.load(buf12, i3 + 8 * i2)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] tmp1 = ops.to_dtype(tmp0, torch.int64, src_dtype=torch.int16)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] tmp2 = ops.to_dtype(tmp1, torch.int32, src_dtype=torch.int64)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] return tmp2\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ranges=[1, 1, 8, 8],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origin_node=clone_3,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([clone_3, convert_element_type_3, sort_1])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ))\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )), 128, 128, Subgraph(name='sdpa_mask0', graph_module=<lambda>(), graph=None))\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] args[5]: 0.125\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] args[6]: {'ROWS_GUARANTEED_SAFE': False, 'PRESCALE_QK': False, 'OUTPUT_LOGSUMEXP': True}\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] args[7]: ()\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] args[8]: ()\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] \n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] The above exception was the direct cause of the following exception:\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] \n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] Traceback (most recent call last):\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_dynamo/convert_frame.py\", line 1039, in __call__\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] result = self._inner_convert(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_dynamo/convert_frame.py\", line 514, in __call__\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] return _compile(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_dynamo/convert_frame.py\", line 902, in _compile\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] guarded_code = compile_inner(code, one_graph, hooks, transform)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_dynamo/convert_frame.py\", line 653, in compile_inner\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] return _compile_inner(code, one_graph, hooks, transform)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_utils_internal.py\", line 85, in wrapper_function\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] return StrobelightCompileTimeProfiler.profile_compile_time(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_strobelight/compile_time_profiler.py\", line 129, in profile_compile_time\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] return func(*args, **kwargs)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_dynamo/convert_frame.py\", line 686, in _compile_inner\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] out_code = transform_code_object(code, transform)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_dynamo/bytecode_transformation.py\", line 1322, in transform_code_object\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] transformations(instructions, code_options)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_dynamo/convert_frame.py\", line 208, in _fn\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] return fn(*args, **kwargs)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_dynamo/convert_frame.py\", line 622, in transform\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] tracer.run()\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_dynamo/symbolic_convert.py\", line 2731, in run\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] super().run()\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_dynamo/symbolic_convert.py\", line 958, in run\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] while self.step():\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_dynamo/symbolic_convert.py\", line 870, in step\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] self.dispatch_table[inst.opcode](self, inst)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_dynamo/symbolic_convert.py\", line 2922, in RETURN_VALUE\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] self._return(inst)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_dynamo/symbolic_convert.py\", line 2907, in _return\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] self.output.compile_subgraph(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_dynamo/output_graph.py\", line 1109, in compile_subgraph\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] self.compile_and_call_fx_graph(tx, list(reversed(stack_values)), root)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_dynamo/output_graph.py\", line 1361, in compile_and_call_fx_graph\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] compiled_fn = self.call_user_compiler(gm)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_dynamo/output_graph.py\", line 1408, in call_user_compiler\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] return self._call_user_compiler(gm)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_dynamo/output_graph.py\", line 1457, in _call_user_compiler\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] raise BackendCompilerFailed(self.compiler_fn, e) from e\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] torch._dynamo.exc.BackendCompilerFailed: backend='inductor' raised:\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] LoweringException: AttributeError: 'View' object has no attribute 'get_stride'\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] target: flex_attention\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] args[0]: TensorBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] View(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ReinterpretView(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] StorageBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ExternKernelOut(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] python_kernel_name='extern_kernels.mm',\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] name=buf0,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] layout=FixedLayout('cuda', torch.float32, size=[8192, 2304], stride=[2304, 1]),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] inputs=[ReinterpretView(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] StorageBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] InputBuffer(name='primals_1', layout=FixedLayout('cuda', torch.float32, size=[8, 1024, 768], stride=[786432, 768, 1]))\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] FixedLayout('cuda', torch.float32, size=[8192, 768], stride=[768, 1]),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([mm])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ), ReinterpretView(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] StorageBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] InputBuffer(name='primals_2', layout=FixedLayout('cuda', torch.float32, size=[2304, 768], stride=[768, 1]))\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] FixedLayout('cuda', torch.float32, size=[768, 2304], stride=[1, 768]),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([mm])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] constant_args=(),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] kwargs={},\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] output_view=None,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] python_kernel_name=extern_kernels.mm,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] cpp_kernel_name=at::mm_out,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ordered_kwargs_for_cpp_kernel=(),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] op_overload=None,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] arg_properties=[{}, {}],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] kwarg_properties=None,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] unbacked_bindings={},\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] mutation_outputs=[],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origin_node=mm,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([mm])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] FixedLayout('cuda', torch.float32, size=[1, 8, 12, 1024, 64], stride=[768, 2359296, 64, 2304, 1]),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([select])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] size=[8, 12, 1024, 64],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] reindex=lambda i0, i1, i2, i3: [0, i0, i1, i2, i3],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([select])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] args[1]: TensorBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] View(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ReinterpretView(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] StorageBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ExternKernelOut(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] python_kernel_name='extern_kernels.mm',\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] name=buf0,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] layout=FixedLayout('cuda', torch.float32, size=[8192, 2304], stride=[2304, 1]),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] inputs=[ReinterpretView(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] StorageBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] InputBuffer(name='primals_1', layout=FixedLayout('cuda', torch.float32, size=[8, 1024, 768], stride=[786432, 768, 1]))\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] FixedLayout('cuda', torch.float32, size=[8192, 768], stride=[768, 1]),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([mm])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ), ReinterpretView(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] StorageBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] InputBuffer(name='primals_2', layout=FixedLayout('cuda', torch.float32, size=[2304, 768], stride=[768, 1]))\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] FixedLayout('cuda', torch.float32, size=[768, 2304], stride=[1, 768]),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([mm])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] constant_args=(),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] kwargs={},\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] output_view=None,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] python_kernel_name=extern_kernels.mm,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] cpp_kernel_name=at::mm_out,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ordered_kwargs_for_cpp_kernel=(),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] op_overload=None,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] arg_properties=[{}, {}],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] kwarg_properties=None,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] unbacked_bindings={},\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] mutation_outputs=[],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origin_node=mm,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([mm])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] FixedLayout('cuda', torch.float32, size=[1, 8, 12, 1024, 64], stride=[768, 2359296, 64, 2304, 1], offset=768),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([select_1])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] size=[8, 12, 1024, 64],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] reindex=lambda i0, i1, i2, i3: [0, i0, i1, i2, i3],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([select_1])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] args[2]: TensorBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] View(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ReinterpretView(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] StorageBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ExternKernelOut(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] python_kernel_name='extern_kernels.mm',\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] name=buf0,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] layout=FixedLayout('cuda', torch.float32, size=[8192, 2304], stride=[2304, 1]),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] inputs=[ReinterpretView(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] StorageBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] InputBuffer(name='primals_1', layout=FixedLayout('cuda', torch.float32, size=[8, 1024, 768], stride=[786432, 768, 1]))\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] FixedLayout('cuda', torch.float32, size=[8192, 768], stride=[768, 1]),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([mm])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ), ReinterpretView(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] StorageBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] InputBuffer(name='primals_2', layout=FixedLayout('cuda', torch.float32, size=[2304, 768], stride=[768, 1]))\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] FixedLayout('cuda', torch.float32, size=[768, 2304], stride=[1, 768]),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([mm])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] constant_args=(),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] kwargs={},\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] output_view=None,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] python_kernel_name=extern_kernels.mm,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] cpp_kernel_name=at::mm_out,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ordered_kwargs_for_cpp_kernel=(),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] op_overload=None,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] arg_properties=[{}, {}],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] kwarg_properties=None,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] unbacked_bindings={},\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] mutation_outputs=[],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origin_node=mm,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([mm])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] FixedLayout('cuda', torch.float32, size=[1, 8, 12, 1024, 64], stride=[768, 2359296, 64, 2304, 1], offset=1536),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([select_2])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] size=[8, 12, 1024, 64],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] reindex=lambda i0, i1, i2, i3: [0, i0, i1, i2, i3],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([select_2])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] args[3]: Subgraph(name='sdpa_score0', graph_module=<lambda>(), graph=None)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] args[4]: (TensorBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ReinterpretView(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] StorageBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] InputBuffer(name='primals_3', layout=FixedLayout('cuda', torch.int32, size=[1, 1, 8], stride=[8, 8, 1]))\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] FixedLayout('cuda', torch.int32, size=[1, 1, 8], stride=[8, 8, 1]),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([slice_2])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ), TensorBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ReinterpretView(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] StorageBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] InputBuffer(name='primals_4', layout=FixedLayout('cuda', torch.int32, size=[1, 1, 8, 8], stride=[64, 64, 8, 1]))\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] FixedLayout('cuda', torch.int32, size=[1, 1, 8, 8], stride=[64, 64, 8, 1]),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([slice_4])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ), TensorBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ReinterpretView(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] StorageBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] InputBuffer(name='primals_5', layout=FixedLayout('cuda', torch.int32, size=[1, 1, 8], stride=[8, 8, 1]))\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] FixedLayout('cuda', torch.int32, size=[1, 1, 8], stride=[8, 8, 1]),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([slice_6])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ), TensorBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ReinterpretView(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] StorageBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] InputBuffer(name='primals_6', layout=FixedLayout('cuda', torch.int32, size=[1, 1, 8, 8], stride=[64, 64, 8, 1]))\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] FixedLayout('cuda', torch.int32, size=[1, 1, 8, 8], stride=[64, 64, 8, 1]),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([slice_8])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ), TensorBox(StorageBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ComputedBuffer(name='buf6', layout=FixedLayout('cuda', torch.int32, size=[1, 1, 8], stride=[8, 8, 1]), data=Pointwise(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] 'cuda',\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] torch.int32,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] def inner_fn(index):\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] _, _, i2 = index\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] tmp0 = ops.load(buf3, i2)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] tmp1 = ops.to_dtype(tmp0, torch.int32, src_dtype=torch.int64)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] return tmp1\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ranges=[1, 1, 8],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origin_node=convert_element_type,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([convert_element_type])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ))\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )), TensorBox(StorageBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ComputedBuffer(name='buf7', layout=FixedLayout('cuda', torch.int32, size=[1, 1, 8, 8], stride=[64, 64, 8, 1]), data=Pointwise(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] 'cuda',\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] torch.int32,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] def inner_fn(index):\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] _, _, i2, i3 = index\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] tmp0 = ops.load(buf5, i3 + 8 * i2)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] tmp1 = ops.to_dtype(tmp0, torch.int64, src_dtype=torch.int16)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] tmp2 = ops.to_dtype(tmp1, torch.int32, src_dtype=torch.int64)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] return tmp2\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ranges=[1, 1, 8, 8],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origin_node=clone_1,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([convert_element_type_1, clone_1, sort])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ))\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )), TensorBox(StorageBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ComputedBuffer(name='buf13', layout=FixedLayout('cuda', torch.int32, size=[1, 1, 8], stride=[8, 8, 1]), data=Pointwise(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] 'cuda',\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] torch.int32,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] def inner_fn(index):\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] _, _, i2 = index\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] tmp0 = ops.load(buf10, i2)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] tmp1 = ops.to_dtype(tmp0, torch.int32, src_dtype=torch.int64)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] return tmp1\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ranges=[1, 1, 8],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origin_node=convert_element_type_2,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([convert_element_type_2])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ))\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )), TensorBox(StorageBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ComputedBuffer(name='buf14', layout=FixedLayout('cuda', torch.int32, size=[1, 1, 8, 8], stride=[64, 64, 8, 1]), data=Pointwise(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] 'cuda',\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] torch.int32,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] def inner_fn(index):\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] _, _, i2, i3 = index\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] tmp0 = ops.load(buf12, i3 + 8 * i2)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] tmp1 = ops.to_dtype(tmp0, torch.int64, src_dtype=torch.int16)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] tmp2 = ops.to_dtype(tmp1, torch.int32, src_dtype=torch.int64)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] return tmp2\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ranges=[1, 1, 8, 8],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origin_node=clone_3,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([clone_3, convert_element_type_3, sort_1])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ))\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )), 128, 128, Subgraph(name='sdpa_mask0', graph_module=<lambda>(), graph=None))\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] args[5]: 0.125\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] args[6]: {'ROWS_GUARANTEED_SAFE': False, 'PRESCALE_QK': False, 'OUTPUT_LOGSUMEXP': True}\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] args[7]: ()\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] args[8]: ()\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] \n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] Set TORCH_LOGS=\"+dynamo\" and TORCHDYNAMO_VERBOSE=1 for more information\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] \n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] Traceback (most recent call last):\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_dynamo/output_graph.py\", line 1438, in _call_user_compiler\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] compiled_fn = compiler_fn(gm, self.example_inputs())\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_dynamo/repro/after_dynamo.py\", line 129, in __call__\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] compiled_gm = compiler_fn(gm, example_inputs)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/__init__.py\", line 2236, in __call__\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] return compile_fx(model_, inputs_, config_patches=self.config)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_inductor/compile_fx.py\", line 1507, in compile_fx\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] return aot_autograd(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_dynamo/backends/common.py\", line 72, in __call__\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] cg = aot_module_simplified(gm, example_inputs, **self.kwargs)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_functorch/aot_autograd.py\", line 1033, in aot_module_simplified\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] compiled_fn = dispatch_and_compile()\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_functorch/aot_autograd.py\", line 1022, in dispatch_and_compile\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] compiled_fn, _ = create_aot_dispatcher_function(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_functorch/aot_autograd.py\", line 435, in create_aot_dispatcher_function\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] return _create_aot_dispatcher_function(flat_fn, flat_args, aot_config)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_functorch/aot_autograd.py\", line 736, in _create_aot_dispatcher_function\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] compiled_fn, fw_metadata = compiler_fn(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_functorch/_aot_autograd/jit_compile_runtime_wrappers.py\", line 564, in aot_dispatch_autograd\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] compiled_fw_func = aot_config.fw_compiler(fw_module, adjusted_flat_args)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_inductor/compile_fx.py\", line 1336, in fw_compiler_base\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] return _fw_compiler_base(model, example_inputs, is_inference)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_inductor/compile_fx.py\", line 1407, in _fw_compiler_base\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] return inner_compile(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_inductor/compile_fx.py\", line 468, in compile_fx_inner\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] return wrap_compiler_debug(_compile_fx_inner, compiler_name=\"inductor\")(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_dynamo/repro/after_aot.py\", line 85, in debug_wrapper\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] inner_compiled_fn = compiler_fn(gm, example_inputs)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_inductor/compile_fx.py\", line 653, in _compile_fx_inner\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] compiled_graph = FxGraphCache.load(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_inductor/codecache.py\", line 1319, in load\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] compiled_graph = compile_fx_fn(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_inductor/compile_fx.py\", line 563, in codegen_and_compile\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] compiled_graph = fx_codegen_and_compile(gm, example_inputs, **fx_kwargs)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_inductor/compile_fx.py\", line 845, in fx_codegen_and_compile\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] graph.run(*example_inputs)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_inductor/graph.py\", line 772, in run\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] return super().run(*args)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/fx/interpreter.py\", line 147, in run\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] self.env[node] = self.run_node(node)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_inductor/graph.py\", line 1280, in run_node\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] result = super().run_node(n)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/fx/interpreter.py\", line 204, in run_node\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] return getattr(self, n.op)(n.target, args, kwargs)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_inductor/graph.py\", line 1037, in call_function\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] raise LoweringException(e, target, args, kwargs).with_traceback(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_inductor/graph.py\", line 1034, in call_function\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] out = lowerings[target](*args, **kwargs) # type: ignore[index]\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_inductor/lowering.py\", line 323, in wrapped\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] out = decomp_fn(*args, **kwargs)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_inductor/kernel/flex_attention.py\", line 627, in flex_attention\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] query.get_stride(),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_inductor/ir.py\", line 6151, in __getattr__\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] fn = getattr(self.data, name)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] torch._inductor.exc.LoweringException: AttributeError: 'View' object has no attribute 'get_stride'\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] target: flex_attention\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] args[0]: TensorBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] View(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ReinterpretView(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] StorageBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ExternKernelOut(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] python_kernel_name='extern_kernels.mm',\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] name=buf0,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] layout=FixedLayout('cuda', torch.float32, size=[8192, 2304], stride=[2304, 1]),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] inputs=[ReinterpretView(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] StorageBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] InputBuffer(name='primals_1', layout=FixedLayout('cuda', torch.float32, size=[8, 1024, 768], stride=[786432, 768, 1]))\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] FixedLayout('cuda', torch.float32, size=[8192, 768], stride=[768, 1]),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([mm])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ), ReinterpretView(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] StorageBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] InputBuffer(name='primals_2', layout=FixedLayout('cuda', torch.float32, size=[2304, 768], stride=[768, 1]))\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] FixedLayout('cuda', torch.float32, size=[768, 2304], stride=[1, 768]),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([mm])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] constant_args=(),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] kwargs={},\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] output_view=None,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] python_kernel_name=extern_kernels.mm,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] cpp_kernel_name=at::mm_out,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ordered_kwargs_for_cpp_kernel=(),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] op_overload=None,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] arg_properties=[{}, {}],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] kwarg_properties=None,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] unbacked_bindings={},\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] mutation_outputs=[],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origin_node=mm,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([mm])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] FixedLayout('cuda', torch.float32, size=[1, 8, 12, 1024, 64], stride=[768, 2359296, 64, 2304, 1]),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([select])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] size=[8, 12, 1024, 64],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] reindex=lambda i0, i1, i2, i3: [0, i0, i1, i2, i3],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([select])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] args[1]: TensorBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] View(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ReinterpretView(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] StorageBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ExternKernelOut(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] python_kernel_name='extern_kernels.mm',\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] name=buf0,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] layout=FixedLayout('cuda', torch.float32, size=[8192, 2304], stride=[2304, 1]),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] inputs=[ReinterpretView(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] StorageBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] InputBuffer(name='primals_1', layout=FixedLayout('cuda', torch.float32, size=[8, 1024, 768], stride=[786432, 768, 1]))\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] FixedLayout('cuda', torch.float32, size=[8192, 768], stride=[768, 1]),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([mm])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ), ReinterpretView(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] StorageBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] InputBuffer(name='primals_2', layout=FixedLayout('cuda', torch.float32, size=[2304, 768], stride=[768, 1]))\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] FixedLayout('cuda', torch.float32, size=[768, 2304], stride=[1, 768]),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([mm])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] constant_args=(),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] kwargs={},\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] output_view=None,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] python_kernel_name=extern_kernels.mm,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] cpp_kernel_name=at::mm_out,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ordered_kwargs_for_cpp_kernel=(),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] op_overload=None,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] arg_properties=[{}, {}],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] kwarg_properties=None,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] unbacked_bindings={},\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] mutation_outputs=[],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origin_node=mm,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([mm])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] FixedLayout('cuda', torch.float32, size=[1, 8, 12, 1024, 64], stride=[768, 2359296, 64, 2304, 1], offset=768),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([select_1])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] size=[8, 12, 1024, 64],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] reindex=lambda i0, i1, i2, i3: [0, i0, i1, i2, i3],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([select_1])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] args[2]: TensorBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] View(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ReinterpretView(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] StorageBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ExternKernelOut(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] python_kernel_name='extern_kernels.mm',\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] name=buf0,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] layout=FixedLayout('cuda', torch.float32, size=[8192, 2304], stride=[2304, 1]),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] inputs=[ReinterpretView(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] StorageBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] InputBuffer(name='primals_1', layout=FixedLayout('cuda', torch.float32, size=[8, 1024, 768], stride=[786432, 768, 1]))\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] FixedLayout('cuda', torch.float32, size=[8192, 768], stride=[768, 1]),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([mm])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ), ReinterpretView(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] StorageBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] InputBuffer(name='primals_2', layout=FixedLayout('cuda', torch.float32, size=[2304, 768], stride=[768, 1]))\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] FixedLayout('cuda', torch.float32, size=[768, 2304], stride=[1, 768]),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([mm])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] constant_args=(),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] kwargs={},\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] output_view=None,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] python_kernel_name=extern_kernels.mm,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] cpp_kernel_name=at::mm_out,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ordered_kwargs_for_cpp_kernel=(),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] op_overload=None,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] arg_properties=[{}, {}],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] kwarg_properties=None,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] unbacked_bindings={},\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] mutation_outputs=[],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origin_node=mm,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([mm])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] FixedLayout('cuda', torch.float32, size=[1, 8, 12, 1024, 64], stride=[768, 2359296, 64, 2304, 1], offset=1536),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([select_2])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] size=[8, 12, 1024, 64],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] reindex=lambda i0, i1, i2, i3: [0, i0, i1, i2, i3],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([select_2])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] args[3]: Subgraph(name='sdpa_score0', graph_module=<lambda>(), graph=None)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] args[4]: (TensorBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ReinterpretView(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] StorageBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] InputBuffer(name='primals_3', layout=FixedLayout('cuda', torch.int32, size=[1, 1, 8], stride=[8, 8, 1]))\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] FixedLayout('cuda', torch.int32, size=[1, 1, 8], stride=[8, 8, 1]),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([slice_2])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ), TensorBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ReinterpretView(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] StorageBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] InputBuffer(name='primals_4', layout=FixedLayout('cuda', torch.int32, size=[1, 1, 8, 8], stride=[64, 64, 8, 1]))\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] FixedLayout('cuda', torch.int32, size=[1, 1, 8, 8], stride=[64, 64, 8, 1]),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([slice_4])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ), TensorBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ReinterpretView(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] StorageBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] InputBuffer(name='primals_5', layout=FixedLayout('cuda', torch.int32, size=[1, 1, 8], stride=[8, 8, 1]))\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] FixedLayout('cuda', torch.int32, size=[1, 1, 8], stride=[8, 8, 1]),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([slice_6])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ), TensorBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ReinterpretView(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] StorageBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] InputBuffer(name='primals_6', layout=FixedLayout('cuda', torch.int32, size=[1, 1, 8, 8], stride=[64, 64, 8, 1]))\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] FixedLayout('cuda', torch.int32, size=[1, 1, 8, 8], stride=[64, 64, 8, 1]),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([slice_8])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ), TensorBox(StorageBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ComputedBuffer(name='buf6', layout=FixedLayout('cuda', torch.int32, size=[1, 1, 8], stride=[8, 8, 1]), data=Pointwise(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] 'cuda',\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] torch.int32,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] def inner_fn(index):\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] _, _, i2 = index\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] tmp0 = ops.load(buf3, i2)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] tmp1 = ops.to_dtype(tmp0, torch.int32, src_dtype=torch.int64)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] return tmp1\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ranges=[1, 1, 8],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origin_node=convert_element_type,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([convert_element_type])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ))\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )), TensorBox(StorageBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ComputedBuffer(name='buf7', layout=FixedLayout('cuda', torch.int32, size=[1, 1, 8, 8], stride=[64, 64, 8, 1]), data=Pointwise(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] 'cuda',\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] torch.int32,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] def inner_fn(index):\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] _, _, i2, i3 = index\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] tmp0 = ops.load(buf5, i3 + 8 * i2)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] tmp1 = ops.to_dtype(tmp0, torch.int64, src_dtype=torch.int16)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] tmp2 = ops.to_dtype(tmp1, torch.int32, src_dtype=torch.int64)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] return tmp2\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ranges=[1, 1, 8, 8],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origin_node=clone_1,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([convert_element_type_1, clone_1, sort])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ))\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )), TensorBox(StorageBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ComputedBuffer(name='buf13', layout=FixedLayout('cuda', torch.int32, size=[1, 1, 8], stride=[8, 8, 1]), data=Pointwise(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] 'cuda',\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] torch.int32,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] def inner_fn(index):\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] _, _, i2 = index\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] tmp0 = ops.load(buf10, i2)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] tmp1 = ops.to_dtype(tmp0, torch.int32, src_dtype=torch.int64)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] return tmp1\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ranges=[1, 1, 8],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origin_node=convert_element_type_2,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([convert_element_type_2])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ))\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )), TensorBox(StorageBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ComputedBuffer(name='buf14', layout=FixedLayout('cuda', torch.int32, size=[1, 1, 8, 8], stride=[64, 64, 8, 1]), data=Pointwise(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] 'cuda',\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] torch.int32,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] def inner_fn(index):\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] _, _, i2, i3 = index\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] tmp0 = ops.load(buf12, i3 + 8 * i2)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] tmp1 = ops.to_dtype(tmp0, torch.int64, src_dtype=torch.int16)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] tmp2 = ops.to_dtype(tmp1, torch.int32, src_dtype=torch.int64)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] return tmp2\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ranges=[1, 1, 8, 8],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origin_node=clone_3,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([clone_3, convert_element_type_3, sort_1])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ))\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )), 128, 128, Subgraph(name='sdpa_mask0', graph_module=<lambda>(), graph=None))\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] args[5]: 0.125\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] args[6]: {'ROWS_GUARANTEED_SAFE': False, 'PRESCALE_QK': False, 'OUTPUT_LOGSUMEXP': True}\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] args[7]: ()\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] args[8]: ()\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] \n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] The above exception was the direct cause of the following exception:\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] \n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] Traceback (most recent call last):\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_dynamo/convert_frame.py\", line 1039, in __call__\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] result = self._inner_convert(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_dynamo/convert_frame.py\", line 514, in __call__\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] return _compile(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_dynamo/convert_frame.py\", line 902, in _compile\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] guarded_code = compile_inner(code, one_graph, hooks, transform)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_dynamo/convert_frame.py\", line 653, in compile_inner\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] return _compile_inner(code, one_graph, hooks, transform)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_utils_internal.py\", line 85, in wrapper_function\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] return StrobelightCompileTimeProfiler.profile_compile_time(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_strobelight/compile_time_profiler.py\", line 129, in profile_compile_time\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] return func(*args, **kwargs)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_dynamo/convert_frame.py\", line 686, in _compile_inner\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] out_code = transform_code_object(code, transform)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_dynamo/bytecode_transformation.py\", line 1322, in transform_code_object\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] transformations(instructions, code_options)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_dynamo/convert_frame.py\", line 208, in _fn\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] return fn(*args, **kwargs)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_dynamo/convert_frame.py\", line 622, in transform\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] tracer.run()\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_dynamo/symbolic_convert.py\", line 2731, in run\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] super().run()\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_dynamo/symbolic_convert.py\", line 958, in run\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] while self.step():\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_dynamo/symbolic_convert.py\", line 870, in step\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] self.dispatch_table[inst.opcode](self, inst)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_dynamo/symbolic_convert.py\", line 2922, in RETURN_VALUE\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] self._return(inst)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_dynamo/symbolic_convert.py\", line 2907, in _return\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] self.output.compile_subgraph(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_dynamo/output_graph.py\", line 1109, in compile_subgraph\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] self.compile_and_call_fx_graph(tx, list(reversed(stack_values)), root)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_dynamo/output_graph.py\", line 1361, in compile_and_call_fx_graph\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] compiled_fn = self.call_user_compiler(gm)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_dynamo/output_graph.py\", line 1408, in call_user_compiler\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] return self._call_user_compiler(gm)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] File \"/usr/local/lib/python3.10/dist-packages/torch/_dynamo/output_graph.py\", line 1457, in _call_user_compiler\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] raise BackendCompilerFailed(self.compiler_fn, e) from e\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] torch._dynamo.exc.BackendCompilerFailed: backend='inductor' raised:\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] LoweringException: AttributeError: 'View' object has no attribute 'get_stride'\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] target: flex_attention\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] args[0]: TensorBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] View(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ReinterpretView(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] StorageBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ExternKernelOut(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] python_kernel_name='extern_kernels.mm',\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] name=buf0,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] layout=FixedLayout('cuda', torch.float32, size=[8192, 2304], stride=[2304, 1]),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] inputs=[ReinterpretView(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] StorageBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] InputBuffer(name='primals_1', layout=FixedLayout('cuda', torch.float32, size=[8, 1024, 768], stride=[786432, 768, 1]))\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] FixedLayout('cuda', torch.float32, size=[8192, 768], stride=[768, 1]),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([mm])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ), ReinterpretView(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] StorageBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] InputBuffer(name='primals_2', layout=FixedLayout('cuda', torch.float32, size=[2304, 768], stride=[768, 1]))\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] FixedLayout('cuda', torch.float32, size=[768, 2304], stride=[1, 768]),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([mm])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] constant_args=(),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] kwargs={},\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] output_view=None,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] python_kernel_name=extern_kernels.mm,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] cpp_kernel_name=at::mm_out,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ordered_kwargs_for_cpp_kernel=(),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] op_overload=None,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] arg_properties=[{}, {}],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] kwarg_properties=None,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] unbacked_bindings={},\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] mutation_outputs=[],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origin_node=mm,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([mm])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] FixedLayout('cuda', torch.float32, size=[1, 8, 12, 1024, 64], stride=[768, 2359296, 64, 2304, 1]),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([select])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] size=[8, 12, 1024, 64],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] reindex=lambda i0, i1, i2, i3: [0, i0, i1, i2, i3],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([select])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] args[1]: TensorBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] View(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ReinterpretView(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] StorageBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ExternKernelOut(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] python_kernel_name='extern_kernels.mm',\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] name=buf0,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] layout=FixedLayout('cuda', torch.float32, size=[8192, 2304], stride=[2304, 1]),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] inputs=[ReinterpretView(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] StorageBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] InputBuffer(name='primals_1', layout=FixedLayout('cuda', torch.float32, size=[8, 1024, 768], stride=[786432, 768, 1]))\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] FixedLayout('cuda', torch.float32, size=[8192, 768], stride=[768, 1]),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([mm])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ), ReinterpretView(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] StorageBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] InputBuffer(name='primals_2', layout=FixedLayout('cuda', torch.float32, size=[2304, 768], stride=[768, 1]))\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] FixedLayout('cuda', torch.float32, size=[768, 2304], stride=[1, 768]),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([mm])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] constant_args=(),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] kwargs={},\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] output_view=None,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] python_kernel_name=extern_kernels.mm,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] cpp_kernel_name=at::mm_out,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ordered_kwargs_for_cpp_kernel=(),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] op_overload=None,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] arg_properties=[{}, {}],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] kwarg_properties=None,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] unbacked_bindings={},\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] mutation_outputs=[],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origin_node=mm,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([mm])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] FixedLayout('cuda', torch.float32, size=[1, 8, 12, 1024, 64], stride=[768, 2359296, 64, 2304, 1], offset=768),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([select_1])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] size=[8, 12, 1024, 64],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] reindex=lambda i0, i1, i2, i3: [0, i0, i1, i2, i3],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([select_1])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] args[2]: TensorBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] View(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ReinterpretView(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] StorageBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ExternKernelOut(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] python_kernel_name='extern_kernels.mm',\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] name=buf0,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] layout=FixedLayout('cuda', torch.float32, size=[8192, 2304], stride=[2304, 1]),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] inputs=[ReinterpretView(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] StorageBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] InputBuffer(name='primals_1', layout=FixedLayout('cuda', torch.float32, size=[8, 1024, 768], stride=[786432, 768, 1]))\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] FixedLayout('cuda', torch.float32, size=[8192, 768], stride=[768, 1]),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([mm])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ), ReinterpretView(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] StorageBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] InputBuffer(name='primals_2', layout=FixedLayout('cuda', torch.float32, size=[2304, 768], stride=[768, 1]))\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] FixedLayout('cuda', torch.float32, size=[768, 2304], stride=[1, 768]),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([mm])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] constant_args=(),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] kwargs={},\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] output_view=None,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] python_kernel_name=extern_kernels.mm,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] cpp_kernel_name=at::mm_out,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ordered_kwargs_for_cpp_kernel=(),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] op_overload=None,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] arg_properties=[{}, {}],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] kwarg_properties=None,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] unbacked_bindings={},\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] mutation_outputs=[],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origin_node=mm,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([mm])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] FixedLayout('cuda', torch.float32, size=[1, 8, 12, 1024, 64], stride=[768, 2359296, 64, 2304, 1], offset=1536),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([select_2])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] size=[8, 12, 1024, 64],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] reindex=lambda i0, i1, i2, i3: [0, i0, i1, i2, i3],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([select_2])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] args[3]: Subgraph(name='sdpa_score0', graph_module=<lambda>(), graph=None)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] args[4]: (TensorBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ReinterpretView(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] StorageBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] InputBuffer(name='primals_3', layout=FixedLayout('cuda', torch.int32, size=[1, 1, 8], stride=[8, 8, 1]))\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] FixedLayout('cuda', torch.int32, size=[1, 1, 8], stride=[8, 8, 1]),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([slice_2])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ), TensorBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ReinterpretView(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] StorageBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] InputBuffer(name='primals_4', layout=FixedLayout('cuda', torch.int32, size=[1, 1, 8, 8], stride=[64, 64, 8, 1]))\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] FixedLayout('cuda', torch.int32, size=[1, 1, 8, 8], stride=[64, 64, 8, 1]),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([slice_4])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ), TensorBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ReinterpretView(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] StorageBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] InputBuffer(name='primals_5', layout=FixedLayout('cuda', torch.int32, size=[1, 1, 8], stride=[8, 8, 1]))\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] FixedLayout('cuda', torch.int32, size=[1, 1, 8], stride=[8, 8, 1]),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([slice_6])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ), TensorBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ReinterpretView(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] StorageBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] InputBuffer(name='primals_6', layout=FixedLayout('cuda', torch.int32, size=[1, 1, 8, 8], stride=[64, 64, 8, 1]))\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] FixedLayout('cuda', torch.int32, size=[1, 1, 8, 8], stride=[64, 64, 8, 1]),\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([slice_8])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ), TensorBox(StorageBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ComputedBuffer(name='buf6', layout=FixedLayout('cuda', torch.int32, size=[1, 1, 8], stride=[8, 8, 1]), data=Pointwise(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] 'cuda',\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] torch.int32,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] def inner_fn(index):\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] _, _, i2 = index\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] tmp0 = ops.load(buf3, i2)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] tmp1 = ops.to_dtype(tmp0, torch.int32, src_dtype=torch.int64)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] return tmp1\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ranges=[1, 1, 8],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origin_node=convert_element_type,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([convert_element_type])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ))\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )), TensorBox(StorageBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ComputedBuffer(name='buf7', layout=FixedLayout('cuda', torch.int32, size=[1, 1, 8, 8], stride=[64, 64, 8, 1]), data=Pointwise(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] 'cuda',\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] torch.int32,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] def inner_fn(index):\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] _, _, i2, i3 = index\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] tmp0 = ops.load(buf5, i3 + 8 * i2)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] tmp1 = ops.to_dtype(tmp0, torch.int64, src_dtype=torch.int16)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] tmp2 = ops.to_dtype(tmp1, torch.int32, src_dtype=torch.int64)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] return tmp2\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ranges=[1, 1, 8, 8],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origin_node=clone_1,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([convert_element_type_1, clone_1, sort])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ))\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )), TensorBox(StorageBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ComputedBuffer(name='buf13', layout=FixedLayout('cuda', torch.int32, size=[1, 1, 8], stride=[8, 8, 1]), data=Pointwise(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] 'cuda',\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] torch.int32,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] def inner_fn(index):\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] _, _, i2 = index\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] tmp0 = ops.load(buf10, i2)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] tmp1 = ops.to_dtype(tmp0, torch.int32, src_dtype=torch.int64)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] return tmp1\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ranges=[1, 1, 8],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origin_node=convert_element_type_2,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([convert_element_type_2])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ))\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )), TensorBox(StorageBox(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ComputedBuffer(name='buf14', layout=FixedLayout('cuda', torch.int32, size=[1, 1, 8, 8], stride=[64, 64, 8, 1]), data=Pointwise(\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] 'cuda',\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] torch.int32,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] def inner_fn(index):\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] _, _, i2, i3 = index\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] tmp0 = ops.load(buf12, i3 + 8 * i2)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] tmp1 = ops.to_dtype(tmp0, torch.int64, src_dtype=torch.int16)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] tmp2 = ops.to_dtype(tmp1, torch.int32, src_dtype=torch.int64)\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] return tmp2\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ranges=[1, 1, 8, 8],\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origin_node=clone_3,\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] origins=OrderedSet([clone_3, convert_element_type_3, sort_1])\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] ))\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] )), 128, 128, Subgraph(name='sdpa_mask0', graph_module=<lambda>(), graph=None))\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] args[5]: 0.125\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] args[6]: {'ROWS_GUARANTEED_SAFE': False, 'PRESCALE_QK': False, 'OUTPUT_LOGSUMEXP': True}\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] args[7]: ()\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] args[8]: ()\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] \n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] Set TORCH_LOGS=\"+dynamo\" and TORCHDYNAMO_VERBOSE=1 for more information\n",
|
|
"W0810 13:55:08.918000 21035 torch/_dynamo/convert_frame.py:1100] \n"
|
|
]
|
|
},
|
|
{
|
|
"data": {
|
|
"image/png": "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\n",
|
|
"text/plain": [
|
|
"<Figure size 640x480 with 1 Axes>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"import torch._dynamo\n",
|
|
"torch._dynamo.config.suppress_errors = True\n",
|
|
"\n",
|
|
"def prepare_function(fn):\n",
|
|
" fn = torch.compile(fn)\n",
|
|
" return fn\n",
|
|
"\n",
|
|
"\n",
|
|
"execution_times = [time_pytorch_function_forward_backward(prepare_function(fn), embeddings_cuda) for name,fn in functions.items()]\n",
|
|
"\n",
|
|
"\n",
|
|
"# Plotting\n",
|
|
"\n",
|
|
"fig, ax = plt.subplots()\n",
|
|
"bars = plt.bar(functions.keys(), execution_times)\n",
|
|
"\n",
|
|
"plt.ylabel(\"Execution time (ms)\")\n",
|
|
"plt.xticks(rotation=45, ha=\"right\")\n",
|
|
"\n",
|
|
"# Calculate new ylim with a margin\n",
|
|
"max_execution_time = max(execution_times)\n",
|
|
"upper_ylim = max_execution_time + 0.2 * max_execution_time # Adding a 20% margin\n",
|
|
"\n",
|
|
"plt.ylim(0, upper_ylim) # Setting new ylim\n",
|
|
"\n",
|
|
"# Annotate bars with execution times\n",
|
|
"for bar in bars:\n",
|
|
" yval = bar.get_height()\n",
|
|
" plt.text(bar.get_x() + bar.get_width()/2, yval + (0.05 * upper_ylim), round(yval, 2), ha=\"center\", va=\"bottom\")\n",
|
|
"\n",
|
|
"\n",
|
|
"plt.tight_layout()\n",
|
|
"plt.savefig(\"3_forward-and-backward-compiled.pdf\")\n",
|
|
"plt.show()"
|
|
]
|
|
}
|
|
],
|
|
"metadata": {
|
|
"accelerator": "GPU",
|
|
"colab": {
|
|
"gpuType": "A100",
|
|
"provenance": []
|
|
},
|
|
"kernelspec": {
|
|
"display_name": "Python 3 (ipykernel)",
|
|
"language": "python",
|
|
"name": "python3"
|
|
},
|
|
"language_info": {
|
|
"codemirror_mode": {
|
|
"name": "ipython",
|
|
"version": 3
|
|
},
|
|
"file_extension": ".py",
|
|
"mimetype": "text/x-python",
|
|
"name": "python",
|
|
"nbconvert_exporter": "python",
|
|
"pygments_lexer": "ipython3",
|
|
"version": "3.11.4"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 5
|
|
}
|