popboat1 commited on
Commit
07bfb51
·
1 Parent(s): 0d48e99

Add dataloaders for all training phases

Browse files
src/utils/__init__.py ADDED
File without changes
src/utils/dataloader.py ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import numpy as np
3
+ import torch
4
+
5
+ def load_tokens(filename):
6
+ # simple numpy array extraction into torch tensor matrix memory
7
+ npt = np.load(filename)
8
+ npt = npt.astype(np.int32)
9
+ ptt = torch.tensor(npt, dtype=torch.long)
10
+ return ptt
11
+
12
+ class DataLoaderLite:
13
+ def __init__(self, B, T, process_rank, num_processes, split, master_process):
14
+ self.B = B
15
+ self.T = T
16
+ self.process_rank = process_rank
17
+ self.num_processes = num_processes
18
+ assert split in {'train', 'val'}
19
+
20
+ # swap directory to parse the dedicated edu fineweb repository location
21
+ data_root = "data/edu_fineweb10B"
22
+ shards = os.listdir(data_root)
23
+ shards = [s for s in shards if split in s]
24
+ shards = sorted(shards)
25
+ shards = [os.path.join(data_root, s) for s in shards]
26
+ self.shards = shards
27
+ assert len(shards) > 0, f"no shards found for split {split}"
28
+ if master_process:
29
+ print(f"found {len(shards)} shards for split {split}")
30
+ self.reset()
31
+
32
+ def reset(self):
33
+ # restart cursor coordinates back to default baseline states
34
+ self.current_shard = 0
35
+ self.tokens = load_tokens(self.shards[self.current_shard])
36
+ self.current_position = self.B * self.T * self.process_rank
37
+
38
+ def next_batch(self):
39
+ B, T = self.B, self.T
40
+ # slice out an extra token coordinate to establish lookahead targets
41
+ buf = self.tokens[self.current_position : self.current_position + B * T + 1]
42
+ x = (buf[:-1]).view(B, T)
43
+ y = (buf[1:]).view(B, T)
44
+
45
+ # advance sequence coordinates forward across total active processes
46
+ self.current_position += B * T * self.num_processes
47
+
48
+ # boundary loop detection to wrap safely over to the next shard asset
49
+ if self.current_position + B * T * self.num_processes + 1 > len(self.tokens):
50
+ self.current_shard = (self.current_shard + 1) % len(self.shards)
51
+ self.tokens = load_tokens(self.shards[self.current_shard])
52
+ self.current_position = B * T * self.process_rank
53
+ return x, y
src/utils/dataloader_masked.py ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import numpy as np
3
+ import torch
4
+
5
+ def load_data(filename):
6
+ # extract two column array containing tracking tokens and target masks
7
+ npt = np.load(filename)
8
+ npt = npt.astype(np.int32)
9
+ ptt = torch.tensor(npt, dtype=torch.long)
10
+ return ptt
11
+
12
+ class DataLoaderMasked:
13
+ def __init__(self, B, T, process_rank, num_processes, split, master_process):
14
+ self.B = B
15
+ self.T = T
16
+ self.process_rank = process_rank
17
+ self.num_processes = num_processes
18
+ assert split in {'train', 'val'}
19
+
20
+ data_root = "data/sft_dataset"
21
+ shards = os.listdir(data_root)
22
+ shards = [s for s in shards if split in s]
23
+ shards = sorted(shards)
24
+ shards = [os.path.join(data_root, s) for s in shards]
25
+ self.shards = shards
26
+ assert len(shards) > 0, f"no shards found for split {split}"
27
+ if master_process:
28
+ print(f"found {len(shards)} shards for split {split}")
29
+ self.reset()
30
+
31
+ def reset(self):
32
+ self.current_shard = 0
33
+ self.data = load_data(self.shards[self.current_shard])
34
+ self.current_position = self.B * self.T * self.process_rank
35
+
36
+ def next_batch(self):
37
+ B, T = self.B, self.T
38
+ buf = self.data[self.current_position : self.current_position + B * T + 1]
39
+
40
+ # partition raw text streams away from structural response mask columns
41
+ x = buf[:-1, 0].view(B, T)
42
+ y = buf[1:, 0].view(B, T)
43
+ m = buf[1:, 1].view(B, T)
44
+
45
+ # replace unmasked prompt context fields with pytorch ignore token index
46
+ y = y.clone()
47
+ y[m == 0] = -100
48
+
49
+ self.current_position += B * T * self.num_processes
50
+ if self.current_position + B * T * self.num_processes + 1 > len(self.data):
51
+ self.current_shard = (self.current_shard + 1) % len(self.shards)
52
+ self.data = load_data(self.shards[self.current_shard])
53
+ self.current_position = B * T * self.process_rank
54
+ return x, y
src/utils/dataloader_ppo.py ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import numpy as np
3
+ import torch
4
+
5
+ def load_data(filename):
6
+ npt = np.load(filename)
7
+ npt = npt.astype(np.int32)
8
+ return torch.tensor(npt, dtype=torch.long)
9
+
10
+ class DataLoaderPPO:
11
+ def __init__(self, B, process_rank, num_processes, split, master_process):
12
+ self.B = B
13
+ self.process_rank = process_rank
14
+ self.num_processes = num_processes
15
+
16
+ data_root = "data/ppo_dataset"
17
+ shards = [os.path.join(data_root, s) for s in os.listdir(data_root) if split in s]
18
+ self.shards = sorted(shards)
19
+ assert len(self.shards) > 0, f"no shards found for split {split}"
20
+
21
+ if master_process:
22
+ print(f"found {len(self.shards)} ppo shards for split {split}")
23
+ self.reset()
24
+
25
+ def reset(self):
26
+ self.current_shard = 0
27
+ self.data = load_data(self.shards[self.current_shard])
28
+ self.current_position = self.B * self.process_rank
29
+
30
+ def next_batch(self):
31
+ B = self.B
32
+ # isolate the exact prompt token batch chunks out of static arrays
33
+ prompts = self.data[self.current_position : self.current_position + B]
34
+
35
+ self.current_position += B * self.num_processes
36
+ if self.current_position + B * self.num_processes > len(self.data):
37
+ self.current_shard = (self.current_shard + 1) % len(self.shards)
38
+ self.data = load_data(self.shards[self.current_shard])
39
+ self.current_position = B * self.process_rank
40
+ return prompts
src/utils/dataloader_reward.py ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import numpy as np
3
+ import torch
4
+
5
+ def load_data(filename):
6
+ npt = np.load(filename)
7
+ npt = npt.astype(np.int32)
8
+ return torch.tensor(npt, dtype=torch.long)
9
+
10
+ class DataLoaderReward:
11
+ def __init__(self, B, T, process_rank, num_processes, split, master_process):
12
+ self.B = B
13
+ self.T = T
14
+ self.process_rank = process_rank
15
+ self.num_processes = num_processes
16
+ assert split in {'train', 'val'}
17
+
18
+ data_root = "data/rm_dataset"
19
+ shards = os.listdir(data_root)
20
+ shards = [s for s in shards if split in s]
21
+ shards = sorted(shards)
22
+ shards = [os.path.join(data_root, s) for s in shards]
23
+ self.shards = shards
24
+ assert len(shards) > 0, f"no shards found for split {split}"
25
+ if master_process:
26
+ print(f"found {len(shards)} reward shards for split {split}")
27
+ self.reset()
28
+
29
+ def reset(self):
30
+ self.current_shard = 0
31
+ self.data = load_data(self.shards[self.current_shard])
32
+ self.current_position = self.B * self.process_rank
33
+
34
+ def next_batch(self):
35
+ B = self.B
36
+ buf = self.data[self.current_position : self.current_position + B]
37
+
38
+ # split custom preference sequence records into winning and losing tensors
39
+ x_chosen = buf[:, 0, :]
40
+ x_rejected = buf[:, 1, :]
41
+
42
+ self.current_position += B * self.num_processes
43
+ if self.current_position + B * self.num_processes > len(self.data):
44
+ self.current_shard = (self.current_shard + 1) % len(self.shards)
45
+ self.data = load_data(self.shards[self.current_shard])
46
+ self.current_position = B * self.process_rank
47
+ return x_chosen, x_rejected