සම්පීඩ්යතාට්රාන්ස්ෆෝමර් අත්හදා බැලීම

මෙයසම්පීඩ්යතා ට්රාන්ස්ෆෝමර් ආකෘතියක් පුහුණු කිරීම සඳහා කරන ලද පයිටෝච් අත්හදා බැලීමකි.

11from typing import List, Tuple, NamedTuple
12
13import torch
14import torch.nn as nn
15
16from labml import experiment, tracker, monit, logger
17from labml.configs import option
18from labml.logger import Text
19from labml_helpers.metrics.simple_state import SimpleStateModule
20from labml_helpers.module import Module
21from labml_helpers.train_valid import BatchIndex, hook_model_outputs
22from labml_nn.experiments.nlp_autoregression import NLPAutoRegressionConfigs
23from labml_nn.transformers.compressive import CompressiveTransformer, AttentionReconstructionLoss, \
24    CompressiveTransformerLayer, Conv1dCompression
27class CompressedMemory(NamedTuple):
28    mem: List[torch.Tensor]
29    c_mem: List[torch.Tensor]

ස්වයංක්රීයප්රතිගාමී ආකෘතිය

32class AutoregressiveModel(Module):
37    def __init__(self, n_vocab: int, d_model: int, transformer: CompressiveTransformer):
38        super().__init__()

ටෝකන්කාවැද්දීම මොඩියුලය

40        self.src_embed = nn.Embedding(n_vocab, d_model)

ට්රාන්ස්ෆෝමර්

42        self.transformer = transformer

අවසන්ස්ථරය

44        self.generator = nn.Linear(d_model, n_vocab)

වෙස්මුහුණු

46        self.mask_x = None
47        self.mask_mem = None
49    def forward(self, x: torch.Tensor, mem: CompressedMemory):

මතකයසහ සම්පීඩිත මතකය ලබා ගන්න

51        if mem is not None:
52            mem, c_mem = mem.mem, mem.c_mem
53        else:
54            mem = []
55            c_mem = []

මතකයේමුළු දිග සහ සම්පීඩිත මතකයේ (වෙස් මුහුණු සඳහා)

58        m_len = len(mem[0]) if mem else 0
59        if c_mem:
60            m_len += len(c_mem[0])

ටෝකනසඳහා පසුකාලීන වෙස් මුහුණක් සාදන්න

63        if self.mask_x is None or self.mask_x.shape[0] < len(x):
64            from labml_nn.transformers.utils import subsequent_mask
65            self.mask_x = subsequent_mask(len(x)).to(x.device)

මතකයසඳහා සියලු (සම්පූර්ණ දෘශ්යතාව) වෙස්මුහුණක් සාදන්න

67        if self.mask_mem is None or self.mask_mem.shape[1] < m_len or self.mask_mem.shape[0] < len(x):
68            self.mask_mem = self.mask_x.new_ones(len(x), m_len, 1)

මතකයක්තිබේ නම් වෙස් මුහුණු සංයුක්ත කරන්න

71        if m_len:
72            mask = torch.cat((self.mask_mem[:len(x), :m_len], self.mask_x[:len(x), :len(x)]), dim=1)

වෙනත්ආකාරයකින් පසුකාලීන ආවරණ පමණක් භාවිතා කරන්න

74        else:
75            mask = self.mask_x[:len(x), :len(x)]

ටෝකන්කාවැද්දීම්

78        x = self.src_embed(x)

ට්රාන්ස්ෆෝමරයහරහා එය ධාවනය කරන්න

80        res, mem = self.transformer(x, mem, c_mem, mask)

ඊළඟටෝකනයේ පිවිසුම් ජනනය කරන්න

82        res = self.generator(res)

84        return res, mem

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

පෙරනිමිවින්යාසයන් අප අත්හදා බැලීම ආරම්භ කරන විට පෙරනිමි වින්යාසයන් ඉක්මවා යා හැකිය.

87class Configs(NLPAutoRegressionConfigs):
94    model: AutoregressiveModel

ටෝකන්කාවැද්දීමේ ප්රමාණය

97    d_model: int = 128

