codon-model 0.0.4__tar.gz → 0.0.5__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {codon_model-0.0.4/codon_model.egg-info → codon_model-0.0.5}/PKG-INFO +1 -1
- {codon_model-0.0.4 → codon_model-0.0.5}/codon/__init__.py +1 -1
- {codon_model-0.0.4 → codon_model-0.0.5}/codon/base.py +76 -10
- {codon_model-0.0.4 → codon_model-0.0.5}/codon/block/__init__.py +4 -1
- {codon_model-0.0.4 → codon_model-0.0.5}/codon/block/attention.py +11 -6
- {codon_model-0.0.4 → codon_model-0.0.5}/codon/block/embedding.py +3 -3
- codon_model-0.0.5/codon/block/fourier.py +106 -0
- {codon_model-0.0.4 → codon_model-0.0.5}/codon/block/mlp.py +38 -0
- {codon_model-0.0.4 → codon_model-0.0.5}/codon/block/transformer.py +42 -13
- codon_model-0.0.5/codon/cli.py +48 -0
- codon_model-0.0.5/codon/dev/clear.py +41 -0
- codon_model-0.0.5/codon/dev/hash.py +54 -0
- {codon_model-0.0.4 → codon_model-0.0.5}/codon/exp/block/bio.py +1 -1
- {codon_model-0.0.4 → codon_model-0.0.5}/codon/kit/train/__init__.py +3 -1
- codon_model-0.0.5/codon/kit/train/language.py +123 -0
- {codon_model-0.0.4 → codon_model-0.0.5}/codon/motif/base.py +4 -8
- codon_model-0.0.5/codon/motif/data/__init__.py +7 -0
- codon_model-0.0.5/codon/motif/data/prev1.py +87 -0
- codon_model-0.0.5/codon/motif/data/sft.py +161 -0
- {codon_model-0.0.4 → codon_model-0.0.5}/codon/motif/motif_a1.py +11 -14
- {codon_model-0.0.4 → codon_model-0.0.5}/codon/motif/motif_v1.py +2 -3
- {codon_model-0.0.4 → codon_model-0.0.5}/codon/ops/attention.py +10 -17
- codon_model-0.0.5/codon/ops/fourier.py +33 -0
- {codon_model-0.0.4 → codon_model-0.0.5}/codon/ops/pixelshuffle.py +0 -1
- codon_model-0.0.5/codon/utils/data/__init__.py +29 -0
- codon_model-0.0.5/codon/utils/data/base.py +404 -0
- codon_model-0.0.5/codon/utils/data/chunked.py +192 -0
- codon_model-0.0.5/codon/utils/generate.py +349 -0
- codon_model-0.0.5/codon/utils/layer/__init__.py +0 -0
- codon_model-0.0.5/codon/utils/lifecycle.py +56 -0
- codon_model-0.0.5/codon/utils/plan.py +314 -0
- codon_model-0.0.5/codon/utils/session.py +323 -0
- {codon_model-0.0.4 → codon_model-0.0.5}/codon/utils/tokens.py +99 -26
- {codon_model-0.0.4 → codon_model-0.0.5/codon_model.egg-info}/PKG-INFO +1 -1
- {codon_model-0.0.4 → codon_model-0.0.5}/codon_model.egg-info/SOURCES.txt +22 -11
- codon_model-0.0.5/codon_model.egg-info/entry_points.txt +2 -0
- {codon_model-0.0.4 → codon_model-0.0.5}/setup.py +5 -0
- codon_model-0.0.4/codon/utils/dataset/__init__.py +0 -22
- codon_model-0.0.4/codon/utils/dataset/base.py +0 -124
- codon_model-0.0.4/codon/utils/dataset/conflux/base.py +0 -316
- codon_model-0.0.4/codon/utils/dataset/conflux/reader.py +0 -239
- codon_model-0.0.4/codon/utils/dataset/conflux/writer.py +0 -229
- codon_model-0.0.4/codon/utils/dataset/corpus.py +0 -630
- codon_model-0.0.4/test/test_conflux_dataset.py +0 -113
- {codon_model-0.0.4 → codon_model-0.0.5}/LICENSE +0 -0
- {codon_model-0.0.4 → codon_model-0.0.5}/codon/block/bio/__init__.py +0 -0
- {codon_model-0.0.4 → codon_model-0.0.5}/codon/block/bio/hebian.py +0 -0
- {codon_model-0.0.4 → codon_model-0.0.5}/codon/block/bio/predictive.py +0 -0
- {codon_model-0.0.4 → codon_model-0.0.5}/codon/block/codebook.py +0 -0
- {codon_model-0.0.4 → codon_model-0.0.5}/codon/block/conv.py +0 -0
- {codon_model-0.0.4 → codon_model-0.0.5}/codon/block/film.py +0 -0
- {codon_model-0.0.4 → codon_model-0.0.5}/codon/block/fusion.py +0 -0
- {codon_model-0.0.4 → codon_model-0.0.5}/codon/block/lora.py +0 -0
- {codon_model-0.0.4 → codon_model-0.0.5}/codon/block/manifold.py +0 -0
- {codon_model-0.0.4 → codon_model-0.0.5}/codon/block/moe.py +0 -0
- {codon_model-0.0.4 → codon_model-0.0.5}/codon/block/pixelshuffle.py +0 -0
- {codon_model-0.0.4/codon/exp → codon_model-0.0.5/codon/dev}/__init__.py +0 -0
- {codon_model-0.0.4/codon/exp/block → codon_model-0.0.5/codon/exp}/__init__.py +0 -0
- {codon_model-0.0.4/codon/exp/ops → codon_model-0.0.5/codon/exp/block}/__init__.py +0 -0
- {codon_model-0.0.4 → codon_model-0.0.5}/codon/exp/block/manifold.py +0 -0
- {codon_model-0.0.4 → codon_model-0.0.5}/codon/exp/block/moe.py +0 -0
- {codon_model-0.0.4/codon/kit → codon_model-0.0.5/codon/exp/ops}/__init__.py +0 -0
- {codon_model-0.0.4/codon/utils → codon_model-0.0.5/codon/kit}/__init__.py +0 -0
- {codon_model-0.0.4 → codon_model-0.0.5}/codon/kit/train/vision.py +0 -0
- {codon_model-0.0.4 → codon_model-0.0.5}/codon/model/__init__.py +0 -0
- {codon_model-0.0.4 → codon_model-0.0.5}/codon/model/patch_disc.py +0 -0
- {codon_model-0.0.4 → codon_model-0.0.5}/codon/model/resnet.py +0 -0
- {codon_model-0.0.4 → codon_model-0.0.5}/codon/model/tcn.py +0 -0
- {codon_model-0.0.4 → codon_model-0.0.5}/codon/motif/__init__.py +0 -0
- /codon_model-0.0.4/codon/utils/dataset/conflux/__init__.py → /codon_model-0.0.5/codon/motif/motif_a2.py +0 -0
- {codon_model-0.0.4 → codon_model-0.0.5}/codon/ops/__init__.py +0 -0
- {codon_model-0.0.4 → codon_model-0.0.5}/codon/ops/bio.py +0 -0
- {codon_model-0.0.4 → codon_model-0.0.5}/codon/ops/manifold/__init__.py +0 -0
- {codon_model-0.0.4 → codon_model-0.0.5}/codon/ops/manifold/conv.py +0 -0
- {codon_model-0.0.4 → codon_model-0.0.5}/codon/ops/manifold/linear.py +0 -0
- {codon_model-0.0.4/codon/utils/layer → codon_model-0.0.5/codon/utils}/__init__.py +0 -0
- {codon_model-0.0.4/codon/utils/dataset → codon_model-0.0.5/codon/utils/data}/dataviewer.py +0 -0
- {codon_model-0.0.4/codon/utils/dataset → codon_model-0.0.5/codon/utils/data}/flatdata.py +0 -0
- {codon_model-0.0.4/codon/utils/dataset → codon_model-0.0.5/codon/utils/data}/image.py +0 -0
- {codon_model-0.0.4 → codon_model-0.0.5}/codon/utils/eval/__init__.py +0 -0
- {codon_model-0.0.4 → codon_model-0.0.5}/codon/utils/eval/activation.py +0 -0
- {codon_model-0.0.4 → codon_model-0.0.5}/codon/utils/eval/base.py +0 -0
- {codon_model-0.0.4 → codon_model-0.0.5}/codon/utils/eval/boundary.py +0 -0
- {codon_model-0.0.4 → codon_model-0.0.5}/codon/utils/eval/cka.py +0 -0
- {codon_model-0.0.4 → codon_model-0.0.5}/codon/utils/eval/confusion.py +0 -0
- {codon_model-0.0.4 → codon_model-0.0.5}/codon/utils/eval/gradcam.py +0 -0
- {codon_model-0.0.4 → codon_model-0.0.5}/codon/utils/eval/layer_rsa.py +0 -0
- {codon_model-0.0.4 → codon_model-0.0.5}/codon/utils/eval/rsa.py +0 -0
- {codon_model-0.0.4 → codon_model-0.0.5}/codon/utils/eval/selectivity.py +0 -0
- {codon_model-0.0.4 → codon_model-0.0.5}/codon/utils/eval/similarity.py +0 -0
- {codon_model-0.0.4 → codon_model-0.0.5}/codon/utils/eval/tsne.py +0 -0
- {codon_model-0.0.4 → codon_model-0.0.5}/codon/utils/info.py +0 -0
- {codon_model-0.0.4 → codon_model-0.0.5}/codon/utils/layer/lora.py +0 -0
- {codon_model-0.0.4 → codon_model-0.0.5}/codon/utils/layer/manifold.py +0 -0
- {codon_model-0.0.4 → codon_model-0.0.5}/codon/utils/mask.py +0 -0
- {codon_model-0.0.4 → codon_model-0.0.5}/codon/utils/safecode.py +0 -0
- {codon_model-0.0.4 → codon_model-0.0.5}/codon/utils/seed.py +0 -0
- {codon_model-0.0.4 → codon_model-0.0.5}/codon/utils/split.py +0 -0
- {codon_model-0.0.4 → codon_model-0.0.5}/codon/utils/theta.py +0 -0
- {codon_model-0.0.4 → codon_model-0.0.5}/codon/utils/transforms.py +0 -0
- {codon_model-0.0.4 → codon_model-0.0.5}/codon_model.egg-info/dependency_links.txt +0 -0
- {codon_model-0.0.4 → codon_model-0.0.5}/codon_model.egg-info/requires.txt +0 -0
- {codon_model-0.0.4 → codon_model-0.0.5}/codon_model.egg-info/top_level.txt +0 -0
- {codon_model-0.0.4 → codon_model-0.0.5}/setup.cfg +0 -0
- {codon_model-0.0.4 → codon_model-0.0.5}/test/test_motifv1_train.py +0 -0
|
@@ -5,6 +5,7 @@ import torch.nn.functional as F
|
|
|
5
5
|
from typing import Callable, Any, Iterator, Union
|
|
6
6
|
|
|
7
7
|
from safetensors.torch import save_model as safe_save_model
|
|
8
|
+
from safetensors.torch import save_file as safe_save_file
|
|
8
9
|
from safetensors.torch import load_model as safe_load_model
|
|
9
10
|
|
|
10
11
|
|
|
@@ -133,41 +134,106 @@ class BasicModel(nn.Module):
|
|
|
133
134
|
|
|
134
135
|
return total
|
|
135
136
|
|
|
136
|
-
def load_pretrained(self, path: str) -> 'BasicModel':
|
|
137
|
+
def load_pretrained(self, path: str, strict: bool = False) -> 'BasicModel':
|
|
137
138
|
'''
|
|
138
139
|
Load a pretrained model from a file.
|
|
139
|
-
|
|
140
140
|
Args:
|
|
141
141
|
path (str): The path to the model file.
|
|
142
|
+
strict (bool, optional): Whether to strictly enforce that the keys
|
|
143
|
+
in state_dict match. Defaults to False.
|
|
142
144
|
'''
|
|
143
145
|
if path.endswith('.safetensors'):
|
|
144
|
-
safe_load_model(self, path)
|
|
146
|
+
safe_load_model(self, path, strict=strict)
|
|
145
147
|
return self
|
|
146
|
-
|
|
147
148
|
state_dict = torch.load(path, map_location=self.device)
|
|
148
|
-
|
|
149
149
|
if isinstance(state_dict, dict):
|
|
150
150
|
if 'model_state_dict' in state_dict:
|
|
151
151
|
state_dict = state_dict['model_state_dict']
|
|
152
152
|
elif 'state_dict' in state_dict:
|
|
153
153
|
state_dict = state_dict['state_dict']
|
|
154
|
+
elif 'model' in state_dict:
|
|
155
|
+
state_dict = state_dict['model']
|
|
154
156
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
+
clean_state_dict = {k.replace('_orig_mod.', ''): v for k, v in state_dict.items()}
|
|
158
|
+
|
|
159
|
+
self.load_state_dict(clean_state_dict, strict=strict)
|
|
157
160
|
return self
|
|
158
161
|
|
|
159
|
-
def save_pretrained(
|
|
162
|
+
def save_pretrained(
|
|
163
|
+
self,
|
|
164
|
+
path: str,
|
|
165
|
+
trainable_only: bool = False,
|
|
166
|
+
include_buffer: bool = True,
|
|
167
|
+
exclude_modules: list[Union[type, nn.Module]] = None,
|
|
168
|
+
only: list[str] = None,
|
|
169
|
+
exclude: list[str] = None
|
|
170
|
+
) -> 'BasicModel':
|
|
160
171
|
'''
|
|
161
172
|
Save the model to a file.
|
|
162
173
|
|
|
163
174
|
Args:
|
|
164
175
|
path (str): The path to save the model file.
|
|
176
|
+
trainable_only (bool, optional): If True, only save parameters that require gradients.
|
|
177
|
+
include_buffer (bool, optional): If False, exclude registered buffers from the saved file.
|
|
178
|
+
exclude_modules (list[Union[type, nn.Module]], optional): Module types or instances to exclude.
|
|
179
|
+
only (list[str], optional): If provided, only save parameters whose keys contain ANY of these strings.
|
|
180
|
+
exclude (list[str], optional): If provided, exclude parameters whose keys contain ANY of these strings.
|
|
165
181
|
'''
|
|
182
|
+
state_dict = self.state_dict()
|
|
183
|
+
is_modified = False
|
|
184
|
+
|
|
185
|
+
exclude_prefixes = []
|
|
186
|
+
if exclude_modules:
|
|
187
|
+
exclude_types = tuple(t for t in exclude_modules if isinstance(t, type))
|
|
188
|
+
exclude_instances = set(m for m in exclude_modules if not isinstance(m, type))
|
|
189
|
+
|
|
190
|
+
for name, module in self.named_modules():
|
|
191
|
+
if module in exclude_instances or (exclude_types and isinstance(module, exclude_types)):
|
|
192
|
+
if name != '': exclude_prefixes.append(name + '.')
|
|
193
|
+
exclude_prefixes = tuple(exclude_prefixes)
|
|
194
|
+
|
|
195
|
+
has_filter = trainable_only or not include_buffer or exclude_prefixes or only or exclude
|
|
196
|
+
|
|
197
|
+
if has_filter:
|
|
198
|
+
trainable_names = {name for name, p in self.named_parameters() if p.requires_grad}
|
|
199
|
+
buffer_names = {name for name, _ in self.named_buffers()}
|
|
200
|
+
|
|
201
|
+
filtered_dict = {}
|
|
202
|
+
for key, tensor in state_dict.items():
|
|
203
|
+
keep = True
|
|
204
|
+
|
|
205
|
+
if exclude_prefixes and key.startswith(exclude_prefixes):
|
|
206
|
+
keep = False
|
|
207
|
+
|
|
208
|
+
elif exclude and any(kw in key for kw in exclude):
|
|
209
|
+
keep = False
|
|
210
|
+
|
|
211
|
+
elif only and not any(kw in key for kw in only):
|
|
212
|
+
keep = False
|
|
213
|
+
|
|
214
|
+
else:
|
|
215
|
+
is_buffer = key in buffer_names
|
|
216
|
+
if not include_buffer and is_buffer:
|
|
217
|
+
keep = False
|
|
218
|
+
elif trainable_only and not is_buffer and key not in trainable_names:
|
|
219
|
+
keep = False
|
|
220
|
+
|
|
221
|
+
if keep:
|
|
222
|
+
filtered_dict[key] = tensor
|
|
223
|
+
else:
|
|
224
|
+
is_modified = True
|
|
225
|
+
|
|
226
|
+
if is_modified:
|
|
227
|
+
state_dict = filtered_dict
|
|
228
|
+
|
|
166
229
|
if path.endswith('.safetensors'):
|
|
167
|
-
|
|
230
|
+
if not is_modified:
|
|
231
|
+
safe_save_model(self, path)
|
|
232
|
+
else:
|
|
233
|
+
safe_save_file(state_dict, path)
|
|
168
234
|
else:
|
|
169
|
-
state_dict = self.state_dict()
|
|
170
235
|
torch.save(state_dict, path)
|
|
236
|
+
|
|
171
237
|
return self
|
|
172
238
|
|
|
173
239
|
def freeze(self) -> 'BasicModel':
|
|
@@ -36,6 +36,7 @@ from .manifold import (
|
|
|
36
36
|
BasicManifoldLinear, RiemannianManifoldLinear,
|
|
37
37
|
BasicManifoldConv2d, RiemannianManifoldConv2d
|
|
38
38
|
)
|
|
39
|
+
from .fourier import MultiHeadFourier
|
|
39
40
|
|
|
40
41
|
__all__ = [
|
|
41
42
|
# attention
|
|
@@ -90,5 +91,7 @@ __all__ = [
|
|
|
90
91
|
'BasicManifoldLinear',
|
|
91
92
|
'RiemannianManifoldLinear',
|
|
92
93
|
'BasicManifoldConv2d',
|
|
93
|
-
'RiemannianManifoldConv2d'
|
|
94
|
+
'RiemannianManifoldConv2d',
|
|
95
|
+
# Fourier
|
|
96
|
+
'MultiHeadFourier',
|
|
94
97
|
]
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
from codon.base import *
|
|
2
2
|
from codon.block.embedding import BasicEmbedding
|
|
3
|
-
from codon.ops.attention import
|
|
3
|
+
from codon.ops.attention import (
|
|
4
|
+
AttentionOutput,
|
|
5
|
+
apply_attention
|
|
6
|
+
)
|
|
4
7
|
|
|
5
8
|
|
|
6
9
|
class MultiHeadAttention(BasicModel):
|
|
@@ -25,6 +28,7 @@ class MultiHeadAttention(BasicModel):
|
|
|
25
28
|
use_qk_norm=True,
|
|
26
29
|
use_gate=False,
|
|
27
30
|
dropout=0.1,
|
|
31
|
+
bias: bool=True,
|
|
28
32
|
is_causal=True
|
|
29
33
|
):
|
|
30
34
|
'''
|
|
@@ -65,12 +69,12 @@ class MultiHeadAttention(BasicModel):
|
|
|
65
69
|
self.k_norm = nn.RMSNorm(self.head_dim)
|
|
66
70
|
|
|
67
71
|
if use_gate:
|
|
68
|
-
self.g_proj = nn.Linear(hidden_size, hidden_size)
|
|
72
|
+
self.g_proj = nn.Linear(hidden_size, hidden_size, bias=bias)
|
|
69
73
|
|
|
70
|
-
self.q_proj = nn.Linear(hidden_size, hidden_size)
|
|
71
|
-
self.k_proj = nn.Linear(hidden_size, self.kv_dim)
|
|
72
|
-
self.v_proj = nn.Linear(hidden_size, self.kv_dim)
|
|
73
|
-
self.o_proj = nn.Linear(hidden_size, hidden_size)
|
|
74
|
+
self.q_proj = nn.Linear(hidden_size, hidden_size, bias=bias)
|
|
75
|
+
self.k_proj = nn.Linear(hidden_size, self.kv_dim, bias=bias)
|
|
76
|
+
self.v_proj = nn.Linear(hidden_size, self.kv_dim, bias=bias)
|
|
77
|
+
self.o_proj = nn.Linear(hidden_size, hidden_size, bias=bias)
|
|
74
78
|
|
|
75
79
|
def forward(
|
|
76
80
|
self,
|
|
@@ -171,3 +175,4 @@ class MultiHeadAttention(BasicModel):
|
|
|
171
175
|
attention_weights=attention_weights,
|
|
172
176
|
past_key_value=current_key_value
|
|
173
177
|
)
|
|
178
|
+
|
|
@@ -69,7 +69,7 @@ class SinusoidalEmbedding(BasicEmbedding):
|
|
|
69
69
|
pe[:, 1::2] = torch.cos(position * div_term)
|
|
70
70
|
|
|
71
71
|
pe = pe.unsqueeze(0)
|
|
72
|
-
self.register_buffer('pe', pe)
|
|
72
|
+
self.register_buffer('pe', pe, persistent=False)
|
|
73
73
|
|
|
74
74
|
def forward(self, x: torch.Tensor, positions: torch.Tensor = None, start_pos: int = 0) -> torch.Tensor:
|
|
75
75
|
'''
|
|
@@ -132,8 +132,8 @@ class BasicRotaryEmbedding(BasicEmbedding):
|
|
|
132
132
|
|
|
133
133
|
emb = torch.cat((freqs, freqs), dim=-1)
|
|
134
134
|
|
|
135
|
-
self.register_buffer('cos_cached', emb.cos())
|
|
136
|
-
self.register_buffer('sin_cached', emb.sin())
|
|
135
|
+
self.register_buffer('cos_cached', emb.cos(), persistent=False)
|
|
136
|
+
self.register_buffer('sin_cached', emb.sin(), persistent=False)
|
|
137
137
|
|
|
138
138
|
def _rotate_half(self, x: torch.Tensor) -> torch.Tensor:
|
|
139
139
|
'''
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import torch
|
|
2
|
+
import torch.nn as nn
|
|
3
|
+
import torch.nn.functional as F
|
|
4
|
+
|
|
5
|
+
from codon.base import BasicModel
|
|
6
|
+
from codon.ops.attention import AttentionOutput
|
|
7
|
+
from codon.ops.fourier import apply_fourier_mixing
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class MultiHeadFourier(BasicModel):
|
|
11
|
+
'''
|
|
12
|
+
Multi-Head Fourier (MHF) module from 'Caracal: Causal Architecture via Spectral Mixing'.
|
|
13
|
+
Replaces dense Attention with O(L log L) frequency-domain mixing.
|
|
14
|
+
'''
|
|
15
|
+
def __init__(
|
|
16
|
+
self,
|
|
17
|
+
hidden_size: int,
|
|
18
|
+
num_heads: int,
|
|
19
|
+
**kwargs
|
|
20
|
+
):
|
|
21
|
+
super().__init__()
|
|
22
|
+
|
|
23
|
+
assert hidden_size % num_heads == 0, 'hidden_size must be divisible by num_heads'
|
|
24
|
+
|
|
25
|
+
self.d_model = hidden_size
|
|
26
|
+
self.n_heads = num_heads
|
|
27
|
+
self.d_head = hidden_size // num_heads
|
|
28
|
+
|
|
29
|
+
self.pre_conv = nn.Conv1d(
|
|
30
|
+
in_channels=self.d_model,
|
|
31
|
+
out_channels=self.d_model,
|
|
32
|
+
kernel_size=3,
|
|
33
|
+
groups=self.d_model,
|
|
34
|
+
bias=False
|
|
35
|
+
)
|
|
36
|
+
self.ln = nn.LayerNorm(self.d_model)
|
|
37
|
+
self.silu = nn.SiLU()
|
|
38
|
+
|
|
39
|
+
self.W_V = nn.Linear(self.d_model, self.d_model)
|
|
40
|
+
self.W_G1 = nn.Linear(self.d_model, self.d_model)
|
|
41
|
+
self.W_G2 = nn.Conv1d(
|
|
42
|
+
in_channels=self.d_model,
|
|
43
|
+
out_channels=self.d_model,
|
|
44
|
+
kernel_size=1,
|
|
45
|
+
groups=self.n_heads
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
self.linear = nn.Linear(self.d_model, self.d_model)
|
|
49
|
+
self.linear.NEED_SCALE_INIT = 1
|
|
50
|
+
|
|
51
|
+
def forward(
|
|
52
|
+
self,
|
|
53
|
+
hidden_states: torch.Tensor,
|
|
54
|
+
use_cache: bool = False,
|
|
55
|
+
past_key_value: tuple = None,
|
|
56
|
+
**kwargs
|
|
57
|
+
) -> AttentionOutput:
|
|
58
|
+
|
|
59
|
+
batch_size, seq_len, _ = hidden_states.size()
|
|
60
|
+
|
|
61
|
+
x_permuted = hidden_states.permute(0, 2, 1) # [B, D, L]
|
|
62
|
+
|
|
63
|
+
if past_key_value is not None:
|
|
64
|
+
conv_state, v_cache, g_cache = past_key_value
|
|
65
|
+
x_padded = torch.cat([conv_state, x_permuted], dim=2)
|
|
66
|
+
x = self.pre_conv(x_padded).permute(0, 2, 1) # [B, 1, D]
|
|
67
|
+
|
|
68
|
+
new_conv_state = x_padded[:, :, 1:]
|
|
69
|
+
else:
|
|
70
|
+
padding = self.pre_conv.kernel_size[0] - 1
|
|
71
|
+
x_padded = F.pad(x_permuted, (padding, 0))
|
|
72
|
+
x = self.pre_conv(x_padded).permute(0, 2, 1) # [B, L, D]
|
|
73
|
+
|
|
74
|
+
new_conv_state = x_padded[:, :, -padding:] if use_cache else None
|
|
75
|
+
|
|
76
|
+
x_norm = self.ln(x)
|
|
77
|
+
|
|
78
|
+
x_v = self.W_V(x_norm).reshape(batch_size, seq_len, self.n_heads, self.d_head).transpose(1, 2)
|
|
79
|
+
|
|
80
|
+
x_g = self.W_G1(x_norm).transpose(1, 2)
|
|
81
|
+
x_g = self.W_G2(self.silu(x_g)).transpose(1, 2)
|
|
82
|
+
x_g = x_g.reshape(batch_size, seq_len, self.n_heads, self.d_head).transpose(1, 2)
|
|
83
|
+
|
|
84
|
+
if past_key_value is not None:
|
|
85
|
+
new_v_cache = torch.cat([v_cache, x_v], dim=2)
|
|
86
|
+
new_g_cache = torch.cat([g_cache, x_g], dim=2)
|
|
87
|
+
|
|
88
|
+
g_flipped = torch.flip(new_g_cache, dims=[2])
|
|
89
|
+
|
|
90
|
+
x_mixed = torch.sum(new_v_cache * g_flipped, dim=2, keepdim=True)
|
|
91
|
+
else:
|
|
92
|
+
x_mixed = apply_fourier_mixing(x_v, x_g, seq_len)
|
|
93
|
+
|
|
94
|
+
new_v_cache = x_v if use_cache else None
|
|
95
|
+
new_g_cache = x_g if use_cache else None
|
|
96
|
+
|
|
97
|
+
x_mixed = x_mixed.transpose(1, 2).contiguous().reshape(batch_size, seq_len, self.d_model)
|
|
98
|
+
output = self.linear(x_mixed)
|
|
99
|
+
|
|
100
|
+
current_key_value = (new_conv_state, new_v_cache, new_g_cache) if use_cache else None
|
|
101
|
+
|
|
102
|
+
return AttentionOutput(
|
|
103
|
+
output=output,
|
|
104
|
+
attention_weights=None,
|
|
105
|
+
past_key_value=current_key_value
|
|
106
|
+
)
|
|
@@ -86,3 +86,41 @@ class MLP(BasicModel):
|
|
|
86
86
|
x = self.dropout(x)
|
|
87
87
|
x = self.fc2(x)
|
|
88
88
|
return x
|
|
89
|
+
|
|
90
|
+
@staticmethod
|
|
91
|
+
def SwiGLU(
|
|
92
|
+
in_features: int,
|
|
93
|
+
hidden_features: int = None,
|
|
94
|
+
out_features: int = None,
|
|
95
|
+
bias: bool = False,
|
|
96
|
+
dropout: float = 0.0,
|
|
97
|
+
) -> 'MLP':
|
|
98
|
+
'''
|
|
99
|
+
Factory method to create a SwiGLU MLP module.
|
|
100
|
+
|
|
101
|
+
SwiGLU formulation:
|
|
102
|
+
output = down_proj(SiLU(gate_proj(x)) * up_proj(x))
|
|
103
|
+
|
|
104
|
+
Args:
|
|
105
|
+
in_features (int): Input dimension.
|
|
106
|
+
hidden_features (int): Intermediate dimension (gate & up proj).
|
|
107
|
+
out_features (int, optional): Output dimension. Defaults to in_features.
|
|
108
|
+
bias (bool, optional): Whether to use bias. LLMs typically set False. Defaults to False.
|
|
109
|
+
dropout (float, optional): Dropout rate. Usually 0.0 for SwiGLU. Defaults to 0.0.
|
|
110
|
+
|
|
111
|
+
Returns:
|
|
112
|
+
MLP: Configured SwiGLU module.
|
|
113
|
+
'''
|
|
114
|
+
if hidden_features is None:
|
|
115
|
+
h = int(in_features * 8 / 3)
|
|
116
|
+
hidden_features = (h + 127) // 128 * 128
|
|
117
|
+
|
|
118
|
+
return MLP(
|
|
119
|
+
in_features=in_features,
|
|
120
|
+
hidden_features=hidden_features,
|
|
121
|
+
out_features=out_features,
|
|
122
|
+
bias=bias,
|
|
123
|
+
use_gate=True,
|
|
124
|
+
dropout=dropout,
|
|
125
|
+
act_layer='silu'
|
|
126
|
+
)
|
|
@@ -5,6 +5,7 @@ from typing import Union, Optional, Tuple
|
|
|
5
5
|
from codon.utils.safecode import safecode
|
|
6
6
|
from codon.block.embedding import BasicEmbedding
|
|
7
7
|
from codon.block.attention import MultiHeadAttention, AttentionOutput
|
|
8
|
+
from codon.block.fourier import MultiHeadFourier
|
|
8
9
|
from codon.block.mlp import MLP
|
|
9
10
|
from codon.block.moe import MoE, MoEOutput
|
|
10
11
|
|
|
@@ -75,6 +76,8 @@ class _TransformerDecoder(BasicModel):
|
|
|
75
76
|
use_qk_norm=True,
|
|
76
77
|
use_attn_gate=False,
|
|
77
78
|
dropout=0.1,
|
|
79
|
+
attn_type: str = 'multihead',
|
|
80
|
+
attn_bias: bool=False,
|
|
78
81
|
idx: Union[int, str] = None
|
|
79
82
|
):
|
|
80
83
|
'''
|
|
@@ -97,17 +100,32 @@ class _TransformerDecoder(BasicModel):
|
|
|
97
100
|
self.num_kv_heads = num_kv_heads
|
|
98
101
|
self.use_qk_norm = use_qk_norm
|
|
99
102
|
self.use_attn_gate = use_attn_gate
|
|
103
|
+
self.attn_bias = attn_bias
|
|
104
|
+
self.attn_type = attn_type.lower()
|
|
100
105
|
|
|
101
106
|
self.attn_norm = nn.RMSNorm(model_dim)
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
107
|
+
|
|
108
|
+
if self.attn_type in ['multihead', 'mha']:
|
|
109
|
+
self.attn = MultiHeadAttention(
|
|
110
|
+
hidden_size=model_dim,
|
|
111
|
+
num_heads=num_heads,
|
|
112
|
+
num_kv_heads=num_kv_heads,
|
|
113
|
+
use_qk_norm=use_qk_norm,
|
|
114
|
+
use_gate=use_attn_gate,
|
|
115
|
+
dropout=dropout,
|
|
116
|
+
is_causal=True,
|
|
117
|
+
bias=attn_bias
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
elif self.attn_type in ['fourier', 'mhf']:
|
|
121
|
+
self.attn = MultiHeadFourier(
|
|
122
|
+
hidden_size=model_dim,
|
|
123
|
+
num_heads=num_heads
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
else:
|
|
127
|
+
raise ValueError(f"Unsupported attn_type: {attn_type}. Choose from 'multihead', 'linear', or 'gated_linear'.")
|
|
128
|
+
|
|
111
129
|
self.fn_norm = nn.RMSNorm(model_dim)
|
|
112
130
|
self.dropout = nn.Dropout(dropout)
|
|
113
131
|
|
|
@@ -228,7 +246,11 @@ class TransformerDenseDecoder(_TransformerDecoder):
|
|
|
228
246
|
use_mlp_gate: bool = False,
|
|
229
247
|
use_qk_norm: bool = True,
|
|
230
248
|
use_attn_gate: bool = False,
|
|
249
|
+
attn_type: str = 'multihead',
|
|
250
|
+
use_swiglu: bool = False,
|
|
231
251
|
dropout: float = 0.1,
|
|
252
|
+
attn_bias: bool=False,
|
|
253
|
+
mlp_bias: bool=False,
|
|
232
254
|
idx: Union[int, str] = None
|
|
233
255
|
):
|
|
234
256
|
'''
|
|
@@ -252,15 +274,18 @@ class TransformerDenseDecoder(_TransformerDecoder):
|
|
|
252
274
|
use_qk_norm=use_qk_norm,
|
|
253
275
|
use_attn_gate=use_attn_gate,
|
|
254
276
|
dropout=dropout,
|
|
255
|
-
|
|
277
|
+
attn_type=attn_type,
|
|
278
|
+
idx=idx,
|
|
279
|
+
attn_bias=attn_bias
|
|
256
280
|
)
|
|
257
281
|
self.mlp = MLP(
|
|
258
282
|
in_features=model_dim,
|
|
259
283
|
hidden_features=int(model_dim * mlp_ratio),
|
|
260
284
|
out_features=model_dim,
|
|
261
285
|
use_gate=use_mlp_gate,
|
|
262
|
-
dropout=dropout
|
|
263
|
-
|
|
286
|
+
dropout=dropout,
|
|
287
|
+
bias=mlp_bias
|
|
288
|
+
) if not use_swiglu else MLP.SwiGLU(model_dim)
|
|
264
289
|
|
|
265
290
|
def flow(self, x: torch.Tensor) -> FlowOutput:
|
|
266
291
|
'''
|
|
@@ -294,7 +319,9 @@ class TransformerMoEDecoder(_TransformerDecoder):
|
|
|
294
319
|
use_expert_gate: bool = False,
|
|
295
320
|
use_qk_norm: bool = True,
|
|
296
321
|
use_attn_gate: bool = False,
|
|
322
|
+
attn_type: str = 'multihead',
|
|
297
323
|
dropout: float = 0.1,
|
|
324
|
+
attn_bias: bool=False,
|
|
298
325
|
idx: Union[int, str] = None
|
|
299
326
|
):
|
|
300
327
|
'''
|
|
@@ -321,7 +348,9 @@ class TransformerMoEDecoder(_TransformerDecoder):
|
|
|
321
348
|
use_qk_norm=use_qk_norm,
|
|
322
349
|
use_attn_gate=use_attn_gate,
|
|
323
350
|
dropout=dropout,
|
|
324
|
-
|
|
351
|
+
attn_type=attn_type,
|
|
352
|
+
idx=idx,
|
|
353
|
+
attn_bias=attn_bias
|
|
325
354
|
)
|
|
326
355
|
self.moe = MoE(
|
|
327
356
|
model_dim=model_dim,
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
import os
|
|
3
|
+
|
|
4
|
+
from codon.dev.hash import hash_target
|
|
5
|
+
from codon.dev.clear import clear_pycache
|
|
6
|
+
|
|
7
|
+
def handle_hash(args):
|
|
8
|
+
'''处理 codon hash 命令'''
|
|
9
|
+
try:
|
|
10
|
+
results = hash_target(args.filename_or_dirname)
|
|
11
|
+
for path, md5_val in results.items():
|
|
12
|
+
print(f'{md5_val} {path}')
|
|
13
|
+
except ValueError as e:
|
|
14
|
+
print(e)
|
|
15
|
+
except Exception as e:
|
|
16
|
+
print(f'发生意外错误: {e}')
|
|
17
|
+
|
|
18
|
+
def handle_clear(args):
|
|
19
|
+
'''处理 codon clear 命令'''
|
|
20
|
+
if not os.path.isdir(args.target_path):
|
|
21
|
+
print(f'错误: 目录不存在 - {args.target_path}')
|
|
22
|
+
return
|
|
23
|
+
clear_pycache(args.target_path)
|
|
24
|
+
|
|
25
|
+
def main():
|
|
26
|
+
parser = argparse.ArgumentParser(
|
|
27
|
+
prog='codon',
|
|
28
|
+
description='Codon Model 统一命令行工具箱'
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
subparsers = parser.add_subparsers(title='可用子命令', dest='command', required=True)
|
|
32
|
+
|
|
33
|
+
# codon hash
|
|
34
|
+
parser_hash = subparsers.add_parser('hash', help='计算文件或目录的 MD5 值')
|
|
35
|
+
parser_hash.add_argument('filename_or_dirname', type=str, help='需要计算 MD5 的文件或文件夹路径')
|
|
36
|
+
parser_hash.set_defaults(func=handle_hash)
|
|
37
|
+
|
|
38
|
+
# codon clear
|
|
39
|
+
parser_clear = subparsers.add_parser('clear', help='递归清理目录下的所有 __pycache__ 缓存')
|
|
40
|
+
parser_clear.add_argument('target_path', type=str, nargs='?', default='.',
|
|
41
|
+
help='要清理的根目录路径 (默认为当前所在目录)')
|
|
42
|
+
parser_clear.set_defaults(func=handle_clear)
|
|
43
|
+
|
|
44
|
+
args = parser.parse_args()
|
|
45
|
+
args.func(args)
|
|
46
|
+
|
|
47
|
+
if __name__ == '__main__':
|
|
48
|
+
main()
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import shutil
|
|
3
|
+
import argparse
|
|
4
|
+
|
|
5
|
+
def clear_pycache(target_dir: str):
|
|
6
|
+
'''
|
|
7
|
+
递归遍历并删除目标路径下的所有 __pycache__ 文件夹。
|
|
8
|
+
|
|
9
|
+
参数:
|
|
10
|
+
target_dir (str): 需要清理的根目录路径。
|
|
11
|
+
'''
|
|
12
|
+
deleted_count = 0
|
|
13
|
+
target_dir = os.path.abspath(target_dir)
|
|
14
|
+
|
|
15
|
+
print(f'开始清理 {target_dir} 下的 __pycache__ ...')
|
|
16
|
+
|
|
17
|
+
for root, dirs, files in os.walk(target_dir):
|
|
18
|
+
if '__pycache__' in dirs:
|
|
19
|
+
cache_dir = os.path.join(root, '__pycache__')
|
|
20
|
+
try:
|
|
21
|
+
shutil.rmtree(cache_dir)
|
|
22
|
+
print(f'Deleted: {cache_dir}')
|
|
23
|
+
deleted_count += 1
|
|
24
|
+
|
|
25
|
+
dirs.remove('__pycache__')
|
|
26
|
+
except Exception as e:
|
|
27
|
+
print(f'Error deleting {cache_dir}: {e}')
|
|
28
|
+
|
|
29
|
+
print(f'清理完成。共移除了 {deleted_count} 个 __pycache__ 缓存目录。')
|
|
30
|
+
|
|
31
|
+
def main():
|
|
32
|
+
parser = argparse.ArgumentParser(description='递归清理目标路径下的所有 __pycache__ 文件夹')
|
|
33
|
+
parser.add_argument('target_path', type=str, nargs='?', default='.',
|
|
34
|
+
help='要清理的根目录路径 (默认为当前所在目录)')
|
|
35
|
+
args = parser.parse_args()
|
|
36
|
+
|
|
37
|
+
if not os.path.isdir(args.target_path):
|
|
38
|
+
print(f'错误: 目录不存在 - {args.target_path}')
|
|
39
|
+
return
|
|
40
|
+
|
|
41
|
+
clear_pycache(args.target_path)
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import hashlib
|
|
2
|
+
import os
|
|
3
|
+
import argparse
|
|
4
|
+
from typing import Dict
|
|
5
|
+
|
|
6
|
+
from tqdm import tqdm
|
|
7
|
+
|
|
8
|
+
def calculate_md5(file_path: str, chunk_size: int = 8192) -> str:
|
|
9
|
+
'''
|
|
10
|
+
计算单个文件的 MD5 摘要,带有阅后即焚的进度条。
|
|
11
|
+
'''
|
|
12
|
+
md5_hash = hashlib.md5()
|
|
13
|
+
try:
|
|
14
|
+
total_size = os.path.getsize(file_path)
|
|
15
|
+
with tqdm(total=total_size, unit='B', unit_scale=True, unit_divisor=1024,
|
|
16
|
+
desc=f'Hashing {os.path.basename(file_path)}', leave=False) as pbar:
|
|
17
|
+
with open(file_path, 'rb') as f:
|
|
18
|
+
for chunk in iter(lambda: f.read(chunk_size), b''):
|
|
19
|
+
md5_hash.update(chunk)
|
|
20
|
+
pbar.update(len(chunk))
|
|
21
|
+
|
|
22
|
+
return md5_hash.hexdigest()
|
|
23
|
+
except Exception as e:
|
|
24
|
+
return f'Error: {e}'
|
|
25
|
+
|
|
26
|
+
def hash_target(target_path: str) -> Dict[str, str]:
|
|
27
|
+
results = {}
|
|
28
|
+
if os.path.isfile(target_path):
|
|
29
|
+
results[target_path] = calculate_md5(target_path)
|
|
30
|
+
elif os.path.isdir(target_path):
|
|
31
|
+
for root, _, files in os.walk(target_path):
|
|
32
|
+
for file in files:
|
|
33
|
+
file_path = os.path.join(root, file)
|
|
34
|
+
results[file_path] = calculate_md5(file_path)
|
|
35
|
+
else:
|
|
36
|
+
raise ValueError(f'无效的路径: {target_path}')
|
|
37
|
+
|
|
38
|
+
return results
|
|
39
|
+
|
|
40
|
+
def main():
|
|
41
|
+
parser = argparse.ArgumentParser(description='计算文件或目录下所有文件的 MD5 值')
|
|
42
|
+
parser.add_argument('target', type=str, help='需要计算 MD5 的文件或文件夹路径')
|
|
43
|
+
args = parser.parse_args()
|
|
44
|
+
|
|
45
|
+
try:
|
|
46
|
+
results = hash_target(args.target)
|
|
47
|
+
for path, md5_val in results.items():
|
|
48
|
+
path = path.replace('\\', '/')
|
|
49
|
+
print(f'{md5_val} ➜ {path}')
|
|
50
|
+
except ValueError as e:
|
|
51
|
+
print(e)
|
|
52
|
+
|
|
53
|
+
if __name__ == '__main__':
|
|
54
|
+
main()
|