File size: 2,244 Bytes
3c62626
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
import torch
import torch.nn as nn
from transformers import PreTrainedModel, GenerationMixin
from transformers.modeling_outputs import CausalLMOutput

from models.config import TinyGPTConfig
from models.transformer_block import TransformerBlock


class TinyGPT(PreTrainedModel, GenerationMixin):
    config_class = TinyGPTConfig

    def __init__(self, config):
        super().__init__(config)
        self.config = config

        self.token_embedding = nn.Embedding(
            config.vocab_size,
            config.embed_dim,
        )

        self.position_embedding = nn.Embedding(
            config.max_seq_len,
            config.embed_dim,
        )

        self.transformer_blocks = nn.ModuleList([
            TransformerBlock(
                config.embed_dim
            )
            for _ in range(config.num_layers)
        ])

        self.ln_f = nn.LayerNorm(
            config.embed_dim
        )

        self.lm_head = nn.Linear(
            config.embed_dim,
            config.vocab_size,
        )

        self.post_init()

    def forward(self, input_ids, **kwargs):
        batch_size, seq_len = input_ids.shape

        positions = torch.arange(
            seq_len,
            device=input_ids.device
        )

        token_emb = self.token_embedding(
            input_ids
        )

        pos_emb = self.position_embedding(
            positions
        )

        x = token_emb + pos_emb

        for block in self.transformer_blocks:
            x = block(x)

        x = self.ln_f(x)

        logits = self.lm_head(x)

        return CausalLMOutput(logits=logits)

    def prepare_inputs_for_generation(self, input_ids, **kwargs):
        return {"input_ids": input_ids}

    def _init_weights(self, module):
        std = 0.02

        if isinstance(module, nn.Linear):
            module.weight.data.normal_(mean=0.0, std=std)
            if module.bias is not None:
                module.bias.data.zero_()

        elif isinstance(module, nn.Embedding):
            module.weight.data.normal_(mean=0.0, std=std)

        elif isinstance(module, nn.LayerNorm):
            module.bias.data.zero_()
            module.weight.data.fill_(1.0)


TinyGPT.register_for_auto_class("AutoModelForCausalLM")