අවධානයයොමු ප්රධානීන් ගණන

99    heads: int = 4

අතහැරදැමීමේ සම්භාවිතාව

101    dropout: float = 0.0

FFNසැඟවුණු ස්ථරයේ විශේෂාංග ගණන

103    d_ff: int = 256

ට්රාන්ස්ෆෝමර්ස්ථර ගණන

105    n_layers: int = 6

තබාගත යුතු මතකයන් ගණන

107    mem_len: int = 8

පුහුණුවසහ වලංගු කිරීම අතර මාරුවීමේදී මතකයන් පවත්වා ගැනීම සඳහා රාජ්ය මොඩියුලය

109    memory = SimpleStateModule()

අවධානයප්රතිසංස්කරණ අලාභය

111    attention_reconstruction_loss: AttentionReconstructionLoss

සම්පීඩනඅනුපාතය

113    compression_rate: int = 4

සම්පීඩිතමතක දිග

115    c_mem_len: int = 128
117    def init(self):

ට්රැකර්වින්යාසයන් සකසන්න

119        tracker.set_scalar("accuracy.*", True)
120        tracker.set_scalar("loss.*", True)

පර්යන්තයේඅවධානය ප්රතිනිර්මාණය කිරීමේ අලාභය මුද්රණය නොකරන්න

122        tracker.set_scalar("ar_loss.*", False)

මොඩියුලප්රතිදානයන් ලොග් කිරීමට කොක්කක් එක් කරන්න

124        hook_model_outputs(self.mode, self.model, 'model')

මෙයපුහුණුව සහ වලංගු කිරීම සඳහා නිරවද්යතා මෙට්රික් සංඛ්යාන සහ මතකයන් වෙනම තබා ගනී.

126        self.state_modules = [self.accuracy, self.memory]

නවමතකයන් සංයුක්ත කර පැරණිතම මතකයන් සම්පීඩනය කරන්න.

128    @torch.no_grad()
129    def merge_compress_memory(self, mem: CompressedMemory, new_mem: List[torch.Tensor]) \
130            -> Tuple[CompressedMemory, List[torch.Tensor]]:

වින්යාසයන්මතකය භාවිතා නොකිරීමට නියම කරන්නේ නම්

136        if self.mem_len == 0 and self.c_mem_len == 0:
137            return CompressedMemory([], []), []

මතකයසහ සම්පීඩිත මතකය ලබා ගන්න

140        if mem is not None:
141            mem, c_mem = mem.mem, mem.c_mem
142        else:
143            mem, c_mem = [], []

පැරණිමතකය සමඟ නව මතකයන් සංයුක්ත කරන්න

146        if mem:
147            mem = [torch.cat((m, x), dim=0) for m, x in zip(mem, new_mem)]
148        else:
149            mem = new_mem

වඩාමතකයන් තිබේ නම් පැරණිතම මතකයන් සම්පීඩනය කරන්න mem_len

152        if len(mem[0]) > self.mem_len:

සෑදීමටසම්පීඩිත මතකයන් ගණන ගණනය කරන්න , අප සතුව ඇති මතකයන් ගණන කොතැනද සහ අප නඩත්තු කරන උපරිම මතකයන් ගණන ( mem_len ).

156            n_c_mem = (len(mem[0]) - self.mem_len + self.compression_rate - 1) // self.compression_rate

සම්පීඩනයකිරීමට මතකයන් ගණන

158            n_old = n_c_mem * self.compression_rate

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

160            mem_to_compress = []

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

162            uncompressed_mem = []

එක්එක් ස්ථරයේ මතකයන් හරහා ගමන් කරන්න.

164            for m in mem:

දීමතකයන් බෙදන්න

166                cm, m = torch.split(m, [n_old, len(m) - n_old])

සම්පීඩනයකිරීමට මතකයන් එකතු කරන්න

168                mem_to_compress.append(cm)

ඉතිරිමතකයන් එකතු කරන්න

170                uncompressed_mem.append(m)

මතකයන්යාවත්කාලීන කරන්න

172            mem = uncompressed_mem

මතකයන්සංකෝචනය කරන්න

