挑战Transformer的新架构Mamba解析以及Pytorch复现

今天我们来详细研究这篇论文“Mamba:具有选择性状态空间的线性时间序列建模”

Mamba一直在人工智能界掀起波澜,被吹捧为Transformer的潜在竞争对手。到底是什么让Mamba在拥挤的序列建中脱颖而出?

在介绍之前先简要回顾一下现有的模型

Transformer:以其注意力机制而闻名,其中序列的任何部分都可以动态地与任何其他部分相互作用,特别是具有因果注意力机制的的Transformer,擅长处理序列中的单个元素。但是它们带来了显著的计算和内存成本,与序列长度的平方(L²)成比例。

循环神经网络(rnn): rnn只考虑当前输入和最后一个隐藏状态,按顺序更新隐藏状态。这种方法允许它们潜在地处理无限序列长度和恒定的内存需求。但是rnn的简单性是一个缺点,限制了它们记住长期依赖关系的能力。此外,rnn中的时间反向传播(BPTT)是内存密集型的,并且可能遭受梯度消失或爆炸的影响,尽管有LSTM等创新部分结解决了这个问题。

State Space Models(S4):这些模型已经显示出很好的特性。它们提供了一种平衡,比rnn更有效地捕获远程依赖关系,同时比transformer更高效地使用内存。

Mamba

选择性状态空间:Mamba建立在状态空间模型的概念之上,但引入了一个新的变化。它利用选择性状态空间,支持跨长序列更高效和有效地捕获相关信息。

线性时间复杂度:与Transformer不同,Mamba在序列长度方面以线性时间运行。这个属性使得它特别适合涉及非常长的序列的任务,而传统模型在这方面会遇到困难。

Mamba以其选择性状态空间的概念引入了传统状态空间模型的一个有趣的改进。这种方法稍微放松了标准状态空间模型的严格状态转换,使其更具适应性和灵活性(有点类似于lstm)。并且Mamba保留了状态空间模型的高效计算特性,使其能够在一次扫描中执行整个序列的前向传递-这一特性更让人想起Transformer。

在训练期间,Mamba的行为类似于Transformer,同时处理整个序列。而lstm必须一步一步地计算前向传递,即使所有输入都是已知的。在推理中,Mamba的行为更符合传统的循环模型,提供有效的序列处理。

先验状态空间模型(ssm)的一个关键限制是其刚性的、输入不变的结构。这些模型为整个序列使用一组固定参数(我们称它们为a和B)。这种结构甚至比lstm等模型更具限制性,在lstm中,信号的转换可能依赖于先前的隐藏状态和输入。

Mamba则一种范式转换,即如何计算向下一个隐藏状态的过渡?在Mamba的体系结构中,转换依赖于当前输入,这种方法在传统ssm的固定计算和循环神经网络的输入依赖动态性之间取得了平衡。

主要组成如下:

固定主干:从一个隐藏状态到下一个隐藏状态的转换仍然是一个固定的计算(由a矩阵定义),允许跨序列的预计算。

输入相关转换:输入影响下一个隐藏状态(由B矩阵定义)的方式取决于当前输入,而不是之前的隐藏状态。与传统ssm相比,这种输入依赖性提供了更大的灵活性。

为了满足这种方法的计算需求,Mamba使用了一种硬件感知算法。该算法使用扫描操作而不是卷积来循环执行计算,这样在gpu上非常高效的。尽管输入依赖转换带来了算法复杂性,但这种效率对于保持高性能至关重要。

Mamba和选择性状态空间模型不是同义词。Mamba是一个使用选择性状态空间概念的实现。这种区别是至关重要的,因为它突出了Mamba的独特贡献:在保持计算效率的同时,使SSM框架更加灵活和响应输入。

SRAM和HBM

gpu包含两种主要类型的内存:HBM (High Bandwidth memory)和SRAM (Static Random-Access memory)。HBM虽然带宽很高,但与更快但更小的SRAM相比,它的访问时间相对较慢。Mamba则使用SRAM在矩阵乘法期间进行快速访问,这是其计算的关键。

计算中的主要瓶颈通常不是计算本身,而是数据在内存类型之间的移动。Mamba通过显著减少传输大量数据的需求来解决这个问题。它通过直接在SRAM中执行算法的关键部分(如离散化和递归计算)来实现,从而减少延迟。

