Windows 下Mamba2 / Vim / Vmamba 情况安装问题记录及解决方法终极版(无需 ...

打印 上一主题 下一主题

主题 892|帖子 892|积分 2676

导航

安装教程导航



  • Mamba 及 Vim 安装问题参看本人博客:Mamba 情况安装踩坑问题汇总及解决方法(初版)
  • Linux 下Mamba 及 Vim 安装问题参看本人博客:Mamba 情况安装踩坑问题汇总及解决方法(重置版)
  • Windows 下 Mamba 的安装参看本人博客:Window 下Mamba 情况安装踩坑问题汇总及解决方法 (无需绕过selective_scan_cuda)
  • Linux 下 Vim 安装问题参看本人博客:Linux 下 Vim 情况安装踩坑问题汇总及解决方法(重置版)
  • Windows 下 Vim 安装问题参看本人博客:Window 下 Vim 情况安装踩坑问题汇总及解决方法
  • Linux 下Vmamba 安装教程参看本人博客:Vmamba 安装教程(无需更改base情况中的cuda版本)
  • Windows 下 VMamba的安装参看本人博客:Windows 下 VMamba 安装教程(无需更改base情况中的cuda版本且可加速)
  • Windows下 Mamba2及高版本 causal_conv1d 安装参考本人博客:Windows 下Mamba2 情况安装问题记录及解决方法(causal_conv1d=1.4.0)
  • Windows 下 Mamba / Vim / Vmamba 情况安装终极版参考本人博客:Windows 下Mamba2 / Vim / Vmamba 情况安装问题记录及解决方法终极版(无需绕过triton)
安装包导航



  • Mamba 安装教程博客中涉及到的全部安装包:mamba 安装包,包括Windows和Linux
  • Vim 安装教程博客中涉及到的全部安装包:vim 安装包,包括Windows和Linux
  • Vmamba 安装教程博客中涉及到的全部安装包:vmamba 安装包,包括Windows和Linux
  • Mamba2 及 更高版本causal_conv1d Windows安装包:mamba 2 windows安装包
(安装问题 / 资源自取售后 / 论文相助想法请+vx:931744281)

  
背景

在笔者之前的系列博客中,比方 Windows 下Mamba2 情况安装问题记录及解决方法(causal_conv1d=1.4.0),以及 Window 下 Vim 情况安装踩坑问题汇总及解决方法 遭遇了与 triton 有关的问题,之后在本人博客 Windows 下安装 triton 教程 之后,终于实现了 mamba / vim / vmamba 在Windows下,无需更改重要代码,直接运行程序。本博客安装版本为:mamba_ssm-2.2.2 和 causal_conv1d-1.4.0。CUDA 版本为12.4。
安装步骤

1. Windows 下前期情况预备

前期情况预备,雷同原来博客 “Windows 下Mamba2 情况安装问题记录及解决方法(causal_conv1d=1.4.0)” ,但是由于 triton-Windows 对 CUDA 版本的高要求,所以详细更改为:
  1. conda create -n mamba python=3.10
  2. conda activate mamba
  3. # CUDA 12.4
  4. pip install torch==2.4.1 torchvision==0.19.1 torchaudio==2.4.1 --index-url https://download.pytorch.org/whl/cu124
  5. python -c "import torch; print(torch.cuda.is_available())" # 验证torch安装
  6. # 安装cuda
  7. conda install nvidia/label/cuda-12.4.0::cuda-nvcc
  8. pip install setuptools==68.2.2
  9. conda install packaging
复制代码
2. triton-windows 情况预备

参考本人之前博客 Windows 下安装 triton 教程 ,包括:


  • 安装 MSVC 和 Windows SDK
  • 修改情况变量
  • vcredist 安装
前期情况都配置无误后,直接下载 whl 安装:
  1. pip install https://github.com/woct0rdho/triton-windows/releases/download/v3.1.0-windows.post5/triton-3.1.0-cp310-cp310-win_amd64.whl
复制代码
也可手动下载下来然后在下载路径下安装:
  1. pip install triton-3.1.0-cp310-cp310-win_amd64.whl
复制代码
验证脚本为:
  1. import torch
  2. import triton
  3. import triton.language as tl
  4. @triton.jit
  5. def add_kernel(x_ptr, y_ptr, output_ptr, n_elements, BLOCK_SIZE: tl.constexpr):
  6.     pid = tl.program_id(axis=0)
  7.     block_start = pid * BLOCK_SIZE
  8.     offsets = block_start + tl.arange(0, BLOCK_SIZE)
  9.     mask = offsets < n_elements
  10.     x = tl.load(x_ptr + offsets, mask=mask)
  11.     y = tl.load(y_ptr + offsets, mask=mask)
  12.     output = x + y
  13.     tl.store(output_ptr + offsets, output, mask=mask)
  14. def add(x: torch.Tensor, y: torch.Tensor):
  15.     output = torch.empty_like(x)
  16.     assert x.is_cuda and y.is_cuda and output.is_cuda
  17.     n_elements = output.numel()
  18.     grid = lambda meta: (triton.cdiv(n_elements, meta["BLOCK_SIZE"]),)
  19.     add_kernel[grid](x, y, output, n_elements, BLOCK_SIZE=1024)
  20.     return output
  21. a = torch.rand(3, device="cuda")
  22. b = a + a
  23. b_compiled = add(a, a)
  24. print(b_compiled - b)
  25. print("If you see tensor([0., 0., 0.], device='cuda:0'), then it works")
复制代码
不报错即阐明配置成功。
3. 从源码编译causal-conv1d 1.4.0 版本

步骤还是参考本人原来博客 “Windows 下Mamba2 情况安装问题记录及解决方法(causal_conv1d=1.4.0)”,不外有可能会遭遇问题,需要先
  1. conda install nvidia/label/cuda-12.4.0::cuda-cccl
复制代码
如果下载缓慢,可以先把安装包下载下来,然后举行当地安装
  1. conda install --use-local cuda-cccl-12.4.99-0.tar.bz2
复制代码
接着是下载工程文件,即
  1. git clone https://github.com/Dao-AILab/causal-conv1d.git
  2. cd causal-conv1d
  3. set CAUSAL_CONV1D_FORCE_BUILD=TRUE  # 也可修改setup.py第37行
  4. # 先按照博客修改源码然后再执行这最后一步
  5. pip install .
复制代码
在实行最后一步编译之前,还是需要修改,参考本人原来博客 “Windows 下Mamba2 情况安装问题记录及解决方法(causal_conv1d=1.4.0)”。
4. 从源码编译 mamba-ssm 版本

前期预备以及部门文件的修改同原来博客 “Windows 下Mamba2 情况安装问题记录及解决方法(causal_conv1d=1.4.0)”,详细来说:
1)mamba-ssm 情况预备,下载工程文件,即
  1. git clone https://github.com/state-spaces/mamba.git
  2. cd mamba
  3. set MAMBA_FORCE_BUILD=TRUE  # 也可修改setup.py第40行
  4. # 先按照博客修改源码然后再执行这最后一步
  5. pip install . --no-build-isolation
