ප්රතිපෝෂණට්රාන්ස්ෆෝමර්

මෙය PyTorch ක්රියාත්මක කිරීම කඩදාසි ප්රතිපෝෂණ මතකය සමඟ අනුක්රමික ට්රාන්ස්ෆෝමර්වල ඉහළ මට්ටමේ නිරූපණයන් වෙත ප්රවේශ වීම .

සාමාන්යට්රාන්ස්ෆෝමර් සමාන්තරව ටෝකන සකසනවා. සෑම ට්රාන්ස්ෆෝමර් ස්ථරයක්ම පෙර ස්ථරයේ ප්රතිදානයන් කෙරෙහි අවධානය යොමු කරයි. ප්රතිපෝෂණ ට්රාන්ස්ෆෝමරය පෙර පියවරයන්හි සියලුම ස්ථරවල ප්රතිදානය කෙරෙහි අවධානය යොමු කරයි. එබැවින් මෙය පුනරාවර්තනය එකතු කරන අතර, අපි ටෝකන්-විසින්-ටෝකන් සැකසිය යුතුය. මෙය පුහුණුව සැලකිය යුතු ලෙස මන්දගාමී වේ (අනුක්රමයේ දිග අනුව 5X - 10X පමණ). කෙසේ වෙතත්, ප්රතිපෝෂණ ට්රාන්ස්ෆෝමර් පුරෝකථනය කිරීමේදී වේගවත් වන්නේ ඔබ මතක දෛශික හැඹිලි කළහොත් ඊළඟ ටෝකනය පුරෝකථනය කළ හැකි බැවිනි.

පුහුණුවවේගවත් කිරීම සඳහා, කඩදාසි සාකච්ඡා කරන්නේ කෙටි අනුක්රමික දිගකින් ආරම්භ කර එය ක්රමයෙන් වැඩි කිරීමයි. ආරම්භක ස්ථානය ලෙස පෙර පුහුණු සමාන්තර ට්රාන්ස්ෆෝමරයක් භාවිතා කිරීම ද ඔවුහු සාකච්ඡා කරති.

මුල්ප්රතිපෝෂණ ට්රාන්ස්ෆෝමරය සියලු ස්ථරවල ප්රතිදානයන් තබා නොගනී. ඒ වෙනුවට එය සියලු ස්ථරවල නිමැවුමේ බර තැබූ එකතුව තබා ගනී. මෙය අනාවැකිය තුළ හැඹිලි සඳහා භාවිතා කරන මතකය අඩු කරයි. මෙම ගොනුවේ පළමු භාගය මෙය ක්රියාත්මක කරයි.

යාවත්කාලීනකරන ලද ප්රතිපෝෂණ ට්රාන්ස්ෆෝමරය බර බෙදා ගන්නා අතර ස්ථර අතර යතුරු සහ අගයන් ගණනය කිරීමට භාවිතා කරයි. ඉන්පසු අපි එක් එක් පියවර සඳහා යතුරු සහ අගයන් එක් වරක් පමණක් ගණනය කර ඒවා හැඹිලි කර තබමු. මෙම ගොනුවේ දෙවන භාගය මෙය ක්රියාත්මක කරයි. කාර්ය සාධනය වැඩි දියුණු කිරීම සඳහා අපි අභිරුචි PyTorch ශ්රිතයක් ක්රියාත්මක කළෙමු.

කුඩාෂේක්ස්පියර් දත්ත කට්ටලය පිළිබඳ ප්රතිපෝෂණ ට්රාන්ස්ෆෝමරයක් පුහුණු කිරීම සඳහා පුහුණු කේතය සහ සටහන් පොතක් මෙන්න.

Open In Colab View Run

43import math
44from typing import Optional
45
46import torch
47from torch import nn
48
49from labml_helpers.module import Module
50from labml_nn.transformers.feed_forward import FeedForward
51from labml_nn.transformers.mha import PrepareForMultiHeadAttention
52from labml_nn.utils import clone_module_list