还引入了一个融合选择扫描层,使其内存需求与使用flash attention的优化Transformer实现相当。这一层对于保持效率至关重要,尤其是在处理模型中依赖于输入的元素时。

结果

Mamba代表了序列建模的重大进步,特别是在其高效使用GPU内存和计算策略方面。它具有高效率处理长序列的能力,使其成为各种应用的有前途的模型,我们下面来使用Pytorch代码来对其进复现。

Pytorch复现

导入基本库

 import torchimport torch.nn as nnimport torch.optim as optimfrom torch.utils.data import DataLoader, Datasetfrom torch.nn import functional as Ffrom einops import rearrangefrom tqdm import tqdmimport mathimport osimport urllib.requestfrom zipfile import ZipFilefrom transformers import AutoTokenizertorch.autograd.set_detect_anomaly(True)

设置标志和超参数

 # Configuration flags and hyperparametersUSE_MAMBA = 1DIFFERENT_H_STATES_RECURRENT_UPDATE_MECHANISM = 0device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

定义超参数和初始化

 d_model = 8state_size = 128  # Example state sizeseq_len = 100  # Example sequence lengthbatch_size = 256  # Example batch sizelast_batch_size = 81  # only for the very last batch of the datasetcurrent_batch_size = batch_sizedifferent_batch_size = Falseh_new = Nonetemp_buffer = None

这里的超参数,如模型维度(d_model)、状态大小、序列长度和批大小。

S6模块是Mamba架构中的一个复杂组件,负责通过一系列线性变换和离散化过程处理输入序列。它在捕获序列的时间动态方面起着关键作用,这是序列建模任务(如语言建模)的一个关键方面。这里包括张量运算和自定义离散化方法来处理序列数据的复杂需求。

 classS6(nn.Module):def__init__(self, seq_len, d_model, state_size, device):super(S6, self).__init__()self.fc1=nn.Linear(d_model, d_model, device=device)self.fc2=nn.Linear(d_model, state_size, device=device)self.fc3=nn.Linear(d_model, state_size, device=device)self.seq_len=seq_lenself.d_model=d_modelself.state_size=state_sizeself.A=nn.Parameter(F.normalize(torch.ones(d_model, state_size, device=device), p=2, dim=-1))nn.init.xavier_uniform_(self.A)self.B=torch.zeros(batch_size, self.seq_len, self.state_size, device=device)self.C=torch.zeros(batch_size, self.seq_len, self.state_size, device=device)self.delta=torch.zeros(batch_size, self.seq_len, self.d_model, device=device)self.dA=torch.zeros(batch_size, self.seq_len, self.d_model, self.state_size, device=device)self.dB=torch.zeros(batch_size, self.seq_len, self.d_model, self.state_size, device=device)# h  [batch_size, seq_len, d_model, state_size]self.h=torch.zeros(batch_size, self.seq_len, self.d_model, self.state_size, device=device)self.y=torch.zeros(batch_size, self.seq_len, self.d_model, device=device)defdiscretization(self):self.dB=torch.einsum("bld,bln->bldn", self.delta, self.B)self.dA=torch.exp(torch.einsum("bld,dn->bldn", self.delta, self.A))returnself.dA, self.dBdefforward(self, x):# Algorithm 2  MAMBA paperself.B=self.fc2(x)self.C=self.fc3(x)self.delta=F.softplus(self.fc1(x))self.discretization()ifDIFFERENT_H_STATES_RECURRENT_UPDATE_MECHANISM:  globalcurrent_batch_sizecurrent_batch_size=x.shape[0]ifself.h.shape[0] !=current_batch_size:different_batch_size=Trueh_new=  torch.einsum('bldn,bldn->bldn', self.dA, self.h[:current_batch_size, ...]) +rearrange(x, "b l d -> b l d 1") *self.dBelse:different_batch_size=Falseh_new=  torch.einsum('bldn,bldn->bldn', self.dA, self.h) +rearrange(x, "b l d -> b l d 1") *self.dB# y  [batch_size, seq_len, d_model]self.y=torch.einsum('bln,bldn->bld', self.C, h_new)globaltemp_buffertemp_buffer=h_new.detach().clone() ifnotself.h.requires_gradelseh_new.clone()returnself.yelse:  # h [batch_size, seq_len, d_model, state_size]h=torch.zeros(x.size(0), self.seq_len, self.d_model, self.state_size, device=x.device)y=torch.zeros_like(x)h=  torch.einsum('bldn,bldn->bldn', self.dA, h) +rearrange(x, "b l d -> b l d 1") *self.dB# y  [batch_size, seq_len, d_model]y=torch.einsum('bln,bldn->bld', self.C, h)returny

