NovaAI6868 commited on
Commit
a46dc3e
·
verified ·
1 Parent(s): 4fda437

Remove old files, keep only latest GGUF release

Browse files
Files changed (6) hide show
  1. all.jsonl +0 -0
  2. checkpoints/checkpoint_final.pt +0 -3
  3. infer.py +0 -70
  4. spm.model +0 -3
  5. spm.vocab +0 -0
  6. train.py +0 -237
all.jsonl DELETED
The diff for this file is too large to render. See raw diff
 
checkpoints/checkpoint_final.pt DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:5944f5d325c8c7f6e666aca78f6883eab157f9d416fc4edd748f0308a2c409f0
3
- size 284829424
 
 
 
 
infer.py DELETED
@@ -1,70 +0,0 @@
1
- # ==========================
2
- # infer.py
3
- # ==========================
4
- # Usage:
5
- # python infer.py --checkpoint checkpoints/checkpoint_epoch3.pt --spm_model spm.model
6
-
7
- import argparse
8
- import torch
9
- import sentencepiece as spm
10
- from train import GPT, GPTConfig
11
-
12
- def top_k_logits(logits, k):
13
- v, ix = torch.topk(logits, k)
14
- out = logits.clone()
15
- out[out < v[..., -1, None]] = -float('Inf')
16
- return out
17
-
18
- def generate(model, sp, device, prompt, max_new_tokens=128, temperature=1.0, top_k=50):
19
- model.eval()
20
- ids = sp.EncodeAsIds('<s>' + prompt + '<sep>')
21
- context = torch.tensor(ids, dtype=torch.long, device=device).unsqueeze(0)
22
-
23
- for _ in range(max_new_tokens):
24
- seq = context if context.size(1) <= model.block_size else context[:, -model.block_size:]
25
- logits, _ = model(seq)
26
- logits = logits[:, -1, :] / max(temperature, 1e-8)
27
- if top_k is not None:
28
- logits = top_k_logits(logits, top_k)
29
- probs = torch.softmax(logits, dim=-1)
30
- next_id = torch.multinomial(probs, num_samples=1)
31
- context = torch.cat([context, next_id], dim=1)
32
- if next_id.item() == sp.EncodeAsIds('</s>')[0]:
33
- break
34
- out_ids = context[0].tolist()
35
- text = sp.DecodeIds([i for i in out_ids if i != 0])
36
- if '<sep>' in text:
37
- parts = text.split('<sep>')
38
- if len(parts) >= 2:
39
- return parts[1].replace('</s>','').strip()
40
- return text
41
-
42
- def main():
43
- parser = argparse.ArgumentParser()
44
- parser.add_argument('--checkpoint', type=str, required=True)
45
- parser.add_argument('--spm_model', type=str, default='spm.model')
46
- parser.add_argument('--device', type=str, default='cuda' if torch.cuda.is_available() else 'cpu')
47
- parser.add_argument('--prompt', type=str, default='你好,请自我介绍。')
48
- parser.add_argument('--max_new_tokens', type=int, default=1024)
49
- parser.add_argument('--temperature', type=float, default=0.8)
50
- parser.add_argument('--top_k', type=int, default=40)
51
- args = parser.parse_args()
52
-
53
- sp = spm.SentencePieceProcessor()
54
- sp.Load(args.spm_model)
55
-
56
- ckpt = torch.load(args.checkpoint, map_location=args.device)
57
- cfg = ckpt.get('config')
58
- config = GPTConfig(vocab_size=cfg['vocab_size'], n_layer=cfg['n_layer'], n_head=cfg['n_head'], n_embd=cfg['n_embd'], block_size=cfg['block_size'], dropout=cfg['dropout'])
59
- model = GPT(config).to(args.device)
60
- model.load_state_dict(ckpt['model_state'])
61
-
62
- param_count = sum(p.numel() for p in model.parameters())
63
- print(f"Loaded model parameters: {param_count:,} ({param_count/1e9:.3f} B)")
64
-
65
- ans = generate(model, sp, args.device, args.prompt, max_new_tokens=args.max_new_tokens, temperature=args.temperature, top_k=args.top_k)
66
- print('\n=== RESPONSE ===\n')
67
- print(ans)
68
-
69
- if __name__ == '__main__':
70
- main()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
spm.model DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:478beeaf55eb5dedd0b87f0cd5c032341faec7b3500f7636d55407f5cc6cc809
3
- size 989403
 
 
 
 
spm.vocab DELETED
The diff for this file is too large to render. See raw diff
 