ප්රතිපෝෂණඅවධානය

මෙමමොඩියුලය මුල් ට්රාන්ස්ෆෝමර් කඩදාසි වලින් අවධානයට සමාන පුනරාවර්තන අවධානයක් ගණනය කරයි.

55class FeedbackAttention(Module):
  • 'හෙඩ්ස්'යනු අවධානය යොමු කරන හිස් සංඛ්යාවකි
  • d_model ට්රාන්ස්ෆෝමරයේ ඇති ලක්ෂණ ගණන
  • dropout_prob අවධානය යොමු කිරීමේ සම්භාවිතාව
  • is_kv_precomputed යතුරද යන්න, අගය ආතතීන් දැනටමත් ගණනය කර ඇත
66    def __init__(self, heads: int, d_model: int, dropout_prob: float = 0.1, *,
67                 is_kv_precomputed: bool = False):
75        super().__init__()

හිසකටවිශේෂාංග ගණන

78        self.d_k = d_model // heads

80        self.heads = heads

මේවා query බහු-ශීර්ෂ අවධානය පරිවර්තනය කරයි.

83        self.query = PrepareForMultiHeadAttention(d_model, heads, self.d_k, bias=False)

මේවාබහු ශීර්ෂ අවධානය value සඳහා පරිවර්තනය කරයි. key

85        if not is_kv_precomputed:
86            self.key = PrepareForMultiHeadAttention(d_model, heads, self.d_k, bias=False)
87            self.value = PrepareForMultiHeadAttention(d_model, heads, self.d_k, bias=True)

යතුරුසහ අගයන් දැනටමත් ගණනය කර ඇත

89        else:
90            self.key = None
91            self.value = None

ප්රතිදානස්ථරය

94        self.output = nn.Linear(d_model, d_model)

හැලීම

96        self.dropout = nn.Dropout(dropout_prob)

සොෆ්ට්මැක්ස්වලට පෙර පරිමාණ සාධකය

98        self.scale = 1 / math.sqrt(self.d_k)

කාලමානය ඔස්සේ අවධානය යොමු කිරීම සඳහා සොෆ්ට්මැක්ස් key

101        self.softmax = nn.Softmax(dim=0)

සාපේක්ෂතනතුරු ගණන

104        self.P = 2 ** 12

විමසුමටසාපේක්ෂව යතුර සඳහා සාපේක්ෂ ස්ථානීය කාවැද්දීම්.

107        self.key_pos_embeddings = nn.Parameter(torch.zeros((self.P, heads, self.d_k)), requires_grad=True)

විමසුමටසාපේක්ෂව යතුර සඳහා සාපේක්ෂ ස්ථානීය කාවැද්දීමේ නැඹුරුව.

109        self.key_pos_bias = nn.Parameter(torch.zeros((self.P, heads)), requires_grad=True)

විමසුමසඳහා ස්ථානීය කාවැද්දීම් විමසුමේ පිහිටුමෙන් ස්වාධීන වේ

111        self.query_pos_bias = nn.Parameter(torch.zeros((heads, self.d_k)), requires_grad=True)

අවශ්යනම් ලොග් වීම හෝ වෙනත් ගණනය කිරීම් සඳහා භාවිතා කළ හැකි වන පරිදි අපි අවධානය ගබඩා කරමු

114        self.attn = None

අවධානයලකුණු ලබා ගන්න

අපිඅවධානය සඳහා සාපේක්ෂ ස්ථානීය කේතීකරණ භාවිතා කරමු, සාපේක්ෂ බහු-හිස අවධානය ආකෘති ට්රාන්ස්ෆෝමර්-එක්ස්එල් කඩදාසිවලට සමානය.

පියවරප්රධාන වත්මන් පියවර ගේ විමසුම සිට අවධානය (වත්මන් පියවර සාපේක්ෂව) වේ,

