
PyTorch量化壓縮API:優(yōu)化深度學(xué)習(xí)模型的關(guān)鍵技術(shù)
圖中的結(jié)構(gòu)主要分為兩部分:編碼器和解碼器。編碼器將輸入序列轉(zhuǎn)換為一組表示,該表示將傳遞給解碼器生成輸出序列。位置編碼(Positional Encoding)是為了在序列中加入位置信息,因?yàn)門(mén)ransformer不具備處理序列位置信息的能力。
PyTorch提供了便捷的API來(lái)實(shí)現(xiàn)Transformer模型。其核心是將左側(cè)的神經(jīng)網(wǎng)絡(luò)封裝為一個(gè)TransformerEncoder
類(lèi)。該類(lèi)需要兩個(gè)關(guān)鍵參數(shù):TransformerEncoderLayer
和層數(shù)(num_layers
)。
class Transformer(nn.Module):
def __init__(self, vocab_size, embedding_dim, hidden_dim, num_class,
dim_feedforward=512, num_head=2, num_layers=2, dropout=0.1, max_len=512, activation='relu'):
super(Transformer, self).__init__()
self.embedding_dim = embedding_dim
self.embeddings = nn.Embedding(vocab_size, embedding_dim)
self.position_embedding = PositionalEncoding(embedding_dim, dropout, max_len)
encoder_layer = nn.TransformerEncoderLayer(hidden_dim, num_head, dim_feedforward, dropout, activation)
self.transformer = nn.TransformerEncoder(encoder_layer, num_layers)
self.output = nn.Linear(hidden_dim, num_class)
def forward(self, inputs, lengths):
inputs = torch.transpose(inputs, 0, 1)
hidden_states = self.embeddings(inputs)
hidden_states = self.position_embedding(hidden_states)
attention_mask = length_to_mask(lengths) == False
hidden_states = self.transformer(hidden_states, src_key_padding_mask=attention_mask).transpose(0, 1)
logits = self.output(hidden_states)
log_probs = F.log_softmax(logits, dim=-1)
return log_probs
TransformerEncoder
是一個(gè)由多個(gè)編碼器層組成的堆棧。每個(gè)編碼器層都由TransformerEncoderLayer
類(lèi)實(shí)例化,這個(gè)類(lèi)具體實(shí)現(xiàn)了自注意力機(jī)制和前饋神經(jīng)網(wǎng)絡(luò)。
class TransformerEncoder(Module):
def __init__(self, encoder_layer, num_layers, norm=None):
super(TransformerEncoder, self).__init__()
self.layers = _get_clones(encoder_layer, num_layers)
self.num_layers = num_layers
self.norm = norm
def forward(self, src: Tensor, mask: Optional[Tensor] = None, src_key_padding_mask: Optional[Tensor] = None) -> Tensor:
output = src
for mod in self.layers:
output = mod(output, src_mask=mask, src_key_padding_mask=src_key_padding_mask)
if self.norm is not None:
output = self.norm(output)
return output
該類(lèi)主要通過(guò)克隆傳入的編碼器層并對(duì)其進(jìn)行堆疊,實(shí)現(xiàn)了多層編碼器的構(gòu)建。每層的輸入輸出維度保持一致,這在后續(xù)的TransformerEncoderLayer
中可以進(jìn)一步驗(yàn)證。
TransformerEncoderLayer
由自注意力機(jī)制和前饋網(wǎng)絡(luò)組成。其實(shí)現(xiàn)基于論文《Attention Is All You Need》,該論文首次提出了Transformer的概念。
class TransformerEncoderLayer(Module):
def __init__(self, d_model, nhead, dim_feedforward=2048, dropout=0.1, activation=F.relu,
layer_norm_eps=1e-5, batch_first=False, norm_first=False,
device=None, dtype=None) -> None:
factory_kwargs = {'device': device, 'dtype': dtype}
super(TransformerEncoderLayer, self).__init__()
self.self_attn = MultiheadAttention(d_model, nhead, dropout=dropout, batch_first=batch_first,
**factory_kwargs)
self.linear1 = Linear(d_model, dim_feedforward, **factory_kwargs)
self.dropout = Dropout(dropout)
self.linear2 = Linear(dim_feedforward, d_model, **factory_kwargs)
self.norm1 = LayerNorm(d_model, eps=layer_norm_eps, **factory_kwargs)
self.norm2 = LayerNorm(d_model, eps=layer_norm_eps, **factory_kwargs)
self.dropout1 = Dropout(dropout)
self.dropout2 = Dropout(dropout)
def forward(self, src: Tensor, src_mask: Optional[Tensor] = None, src_key_padding_mask: Optional[Tensor] = None) -> Tensor:
x = src
x = self.norm1(x + self._sa_block(x, src_mask, src_key_padding_mask))
x = self.norm2(x + self._ff_block(x))
return x
def _sa_block(self, x: Tensor, attn_mask: Optional[Tensor], key_padding_mask: Optional[Tensor]) -> Tensor:
x = self.self_attn(x, x, x, attn_mask=attn_mask, key_padding_mask=key_padding_mask, need_weights=False)[0]
return self.dropout1(x)
def _ff_block(self, x: Tensor) -> Tensor:
x = self.linear2(self.dropout(self.activation(self.linear1(x))))
return self.dropout2(x)
在forward函數(shù)中,通過(guò)自注意力機(jī)制和前饋網(wǎng)絡(luò)模塊的運(yùn)算,輸入的張量經(jīng)過(guò)兩次加法運(yùn)算后依舊保持了原始的維度,這也證明了TransformerEncoder
中的層堆疊是維度一致的。
在activations.py
文件中,我們可以看到PyTorch對(duì)幾種常用激活函數(shù)的實(shí)現(xiàn)。這些激活函數(shù)在深度學(xué)習(xí)模型中用于引入非線性特性。
class PytorchGELUTanh(nn.Module):
def __init__(self):
super().__init__()
if version.parse(torch.__version__) =1.12.0 is required to use '
'PytorchGELUTanh. Please upgrade torch.'
)
def forward(self, input: Tensor) -> Tensor:
return nn.functional.gelu(input, approximate='tanh')
class NewGELUActivation(nn.Module):
def forward(self, input: Tensor) -> Tensor:
return 0.5 * input * (1.0 + torch.tanh(math.sqrt(2.0 / math.pi) * (input + 0.044715 * torch.pow(input, 3.0))))
這些實(shí)現(xiàn)展示了激活函數(shù)的多樣性和PyTorch在實(shí)現(xiàn)這些函數(shù)時(shí)對(duì)性能和準(zhǔn)確度的權(quán)衡。
Transformer是一種用于處理序列數(shù)據(jù)的深度學(xué)習(xí)模型,具有很強(qiáng)的并行處理能力。其通過(guò)自注意力機(jī)制實(shí)現(xiàn)了對(duì)序列中每個(gè)元素的全局依賴(lài)建模。
PyTorch通過(guò)nn.TransformerEncoder
和nn.TransformerEncoderLayer
等類(lèi)提供了對(duì)Transformer模型的實(shí)現(xiàn)。這些類(lèi)封裝了自注意力機(jī)制和前饋網(wǎng)絡(luò)的細(xì)節(jié),使得用戶可以專(zhuān)注于模型的高層搭建。
用戶可以通過(guò)繼承nn.Module
類(lèi)并實(shí)現(xiàn)forward
方法來(lái)自定義激活函數(shù)。PyTorch提供了多種激活函數(shù)的實(shí)現(xiàn)作為參考。
由于Transformer模型不具備處理輸入序列中位置信息的能力,因此需要通過(guò)位置編碼將位置信息顯式地加入到輸入中,以幫助模型學(xué)習(xí)序列中的順序關(guān)系。
可以通過(guò)調(diào)整模型的超參數(shù)(如層數(shù)、隱藏層維度、注意力頭數(shù)等),優(yōu)化數(shù)據(jù)預(yù)處理流程,以及利用GPU加速計(jì)算等方法來(lái)提高Transformer模型的性能。
對(duì)比大模型API的內(nèi)容創(chuàng)意新穎性、情感共鳴力、商業(yè)轉(zhuǎn)化潛力
一鍵對(duì)比試用API 限時(shí)免費(fèi)