这个S6的模块,可以处理离散化过程和正向传播。

MambaBlock类是一个定制的神经网络模块,被设计为Mamba模型的关键构建块。它封装了几个层和操作来处理输入数据。

包括线性投影、卷积、激活函数、自定义S6模块和残差连接。该块是Mamba模型的基本组件,负责通过一系列转换处理输入序列,以捕获数据中的相关模式和特征。这些不同层和操作的组合允许MambaBlock有效地处理复杂的序列建模任务。

 classMambaBlock(nn.Module):def__init__(self, seq_len, d_model, state_size, device):super(MambaBlock, self).__init__()self.inp_proj=nn.Linear(d_model, 2*d_model, device=device)self.out_proj=nn.Linear(2*d_model, d_model, device=device)# For residual skip connectionself.D=nn.Linear(d_model, 2*d_model, device=device)# Set _no_weight_decay attribute on biasself.out_proj.bias._no_weight_decay=True# Initialize bias to a small constant valuenn.init.constant_(self.out_proj.bias, 1.0)self.S6=S6(seq_len, 2*d_model, state_size, device)# Add 1D convolution with kernel size 3self.conv=nn.Conv1d(seq_len, seq_len, kernel_size=3, padding=1, device=device)# Add linear layer for conv outputself.conv_linear=nn.Linear(2*d_model, 2*d_model, device=device)# rmsnormself.norm=RMSNorm(d_model, device=device)defforward(self, x):"""x_proj.shape = torch.Size([batch_size, seq_len, 2*d_model])x_conv.shape = torch.Size([batch_size, seq_len, 2*d_model])x_conv_act.shape = torch.Size([batch_size, seq_len, 2*d_model])"""# Refer to Figure 3 in the MAMBA paperx=self.norm(x)x_proj=self.inp_proj(x)# Add 1D convolution with kernel size 3x_conv=self.conv(x_proj)x_conv_act=F.silu(x_conv)# Add linear layer for conv outputx_conv_out=self.conv_linear(x_conv_act)x_ssm=self.S6(x_conv_out)x_act=F.silu(x_ssm)  # Swish activation can be implemented as x * sigmoid(x)# residual skip connection with nonlinearity introduced by multiplicationx_residual=F.silu(self.D(x))x_combined=x_act*x_residualx_out=self.out_proj(x_combined)returnx_out

MambaBlock是Mamba核心功能

Mamba模型

包括一系列MambaBlock模块。每个块都顺序处理输入数据,一个块的输出作为下一个块的输入。这种顺序处理允许模型捕获输入数据中的复杂模式和关系,使其对涉及顺序建模的任务有效。多个块的堆叠是深度学习架构中的常见设计,因为它使模型能够学习数据的分层表示。

 classMamba(nn.Module):def__init__(self, seq_len, d_model, state_size, device):super(Mamba, self).__init__()self.mamba_block1=MambaBlock(seq_len, d_model, state_size, device)self.mamba_block2=MambaBlock(seq_len, d_model, state_size, device)self.mamba_block3=MambaBlock(seq_len, d_model, state_size, device)defforward(self, x):x=self.mamba_block1(x)x=self.mamba_block2(x)x=self.mamba_block3(x)returnx

RMSNorm是一个自定义规范化层,这一层用于规范神经网络的激活,这可以帮助稳定和加快训练。

 classRMSNorm(nn.Module):def__init__(self,d_model: int,eps: float=1e-5,device: str='cuda'):super().__init__()self.eps=epsself.weight=nn.Parameter(torch.ones(d_model, device=device))defforward(self, x):output=x*torch.rsqrt(x.pow(2).mean(-1, keepdim=True) +self.eps) *self.weightreturnoutput

