foghollowleon commited on
Commit
567bfbb
·
verified ·
1 Parent(s): 75565a5

Add train.py, README.md, config.json, training_args.json, model.safetensors

Browse files
Files changed (5) hide show
  1. README.md +81 -0
  2. config.json +19 -0
  3. model.safetensors +3 -0
  4. train.py +126 -0
  5. training_args.json +9 -0
README.md ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: apache-2.0
3
+ tags:
4
+ - pytorch
5
+ - dino
6
+ - multitask
7
+ - wip
8
+ - smoke-test
9
+ ---
10
+
11
+ # Dino for Multitask
12
+
13
+ ## Overview
14
+
15
+ Working implementation of **Dino** for **Multitask** using a **tiny** configuration. The repository focuses on transparent code and repeatable smoke tests; benchmark claims are deliberately omitted.
16
+
17
+ ---
18
+
19
+ ## Acknowledgments
20
+
21
+ This repo borrows ideas freely from public reference implementations; credit to their authors.
22
+
23
+ ---
24
+
25
+ ## Repository Status
26
+
27
+ - Single-file implementation; the `__main__` block runs a smoke test.
28
+ - `config.json` and `training_args.json` hold the generated settings.
29
+ - `model.safetensors` is freshly initialized — plumbing, not results.
30
+ - No benchmark numbers are reported on purpose.
31
+
32
+ ---
33
+
34
+ ## Limitations
35
+
36
+ - weights are random-init, so outputs carry no signal
37
+ - robustness, fairness and domain transfer are untested
38
+ - the API may change without notice while the design settles
39
+
40
+ ---
41
+
42
+ ## Environment
43
+
44
+ | Item | Value |
45
+ |---|---|
46
+ | Python | >= 3.9 |
47
+ | torch | 2.x |
48
+ | safetensors | any recent |
49
+ | transformers | optional, for loaders |
50
+
51
+ ---
52
+
53
+ ## Default Experiment Recipe
54
+
55
+ The generated recipe uses lion with a step schedule.
56
+
57
+ These values exist so the script runs end-to-end. A meaningful experiment needs its own tuning budget and at least three seeds.
58
+
59
+ ---
60
+
61
+ ## Quick Check
62
+
63
+ Run `python train.py --help` for the built-in smoke test. Because this is a custom implementation, generic automatic loading APIs require an explicit adapter before use.
64
+
65
+ ---
66
+
67
+ ## Files
68
+
69
+ | File | Purpose |
70
+ |---|---|
71
+ | `train.py` | primary artifact |
72
+ | `README.md` | this documentation |
73
+ | `config.json` | architecture configuration |
74
+ | `training_args.json` | default experiment settings |
75
+ | `model.safetensors` | initialization checkpoint |
76
+
77
+ ---
78
+
79
+ ## License
80
+
81
+ Distributed under the **apache-2.0** license. External datasets keep their own terms — check them separately.
config.json ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "architectures": [
3
+ "CustomResearchModel"
4
+ ],
5
+ "architecture": "dino",
6
+ "model_type": "dino",
7
+ "hidden_size": 256,
8
+ "num_hidden_layers": 8,
9
+ "num_attention_heads": 4,
10
+ "intermediate_size": 512,
11
+ "hidden_act": "swish",
12
+ "max_position_embeddings": 128,
13
+ "layer_norm_eps": 1e-12,
14
+ "checkpoint_status": "initialization-only",
15
+ "notes": "Untrained checkpoint for smoke tests; no benchmark claim.",
16
+ "use_cache": true,
17
+ "torch_dtype": "float32",
18
+ "vocab_size": 2048
19
+ }
model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:e3990cda25902d73cccd4fdcf05e4f1f7044f24715df75f28209540bdb83e1db
3
+ size 132832
train.py ADDED
@@ -0,0 +1,126 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ import torch.nn as nn
3
+ import math
4
+
5
+
6
+ class DinoModel(nn.Module):
7
+ '''
8
+ dino model with flash attention.
9
+ Scale: tiny (dim=128, layers=3, heads=2)
10
+ Fusion: tucker, Task: multitask
11
+ '''
12
+
13
+ def __init__(self, embed_dim=128, num_layers=3, num_heads=2, num_classes=10):
14
+ super().__init__()
15
+ self.embed_dim = embed_dim
16
+ self.num_layers = num_layers
17
+ self.num_heads = num_heads
18
+
19
+ # image patch embedding
20
+ self.patch_proj = nn.Conv2d(3, embed_dim, kernel_size=16, stride=16)
21
+ self.cls_token = nn.Parameter(torch.randn(1, 1, embed_dim) * 0.02)
22
+ self.pos_embed = nn.Parameter(torch.randn(1, 197, embed_dim) * 0.02)
23
+ self.dropout = nn.Dropout(0.1)
24
+
25
+ # image transformer blocks
26
+ self.image_blocks = nn.ModuleList([
27
+ nn.TransformerEncoderLayer(
28
+ embed_dim, num_heads, embed_dim * 4, 0.1,
29
+ activation='gelu', batch_first=True, norm_first=True
30
+ )
31
+ for _ in range(num_layers)
32
+ ])
33
+ self.image_norm = nn.LayerNorm(embed_dim)
34
+
35
+ # text embedding
36
+ self.text_embed = nn.Embedding(30522, embed_dim, padding_idx=0)
37
+ self.text_pos = nn.Parameter(torch.randn(1, 128, embed_dim) * 0.02)
38
+ self.text_blocks = nn.ModuleList([
39
+ nn.TransformerEncoderLayer(
40
+ embed_dim, num_heads, embed_dim * 4, 0.1,
41
+ activation='gelu', batch_first=True, norm_first=True
42
+ )
43
+ for _ in range(num_layers)
44
+ ])
45
+ self.text_norm = nn.LayerNorm(embed_dim)
46
+
47
+ # fusion
48
+ self.fusion_blocks = nn.ModuleList([
49
+ nn.TransformerEncoderLayer(
50
+ embed_dim, num_heads, embed_dim * 4, 0.1,
51
+ activation='gelu', batch_first=True, norm_first=True
52
+ )
53
+ for _ in range(2)
54
+ ])
55
+ self.fusion_norm = nn.LayerNorm(embed_dim)
56
+
57
+ # task head
58
+ self.classifier = nn.Sequential(
59
+ nn.Linear(embed_dim, embed_dim),
60
+ nn.SiLU(),
61
+ nn.Dropout(0.1),
62
+ nn.Linear(embed_dim, num_classes),
63
+ )
64
+
65
+ self._initialize_weights()
66
+
67
+ def _initialize_weights(self):
68
+ for m in self.modules():
69
+ if isinstance(m, nn.Linear):
70
+ nn.init.kaiming_normal_(m.weight)
71
+ if m.bias is not None:
72
+ nn.init.zeros_(m.bias)
73
+ elif isinstance(m, nn.Embedding):
74
+ nn.init.trunc_normal_(m.weight, std=0.02)
75
+ if m.padding_idx is not None:
76
+ m.weight[m.padding_idx].zero_()
77
+ elif isinstance(m, nn.LayerNorm):
78
+ nn.init.ones_(m.weight)
79
+ nn.init.zeros_(m.bias)
80
+
81
+ def encode_image(self, images):
82
+ x = self.patch_proj(images)
83
+ x = x.flatten(2).transpose(1, 2)
84
+ cls = self.cls_token.expand(x.size(0), -1, -1)
85
+ x = torch.cat([cls, x], dim=1)
86
+ x = x + self.pos_embed
87
+ x = self.dropout(x)
88
+ for block in self.image_blocks:
89
+ x = block(x)
90
+ return self.image_norm(x)
91
+
92
+ def encode_text(self, input_ids, attention_mask=None):
93
+ x = self.text_embed(input_ids)
94
+ x = x + self.text_pos[:, :input_ids.size(1)]
95
+ x = self.dropout(x)
96
+ padding = (attention_mask == 0) if attention_mask is not None else None
97
+ for block in self.text_blocks:
98
+ x = block(x, src_key_padding_mask=padding)
99
+ return self.text_norm(x)
100
+
101
+ def forward(self, images, input_ids, attention_mask=None, labels=None):
102
+ image_features = self.encode_image(images)
103
+ text_features = self.encode_text(input_ids, attention_mask)
104
+
105
+ fused = text_features
106
+ for block in self.fusion_blocks:
107
+ fused = block(fused)
108
+ fused = self.fusion_norm(fused[:, 0])
109
+ logits = self.classifier(fused)
110
+
111
+ loss = None
112
+ if labels is not None:
113
+ loss = nn.functional.cross_entropy(logits, labels)
114
+
115
+ return {'logits': logits, 'loss': loss}
116
+
117
+
118
+ if __name__ == '__main__':
119
+ model = DinoModel()
120
+ total = sum(p.numel() for p in model.parameters())
121
+ print(f'DinoModel: {total:,} params ({total/1e6:.2f}M)')
122
+ img = torch.randn(2, 3, 224, 224)
123
+ ids = torch.randint(0, 30522, (2, 128))
124
+ mask = torch.ones(2, 128)
125
+ out = model(img, ids, mask, torch.tensor([0, 1]))
126
+ print(f'Output: {out["logits"].shape}, Loss: {out["loss"].item():.4f}')
training_args.json ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "optimizer": "lion",
3
+ "scheduler": "step",
4
+ "learning_rate": 0.0002,
5
+ "batch_size": 32,
6
+ "epochs": 30,
7
+ "seed": 123,
8
+ "status": "default recipe; not a completed run"
9
+ }