මුල්කාවැද්දීම්වල රේඛීය පරිවර්තනයන් වන අතර ස්ථානීය කේතීකරණයේ රේඛීය පරිවර්තනයන් වේ .

අපිපදය වෙනුවට ආදේශ කරමු .

116    def get_scores(self, query: torch.Tensor, key: torch.Tensor):

144        key_pos_emb = self.key_pos_embeddings[-key.shape[0]:]

146        query_pos_bias = self.query_pos_bias[None, :, :]

148        key_pos_bias = self.key_pos_bias[-key.shape[0]:]

151        ac = torch.einsum('bhd,jbhd->jbh', query + query_pos_bias, key)

153        bd = torch.einsum('bhd,jhd->jbh', query, key_pos_emb) + key_pos_bias[:, None, :]

156        return ac + bd
  • query හැඩය ඇත [batch_size, d_model]
  • key සහ හැඩය value ඇත [seq_len, batch_size, d_model]
158    def forward(self, *,
159                query: torch.Tensor,
160                key: torch.Tensor,
161                value: torch.Tensor):

සූදානම්වන්න query , key සහ අවධානය ගණනය කිරීම value සඳහා key සහ පසුව හැඩය value ඇත [seq_len, batch_size, heads, d_k] සහ හැඩය query ඇත [batch_size, heads, d_k]

170        query = self.query(query)
171        if self.key:
172            key = self.key(key)
173        if self.value:
174            value = self.value(value)

අවධානයලකුණු ගණනය කරන්න. හැඩයේ ආතතියෙන් ප්රති Results ල [seq_len, batch_size, heads]

178        scores = self.get_scores(query, key)

පරිමාණලකුණු

181        scores *= self.scale

සොෆ්ට්මැක්ස්

184        attn = self.softmax(scores)

අතහැරදැමීම යොදන්න

187        attn = self.dropout(attn)

අගයන්අනුව ගුණ කරන්න

190        x = torch.einsum("jbh,jbhd->bhd", attn, value)

බහුහිස් සංයුක්ත කරන්න

193        x = x.reshape(x.shape[0], -1)

ප්රතිදානස්ථරය

196        return self.output(x)

ප්රතිපෝෂණට්රාන්ස්ෆෝමර් ස්ථරය

මෙයප්රතිපෝෂණ ට්රාන්ස්ෆෝමරයේ තනි ට්රාන්ස්ෆෝමර් තට්ටුවක් ක්රියාත්මක කරයි.

199class FeedbackTransformerLayer(Module):
  • d_model ට්රාන්ස්ෆෝමරයේ ඇති ලක්ෂණ ගණන
  • attn යනු ප්රතිපෝෂණ අවධානය මොඩියුලයයි
  • feed_forward ස්ථාන-wise ානවන්ත ආහාර ඉදිරි ස්ථරයයි
  • dropout_prob යනු අවධානය සහ පෝෂණය කිරීමෙන් පසු ස්ථර අතහැර දැමීමේ සම්භාවිතාවයයි
206    def __init__(self, *,
207                 d_model: int,
208                 attn: FeedbackAttention,
209                 feed_forward: FeedForward,
210                 dropout_prob: float):
217        super().__init__()

ට්රාන්ස්ෆෝමර්ප්රමාණය

219        self.size = d_model

221        self.attn = attn
222        self.feed_forward = feed_forward
223        self.dropout = nn.Dropout(dropout_prob)

සාමාන්යකරණයස්ථර

226        self.norm_self_attn = nn.LayerNorm([d_model])
227        self.norm_ff = nn.LayerNorm([d_model])
229    def forward(self, *,
230                x: torch.Tensor,
231                key: Optional[torch.Tensor],
232                value: Optional[torch.Tensor]):

මතකයක්තිබේ නම්

234        if key is not None:

ස්වයංඅවධානය යොමු කිරීමට පෙර දෛශික සාමාන්යකරණය කරන්න

236            z = self.norm_self_attn(x)