这一层的用法:

 x=torch.rand(batch_size, seq_len, d_model, device=device)# Create the Mamba modelmamba=Mamba(seq_len, d_model, state_size, device)# rmsnormnorm=RMSNorm(d_model)x=norm(x)# Forward passtest_output=mamba(x)print(f"test_output.shape = {test_output.shape}")  # Should be [batch_size, seq_len, d_model]

上面就是模型的全部基本代码,下面就可以进行数据准备和训练

我们自定义一个Enwiki8Dataset

 classEnwiki8Dataset(Dataset):def__init__(self, data):self.data=datadef__len__(self):returnlen(self.data['input_ids'])def__getitem__(self, idx):item= {key: val[idx].clone().detach() forkey, valinself.data.items()}returnitem

pad_sequences_3d用于将一批序列填充到统一的长度,确保批中的每个序列具有相同数量的元素(或时间步长)。这在许多机器学习任务中尤其重要,因为输入数据必须具有一致的形状。

 # Define a function for paddingdefpad_sequences_3d(sequences, max_len=None, pad_value=0):# Assuming sequences is a tensor of shape (batch_size, seq_len, feature_size)batch_size, seq_len, feature_size=sequences.shapeifmax_lenisNone:max_len=seq_len+1# Initialize padded_sequences with the pad_valuepadded_sequences=torch.full((batch_size, max_len, feature_size), fill_value=pad_value, dtype=sequences.dtype, device=sequences.device)# Pad each sequence to the max_lenpadded_sequences[:, :seq_len, :] =sequencesreturnpadded_sequences

训练过程还是传统的pytorch过程:

 deftrain(model, tokenizer, data_loader, optimizer, criterion, device, max_grad_norm=1.0, DEBUGGING_IS_ON=False):model.train()total_loss=0forbatchindata_loader:optimizer.zero_grad()input_data=batch['input_ids'].clone().to(device)attention_mask=batch['attention_mask'].clone().to(device)target=input_data[:, 1:]input_data=input_data[:, :-1]# Pad all the sequences in the batch:input_data=pad_sequences_3d(input_data, pad_value=tokenizer.pad_token_id)target=pad_sequences_3d(target, max_len=input_data.size(1), pad_value=tokenizer.pad_token_id)ifUSE_MAMBA:output=model(input_data)loss=criterion(output, target)loss.backward(retain_graph=True)forname, paraminmodel.named_parameters():if'out_proj.bias'notinname:# clip weights but not bias for out_projtorch.nn.utils.clip_grad_norm_(param, max_norm=max_grad_norm)ifDEBUGGING_IS_ON:forname, parameterinmodel.named_parameters():ifparameter.gradisnotNone:print(f"{name} gradient: {parameter.grad.data.norm(2)}")else:print(f"{name} has no gradient")ifUSE_MAMBAandDIFFERENT_H_STATES_RECURRENT_UPDATE_MECHANISM:model.S6.h[:current_batch_size, ...].copy_(temp_buffer)optimizer.step()total_loss+=loss.item()returntotal_loss/len(data_loader)

评估函数也是一样:

 defevaluate(model, data_loader, criterion, device):model.eval()total_loss=0withtorch.no_grad():forbatchindata_loader:input_data=batch['input_ids'].clone().detach().to(device)attention_mask=batch['attention_mask'].clone().detach().to(device)target=input_data[:, 1:]input_data=input_data[:, :-1]# Pad all the sequences in the batch:input_data=pad_sequences_3d(input_data, pad_value=tokenizer.pad_token_id)target=pad_sequences_3d(target, max_len=input_data.size(1), pad_value=tokenizer.pad_token_id)ifUSE_MAMBA:output=model(input_data)loss=criterion(output, target)total_loss+=loss.item()returntotal_loss/len(data_loader)

最后,calculate_perplexity用于评估语言模型(如Mamba)的性能。

 defcalculate_perplexity(loss):returnmath.exp(loss)

load_enwiki8_dataset函数用于下载和提取enwiki8数据集,该数据集通常用于对语言模型进行基准测试。

 defload_enwiki8_dataset():print(f"Download and extract enwiki8 data")url="http://mattmahoney.net/dc/enwik8.zip"urllib.request.urlretrieve(url, "enwik8.zip")withZipFile("enwik8.zip") asf:data=f.read("enwik8").decode("utf-8")returndata