175            new_c_mem = []
176            for i, layer in enumerate(self.model.transformer.layers):
177                new_c_mem.append(layer.compress(mem_to_compress[i]))

පැරණිසම්පීඩිත මතකයන් සමඟ අලුතින් සම්පීඩිත මතකයන් සංයුක්ත කරන්න

180            if c_mem:
181                c_mem = [torch.cat((m, nm), dim=0) for m, nm in zip(c_mem, new_c_mem)]

පැරණිසම්පීඩිත මතකයන් නොමැති නම්

183            else:
184                c_mem = new_c_mem

පැරණිමතකයන් ඉවත් කරන්න

187            if len(c_mem[0]) > self.c_mem_len:
188                c_mem = [m[-self.c_mem_len:] for m in c_mem]

මතකයන්ගණන අඩු නම් කිසිදු මතකයන් සම්පීඩිත නොවේ mem_len

190        else:
191            mem_to_compress = []

මතකයන්සහ සම්පීඩිත මතකයන් නැවත ලබා දෙන්න. සම්පීඩිත බව මතකයන් ප්රතිසංස්කරණය අහිමි ගණනය කිරීම සඳහා අවශ්ය වේ.

195        return CompressedMemory(mem, c_mem), mem_to_compress

පුහුණුව/වලංගුකිරීමේ පියවර

197    def step(self, batch: any, batch_idx: BatchIndex):

උපාංගයවෙත දත්ත ගෙනයන්න

203        data, target = batch[0].to(self.device), batch[1].to(self.device)

පුහුණුප්රකාරයේදී ගෝලීය පියවර යාවත්කාලීන කරන්න (සැකසූ ටෝකන ගණන)

206        if self.mode.is_train:
207            tracker.add_global_step(data.shape[0] * data.shape[1])

ආකෘතිප්රතිදානයන් ග්රහණය කර ගත යුතුද යන්න

210        with self.mode.update(is_log_activations=batch_idx.is_last):

මතකයන්ලබා ගන්න

212            mem = self.memory.get()

ආකෘතියධාවනය කරන්න

214            output, new_mem = self.model(data, mem)

මතකයඒකාබද්ධ කර සම්පීඩනය කරන්න

216            mem, mem_to_compress = self.merge_compress_memory(mem, new_mem)

මතකයන්යාවත්කාලීන කරන්න

218            self.memory.set(mem)

හරස්එන්ට්රොපි අලාභය ගණනය කර ලොග් කරන්න

221        loss = self.loss_func(output, target)
222        tracker.add("loss.", loss)

මතකයන්මෙම පියවර සම්පීඩිත නම් අවධානය ප්රතිසංස්කරණය අහිමි ගණනය

225        if mem_to_compress:

අවධානයයොමු ප්රතිසංස්කරණය අහිමි ලබා ගන්න

227            ar_loss = self.attention_reconstruction_loss(new_mem, mem_to_compress)

ධාවනඅවධානය ප්රතිසංස්කරණ අලාභය

229            tracker.add("ar_loss.", ar_loss)

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

231            loss = loss + ar_loss

ගණනයකිරීම සහ ලොග් කිරීමේ නිරවද්යතාවය

234        self.accuracy(output, target)
235        self.accuracy.track()

ආකෘතියපුහුණු කරන්න

238        if self.mode.is_train:

අනුක්රමිකගණනය කරන්න

240            loss.backward()

ක්ලිප්අනුක්රමික

242            torch.nn.utils.clip_grad_norm_(self.model.parameters(), max_norm=self.grad_norm_clip)

ප්රශස්තිකරණපියවර ගන්න

244            self.optimizer.step()

සෑමයුගලයකම අවසාන කණ්ඩායමේ ආදර්ශ පරාමිතීන් සහ අනුක්රමික ලොග් කරන්න

246            if batch_idx.is_last:
247                tracker.add('model', self.model)

අනුක්රමිකඉවත්

249            self.optimizer.zero_grad()

ලුහුබැඳඇති ප්රමිතික සුරකින්න

252        tracker.save()

පුහුණුවඅතරතුර වරින් වර සාම්පල ජනනය කිරීම සඳහා නියැදි කිරීමේ කාර්යය