ස්වයංඅවධානය හරහා ධාවනය කරන්න, i.e. යතුරු සහ වටිනාකම් ස්වයං සිට

238            self_attn = self.attn(query=z, key=key, value=value)

ස්වයංඅවධානය ප්රතිඵල එකතු

240            x = x + self.dropout(self_attn)

පෝෂණයසඳහා සාමාන්යකරණය කරන්න

243        z = self.norm_ff(x)

Feed-forwardජාලය හරහා ගමන් කරන්න

245        ff = self.feed_forward(z)

ප්රතිපෝෂණඉදිරි ප්රති results ල නැවත එක් කරන්න

247        x = x + self.dropout(ff)

250        return x

ප්රතිපෝෂණට්රාන්ස්ෆෝමර් මොඩියුලය

253class FeedbackTransformer(Module):
  • layer අපි එක් එක් ස්ථරයක් සඳහා පරිගණක ක්රිඩාවට සමාන වන ප්රතිපෝෂණ ට්රාන්ස්ෆෝමර් ස්ථරය, වේ
  • n_layers ට්රාන්ස්ෆෝමරයේ ස්ථර ගණන
258    def __init__(self, layer: FeedbackTransformerLayer, n_layers: int):
264        super().__init__()

ට්රාන්ස්ෆෝමර්ස්ථරයේ පිටපත් සාදන්න

266        self.layers = clone_module_list(layer, n_layers)

අවසානසාමාන්යකරණ ස්තරය

268        self.norm = nn.LayerNorm([layer.size])

මතකදෛශික ගණනය කරනු ලබන්නේ එක් එක් ස්ථරයේ නිරූපණවල බර කිරන ලද එකතුවකි. ඒ සඳහා බර පරාමිතිය මෙයයි.

271        self.weights = nn.Parameter(torch.ones(n_layers + 1), requires_grad=True)

බරතැබූ මුදල ගැනීමට පෙර බර සඳහා සොෆ්ට්මැක්ස්

273        self.softmax = nn.Softmax(0)
  • x_seq හැඩය සහිත ආදානය වේ [seq_len, batch_size, d_model]
275    def forward(self, x_seq: torch.Tensor):

අනුක්රමිකඅක්ෂය දිගේ ලැයිස්තුවකට ආදානය බෙදන්න

281        x_seq = torch.unbind(x_seq, dim=0)

ප්රතිදානයන්ගබඩා කිරීම සඳහා ලැයිස්තුව

283        res = []

මතකදෛශික ගබඩා කිරීමට ලැයිස්තුව

285        mem = []

එක්එක් ආදාන පියවර සඳහා

287        for x in x_seq:

ස්ථරප්රතිදානයන් ගබඩා කිරීම සඳහා ලැයිස්තුව

289            layer_outputs = [x]

මතකයක්තිබේ නම්, ඒවා දෛශිකයකට ගොඩගසන්න

292            mem_tensor = torch.stack(mem) if mem else None

එක්එක් ස්ථරය හරහා ධාවනය කරන්න

295            for layer in self.layers:

ස්ථරප්රතිදානය ලබා ගන්න

297                x = layer(x=x, key=mem_tensor, value=mem_tensor)

ස්ථරප්රතිදානයන් ලැයිස්තුවට ඒවා එකතු කරන්න

299                layer_outputs.append(x)

ස්ථරයේප්රතිදානයන් ටෙන්සරයකට ගොඩගසන්න

302            layer_outputs = torch.stack(layer_outputs)

ස්ථරප්රතිදානවල බර තැබූ එකතුවක් ලෙස මතක දෛශිකය ගණනය කරන්න

304            mem.append(torch.einsum('lbd,l->bd', layer_outputs, self.softmax(self.weights)))

ප්රති. ල සඳහා ප්රතිදානය එක් කරන්න

306            res.append(x)

නිමැවුම්ආතතීන් ගොඩගසන්න

309        res = torch.stack(res)