encode_dataset函数设计用于标记和编码数据集,为神经网络模型(如Mamba)处理数据集做准备。

 # Tokenize and encode the datasetdefencode_dataset(tokenizer, text_data):defbatch_encode(tokenizer, text_data, batch_size=1000):# Tokenize in batchesbatched_input_ids= []foriinrange(0, len(text_data), batch_size):batch=text_data[i:i+batch_size]inputs=tokenizer(batch, add_special_tokens=True, truncation=True,padding='max_length', max_length=seq_len,return_tensors='pt')batched_input_ids.append(inputs['input_ids'])returntorch.cat(batched_input_ids)# Assuming enwiki8_data is a list of sentencesinput_ids=batch_encode(tokenizer, enwiki8_data)# vocab_size is the number of unique tokens in the tokenizer's vocabularyglobalvocab_sizevocab_size=len(tokenizer.vocab)  # Note that for some tokenizers, we might access the vocab directlyprint(f"vocab_size = {vocab_size}")# Create an embedding layer# embedding_dim is the size of the embedding vectors (MAMBA model's D)embedding_layer=nn.Embedding(num_embeddings=vocab_size, embedding_dim=d_model)# Pass `input_ids` through the embedding layer# This will change `input_ids` from shape [B, L] to [B, L, D]defbatch_embedding_calls(input_ids, embedding_layer, batch_size=256):# Check if input_ids is already a tensor, if not convert itifnotisinstance(input_ids, torch.Tensor):input_ids=torch.tensor(input_ids, dtype=torch.long)# Calculate the number of batches needednum_batches=math.ceil(input_ids.size(0) /batch_size)# List to hold the output embeddingsoutput_embeddings= []# Process each batchforiinrange(num_batches):# Calculate start and end indices for the current batchstart_idx=i*batch_sizeend_idx=start_idx+batch_size# Get the batchinput_id_batch=input_ids[start_idx:end_idx]# Call the embedding layerwithtorch.no_grad():  # No need gradients for this operationbatch_embeddings=embedding_layer(input_id_batch)# Append the result to the listoutput_embeddings.append(batch_embeddings)# Concatenate the embeddings from each batch into a single tensorall_embeddings=torch.cat(output_embeddings, dim=0)returnall_embeddings# `input_ids` is a list or tensor of the input IDs and `embedding_layer` is model's embedding layerifUSE_MAMBA:# Set `batch_size` to a value that works for memory constraintsencoded_inputs=batch_embedding_calls(input_ids, embedding_layer, batch_size=1).float()attention_mask= (input_ids!=tokenizer.pad_token_id).type(input_ids.dtype)returnencoded_inputs, attention_mask

下面就可以进行训练了

 # Load a pretrained tokenizertokenizer=AutoTokenizer.from_pretrained('bert-base-uncased')# Assuming encoded_inputs is a preprocessed tensor of shape [num_samples, seq_len, d_model]encoded_inputs_file='encoded_inputs_mamba.pt'ifos.path.exists(encoded_inputs_file):print("Loading pre-tokenized data...")encoded_inputs=torch.load(encoded_inputs_file)else:print("Tokenizing raw data...")enwiki8_data=load_enwiki8_dataset()encoded_inputs, attention_mask=encode_dataset(tokenizer, enwiki8_data)torch.save(encoded_inputs, encoded_inputs_file)print(f"finished tokenizing data")# Combine into a single dictionarydata= {'input_ids': encoded_inputs,'attention_mask': attention_mask}# Split the data into train and validation setstotal_size=len(data['input_ids'])train_size=int(total_size*0.8)train_data= {key: val[:train_size] forkey, valindata.items()}val_data= {key: val[train_size:] forkey, valindata.items()}train_dataset=Enwiki8Dataset(train_data)val_dataset=Enwiki8Dataset(val_data)train_loader=DataLoader(train_dataset, batch_size=batch_size, shuffle=True)val_loader=DataLoader(val_dataset, batch_size=batch_size, shuffle=False)# Initialize the modelmodel=Mamba(seq_len, d_model, state_size, device).to(device)# Define the loss function and optimizercriterion=nn.CrossEntropyLoss()optimizer=optim.AdamW(model.parameters(), lr=5e-6)# Training loopnum_epochs=25  # Number of epochs to train forforepochintqdm(range(num_epochs)):  # loop over the dataset multiple timestrain_loss=train(model, tokenizer, train_loader, optimizer, criterion, device, max_grad_norm=10.0, DEBUGGING_IS_ON=False)val_loss=evaluate(model, val_loader, criterion, device)val_perplexity=calculate_perplexity(val_loss)print(f'Epoch: {epoch+1}, Training Loss: {train_loss:.4f}, Validation Loss: {val_loss:.4f}, Validation Perplexity: {val_perplexity:.4f}')