复制代码
2)在实行最后一步编译之前,还是需要修改,参考本人原来博客 “Windows 下Mamba2 情况安装问题记录及解决方法(causal_conv1d=1.4.0)”
5. Mamba 情况运行验证

参考官方的 readme 文件,运行以下示例:
  1. import torch
  2. from mamba_ssm import Mamba
  3. from mamba_ssm import Mamba2
  4. batch, length, dim = 2, 64, 16
  5. x = torch.randn(batch, length, dim).to("cuda")
  6. model = Mamba(
  7.     # This module uses roughly 3 * expand * d_model^2 parameters
  8.     d_model=dim, # Model dimension d_model
  9.     d_state=16,  # SSM state expansion factor
  10.     d_conv=4,    # Local convolution width
  11.     expand=2,    # Block expansion factor
  12. ).to("cuda")
  13. y = model(x)
  14. assert y.shape == x.shape
  15. print('Mamba:', x.shape)
  16. batch, length, dim = 2, 64, 256
  17. x = torch.randn(batch, length, dim).to("cuda")
  18. model = Mamba2(
  19.     # This module uses roughly 3 * expand * d_model^2 parameters
  20.     d_model=dim, # Model dimension d_model
  21.     d_state=64,  # SSM state expansion factor, typically 64 or 128
  22.     d_conv=4,    # Local convolution width
  23.     expand=2,    # Block expansion factor
  24. ).to("cuda")
  25. y = model(x)
  26. assert y.shape == x.shape
  27. print('Mamba2:', x.shape)
复制代码
正常输出结果无报错。如下图所示,不再出现 KeyError: 'HOME' :

6. Windows 下 Vim 的安装

Vim 官方代码仓给的 causal-conv1d 源码有误,过于老旧且不兼容,causal-conv1d版本应≥1.1.0,其他部门还是参考原来的博客 Window 下 Vim 情况安装踩坑问题汇总及解决方法:
  1. git clone https://github.com/Dao-AILab/causal-conv1d.git
  2. cd causal-conv1d
  3. git checkout v1.1.1  # 安装最新版的话,此步可省略
  4. set CAUSAL_CONV1D_FORCE_BUILD=TRUE
  5. pip install .
复制代码
注意在 pip install -r vim/vim_requirements.txt 其他情况时,将 vim/vim_requirements.txt 里面的triton版本注释掉。
7. Vim 情况运行验证