ප්රතිදානයසාමාන්යකරණය කරන්න

311        return self.norm(res)

ස්ථරඅතර බෙදාගත් යතුරු සහ අගයන්

සිරස්ක්රියාකාරිත්වය ක්රියාත්මක කිරීම

අපිpython ලැයිස්තුවකට appending හා පසුව කරන්නේ වෙනුවට අභිරුචි ශ්රිතයක් ක්රියාත්මක torch.stack . මෙම බොහෝ සෙයින් අනුක්රමය ඔස්සේ එක් එක් පියවර torch.stack දී ඉල්ලා පුරා කාර්ය සාධනය වැඩි දියුණු කරන ලදි. සෑම විටම කැඳවනු torch.stack ලැබේ, එය නව ආතතියක් නිර්මාණය කරයි, මෙම ක්රමය සහ ඒ සමඟ ඇති පන්ති Stack කොටස් මතකය එක් එක් පියවර සඳහා.

318class StackFunction(torch.autograd.Function):
  • ctx යනු ශ්රිතයේ සන්දර්භය (එය අපට හැඹිලි දේවල් වලට ඉඩ දෙයි)
  • memory යනු හවුල් මතක ටෙන්සරය වන අතර එහිදී අපි එක් එක් පියවරේ අගයන් ගබඩා කර ගබඩා කරමු (යතුරු සහ අගයන්)
  • memory_grad යනු එක් එක් පියවරේ අනුක්රමික ගබඩා කිරීම හා රැස් කිරීම සඳහා හවුල් මතක ආතතියකි
  • last අවසාන අගය ගොඩගැසී ඇත
  • n පියවර ගණන (එනම් අඩුක්කුව ප්රමාණය)

මෙයපියවර සඳහා ගොඩගැසී ඇති ටෙන්සරය නැවත ලබා දෙයි n .

330    @staticmethod
331    def forward(ctx, memory, memory_grad, last, n):

හැඹිලිසමුච්චිත අනුක්රමික

343        ctx._mem_grad = memory_grad

තොගයේප්රමාණය හැඹිලිය

345        ctx._n = n

තොගයආපසු දෙන්න

347        return memory[:n + 1]
  • grad_output forward ශ්රිතයේ ප්රතිදානය සම්බන්ධයෙන් ශ්රේණිය වේ

මෙයහවුල් මතක ටෙන්සරයේ ඇති අනුක්රමික සමුච්චය වන අතර තොගයේ last ප්රති result ලය සම්බන්ධයෙන් අනුක්රමික ආපසු ලබා දෙන්න.

349    @staticmethod
350    def backward(ctx, grad_output):

තොගයේවත්මන් ප්රමාණය ලබා ගන්න

358        n = ctx._n

සමුච්චිතඅනුක්රමික ලබා ගන්න

360        memory_grad = ctx._mem_grad

අනුක්රමිකඑකතු කරන්න

362        memory_grad[:n + 1] += grad_output

W.r.tඅනුක්රමික තොගයේ අවසාන අගය වෙත ආපසු ලබා දෙන්න

364        return None, None, memory_grad[n], None

සිරස්මොඩියුලය

මෙයඉහත අර්ථ දක්වා ඇති සිරස් ශ්රිතය භාවිතා කරන අතර අවශ්ය ආරම්භකකරණයන් සිදු කරයි.

367class Stack:
  • max_len අඩුක්කුව උපරිම ප්රමාණය
374    def __init__(self, max_len: int):
378        self.max_len = max_len
379        self.memory = None
380        self.memory_grad = None
381        self.last = None
382        self.n = -1
383        self.last_get_n = -1
  • n අඩුක්කුව ප්රමාණය වේ
  • value අඩුක්කුව එකතු කළ යුතු බව tensor වේ
385    def append(self, n: int, value: torch.Tensor):