train.py DELETED
@@ -1,237 +0,0 @@
1
- # ==========================
2
- # train.py
3
- # ==========================
4
- # Usage:
5
- # python train.py --data_path all.jsonl --spm_model spm.model
6
- # Requirements:
7
- # pip install torch sentencepiece tqdm
8
-
9
- import os
10
- import json
11
- import sentencepiece as spm
12
- from argparse import ArgumentParser
13
- from tqdm import tqdm
14
-
15
- import torch
16
- from torch import nn
17
- from torch.utils.data import Dataset, DataLoader
18
-
19
- # --------------------------
20
- # Simple Decoder-only Transformer (GPT-like)
21
- # --------------------------
22
-
23
- class GPTConfig:
24
- def __init__(self, vocab_size, n_layer=12, n_head=12, n_embd=768, block_size=1024, dropout=0.1):
25
- self.vocab_size = vocab_size
26
- self.n_layer = n_layer
27
- self.n_head = n_head
28
- self.n_embd = n_embd
29
- self.block_size = block_size
30
- self.dropout = dropout
31
-
32
-
33
- class CausalSelfAttention(nn.Module):
34
- def __init__(self, config):
35
- super().__init__()
36
- assert config.n_embd % config.n_head == 0
37
- self.c_attn = nn.Linear(config.n_embd, 3 * config.n_embd)
38
- self.c_proj = nn.Linear(config.n_embd, config.n_embd)
39
- self.n_head = config.n_head
40
- self.dropout = nn.Dropout(config.dropout)
41
-
42
- def forward(self, x, attn_mask=None):
43
- B, T, C = x.size()
44
- qkv = self.c_attn(x) # (B, T, 3*C)
45
- q, k, v = qkv.split(C, dim=2)
46
- # reshape for multi-head
47
- q = q.view(B, T, self.n_head, C // self.n_head).transpose(1,2) # (B, nh, T, hs)
48
- k = k.view(B, T, self.n_head, C // self.n_head).transpose(1,2)
49
- v = v.view(B, T, self.n_head, C // self.n_head).transpose(1,2)
50
-
51
- att = (q @ k.transpose(-2, -1)) / (C // self.n_head) ** 0.5 # (B, nh, T, T)
52
- # causal mask
53
- mask = torch.tril(torch.ones(T, T, device=x.device)).view(1, 1, T, T)
54
- att = att.masked_fill(mask == 0, float('-inf'))
55
- att = torch.softmax(att, dim=-1)
56
- att = self.dropout(att)
57
-
58
- y = att @ v # (B, nh, T, hs)
59
- y = y.transpose(1,2).contiguous().view(B, T, C)
60
- y = self.c_proj(y)
61
- y = self.dropout(y)
62
- return y
63
-
64
-
65
- class Block(nn.Module):
66
- def __init__(self, config):
67
- super().__init__()
68
- self.ln1 = nn.LayerNorm(config.n_embd)
69
- self.attn = CausalSelfAttention(config)
70
- self.ln2 = nn.LayerNorm(config.n_embd)
71
- self.mlp = nn.Sequential(
72
- nn.Linear(config.n_embd, 4 * config.n_embd),
73
- nn.GELU(),
74
- nn.Linear(4 * config.n_embd, config.n_embd),
75
- nn.Dropout(config.dropout),
76
- )
77
-
78
- def forward(self, x):
79
- x = x + self.attn(self.ln1(x))
80
- x = x + self.mlp(self.ln2(x))
81
- return x
82
-
83
-
84
- class GPT(nn.Module):
85
- def __init__(self, config):
86
- super().__init__()
87
- self.tok_emb = nn.Embedding(config.vocab_size, config.n_embd)
88
- self.pos_emb = nn.Parameter(torch.zeros(1, config.block_size, config.n_embd))
89
- self.drop = nn.Dropout(config.dropout)
90
- self.blocks = nn.ModuleList([Block(config) for _ in range(config.n_layer)])
91
- self.ln_f = nn.LayerNorm(config.n_embd)
92
- self.head = nn.Linear(config.n_embd, config.vocab_size, bias=False)
93
- self.block_size = config.block_size
94
-
95
- # initialize
96
- self.apply(self._init_weights)
97
-
98
- def _init_weights(self, module):
99
- if isinstance(module, nn.Linear):
100
- nn.init.normal_(module.weight, mean=0.0, std=0.02)
101
- if module.bias is not None:
102
- nn.init.zeros_(module.bias)
103
- elif isinstance(module, nn.Embedding):
104
- nn.init.normal_(module.weight, mean=0.0, std=0.02)
105
-
106
- def forward(self, idx, targets=None):
107
- B, T = idx.size()
108
- assert T <= self.block_size
109
- token_embeddings = self.tok_emb(idx) # (B, T, C)
110
- x = token_embeddings + self.pos_emb[:, :T, :]
111
- x = self.drop(x)
112
- for block in self.blocks:
113
- x = block(x)
114
- x = self.ln_f(x)
115
- logits = self.head(x)
116
-
117
- loss = None
118
- if targets is not None:
119
- # shift logits and targets for next-token prediction
120
- logits = logits[:, :-1, :].contiguous()
121
- targets = targets[:, 1:].contiguous()
122
- loss = nn.functional.cross_entropy(logits.view(-1, logits.size(-1)), targets.view(-1))
123
- return logits, loss
124
-
125
-
126
- # --------------------------
127
- # Dataset and helpers
128
- # --------------------------
129
-
130
- class QADataset(Dataset):
131
- def __init__(self, path, sp_model, block_size=1024):
132
- self.examples = []
133
- self.block_size = block_size
134
- self.sp = sp_model
135
- with open(path, 'r', encoding='utf-8') as f:
136
- for line in f:
137
- obj = json.loads(line)
138
- q = obj.get('question','')
139
- a = obj.get('answer','')
140
- # format: <bos> question <sep> answer <eos>
141
- text = "<s>" + q + "<sep>" + a + "</s>"
142
- ids = self.sp.EncodeAsIds(text)
143
- if len(ids) > 2:
144
- # truncate or pad later
145
- self.examples.append(ids)
146
-
147
- def __len__(self):
148
- return len(self.examples)
149
-
150
- def __getitem__(self, idx):
151
- ids = self.examples[idx]
152
- # pad/truncate to block_size
153
- if len(ids) > self.block_size:
154
- ids = ids[:self.block_size]
155
- else:
156
- ids = ids + [0] * (self.block_size - len(ids))
157
- return torch.tensor(ids, dtype=torch.long)
158
-
159
-
160
- def collate_fn(batch):
161
- batch = torch.stack(batch, dim=0)
162
- return batch, batch # inputs and targets are same sequence for causal LM
163
-
164
-
165
- # --------------------------
166
- # Main training loop
167
- # --------------------------
168
-
169
-
170
- def train(args):
171
- # prepare sentencepiece model (if not exists, train it)
172
- if not os.path.exists(args.spm_model):
173
- print('Training SentencePiece model...')
174
- # create a temporary file with concatenated text
175
- tmp_txt = 'spm_input.txt'
176
- with open(args.data_path, 'r', encoding='utf-8') as fin, open(tmp_txt, 'w', encoding='utf-8') as fout:
177
- for line in fin:
178
- obj = json.loads(line)
179
- text = obj.get('question','') + '\n' + obj.get('answer','') + '\n'
180
- fout.write(text)
181
- spm.SentencePieceTrainer.Train(f'--input={tmp_txt} --model_prefix=spm --vocab_size={args.vocab_size} --model_type=bpe --character_coverage=0.9995')
182
- os.remove(tmp_txt)
183
- sp = spm.SentencePieceProcessor()
184
- sp.Load('spm.model')
185
- else:
186
- sp = spm.SentencePieceProcessor()
187
- sp.Load(args.spm_model)
188
-
189
- dataset = QADataset(args.data_path, sp, block_size=args.block_size)
190
- print(f"Loaded {len(dataset)} examples")
191
- dataloader = DataLoader(dataset, batch_size=args.batch_size, shuffle=True, collate_fn=lambda x: collate_fn(x))
192
-
193
- config = GPTConfig(vocab_size=args.vocab_size, n_layer=args.n_layer, n_head=args.n_head, n_embd=args.n_embd, block_size=args.block_size, dropout=args.dropout)
194
- model = GPT(config).to(args.device)
195
-
196
- # print parameter count
197
- param_count = sum(p.numel() for p in model.parameters())
198
- print(f"Model parameters: {param_count:,} ({param_count/1e9:.3f} B)")
199
-
200
- optimizer = torch.optim.AdamW(model.parameters(), lr=args.lr)
201
-
202
- model.train()
203
- for epoch in range(args.epochs):
204
- pbar = tqdm(dataloader, desc=f"Epoch {epoch+1}/{args.epochs}")
205
- for batch_inputs, batch_targets in pbar:
206
- batch_inputs = batch_inputs.to(args.device)
207
- batch_targets = batch_targets.to(args.device)
208
- logits, loss = model(batch_inputs, targets=batch_targets)
209
- optimizer.zero_grad()
210
- loss.backward()
211
- torch.nn.utils.clip_grad_norm_(model.parameters(), 1.0)
212
- optimizer.step()
213
- pbar.set_postfix(loss=loss.item())
214
-
215
- # save checkpoint each epoch
216
- os.makedirs(args.out_dir, exist_ok=True)
217
- torch.save({'model_state': model.state_dict(), 'sp_model': args.spm_model, 'config': vars(config)}, os.path.join(args.out_dir, f'checkpoint_final.pt'))
218
-
219
-
220
- if __name__ == '__main__':
221
- parser = ArgumentParser()
222
- parser.add_argument('--data_path', type=str, default='all.jsonl')
223
- parser.add_argument('--spm_model', type=str, default='spm.model')
224
- parser.add_argument('--vocab_size', type=int, default=32000)
225
- parser.add_argument('--block_size', type=int, default=1024)
226
- parser.add_argument('--n_layer', type=int, default=3)
227
- parser.add_argument('--n_head', type=int, default=3)
228
- parser.add_argument('--n_embd', type=int, default=768)
229
- parser.add_argument('--batch_size', type=int, default=30)
230
- parser.add_argument('--epochs', type=int, default=300)
231
- parser.add_argument('--lr', type=float, default=3e-4)
232
- parser.add_argument('--dropout', type=float, default=0.1)
233
- parser.add_argument('--device', type=str, default='cuda' if torch.cuda.is_available() else 'cpu')
234
- parser.add_argument('--out_dir', type=str, default='checkpoints')
235
- args = parser.parse_args()
236
- train(args)
237
-