NovatasticRoScript commited on
Commit
cb5d220
·
verified ·
1 Parent(s): f57382f

Upload folder using huggingface_hub

Browse files
Files changed (5) hide show
  1. README.md +9 -0
  2. config.json +1 -0
  3. model.pt +3 -0
  4. modeling.py +73 -0
  5. vocab.json +1 -0
README.md ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ # Atomight-V1-GRAFT-0.8M
2
+
3
+ Custom from-scratch hybrid discriminative+generative model for abstract reasoning (RAVEN / PGM / I-RAVEN-X style matrix puzzles).
4
+
5
+ Architecture: GRAFT (Grid Relational Attention Fusion Transformer), ~0.79M params.
6
+
7
+ Narration is templated (captions the classifier's decision, not an independent derivation from ground-truth attribute labels).
8
+
9
+ Load with the GRAFT class definition (see modeling.py) + model.pt state_dict.
config.json ADDED
@@ -0,0 +1 @@
 
 
1
+ {"D": 128, "D2": 96, "vocab_size": 49, "architecture": "GRAFT"}
model.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:a3c126b5fdfecb5dbf8d8ed177005fa6d843ac03c759697281a84d1c63fb1c13
3
+ size 3173304
modeling.py ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ import torch.nn as nn
3
+ import torch.nn.functional as F
4
+
5
+ D = 128
6
+ D2 = 96
7
+
8
+ class DepthwiseSeparableConv(nn.Module):
9
+ def __init__(self, in_ch, out_ch):
10
+ super().__init__()
11
+ self.dw = nn.Conv2d(in_ch, in_ch, 3, padding=1, groups=in_ch)
12
+ self.pw = nn.Conv2d(in_ch, out_ch, 1)
13
+ def forward(self, x):
14
+ return self.pw(self.dw(x))
15
+
16
+ class AtomEncoder(nn.Module):
17
+ def __init__(self, embed_dim=D):
18
+ super().__init__()
19
+ self.net = nn.Sequential(
20
+ nn.Conv2d(1, 16, 3, stride=2, padding=1), nn.GELU(),
21
+ nn.Conv2d(16, 32, 3, stride=2, padding=1), nn.GELU(),
22
+ DepthwiseSeparableConv(32, 64), nn.GELU(),
23
+ nn.AdaptiveAvgPool2d(1),
24
+ )
25
+ self.proj = nn.Linear(64, embed_dim)
26
+ def forward(self, x):
27
+ return self.proj(self.net(x).flatten(1))
28
+
29
+ class GridRelationalAttention(nn.Module):
30
+ def __init__(self, dim=D, heads=4, n_relations=4):
31
+ super().__init__()
32
+ self.missing_token = nn.Parameter(torch.randn(dim) * 0.02)
33
+ self.row_attn = nn.MultiheadAttention(dim, heads, batch_first=True)
34
+ self.col_attn = nn.MultiheadAttention(dim, heads, batch_first=True)
35
+ self.relation_queries = nn.Parameter(torch.randn(n_relations, dim) * 0.02)
36
+ self.cross_attn = nn.MultiheadAttention(dim, heads, batch_first=True)
37
+ self.rule_proj = nn.Linear(n_relations * dim, dim)
38
+ self.n_relations, self.dim = n_relations, dim
39
+
40
+ def forward(self, context_panels):
41
+ B = context_panels.shape[0]
42
+ missing = self.missing_token.expand(B, 1, self.dim)
43
+ grid = torch.cat([context_panels, missing], dim=1)
44
+ rows_idx = [[0,1,2],[3,4,5],[6,7,8]]
45
+ cols_idx = [[0,3,6],[1,4,7],[2,5,8]]
46
+ row_vecs = torch.cat([
47
+ self.row_attn(grid[:, idx, :], grid[:, idx, :], grid[:, idx, :])[0].mean(1, keepdim=True)
48
+ for idx in rows_idx
49
+ ], dim=1)
50
+ col_vecs = torch.cat([
51
+ self.col_attn(grid[:, idx, :], grid[:, idx, :], grid[:, idx, :])[0].mean(1, keepdim=True)
52
+ for idx in cols_idx
53
+ ], dim=1)
54
+ combined_ctx = torch.cat([row_vecs, col_vecs], dim=1)
55
+ rq = self.relation_queries.unsqueeze(0).expand(B, -1, -1)
56
+ rel_out, _ = self.cross_attn(rq, combined_ctx, combined_ctx)
57
+ return self.rule_proj(rel_out.flatten(1))
58
+
59
+ class CandidateScorer(nn.Module):
60
+ def __init__(self, dim=D):
61
+ super().__init__()
62
+ self.score_proj = nn.Linear(dim, dim)
63
+ def forward(self, rule_embedding, candidate_embeds):
64
+ proj_rule = self.score_proj(rule_embedding)
65
+ return torch.einsum("bd,bkd->bk", proj_rule, candidate_embeds)
66
+
67
+ class GRAFT(nn.Module):
68
+ def __init__(self, vocab_size, narrator_cls):
69
+ super().__init__()
70
+ self.encoder = AtomEncoder()
71
+ self.gra = GridRelationalAttention()
72
+ self.scorer = CandidateScorer()
73
+ self.narrator = narrator_cls(vocab_size=vocab_size)
vocab.json ADDED
@@ -0,0 +1 @@
 
 
1
+ ["<pad>", "<bos>", "<eos>", " ", "'", "(", ")", ",", "-", ".", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ":", "?", "_", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"]