අගයක්එකතු කිරීමෙන් පසු ඔබට අඩුක්කුව ලබා ගත යුතුය (භාවිතා කරන්න). එසේ නොමැතිනම් මෙම ක්රියාත්මක කිරීම අසමත් වේ

393        assert n == 0 or self.last_get_n == n - 1, f"{n}, {self.last_get_n}"

අනුක්රමිකනොමැතිව මෙය කරන්න

396        with torch.no_grad():

තොගයතබා ගැනීම සඳහා හවුල් මතක ටෙන්සරය ආරම්භ කරන්න

398            if self.memory is None or self.memory.shape[1:] != value.shape:

මෙයසිදුවිය යුත්තේ තොගය හිස් වූ විට පමණි

400                assert n == 0

අඩුක්කුවසඳහා ටෙන්සරයක් සාදන්න

402                self.memory = value.new_zeros(self.max_len, *value.shape, requires_grad=False)

අනුක්රමිකසමුච්චය කිරීමට tensor සාදන්න

404                self.memory_grad = value.new_zeros(self.memory.shape, requires_grad=False)

මතකයදැනටමත් ආරම්භ කර ඇති නමුත් අපි තොගය නැවත සකසමින් සිටිමු.

මෙයතවත් කාර්යයක් විය හැකිය reset , නමුත් මෙය භාවිතා කිරීම පහසු බව අපට පෙනී ගියේය.

409            elif n == 0:

සමුච්චිතඅනුක්රමික නැවත සකසන්න

411                self.memory_grad.fill_(0.)

තොගයේනිවැරදි ස්ථානයේ වටිනාකම සකසන්න

414            self.memory.data[n] = value.detach()

(නිදොස්කරණය සඳහා) අඩුක්කුව පිළිබඳ වාර්තාවක් තබා ගන්න

416            self.n = n

තොගයටඑකතු කරන ලද අවසාන අගය පිළිබඳ වාර්තාවක් තබා ගන්න. ආපස්සට ප්රචාරය කිරීම සඳහා අපට මෙය සම්මත කර ගත යුතුය. StackFunction

421        self.last = value

තොගයආපසු ලබා දෙයි

423    def get(self):

එයභාවිතා කරන විට අඩුක්කුව ප්රමාණය පිළිබඳ වාර්තාවක් තබා ගන්න. මෙය සනීපාරක්ෂක පරීක්ෂණයක් සඳහා භාවිතා වේ append .

430        self.last_get_n = self.n

පසුපසටප්රචාරණය කිරීමේදී PyTorch විසින් කැඳවනු ලබන StackFunctionStackFunction.backwards සියල්ල හරහා ගන්න.

433        return StackFunction.apply(self.memory, self.memory_grad, self.last, self.n)

මතකයමුදා හැරීමට

435    def free(self):
440        self.memory = None
441        self.memory_grad = None
442        self.last = None

යාවත්කාලීනකරන ලද ප්රතිපෝෂණ ට්රාන්ස්ෆෝමර් මොඩියුලය

යතුරුසහ අගයන් හැඹිලි කරන යාවත්කාලීන කරන ලද ප්රතිපෝෂණ ට්රාන්ස්ෆෝමර් මොඩියුලය මෙයයි.

445class FeedbackTransformerKV(Module):
  • layer අපි එක් එක් ස්ථරයක් සඳහා පරිගණක ක්රිඩාවට සමාන වන ප්රතිපෝෂණ ට්රාන්ස්ෆෝමර් ස්ථරය, වේ
  • n_layers ට්රාන්ස්ෆෝමරයේ ස්ථර ගණන
  • d_model ට්රාන්ස්ෆෝමරයේ ඇති ලක්ෂණ ගණන
  • 'හෙඩ්ස්'යනු අවධානය යොමු කරන හිස් සංඛ්යාවකි
452    def __init__(self, layer: FeedbackTransformerLayer, n_layers: int, d_model: int, heads: int):
460        super().__init__()

ට්රාන්ස්ෆෝමර්ස්ථරයේ පිටපත් සාදන්න