运行以下示例:
  1. # Copyright (c) 2015-present, Facebook, Inc.
  2. # All rights reserved.
  3. import torch
  4. import torch.nn as nn
  5. from functools import partial
  6. from torch import Tensor
  7. from typing import Optional
  8. from timm.models.vision_transformer import VisionTransformer, _cfg
  9. from timm.models.registry import register_model
  10. from timm.models.layers import trunc_normal_, lecun_normal_
  11. from timm.models.layers import DropPath, to_2tuple
  12. from timm.models.vision_transformer import _load_weights
  13. import math
  14. from collections import namedtuple
  15. from mamba_ssm.modules.mamba_simple import Mamba
  16. from mamba_ssm.utils.generation import GenerationMixin
  17. from mamba_ssm.utils.hf import load_config_hf, load_state_dict_hf
  18. from rope import *
  19. import random
  20. try:
  21.     from mamba_ssm.ops.triton.layernorm import RMSNorm, layer_norm_fn, rms_norm_fn
  22. except ImportError:
  23.     RMSNorm, layer_norm_fn, rms_norm_fn = None, None, None
  24. __all__ = [
  25.     'vim_tiny_patch16_224', 'vim_small_patch16_224', 'vim_base_patch16_224',
  26.     'vim_tiny_patch16_384', 'vim_small_patch16_384', 'vim_base_patch16_384',
  27. ]
  28. class PatchEmbed(nn.Module):
  29.     """ 2D Image to Patch Embedding
  30.     """
  31.     def __init__(self, img_size=224, patch_size=16, stride=16, in_chans=3, embed_dim=768, norm_layer=None,
  32.                  flatten=True):
  33.         super().__init__()
  34.         img_size = to_2tuple(img_size)
  35.         patch_size = to_2tuple(patch_size)
  36.         self.img_size = img_size
  37.         self.patch_size = patch_size
  38.         self.grid_size = ((img_size[0] - patch_size[0]) // stride + 1, (img_size[1] - patch_size[1]) // stride + 1)
  39.         self.num_patches = self.grid_size[0] * self.grid_size[1]
  40.         self.flatten = flatten
  41.         self.proj = nn.Conv2d(in_chans, embed_dim, kernel_size=patch_size, stride=stride)
  42.         self.norm = norm_layer(embed_dim) if norm_layer else nn.Identity()
  43.     def forward(self, x):
  44.         B, C, H, W = x.shape
  45.         assert H == self.img_size[0] and W == self.img_size[1], \
  46.             f"Input image size ({H}*{W}) doesn't match model ({self.img_size[0]}*{self.img_size[1]})."
  47.         x = self.proj(x)
  48.         if self.flatten:
  49.             x = x.flatten(2).transpose(1, 2)  # BCHW -> BNC
  50.         x = self.norm(x)
  51.         return x
  52. class Block(nn.Module):
  53.     def __init__(
  54.             self, dim, mixer_cls, norm_cls=nn.LayerNorm, fused_add_norm=False, residual_in_fp32=False, drop_path=0.,
  55.     ):
  56.         """
  57.         Simple block wrapping a mixer class with LayerNorm/RMSNorm and residual connection"
  58.         This Block has a slightly different structure compared to a regular
  59.         prenorm Transformer block.
  60.         The standard block is: LN -> MHA/MLP -> Add.
  61.         [Ref: https://arxiv.org/abs/2002.04745]
  62.         Here we have: Add -> LN -> Mixer, returning both
  63.         the hidden_states (output of the mixer) and the residual.
  64.         This is purely for performance reasons, as we can fuse add and LayerNorm.
  65.         The residual needs to be provided (except for the very first block).
  66.         """
  67.         super().__init__()
  68.         self.residual_in_fp32 = residual_in_fp32
  69.         self.fused_add_norm = fused_add_norm
  70.         self.mixer = mixer_cls(dim)
  71.         self.norm = norm_cls(dim)
  72.         self.drop_path = DropPath(drop_path) if drop_path > 0. else nn.Identity()
  73.         if self.fused_add_norm:
  74.             assert RMSNorm is not None, "RMSNorm import fails"
  75.             assert isinstance(
  76.                 self.norm, (nn.LayerNorm, RMSNorm)
  77.             ), "Only LayerNorm and RMSNorm are supported for fused_add_norm"
  78.     def forward(
  79.             self, hidden_states: Tensor, residual: Optional[Tensor] = None, inference_params=None
  80.     ):
  81.         r"""Pass the input through the encoder layer.
  82.         Args:
  83.             hidden_states: the sequence to the encoder layer (required).
  84.             residual: hidden_states = Mixer(LN(residual))
  85.         """
  86.         if not self.fused_add_norm:
  87.             if residual is None:
  88.                 residual = hidden_states
  89.             else:
  90.                 residual = residual + self.drop_path(hidden_states)
  91.             hidden_states = self.norm(residual.to(dtype=self.norm.weight.dtype))
  92.             if self.residual_in_fp32:
  93.                 residual = residual.to(torch.float32)
  94.         else:
  95.             fused_add_norm_fn = rms_norm_fn if isinstance(self.norm, RMSNorm) else layer_norm_fn
  96.             if residual is None:
  97.                 hidden_states, residual = fused_add_norm_fn(
  98.                     hidden_states,
  99.                     self.norm.weight,
  100.                     self.norm.bias,
  101.                     residual=residual,
  102.                     prenorm=True,
  103.                     residual_in_fp32=self.residual_in_fp32,
  104.                     eps=self.norm.eps,
  105.                 )
  106.             else:
  107.                 hidden_states, residual = fused_add_norm_fn(
  108.                     self.drop_path(hidden_states),
  109.                     self.norm.weight,
  110.                     self.norm.bias,
  111.                     residual=residual,
  112.                     prenorm=True,
  113.                     residual_in_fp32=self.residual_in_fp32,
  114.                     eps=self.norm.eps,
  115.                 )
  116.         hidden_states = self.mixer(hidden_states, inference_params=inference_params)
  117.         return hidden_states, residual
  118.     def allocate_inference_cache(self, batch_size, max_seqlen, dtype=None, **kwargs):
  119.         return self.mixer.allocate_inference_cache(batch_size, max_seqlen, dtype=dtype, **kwargs)
  120. def create_block(
  121.         d_model,
  122.         ssm_cfg=None,
  123.         norm_epsilon=1e-5,
  124.         drop_path=0.,
  125.         rms_norm=False,
  126.         residual_in_fp32=False,
  127.         fused_add_norm=False,
  128.         layer_idx=None,
  129.         device=None,
  130.         dtype=None,
  131.         if_bimamba=False,
  132.         bimamba_type="none",
  133.         if_divide_out=False,
  134.         init_layer_scale=None,
  135. ):
  136.     if if_bimamba:
  137.         bimamba_type = "v1"
  138.     if ssm_cfg is None:
  139.         ssm_cfg = {}
  140.     factory_kwargs = {"device": device, "dtype": dtype}
  141.     mixer_cls = partial(Mamba, layer_idx=layer_idx, bimamba_type=bimamba_type, if_divide_out=if_divide_out,
  142.                         init_layer_scale=init_layer_scale, **ssm_cfg, **factory_kwargs)
  143.     norm_cls = partial(
  144.         nn.LayerNorm if not rms_norm else RMSNorm, eps=norm_epsilon, **factory_kwargs
  145.     )
  146.     block = Block(
  147.         d_model,
  148.         mixer_cls,
  149.         norm_cls=norm_cls,
  150.         drop_path=drop_path,
  151.         fused_add_norm=fused_add_norm,
  152.         residual_in_fp32=residual_in_fp32,
  153.     )
  154.     block.layer_idx = layer_idx
  155.     return block
  156. # https://github.com/huggingface/transformers/blob/c28d04e9e252a1a099944e325685f14d242ecdcd/src/transformers/models/gpt2/modeling_gpt2.py#L454
  157. def _init_weights(
  158.         module,
  159.         n_layer,
  160.         initializer_range=0.02,  # Now only used for embedding layer.
  161.         rescale_prenorm_residual=True,
  162.         n_residuals_per_layer=1,  # Change to 2 if we have MLP
  163. ):
  164.     if isinstance(module, nn.Linear):
  165.         if module.bias is not None:
  166.             if not getattr(module.bias, "_no_reinit", False):
  167.                 nn.init.zeros_(module.bias)
  168.     elif isinstance(module, nn.Embedding):
  169.         nn.init.normal_(module.weight, std=initializer_range)
  170.     if rescale_prenorm_residual:
  171.         # Reinitialize selected weights subject to the OpenAI GPT-2 Paper Scheme:
  172.         #   > A modified initialization which accounts for the accumulation on the residual path with model depth. Scale
  173.         #   > the weights of residual layers at initialization by a factor of 1/√N where N is the # of residual layers.
  174.         #   >   -- GPT-2 :: https://openai.com/blog/better-language-models/
  175.         #
  176.         # Reference (Megatron-LM): https://github.com/NVIDIA/Megatron-LM/blob/main/megatron/model/gpt_model.py
  177.         for name, p in module.named_parameters():
  178.             if name in ["out_proj.weight", "fc2.weight"]:
  179.                 # Special Scaled Initialization --> There are 2 Layer Norms per Transformer Block
  180.                 # Following Pytorch init, except scale by 1/sqrt(2 * n_layer)
  181.                 # We need to reinit p since this code could be called multiple times
  182.                 # Having just p *= scale would repeatedly scale it down
  183.                 nn.init.kaiming_uniform_(p, a=math.sqrt(5))
  184.                 with torch.no_grad():
  185.                     p /= math.sqrt(n_residuals_per_layer * n_layer)
  186. def segm_init_weights(m):
  187.     if isinstance(m, nn.Linear):
  188.         trunc_normal_(m.weight, std=0.02)
  189.         if isinstance(m, nn.Linear) and m.bias is not None:
  190.             nn.init.constant_(m.bias, 0)
  191.     elif isinstance(m, nn.Conv2d):
  192.         # NOTE conv was left to pytorch default in my original init
  193.         lecun_normal_(m.weight)
  194.         if m.bias is not None:
  195.             nn.init.zeros_(m.bias)
  196.     elif isinstance(m, (nn.LayerNorm, nn.GroupNorm, nn.BatchNorm2d)):
  197.         nn.init.zeros_(m.bias)
  198.         nn.init.ones_(m.weight)
  199. class VisionMamba(nn.Module):
  200.     def __init__(self,
  201.                  img_size=224,
  202.                  patch_size=16,
  203.                  stride=16,
  204.                  depth=24,
  205.                  embed_dim=192,
  206.                  channels=3,
  207.                  num_classes=1000,
  208.                  ssm_cfg=None,
  209.                  drop_rate=0.,
  210.                  drop_path_rate=0.1,
  211.                  norm_epsilon: float = 1e-5,
  212.                  rms_norm: bool = False,
  213.                  initializer_cfg=None,
  214.                  fused_add_norm=False,
  215.                  residual_in_fp32=False,
  216.                  device=None,
  217.                  dtype=None,
  218.                  ft_seq_len=None,
  219.                  pt_hw_seq_len=14,
  220.                  if_bidirectional=False,
  221.                  final_pool_type='none',
  222.                  if_abs_pos_embed=False,
  223.                  if_rope=False,
  224.                  if_rope_residual=False,
  225.                  flip_img_sequences_ratio=-1.,
  226.                  if_bimamba=False,
  227.                  bimamba_type="none",
  228.                  if_cls_token=False,
  229.                  if_divide_out=False,
  230.                  init_layer_scale=None,
  231.                  use_double_cls_token=False,
  232.                  use_middle_cls_token=False,
  233.                  **kwargs):
  234.         factory_kwargs = {"device": device, "dtype": dtype}
  235.         # add factory_kwargs into kwargs
  236.         kwargs.update(factory_kwargs)
  237.         super().__init__()
  238.         self.residual_in_fp32 = residual_in_fp32
  239.         self.fused_add_norm = fused_add_norm
  240.         self.if_bidirectional = if_bidirectional
  241.         self.final_pool_type = final_pool_type
  242.         self.if_abs_pos_embed = if_abs_pos_embed
  243.         self.if_rope = if_rope
  244.         self.if_rope_residual = if_rope_residual
  245.         self.flip_img_sequences_ratio = flip_img_sequences_ratio
  246.         self.if_cls_token = if_cls_token
  247.         self.use_double_cls_token = use_double_cls_token
  248.         self.use_middle_cls_token = use_middle_cls_token
  249.         self.num_tokens = 1 if if_cls_token else 0
  250.         # pretrain parameters
  251.         self.num_classes = num_classes
  252.         self.d_model = self.num_features = self.embed_dim = embed_dim  # num_features for consistency with other models
  253.         self.patch_embed = PatchEmbed(
  254.             img_size=img_size, patch_size=patch_size, stride=stride, in_chans=channels, embed_dim=embed_dim)
  255.         num_patches = self.patch_embed.num_patches
  256.         if if_cls_token:
  257.             if use_double_cls_token:
  258.                 self.cls_token_head = nn.Parameter(torch.zeros(1, 1, self.embed_dim))
  259.                 self.cls_token_tail = nn.Parameter(torch.zeros(1, 1, self.embed_dim))
  260.                 self.num_tokens = 2
  261.             else:
  262.                 self.cls_token = nn.Parameter(torch.zeros(1, 1, self.embed_dim))
  263.                 # self.num_tokens = 1
  264.         if if_abs_pos_embed:
  265.             self.pos_embed = nn.Parameter(torch.zeros(1, num_patches + self.num_tokens, self.embed_dim))
  266.             self.pos_drop = nn.Dropout(p=drop_rate)
  267.         if if_rope:
  268.             half_head_dim = embed_dim // 2
  269.             hw_seq_len = img_size // patch_size
  270.             self.rope = VisionRotaryEmbeddingFast(
  271.                 dim=half_head_dim,
  272.                 pt_seq_len=pt_hw_seq_len,
  273.                 ft_seq_len=hw_seq_len
  274.             )
  275.         self.head = nn.Linear(self.num_features, num_classes) if num_classes > 0 else nn.Identity()
  276.         # TODO: release this comment
  277.         dpr = [x.item() for x in torch.linspace(0, drop_path_rate, depth)]  # stochastic depth decay rule
  278.         # import ipdb;ipdb.set_trace()
  279.         inter_dpr = [0.0] + dpr
  280.         self.drop_path = DropPath(drop_path_rate) if drop_path_rate > 0. else nn.Identity()
  281.         # transformer blocks
  282.         self.layers = nn.ModuleList(
  283.             [
  284.                 create_block(
  285.                     embed_dim,
  286.                     ssm_cfg=ssm_cfg,
  287.                     norm_epsilon=norm_epsilon,
  288.                     rms_norm=rms_norm,
  289.                     residual_in_fp32=residual_in_fp32,
  290.                     fused_add_norm=fused_add_norm,
  291.                     layer_idx=i,
  292.                     if_bimamba=if_bimamba,
  293.                     bimamba_type=bimamba_type,
  294.                     drop_path=inter_dpr[i],
  295.                     if_divide_out=if_divide_out,
  296.                     init_layer_scale=init_layer_scale,
  297.                     **factory_kwargs,
  298.                 )
  299.                 for i in range(depth)
  300.             ]
  301.         )
  302.         # output head
  303.         self.norm_f = (nn.LayerNorm if not rms_norm else RMSNorm)(
  304.             embed_dim, eps=norm_epsilon, **factory_kwargs
  305.         )
  306.         # self.pre_logits = nn.Identity()
  307.         # original init
  308.         self.patch_embed.apply(segm_init_weights)
  309.         self.head.apply(segm_init_weights)
  310.         if if_abs_pos_embed:
  311.             trunc_normal_(self.pos_embed, std=.02)
  312.         if if_cls_token:
  313.             if use_double_cls_token:
  314.                 trunc_normal_(self.cls_token_head, std=.02)
  315.                 trunc_normal_(self.cls_token_tail, std=.02)
  316.             else:
  317.                 trunc_normal_(self.cls_token, std=.02)
  318.         # mamba init
  319.         self.apply(
  320.             partial(
  321.                 _init_weights,
  322.                 n_layer=depth,
  323.                 **(initializer_cfg if initializer_cfg is not None else {}),
  324.             )
  325.         )
  326.     def allocate_inference_cache(self, batch_size, max_seqlen, dtype=None, **kwargs):
  327.         return {
  328.             i: layer.allocate_inference_cache(batch_size, max_seqlen, dtype=dtype, **kwargs)
  329.             for i, layer in enumerate(self.layers)
  330.         }
  331.     @torch.jit.ignore
  332.     def no_weight_decay(self):
  333.         return {"pos_embed", "cls_token", "dist_token", "cls_token_head", "cls_token_tail"}
  334.     @torch.jit.ignore()
  335.     def load_pretrained(self, checkpoint_path, prefix=""):
  336.         _load_weights(self, checkpoint_path, prefix)
  337.     def forward_features(self, x, inference_params=None, if_random_cls_token_position=False,
  338.                          if_random_token_rank=False):
  339.         # taken from https://github.com/rwightman/pytorch-image-models/blob/master/timm/models/vision_transformer.py
  340.         # with slight modifications to add the dist_token
  341.         x = self.patch_embed(x)
  342.         B, M, _ = x.shape
  343.         if self.if_cls_token:
  344.             if self.use_double_cls_token:
  345.                 cls_token_head = self.cls_token_head.expand(B, -1, -1)
  346.                 cls_token_tail = self.cls_token_tail.expand(B, -1, -1)
  347.                 token_position = [0, M + 1]
  348.                 x = torch.cat((cls_token_head, x, cls_token_tail), dim=1)
  349.                 M = x.shape[1]
  350.             else:
  351.                 if self.use_middle_cls_token:
  352.                     cls_token = self.cls_token.expand(B, -1, -1)
  353.                     token_position = M // 2
  354.                     # add cls token in the middle
  355.                     x = torch.cat((x[:, :token_position, :], cls_token, x[:, token_position:, :]), dim=1)
  356.                 elif if_random_cls_token_position:
  357.                     cls_token = self.cls_token.expand(B, -1, -1)
  358.                     token_position = random.randint(0, M)
  359.                     x = torch.cat((x[:, :token_position, :], cls_token, x[:, token_position:, :]), dim=1)
  360.                     print("token_position: ", token_position)
  361.                 else:
  362.                     cls_token = self.cls_token.expand(B, -1, -1)  # stole cls_tokens impl from Phil Wang, thanks
  363.                     token_position = 0
  364.                     x = torch.cat((cls_token, x), dim=1)
  365.                 M = x.shape[1]
  366.         if self.if_abs_pos_embed:
  367.             # if new_grid_size[0] == self.patch_embed.grid_size[0] and new_grid_size[1] == self.patch_embed.grid_size[1]:
  368.             #     x = x + self.pos_embed
  369.             # else:
  370.             #     pos_embed = interpolate_pos_embed_online(
  371.             #                 self.pos_embed, self.patch_embed.grid_size, new_grid_size,0
  372.             #             )
  373.             x = x + self.pos_embed
  374.             x = self.pos_drop(x)
  375.         if if_random_token_rank:
  376.             # 生成随机 shuffle 索引
  377.             shuffle_indices = torch.randperm(M)
  378.             if isinstance(token_position, list):
  379.                 print("original value: ", x[0, token_position[0], 0], x[0, token_position[1], 0])
  380.             else:
  381.                 print("original value: ", x[0, token_position, 0])
  382.             print("original token_position: ", token_position)
  383.             # 执行 shuffle
  384.             x = x[:, shuffle_indices, :]
  385.             if isinstance(token_position, list):
  386.                 # 找到 cls token 在 shuffle 之后的新位置
  387.                 new_token_position = [torch.where(shuffle_indices == token_position[i])[0].item() for i in
  388.                                       range(len(token_position))]
  389.                 token_position = new_token_position
  390.             else:
  391.                 # 找到 cls token 在 shuffle 之后的新位置
  392.                 token_position = torch.where(shuffle_indices == token_position)[0].item()
  393.             if isinstance(token_position, list):
  394.                 print("new value: ", x[0, token_position[0], 0], x[0, token_position[1], 0])
  395.             else:
  396.                 print("new value: ", x[0, token_position, 0])
  397.             print("new token_position: ", token_position)
  398.         if_flip_img_sequences = False
  399.         if self.flip_img_sequences_ratio > 0 and (self.flip_img_sequences_ratio - random.random()) > 1e-5:
  400.             x = x.flip([1])
  401.             if_flip_img_sequences = True
  402.         # mamba impl
  403.         residual = None
  404.         hidden_states = x
  405.         if not self.if_bidirectional:
  406.             for layer in self.layers:
  407.                 if if_flip_img_sequences and self.if_rope:
  408.                     hidden_states = hidden_states.flip([1])
  409.                     if residual is not None:
  410.                         residual = residual.flip([1])
  411.                 # rope about
  412.                 if self.if_rope:
  413.                     hidden_states = self.rope(hidden_states)
  414.                     if residual is not None and self.if_rope_residual:
  415.                         residual = self.rope(residual)
  416.                 if if_flip_img_sequences and self.if_rope:
  417.                     hidden_states = hidden_states.flip([1])
  418.                     if residual is not None:
  419.                         residual = residual.flip([1])
  420.                 hidden_states, residual = layer(
  421.                     hidden_states, residual, inference_params=inference_params
  422.                 )
  423.         else:
  424.             # get two layers in a single for-loop
  425.             for i in range(len(self.layers) // 2):
  426.                 if self.if_rope:
  427.                     hidden_states = self.rope(hidden_states)
  428.                     if residual is not None and self.if_rope_residual:
  429.                         residual = self.rope(residual)
  430.                 hidden_states_f, residual_f = self.layers[i * 2](
  431.                     hidden_states, residual, inference_params=inference_params
  432.                 )
  433.                 hidden_states_b, residual_b = self.layers[i * 2 + 1](
  434.                     hidden_states.flip([1]), None if residual == None else residual.flip([1]),
  435.                     inference_params=inference_params
  436.                 )
  437.                 hidden_states = hidden_states_f + hidden_states_b.flip([1])
  438.                 residual = residual_f + residual_b.flip([1])
  439.         if not self.fused_add_norm:
  440.             if residual is None:
  441.                 residual = hidden_states
  442.             else:
  443.                 residual = residual + self.drop_path(hidden_states)
  444.             hidden_states = self.norm_f(residual.to(dtype=self.norm_f.weight.dtype))
  445.         else:
  446.             # Set prenorm=False here since we don't need the residual
  447.             fused_add_norm_fn = rms_norm_fn if isinstance(self.norm_f, RMSNorm) else layer_norm_fn
  448.             hidden_states = fused_add_norm_fn(
  449.                 self.drop_path(hidden_states),
  450.                 self.norm_f.weight,
  451.                 self.norm_f.bias,
  452.                 eps=self.norm_f.eps,
  453.                 residual=residual,
  454.                 prenorm=False,
  455.                 residual_in_fp32=self.residual_in_fp32,
  456.             )
  457.         # return only cls token if it exists
  458.         if self.if_cls_token:
  459.             if self.use_double_cls_token:
  460.                 return (hidden_states[:, token_position[0], :] + hidden_states[:, token_position[1], :]) / 2
  461.             else:
  462.                 if self.use_middle_cls_token:
  463.                     return hidden_states[:, token_position, :]
  464.                 elif if_random_cls_token_position:
  465.                     return hidden_states[:, token_position, :]
  466.                 else:
  467.                     return hidden_states[:, token_position, :]
  468.         if self.final_pool_type == 'none':
  469.             return hidden_states[:, -1, :]
  470.         elif self.final_pool_type == 'mean':
  471.             return hidden_states.mean(dim=1)
  472.         elif self.final_pool_type == 'max':
  473.             return hidden_states
  474.         elif self.final_pool_type == 'all':
  475.             return hidden_states
  476.         else:
  477.             raise NotImplementedError
  478.     def forward(self, x, return_features=False, inference_params=None, if_random_cls_token_position=False,
  479.                 if_random_token_rank=False):
  480.         x = self.forward_features(x, inference_params, if_random_cls_token_position=if_random_cls_token_position,
  481.                                   if_random_token_rank=if_random_token_rank)
  482.         # if return_features:
  483.         #     return x
  484.         # x = self.head(x)
  485.         # if self.final_pool_type == 'max':
  486.         #     x = x.max(dim=1)[0]
  487.         return x
  488. @register_model
  489. def vim_tiny_patch16_224_bimambav2_final_pool_mean_abs_pos_embed_with_midclstok_div2(pretrained=False, **kwargs):
  490.     model = VisionMamba(
  491.         patch_size=16, embed_dim=192, depth=24, rms_norm=True, residual_in_fp32=True, fused_add_norm=True,
  492.         final_pool_type='mean', if_abs_pos_embed=True, if_rope=False, if_rope_residual=False, bimamba_type="v2",
  493.         if_cls_token=True, if_divide_out=True, use_middle_cls_token=True, **kwargs)
  494.     model.default_cfg = _cfg()
  495.     if pretrained:
  496.         checkpoint = torch.hub.load_state_dict_from_url(
  497.             url="to.do",
  498.             map_location="cpu", check_hash=True
  499.         )
  500.         model.load_state_dict(checkpoint["model"])
  501.     return model
  502. @register_model
  503. def vim_tiny_patch16_stride8_224_bimambav2_final_pool_mean_abs_pos_embed_with_midclstok_div2(pretrained=False,
  504.                                                                                              **kwargs):
  505.     model = VisionMamba(
  506.         patch_size=16, stride=8, embed_dim=192, depth=24, rms_norm=True, residual_in_fp32=True, fused_add_norm=True,
  507.         final_pool_type='mean', if_abs_pos_embed=True, if_rope=False, if_rope_residual=False, bimamba_type="v2",
  508.         if_cls_token=True, if_divide_out=True, use_middle_cls_token=True, **kwargs)
  509.     model.default_cfg = _cfg()
  510.     if pretrained:
  511.         checkpoint = torch.hub.load_state_dict_from_url(
  512.             url="to.do",
  513.             map_location="cpu", check_hash=True
  514.         )
  515.         model.load_state_dict(checkpoint["model"])
  516.     return model
  517. @register_model
  518. def vim_small_patch16_224_bimambav2_final_pool_mean_abs_pos_embed_with_midclstok_div2(pretrained=False, **kwargs):
  519.     model = VisionMamba(
  520.         patch_size=16, embed_dim=384, depth=24, rms_norm=True, residual_in_fp32=True, fused_add_norm=True,
  521.         final_pool_type='mean', if_abs_pos_embed=True, if_rope=False, if_rope_residual=False, bimamba_type="v2",
  522.         if_cls_token=True, if_divide_out=True, use_middle_cls_token=True, **kwargs)
  523.     model.default_cfg = _cfg()
  524.     if pretrained:
  525.         checkpoint = torch.hub.load_state_dict_from_url(
  526.             url="to.do",
  527.             map_location="cpu", check_hash=True
  528.         )
  529.         model.load_state_dict(checkpoint["model"])
  530.     return model
  531. @register_model
  532. def vim_small_patch16_stride8_224_bimambav2_final_pool_mean_abs_pos_embed_with_midclstok_div2(pretrained=False,
  533.                                                                                               **kwargs):
  534.     model = VisionMamba(
  535.         patch_size=16, stride=8, embed_dim=384, depth=24, rms_norm=True, residual_in_fp32=True, fused_add_norm=True,
  536.         final_pool_type='mean', if_abs_pos_embed=True, if_rope=False, if_rope_residual=False, bimamba_type="v2",
  537.         if_cls_token=True, if_divide_out=True, use_middle_cls_token=True, **kwargs)
  538.     model.default_cfg = _cfg()
  539.     if pretrained:
  540.         checkpoint = torch.hub.load_state_dict_from_url(
  541.             url="to.do",
  542.             map_location="cpu", check_hash=True
  543.         )
  544.         model.load_state_dict(checkpoint["model"])
  545.     return model
  546. if __name__ == '__main__':
  547.     # cuda or cpu
  548.     device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
  549.     print(device)
  550.     # 实例化模型得到分类结果
  551.     inputs = torch.randn(1, 3, 224, 224).to(device)
  552.     model = vim_small_patch16_stride8_224_bimambav2_final_pool_mean_abs_pos_embed_with_midclstok_div2(
  553.          pretrained=False).to(device)
  554.     # print(model)
  555.     outputs = model(inputs)
  556.     print(outputs.shape)
  557.     # 实例化mamba模块,输入输出特征维度不变 B C H W
  558.     x = torch.rand(10, 16, 64, 128).to(device)
  559.     B, C, H, W = x.shape
  560.     print("输入特征维度:", x.shape)
  561.     x = x.view(B, C, H * W).permute(0, 2, 1)
  562.     print("维度变换:", x.shape)
  563.     mamba = create_block(d_model=C).to(device)
  564.     # mamba模型代码中返回的是一个元组:hidden_states, residual
  565.     hidden_states, residual = mamba(x)
  566.     x = hidden_states.permute(0, 2, 1).view(B, C, H, W)
  567.     print("输出特征维度:", x.shape)
复制代码
正常输出结果无报错。如下图所示,不再出现 KeyError: 'HOME' 或者 RuntimeError: failed to find C compiler:

8. Windows 下 Vmamba 的安装

依旧参考原来的博客:Windows 下 VMamba 安装教程(无需更改base情况中的cuda版本且可加速) 。
9. Vmamba 情况运行验证

运行以下示例:
  1. import torch
  2. import triton
  3. import triton.language as tl
  4. @triton.jit
  5. def add_kernel(x_ptr, y_ptr, output_ptr, n_elements, BLOCK_SIZE: tl.constexpr):
  6.     pid = tl.program_id(axis=0)
  7.     block_start = pid * BLOCK_SIZE
  8.     offsets = block_start + tl.arange(0, BLOCK_SIZE)
  9.     mask = offsets < n_elements
  10.     x = tl.load(x_ptr + offsets, mask=mask)
  11.     y = tl.load(y_ptr + offsets, mask=mask)
  12.     output = x + y
  13.     tl.store(output_ptr + offsets, output, mask=mask)
  14. def add(x: torch.Tensor, y: torch.Tensor):
  15.     output = torch.empty_like(x)
  16.     assert x.is_cuda and y.is_cuda and output.is_cuda
  17.     n_elements = output.numel()
  18.     grid = lambda meta: (triton.cdiv(n_elements, meta["BLOCK_SIZE"]),)
  19.     add_kernel[grid](x, y, output, n_elements, BLOCK_SIZE=1024)
  20.     return output
  21. a = torch.rand(3, device="cuda")
  22. b = a + a
  23. b_compiled = add(a, a)
  24. print(b_compiled - b)
  25. print("If you see tensor([0., 0., 0.], device='cuda:0'), then it works")
复制代码
正常输出结果无报错。如下图所示,不再出现 KeyError: 'HOME' 或者 RuntimeError: failed to find C compiler:

出现的问题

1. 出现 fatal error C1083: 无法打开包括文件: “nv/target”'

详细来说出现以下报错
  1. D:\software\Anaconda\envs\mamba\include\cuda_fp16.h(4100): fatal error C1083: 无法打开包括文件: “nv/target”: No such file or directory
复制代码
即出现

阐明其中情况中缺少 CUDA C++ 核心计算库 (CUDA C++ Core Libraries, CCCL),解决方法即为:
conda install nvidia/label/cuda-12.4.0::cuda-cccl


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

锦通

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表