以上就是训练的完整代码

总结

我们介绍了Mamba的概念和架构,并且从头开始构建Mamba复现,这样可以将理论转化为实践。通过这种动手的方法,可以看到Mamba序列建模方法和效率。如果你想直接使用,可以看论文提供的代码

https://avoid.overfit.cn/post/96ca1d7044b4405a9b0a0f6154099078

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/611007.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一文读懂数字工厂管理系统解决方案

随着科技的飞速发展,数字化转型已成为企业提升竞争力、优化运营管理的必由之路。数字工厂管理系统作为这一转型的核心组成部分,正逐渐受到业界的广泛关注。本文将深入探讨数字工厂管理系统解决方案的核心理念、功能模块、实施步骤及其对企业发展的影响。…

Kubernetes 核心实战之三(精华篇 3/3)

文章目录 6、Ingress ★6.1 安装 Ingress6.2 访问6.3 安装不成功的bug解决6.4 测试使用6.4.1 搭建测试环境6.4.2 配置 Ingress的规则6.4.3 测试I6.4.4 测试II6.4.5 路径重写6.4.6 限流 7. Kubernetes 存储抽象7.1 NFS 搭建7.2 原生方式 数据挂载7.3 PV 和 PVC ★7.3.1 创建 PV …

语义解析:连接自然语言与机器智能的桥梁

文章目录 01 语义解析的应用场景场景一:场景二: 02 语义解析和大模型的关系 语义解析技术可以提高人机交互的效率和准确性,在自然语言处理、数据分析、智能客服、智能家居等领域都有广泛的应用前景。特别是在大数据时代,语义解析能…

2024年甘肃省职业院校技能大赛 “信息安全管理与评估”赛项样题卷①

2024年甘肃省职业院校技能大赛 高职学生组电子与信息大类信息安全管理与评估赛项样题 第一阶段:第二阶段:模块二 网络安全事件响应、数字取证调查、应用程序安全第二阶段 网络安全事件响应第一部分 网络安全事件响应第二部分 数字取证调查第三部分 应用程…

[Linux进程(一)] 什么是进程?PCB的底层是什么?以及进程标识符pid与ppid

文章目录 1、前言2、描述进程 — PCB(os怎么管理进程呢)3、查看进程3.1 方法一3.2 方法二 4、系统调用获取进程标示符(PID)4.1 获取进程的ID4.2 获取进程的父进程ID 5、系统调用创建子进程-fork 1、前言 大家经常都在讲进程,而它到底是什么呢? 这里给大…

Android逆向学习(六)绕过app签名校验,通过frida,io重定向(上)

Android逆向学习(六)绕过app签名校验,通过frida,io重定向(上) 一、写在前面 这是吾爱破解正己大大教程的第五个作业,然后我的系统还是ubuntu,建议先看一下上一个博客,关…

Zookeeper设计理念与源码剖析