462        self.layers = clone_module_list(layer, n_layers)

අවසානසාමාන්යකරණ ස්තරය

464        self.norm = nn.LayerNorm([layer.size])

මතකදෛශික ගණනය කරනු ලබන්නේ එක් එක් ස්ථරයේ නිරූපණවල බර කිරන ලද එකතුවකි. ඒ සඳහා බර පරාමිතිය මෙයයි.

467        self.weights = nn.Parameter(torch.ones(n_layers + 1), requires_grad=True)

බරතැබූ මුදල ගැනීමට පෙර බර සඳහා සොෆ්ට්මැක්ස්

469        self.softmax = nn.Softmax(0)

හිසෙහිවිශේෂාංග ගණන

472        d_k = d_model // heads

යතුරුලබා ගැනීම සඳහා කාවැද්දීම් (මතකය) පරිවර්තනය කිරීමේ මොඩියුලය

474        self.key = PrepareForMultiHeadAttention(d_model, heads, d_k, bias=False)

යතුරුලබා ගැනීම සඳහා කාවැද්දීම් (මතකය) පරිවර්තනය කිරීමේ මොඩියුලය

476        self.value = PrepareForMultiHeadAttention(d_model, heads, d_k, bias=False)

සිරස්වඇති යතුරු සඳහා මතකය

479        self.mem_key = Stack(512)

සිරස්වඇති අගයන් සඳහා මතකය

481        self.mem_value = Stack(512)
  • x_seq හැඩය සහිත ආදානය වේ [seq_len, batch_size, d_model]
483    def forward(self, x_seq: torch.Tensor):

අනුක්රමිකඅක්ෂය දිගේ ලැයිස්තුවකට ආදානය බෙදන්න

489        x_seq = torch.unbind(x_seq, dim=0)

ප්රතිදානයන්ගබඩා කිරීම සඳහා ලැයිස්තුව

491        res = []

එක්එක් ආදාන පියවර සඳහා

493        for step, x in enumerate(x_seq):

ස්ථරප්රතිදානයන් ගබඩා කිරීම සඳහා ලැයිස්තුව

495            layer_outputs = [x]

යතුරුසහ වටිනාකම් තොගයක්

498            key_tensor = None
499            value_tensor = None

අපිආරම්භක පියවර ඔබ්බට නම් යතුරු සහ අගයන් tensors ලබා ගන්න

501            if step > 0:
502                key_tensor = self.mem_key.get()
503                value_tensor = self.mem_value.get()

එක්එක් ස්ථරය හරහා ධාවනය කරන්න

506            for layer in self.layers:

ස්ථරප්රතිදානය ලබා ගන්න

508                x = layer(x=x, key=key_tensor, value=value_tensor)

ස්ථරප්රතිදානයන් ලැයිස්තුවට ඒවා එකතු කරන්න

510                layer_outputs.append(x)

ස්ථරයේප්රතිදානයන් ටෙන්සරයකට ගොඩගසන්න

513            layer_outputs = torch.stack(layer_outputs)

ස්ථරප්රතිදානවල බර තැබූ එකතුවක් ලෙස මතක දෛශිකය ගණනය කරන්න

515            mem = torch.einsum('lbd,l->bd', layer_outputs, self.softmax(self.weights))

මතකයෙන්යතුරු ගණනය කර එය තොගයට එක් කරන්න

517            self.mem_key.append(step, self.key(mem))

මතකයෙන්අගයන් ගණනය කර එය තොගයට එක් කරන්න

519            self.mem_value.append(step, self.value(mem))

ප්රති. ල සඳහා ප්රතිදානය එක් කරන්න

521            res.append(x)

නිමැවුම්ආතතීන් ගොඩගසන්න

524        res = torch.stack(res)

ප්රතිදානයසාමාන්යකරණය කරන්න

526        return self.norm(res)
528    def free(self):
529        self.mem_key.free()
530        self.mem_value.free()