254    def sample(self):

විමසුමක්ආරම්භ කිරීම

260        prompt = self.prompt

මුද්රණයසඳහා ප්රතිදානය එකතු කරන්න

262        log = [(prompt, Text.subtle)]

මතකය

264        mem = CompressedMemory([], [])

සාම්පල25 ටෝකන

266        for i in monit.iterate('Sample', 25):

විමසුමටෝකෙන්කරන්න

268            data = self.text.text_to_i(prompt).unsqueeze(-1)

උපාංගයවෙත ගෙන යන්න

270            data = data.to(self.device)

ආදර්ශප්රතිදානය ලබා ගන්න

272            output, new_mem = self.model(data, mem)

ආදර්ශඅනාවැකිය ලබා ගන්න (කෑදර)

274            output = output.argmax(dim=-1).squeeze(1)

විමසුමටඅනාවැකිය එක් කරන්න

276            prompt += self.prompt_separator + self.text.itos[output[-1]]

ඊළඟපුනරාවර්තනයේදී අවසාන චරිතය ආකෘතියට පමණක් පෝෂණය කරන්න, විවේකය මතකයන් ලෙස ඉදිරියට යනු ඇත

278            prompt = prompt[-1:]

ලොග්වීම සඳහා අනාවැකිය එක් කරන්න

280            log += [(self.prompt_separator + self.text.itos[output[-1]], Text.value)]

මතකයයාවත්කාලීන කිරීම සහ සම්පීඩනය කිරීම

282            mem, _ = self.merge_compress_memory(mem, new_mem)

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

285        logger.log(log)

ස්වයංක්රීයප්රතිගාමී ආකෘතිය ආරම්භ කරන්න

288@option(Configs.model)
289def autoregressive_model(c: Configs):
293    from labml_nn.transformers.xl import RelativeMultiHeadAttention
294    from labml_nn.transformers.feed_forward import FeedForward
295    m = AutoregressiveModel(c.n_tokens, c.d_model, CompressiveTransformer(
296        CompressiveTransformerLayer(d_model=c.d_model,
297                                    self_attn=RelativeMultiHeadAttention(c.heads, c.d_model, c.dropout),
298                                    feed_forward=FeedForward(c.d_model, c.d_ff, c.dropout),
299                                    dropout_prob=c.dropout,
300                                    compress=Conv1dCompression(c.compression_rate, c.d_model)), c.n_layers))
301    return m.to(c.device)

අවධානයප්රතිසංස්කරණ අලාභය ආරම්භ කරන්න

304@option(Configs.attention_reconstruction_loss)
305def attention_reconstruction_loss(c: Configs):
309    return AttentionReconstructionLoss(c.model.transformer.layers)

අත්හදාබැලීම ක්රියාත්මක කරන්න

312def main():

අත්හදාබැලීම සාදන්න

317    experiment.create(name="compressive_transformer", comment='')

වින්යාසසාදන්න

319    conf = Configs()

වින්යාසයන්පූරණය කරන්න

321    experiment.configs(conf,

අභිබවායාම සඳහා වින්යාසයන් පිළිබඳ ශබ්දකෝෂයක්

323                       {'tokenizer': 'character',
324                        'text': 'tiny_shakespeare',
325                        'optimizer.learning_rate': 2.5e-4,
326                        'optimizer.optimizer': 'AdamW',
327                        'prompt': 'It is',
328                        'prompt_separator': '',
329
330                        'train_loader': 'sequential_train_loader',
331                        'valid_loader': 'sequential_valid_loader',
332
333                        'seq_len': 8,
334                        'mem_len': 8,
335                        'epochs': 128,
336                        'batch_size': 32,
337                        'inner_iterations': 25,
338                        'compression_rate': 2,
339                        })

ඉතිරිකිරීම සහ පැටවීම සඳහා ආකෘති සකසන්න

342    experiment.add_pytorch_models({'model': conf.model})

අත්හදාබැලීම ආරම්භ කරන්න

345    with experiment.start():

TrainValidConfigs.run

347        conf.run()

351if __name__ == '__main__':
352    main()