Zookeeper 架构理解 整体架构 Follower server 可以直接处理读请求,但不能直接处理写请求。写请求只能转发给 leader server 进行处理。最终所有的写请求在 leader server 端串行执行。(因为分布式环境下永远无法精确地确认不同服务器不同事件发生的先后…

逐步分解,一文教会你如何用 jenkins+docker 实现主从模式

jenkins 主从模式想必大家都不陌生,大家在学习过程中为了学习方便都在自己本地搭建了 jenkins 环境,然后通过 javaweb 方式实现,对于 docker 下实现主从模式大家好像兴趣挺大。 今天就通过这篇文章给大家讲讲怎么玩,希望对大家有帮…

Vivado开发FPGA使用流程、教程 verilog(建立工程、编译文件到最终烧录的全流程)

目录 一、概述 二、工程创建 三、添加设计文件并编译 四、线上仿真 五、布局布线 六、生成比特流文件 七、烧录 一、概述 vivado开发FPGA流程分为创建工程、添加设计文件、编译、线上仿真、布局布线(添加约束文件)、生成比特流文件、烧录等步骤&a…

交叉编译ARM64架构electron详解

基本介绍 本文主要参考Electron官方文档中 构建说明 和 构建步骤(Linux) 在amd64环境内构建arm64的electron包。 如果是arm64环境请查看文章arm64架构编译electron长征路 一、环境说明 操作系统版本:统信1060 操作系统架构:amd64 内存:32G 如下图: electron版本:v25…

企业微信forMAC,如何左右翻动预览图片

1、control commandshifd 进入企业微信的debug调试模式 2、按照如下步骤选择 3、重启企业微信

【K8S 存储卷】K8S的存储卷+PV/PVC

目录 一、K8S的存储卷 1、概念: 2、挂载的方式: 2.1、emptyDir: 2.2、hostPath: 2.3、NFS共享存储: 二、PV和PVC: 1、概念 2、请求方式 3、静态请求流程图: 4、PV和PVC的生命周期 5、…

基于ubuntu2204使用kubeadm部署k8s集群

部署k8s集群 基础环境配置安装container安装runc安装CNI插件部署1.24版本k8s集群(flannel)安装crictl使用kubeadm部署集群节点加入集群部署flannel网络配置dashboard 本集群基于ubuntu2204系统使用kubeadm工具部署1.24版本k8s,容器运行时使用…

Unity | Shader基础知识(第九集:shader常用单词基础知识速成)

目录 一、顶点(Vertex)和法线(Normal) 二、UV信息 三、 基础数据种类 1 基础数据种类 2 基础数据数组 3 基础数据数组的赋值 4 对数据数组的调用 四、 基础矩阵 1 基础矩阵种类 2 对矩阵数组的调用 2.1对一个数据的调用 2.2对多个数据的调用 2…

机器之心 AI 技术--人工智能助力个性化视频实战经验分享(文末送书)

【清华社&机器之心】视频生成前沿研究与应用特别活动 在视频生成即将迎来技术和应用大爆发之际,为了帮助企业和广大从业者掌握技术前沿,把握时代机遇,机器之心AI论坛就将国内的视频生成技术力量齐聚一堂,共同分享国内顶尖力量…

华为云AI:轻松实现图像识别调用

文章目录 前言一、环境配置关键步骤 二、图像识别实例媒资图像标签名人识别 总结 前言 基于华为云AI服务和java使用SDK实现图像识别,主要以媒资图像标签和名人识别为例。 一、环境配置 Maven(没有直接下载华为的SDK包,而是使用Maven安装依赖…

韩语翻译是怎么收费的

近年来,随着中韩交流的日益密切,韩语翻译在国内的需求呈现出不断增长的态势。无论是韩语笔译还是口译,其应用领域都非常广泛。那么,韩语翻译的价格是否高昂?翻译公司又是如何进行报价的呢? 在翻译领域&…

C2-3.3.2 机器学习/深度学习——数据增强

C2-3.3.2 数据增强 参考链接 1、为什么要使用数据增强? ※总结最经典的一句话:希望模型学习的更稳健 当数据量不足时候: 人工智能三要素之一为数据,但获取大量数据成本高,但数据又是提高模型精度和泛化效果的重要因…

UCF101 数据集介绍与下载

一、介绍 UCF101 是一个现实动作视频的动作识别数据集,收集自YouTube,提供了来自101个动作类别的13320个视频。官方:https://www.crcv.ucf.edu/research/data-sets/ucf101/ 数据集名称:UCF-101(2012) 总视…

06、Kafka ------ 各个功能的作用解释(ISR 同步副本、非同步副本、自动创建主题、修改主题、删除主题)

目录 CMAK 各个功能的作用解释★ ISR副本 (同步副本)★ 非同步副本★ 自动创建主题★ 修改主题★ 删除主题 CMAK 各个功能的作用解释 ★ ISR副本 (同步副本) 简单来说 ,ISR 副本 就是 Kafka 认为与 领导者副本 同步的副本。 ISR&#xff0…