Spaces:
Paused
Paused
| # Copyright (c) 2026 SandAI. All Rights Reserved. | |
| # | |
| # Licensed under the Apache License, Version 2.0 (the "License"); | |
| # you may not use this file except in compliance with the License. | |
| # You may obtain a copy of the License at | |
| # | |
| # http://www.apache.org/licenses/LICENSE-2.0 | |
| # | |
| # Unless required by applicable law or agreed to in writing, software | |
| # distributed under the License is distributed on an "AS IS" BASIS, | |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| # See the License for the specific language governing permissions and | |
| # limitations under the License. | |
| from typing import Callable | |
| import torch | |
| from magi_compiler.api import magi_compile | |
| from magi_compiler.utils import magi_logger, nvtx | |
| # 先补全依赖的类定义(确保代码可独立运行) | |
| class ModelConfig: | |
| def __init__( | |
| self, | |
| hidden_size, | |
| num_layers, | |
| num_heads_q, | |
| num_heads_kv, | |
| head_dim, | |
| intermediate_size, | |
| activation_type, | |
| params_dtype=torch.float32, | |
| eps=1e-06, | |
| ): | |
| self.hidden_size = hidden_size | |
| self.num_layers = num_layers | |
| self.num_heads_q = num_heads_q | |
| self.num_heads_kv = num_heads_kv | |
| self.head_dim = head_dim | |
| self.intermediate_size = intermediate_size | |
| self.activation_type = activation_type | |
| self.params_dtype = params_dtype | |
| self.eps = eps | |
| def __repr__(self): | |
| return ( | |
| f"ModelConfig(hidden_size={self.hidden_size}, num_layers={self.num_layers}, " | |
| f"num_heads_q={self.num_heads_q}, num_heads_kv={self.num_heads_kv}, " | |
| f"head_dim={self.head_dim}, intermediate_size={self.intermediate_size}, " | |
| f"activation_type='{self.activation_type}', params_dtype={self.params_dtype}, eps={self.eps})" | |
| ) | |
| class CompiledTransformerModel(torch.nn.Module): | |
| def __init__(self, config: ModelConfig): | |
| super().__init__() | |
| self.mod = TransformerModel(config) | |
| def forward(self, x): | |
| return self.mod(x) | |
| class TransformerModel(torch.nn.Module): | |
| def __init__(self, config: ModelConfig): | |
| super().__init__() | |
| self.config = config | |
| self.layers = torch.nn.ModuleList([TransformerLayer(config) for _ in range(config.num_layers)]) | |
| self.final_norm = torch.nn.LayerNorm(config.hidden_size, eps=config.eps, bias=False) | |
| def forward(self, x): | |
| for layer in self.layers: | |
| x = layer(x) | |
| x = self.final_norm(x) | |
| return x | |
| class TransformerLayer(torch.nn.Module): | |
| def __init__(self, config: ModelConfig): | |
| super().__init__() | |
| self.attn_norm = torch.nn.LayerNorm(config.hidden_size, eps=config.eps, bias=False) | |
| self.attention = GroupedQueryAttention(config) | |
| self.mlp_norm = torch.nn.LayerNorm(config.hidden_size, eps=config.eps, bias=False) | |
| self.mlp = MLPLayer(config) | |
| def forward(self, x): | |
| x = x + self.attention(self.attn_norm(x)) | |
| x = x + self.mlp(self.mlp_norm(x)) | |
| return x | |
| class GroupedQueryAttention(torch.nn.Module): | |
| def __init__(self, config: ModelConfig): | |
| super().__init__() | |
| self.n_heads_q = config.num_heads_q # 32 | |
| self.n_heads_kv = config.num_heads_kv # 8 | |
| self.head_dim = config.head_dim # 128 | |
| self.n_rep = self.n_heads_q // self.n_heads_kv # 32//8=4 | |
| self.hidden_size = config.hidden_size # 4096 | |
| self.q_size = self.n_heads_q * self.head_dim # 32*128=4096 | |
| self.kv_size = self.n_heads_kv * self.head_dim # 8*128=1024 | |
| self.qkv_proj = torch.nn.Linear(config.hidden_size, self.q_size + 2 * self.kv_size, bias=False) | |
| self.o_proj = torch.nn.Linear(self.q_size, config.hidden_size, bias=False) | |
| def forward(self, x): | |
| qkv = self.qkv_proj(x) | |
| q, k, v = torch.split(qkv, [self.q_size, self.kv_size, self.kv_size], dim=-1) | |
| q = q.view(1, -1, self.n_heads_q, self.head_dim) | |
| k = k.view(1, -1, self.n_heads_kv, self.head_dim) | |
| v = v.view(1, -1, self.n_heads_kv, self.head_dim) | |
| if self.n_rep > 1: | |
| k = k.repeat_interleave(self.n_rep, dim=2) | |
| v = v.repeat_interleave(self.n_rep, dim=2) | |
| q = q.transpose(1, 2) | |
| k = k.transpose(1, 2) | |
| v = v.transpose(1, 2) | |
| out: torch.Tensor = my_attention(q, k, v) | |
| # out = q | |
| out = out.transpose(1, 2) | |
| out = out.squeeze(0) | |
| out = out.view(-1, self.q_size) | |
| out = self.o_proj(out) | |
| return out | |
| return x # 临时屏蔽注意力计算,专注测试 MLP 部分的性能 | |
| class MLPModel(torch.nn.Module): | |
| def __init__(self, config: ModelConfig): | |
| super().__init__() | |
| self.config = config | |
| self.layers = torch.nn.ModuleList([MLPLayer(config) for _ in range(config.num_layers)]) | |
| def forward(self, x): | |
| for layer in self.layers: | |
| x = layer(x) | |
| return x | |
| class MLPLayer(torch.nn.Module): | |
| def __init__(self, config: ModelConfig): | |
| super().__init__() | |
| self.pre_norm = torch.nn.LayerNorm(config.hidden_size, eps=config.eps, bias=False) | |
| self.fc1 = torch.nn.Linear(config.hidden_size, config.intermediate_size, bias=False) | |
| self.activation = torch.nn.GELU() | |
| self.fc2 = torch.nn.Linear(config.intermediate_size, config.hidden_size, bias=False) | |
| def forward(self, x): | |
| x = self.pre_norm(x) | |
| # x = self.fc1(x) | |
| x = self.activation(x) | |
| # x = self.fc2(x) | |
| return x | |
| class CompiledMiniMLP(torch.nn.Module): | |
| def __init__(self, config: ModelConfig): | |
| super().__init__() | |
| self.mod = MLPModel(config) | |
| def forward(self, x): | |
| return self.mod(x) | |
| def benchmark_func(func: Callable, warmup_steps: int = 10, run_steps: int = 10, desc: str = "测试") -> float: | |
| torch.cuda.synchronize() | |
| start_event = torch.cuda.Event(enable_timing=True) | |
| end_event = torch.cuda.Event(enable_timing=True) | |
| def warmup(): | |
| for _ in range(warmup_steps): | |
| _ = func() | |
| torch.cuda.synchronize() # 确保预热的 CUDA 操作全部完成 | |
| warmup() | |
| total_elapsed_ms = None | |
| def run(): | |
| nonlocal total_elapsed_ms | |
| total_elapsed_ms = 0.0 # 总耗时(毫秒) | |
| start_event.record() | |
| for _ in range(run_steps): | |
| func() # 要求func内部所有CUDA操作都已提交并完成! | |
| end_event.record() | |
| end_event.synchronize() # 确保结束事件已完成 | |
| total_elapsed_ms += start_event.elapsed_time(end_event) | |
| run() | |
| avg_time = total_elapsed_ms / run_steps / 1000.0 | |
| total_time = total_elapsed_ms / 1000.0 | |
| magi_logger.info("[%s] 完成!平均耗时: %.6f 秒/次 | 总耗时: %.6f 秒 (CUDA Event 精准计时)", desc, avg_time, total_time, rank=0) | |
| torch.cuda.synchronize() | |
| return avg_time | |
| def my_attention(q: torch.Tensor, k: torch.Tensor, v: torch.Tensor) -> torch.Tensor: | |
| return torch.nn.functional.scaled_dot_product_attention(q, k, v) | |
| def _(q: torch.Tensor, k: torch.Tensor, v: torch.Tensor) -> torch.Tensor: | |
| return torch.empty_like(q) | |