codon-model 0.0.5a4__tar.gz → 0.0.6a2__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.
Files changed (108) hide show
  1. {codon_model-0.0.5a4/codon_model.egg-info → codon_model-0.0.6a2}/PKG-INFO +8 -2
  2. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/__init__.py +1 -1
  3. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/base.py +18 -7
  4. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/block/__init__.py +4 -1
  5. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/block/attention.py +178 -358
  6. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/block/embedding.py +368 -350
  7. codon_model-0.0.6a2/codon/block/fourier.py +106 -0
  8. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/block/transformer.py +6 -21
  9. codon_model-0.0.6a2/codon/builtins/download.py +129 -0
  10. codon_model-0.0.6a2/codon/builtins/mixins/remote.py +142 -0
  11. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/cli.py +8 -8
  12. codon_model-0.0.5a4/codon/dev/clean.py → codon_model-0.0.6a2/codon/dev/clear.py +2 -2
  13. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/dev/hash.py +2 -1
  14. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/kit/train/__init__.py +3 -1
  15. codon_model-0.0.6a2/codon/kit/train/language.py +123 -0
  16. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/motif/__init__.py +5 -3
  17. codon_model-0.0.6a2/codon/motif/base.py +363 -0
  18. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/motif/motif_a1.py +19 -3
  19. codon_model-0.0.6a2/codon/motif/onnx.py +346 -0
  20. codon_model-0.0.6a2/codon/ops/attention.py +115 -0
  21. codon_model-0.0.6a2/codon/ops/fourier.py +33 -0
  22. codon_model-0.0.6a2/codon/utils/__init__.py +0 -0
  23. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/utils/data/chunked.py +4 -3
  24. codon_model-0.0.6a2/codon/utils/generate.py +112 -0
  25. codon_model-0.0.6a2/codon/utils/layer/__init__.py +0 -0
  26. codon_model-0.0.6a2/codon/utils/onnx.py +39 -0
  27. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/utils/plan.py +10 -7
  28. codon_model-0.0.6a2/codon/utils/service.py +364 -0
  29. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/utils/session.py +103 -10
  30. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/utils/tokens.py +12 -4
  31. {codon_model-0.0.5a4 → codon_model-0.0.6a2/codon_model.egg-info}/PKG-INFO +8 -2
  32. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon_model.egg-info/SOURCES.txt +12 -1
  33. codon_model-0.0.6a2/codon_model.egg-info/requires.txt +15 -0
  34. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/setup.py +1 -1
  35. codon_model-0.0.5a4/codon/motif/base.py +0 -227
  36. codon_model-0.0.5a4/codon/ops/attention.py +0 -216
  37. codon_model-0.0.5a4/codon_model.egg-info/requires.txt +0 -9
  38. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/LICENSE +0 -0
  39. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/block/bio/__init__.py +0 -0
  40. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/block/bio/hebian.py +0 -0
  41. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/block/bio/predictive.py +0 -0
  42. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/block/codebook.py +0 -0
  43. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/block/conv.py +0 -0
  44. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/block/film.py +0 -0
  45. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/block/fusion.py +0 -0
  46. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/block/lora.py +0 -0
  47. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/block/manifold.py +0 -0
  48. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/block/mlp.py +0 -0
  49. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/block/moe.py +0 -0
  50. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/block/pixelshuffle.py +0 -0
  51. {codon_model-0.0.5a4/codon/dev → codon_model-0.0.6a2/codon/builtins}/__init__.py +0 -0
  52. {codon_model-0.0.5a4/codon/exp → codon_model-0.0.6a2/codon/builtins/mixins}/__init__.py +0 -0
  53. {codon_model-0.0.5a4/codon/exp/block → codon_model-0.0.6a2/codon/dev}/__init__.py +0 -0
  54. {codon_model-0.0.5a4/codon/exp/ops → codon_model-0.0.6a2/codon/exp}/__init__.py +0 -0
  55. {codon_model-0.0.5a4/codon/kit → codon_model-0.0.6a2/codon/exp/block}/__init__.py +0 -0
  56. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/exp/block/bio.py +0 -0
  57. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/exp/block/manifold.py +0 -0
  58. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/exp/block/moe.py +0 -0
  59. {codon_model-0.0.5a4/codon/utils → codon_model-0.0.6a2/codon/exp/ops}/__init__.py +0 -0
  60. {codon_model-0.0.5a4/codon/utils/layer → codon_model-0.0.6a2/codon/kit}/__init__.py +0 -0
  61. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/kit/train/vision.py +0 -0
  62. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/model/__init__.py +0 -0
  63. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/model/patch_disc.py +0 -0
  64. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/model/resnet.py +0 -0
  65. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/model/tcn.py +0 -0
  66. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/motif/data/__init__.py +0 -0
  67. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/motif/data/prev1.py +0 -0
  68. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/motif/data/sft.py +0 -0
  69. /codon_model-0.0.5a4/codon/kit/train/language.py → /codon_model-0.0.6a2/codon/motif/motif_a2.py +0 -0
  70. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/motif/motif_v1.py +0 -0
  71. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/ops/__init__.py +0 -0
  72. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/ops/bio.py +0 -0
  73. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/ops/manifold/__init__.py +0 -0
  74. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/ops/manifold/conv.py +0 -0
  75. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/ops/manifold/linear.py +0 -0
  76. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/ops/pixelshuffle.py +0 -0
  77. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/utils/data/__init__.py +0 -0
  78. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/utils/data/base.py +0 -0
  79. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/utils/data/dataviewer.py +0 -0
  80. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/utils/data/flatdata.py +0 -0
  81. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/utils/data/image.py +0 -0
  82. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/utils/eval/__init__.py +0 -0
  83. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/utils/eval/activation.py +0 -0
  84. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/utils/eval/base.py +0 -0
  85. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/utils/eval/boundary.py +0 -0
  86. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/utils/eval/cka.py +0 -0
  87. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/utils/eval/confusion.py +0 -0
  88. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/utils/eval/gradcam.py +0 -0
  89. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/utils/eval/layer_rsa.py +0 -0
  90. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/utils/eval/rsa.py +0 -0
  91. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/utils/eval/selectivity.py +0 -0
  92. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/utils/eval/similarity.py +0 -0
  93. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/utils/eval/tsne.py +0 -0
  94. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/utils/info.py +0 -0
  95. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/utils/layer/lora.py +0 -0
  96. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/utils/layer/manifold.py +0 -0
  97. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/utils/lifecycle.py +0 -0
  98. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/utils/mask.py +0 -0
  99. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/utils/safecode.py +0 -0
  100. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/utils/seed.py +0 -0
  101. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/utils/split.py +0 -0
  102. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/utils/theta.py +0 -0
  103. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon/utils/transforms.py +0 -0
  104. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon_model.egg-info/dependency_links.txt +0 -0
  105. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon_model.egg-info/entry_points.txt +0 -0
  106. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/codon_model.egg-info/top_level.txt +0 -0
  107. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/setup.cfg +0 -0
  108. {codon_model-0.0.5a4 → codon_model-0.0.6a2}/test/test_motifv1_train.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codon-model
3
- Version: 0.0.5a4
3
+ Version: 0.0.6a2
4
4
  Summary: Codon model package
5
5
  Author: CodonTeam
6
6
  Requires-Python: >=3.8
@@ -13,7 +13,13 @@ Requires-Dist: pandas
13
13
  Requires-Dist: numpy
14
14
  Requires-Dist: pyarrow
15
15
  Requires-Dist: pillow
16
- Requires-Dist: flash-linear-attention
16
+ Requires-Dist: fastapi
17
+ Requires-Dist: uvicorn
18
+ Requires-Dist: onnx
19
+ Requires-Dist: onnxsim
20
+ Requires-Dist: onnxscript
21
+ Requires-Dist: onnx-simplifier
22
+ Requires-Dist: onnxconverter_common
17
23
  Dynamic: author
18
24
  Dynamic: license-file
19
25
  Dynamic: requires-dist
@@ -1,5 +1,5 @@
1
1
  from typing import Optional
2
2
 
3
- __version__ = '0.0.5a4'
3
+ __version__ = '0.0.6a2'
4
4
 
5
5
  __seed__: Optional[int] = None
@@ -2,14 +2,18 @@ import torch
2
2
  import torch.nn as nn
3
3
  import torch.nn.functional as F
4
4
 
5
- from typing import Callable, Any, Iterator, Union
5
+ from typing import Callable, Any, Iterator, Union, TypeVar
6
6
 
7
7
  from safetensors.torch import save_model as safe_save_model
8
8
  from safetensors.torch import save_file as safe_save_file
9
9
  from safetensors.torch import load_model as safe_load_model
10
10
 
11
+ from codon.builtins.mixins.remote import RemoteResourceMixin
11
12
 
12
- class BasicModel(nn.Module):
13
+
14
+ TBasicModel = TypeVar('TBasicModel', bound='BasicModel')
15
+
16
+ class BasicModel(nn.Module, RemoteResourceMixin):
13
17
  '''
14
18
  Base class for all models, providing common functionality like gradient checkpointing and parameter counting.
15
19
  '''
@@ -62,6 +66,10 @@ class BasicModel(nn.Module):
62
66
  )
63
67
  return function(*args, **kwargs)
64
68
 
69
+ @property
70
+ def trainable_params(self) -> Iterator[torch.nn.Parameter]:
71
+ return self.get_params(trainable_only=True)
72
+
65
73
  def get_params(self, trainable_only:bool=False) -> Iterator[torch.nn.Parameter]:
66
74
  '''
67
75
  Get an iterator over the model parameters.
@@ -134,7 +142,7 @@ class BasicModel(nn.Module):
134
142
 
135
143
  return total
136
144
 
137
- def load_pretrained(self, path: str, strict: bool = False) -> 'BasicModel':
145
+ def load_pretrained(self: TBasicModel, path: str, strict: bool = False) -> TBasicModel:
138
146
  '''
139
147
  Load a pretrained model from a file.
140
148
  Args:
@@ -160,14 +168,14 @@ class BasicModel(nn.Module):
160
168
  return self
161
169
 
162
170
  def save_pretrained(
163
- self,
171
+ self: TBasicModel,
164
172
  path: str,
165
173
  trainable_only: bool = False,
166
174
  include_buffer: bool = True,
167
175
  exclude_modules: list[Union[type, nn.Module]] = None,
168
176
  only: list[str] = None,
169
177
  exclude: list[str] = None
170
- ) -> 'BasicModel':
178
+ ) -> TBasicModel:
171
179
  '''
172
180
  Save the model to a file.
173
181
 
@@ -236,7 +244,7 @@ class BasicModel(nn.Module):
236
244
 
237
245
  return self
238
246
 
239
- def freeze(self) -> 'BasicModel':
247
+ def freeze(self: TBasicModel) -> TBasicModel:
240
248
  '''
241
249
  Freeze all parameters in the model by setting requires_grad to False.
242
250
 
@@ -247,7 +255,7 @@ class BasicModel(nn.Module):
247
255
  param.requires_grad = False
248
256
  return self
249
257
 
250
- def unfreeze(self) -> 'BasicModel':
258
+ def unfreeze(self: TBasicModel) -> TBasicModel:
251
259
  '''
252
260
  Unfreeze all parameters in the model by setting requires_grad to True.
253
261
 
@@ -257,3 +265,6 @@ class BasicModel(nn.Module):
257
265
  for param in self.parameters():
258
266
  param.requires_grad = True
259
267
  return self
268
+
269
+ def compile(self: TBasicModel) -> TBasicModel:
270
+ return torch.compile(self)
@@ -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,358 +1,178 @@
1
- from codon.base import *
2
- from codon.block.embedding import BasicEmbedding
3
- from codon.ops.attention import (
4
- AttentionOutput,
5
- apply_attention, chunk_linear_attn, chunk_gla
6
- )
7
-
8
-
9
- class MultiHeadAttention(BasicModel):
10
- '''
11
- Multi-Head Attention module.
12
- Supports Grouped Query Attention (GQA), QK Normalization, and Gating mechanisms.
13
-
14
- Attributes:
15
- q_proj (nn.Linear): Linear layer for query projection.
16
- k_proj (nn.Linear): Linear layer for key projection.
17
- v_proj (nn.Linear): Linear layer for value projection.
18
- o_proj (nn.Linear): Linear layer for output projection.
19
- q_norm (nn.RMSNorm, optional): Normalization layer for queries.
20
- k_norm (nn.RMSNorm, optional): Normalization layer for keys.
21
- g_proj (nn.Linear, optional): Linear layer for gating mechanism.
22
- '''
23
- def __init__(
24
- self,
25
- hidden_size,
26
- num_heads,
27
- num_kv_heads=None,
28
- use_qk_norm=True,
29
- use_gate=False,
30
- dropout=0.1,
31
- bias: bool=True,
32
- is_causal=True
33
- ):
34
- '''
35
- Initialize the Multi-Head Attention module.
36
-
37
- Args:
38
- hidden_size (int): Size of the hidden layer.
39
- num_heads (int): Number of attention heads.
40
- num_kv_heads (int, optional): Number of key/value heads for GQA.
41
- If None, defaults to num_heads.
42
- use_qk_norm (bool, optional): Whether to apply RMSNorm to queries and keys.
43
- Defaults to True.
44
- use_gate (bool, optional): Whether to apply a gating mechanism. Defaults to False.
45
- dropout (float, optional): Dropout probability. Defaults to 0.1.
46
- is_causal (bool, optional): Whether to apply a causal mask.
47
- Defaults to True (for Decoder architectures).
48
- '''
49
- super(MultiHeadAttention, self).__init__()
50
-
51
- if num_kv_heads is None: num_kv_heads = num_heads
52
-
53
- assert hidden_size % num_heads == 0
54
- assert num_heads % num_kv_heads == 0
55
-
56
- self.hidden_size = hidden_size
57
- self.num_heads = num_heads
58
- self.num_kv_heads = num_kv_heads
59
- self.num_kv_queries = num_heads // num_kv_heads
60
- self.head_dim = hidden_size // num_heads
61
- self.kv_dim = self.num_kv_heads * self.head_dim
62
- self.use_qk_norm = use_qk_norm
63
- self.use_gate = use_gate
64
- self.dropout = dropout
65
- self.is_causal = is_causal
66
-
67
- if use_qk_norm:
68
- self.q_norm = nn.RMSNorm(self.head_dim)
69
- self.k_norm = nn.RMSNorm(self.head_dim)
70
-
71
- if use_gate:
72
- self.g_proj = nn.Linear(hidden_size, hidden_size, bias=bias)
73
-
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)
78
-
79
- def forward(
80
- self,
81
- hidden_states: torch.Tensor,
82
- kv_states: torch.Tensor = None,
83
- attention_mask: torch.Tensor = None,
84
- output_attentions: bool = False,
85
- position_emb: BasicEmbedding = None,
86
- embedding_start: int = 0,
87
- embedding_pos: torch.Tensor = None,
88
- past_key_value: tuple[torch.Tensor, torch.Tensor] = None,
89
- use_cache: bool = False
90
- ) -> AttentionOutput:
91
- '''
92
- Perform forward pass of Multi-Head Attention.
93
-
94
- Args:
95
- hidden_states (torch.Tensor): Input hidden states.
96
- kv_states (torch.Tensor, optional): Hidden states for keys/values.
97
- If None, uses hidden_states. Defaults to None.
98
- attention_mask (torch.Tensor, optional): Attention mask.
99
- Defaults to None.
100
- output_attentions (bool, optional): Whether to output attention weights.
101
- Defaults to False.
102
- position_emb (BasicEmbedding, optional): Positional embedding module.
103
- Defaults to None.
104
- embedding_start (int, optional): Starting position for embedding. Defaults to 0.
105
- embedding_pos (torch.Tensor, optional): Explicit position indices for positional embedding.
106
- Defaults to None.
107
- past_key_value (tuple[torch.Tensor, torch.Tensor], optional): Past key-value cache.
108
- Defaults to None.
109
- use_cache (bool, optional): Whether to use KV cache. Defaults to False.
110
-
111
- Returns:
112
- AttentionOutput: Object containing output, attention weights, and KV cache.
113
- '''
114
-
115
- if kv_states is None:
116
- kv_states = hidden_states
117
-
118
- batch_size, q_len, _ = hidden_states.shape
119
- kv_len_input = kv_states.shape[1]
120
-
121
- if self.use_gate:
122
- G = torch.sigmoid(self.g_proj(hidden_states))
123
-
124
- Q = self.q_proj(hidden_states)
125
- K = self.k_proj(kv_states)
126
- V = self.v_proj(kv_states)
127
-
128
- Q = Q.view(batch_size, q_len, self.num_heads, self.head_dim).transpose(1, 2)
129
- K = K.view(batch_size, kv_len_input, self.num_kv_heads, self.head_dim).transpose(1, 2)
130
- V = V.view(batch_size, kv_len_input, self.num_kv_heads, self.head_dim).transpose(1, 2)
131
-
132
- if self.use_qk_norm:
133
- Q = self.q_norm(Q)
134
- K = self.k_norm(K)
135
-
136
- if position_emb is not None:
137
- Q = position_emb(Q, start_pos=embedding_start, positions=embedding_pos)
138
- K = position_emb(K, start_pos=embedding_start, positions=embedding_pos)
139
-
140
- current_key_value = None
141
- if use_cache:
142
- if past_key_value is not None:
143
- past_k, past_v = past_key_value
144
- K = torch.cat((past_k, K), dim=2)
145
- V = torch.cat((past_v, V), dim=2)
146
- current_key_value = (K, V)
147
-
148
- kv_seq_len_total = K.shape[2]
149
-
150
- if self.num_kv_queries > 1:
151
- # [B, H_kv, 1, L, D] -> [B, H_kv, G, L, D]
152
- K = K[:, :, None, :, :].expand(batch_size, self.num_kv_heads, self.num_kv_queries, kv_seq_len_total, self.head_dim)
153
- V = V[:, :, None, :, :].expand(batch_size, self.num_kv_heads, self.num_kv_queries, kv_seq_len_total, self.head_dim)
154
-
155
- K = K.reshape(batch_size, self.num_heads, kv_seq_len_total, self.head_dim)
156
- V = V.reshape(batch_size, self.num_heads, kv_seq_len_total, self.head_dim)
157
-
158
- attn_output = apply_attention(
159
- Q, K, V,
160
- attention_mask=attention_mask,
161
- output_attentions=output_attentions,
162
- is_causal=self.is_causal,
163
- dropout=self.dropout if self.training else 0.0
164
- )
165
-
166
- output = attn_output.output
167
- attention_weights = attn_output.attention_weights
168
- output = output.transpose(1, 2).contiguous().view(batch_size, q_len, self.hidden_size)
169
- output = self.o_proj(output)
170
-
171
- if self.use_gate: output = output * G
172
-
173
- return AttentionOutput(
174
- output=output,
175
- attention_weights=attention_weights,
176
- past_key_value=current_key_value
177
- )
178
-
179
-
180
- class LinearAttention(BasicModel):
181
- def __init__(self, hidden_size, num_heads, num_kv_heads=None, use_qk_norm=True, use_gate=False, dropout=0.1, is_causal=True, bias: bool=True):
182
- super().__init__()
183
- if num_kv_heads is None: num_kv_heads = num_heads
184
- assert hidden_size % num_heads == 0
185
- assert num_heads % num_kv_heads == 0
186
-
187
- self.hidden_size = hidden_size
188
- self.num_heads = num_heads
189
- self.num_kv_heads = num_kv_heads
190
- self.num_kv_queries = num_heads // num_kv_heads
191
- self.head_dim = hidden_size // num_heads
192
- self.kv_dim = self.num_kv_heads * self.head_dim
193
- self.use_qk_norm = use_qk_norm
194
- self.use_gate = use_gate
195
- self.dropout = dropout
196
- self.is_causal = is_causal
197
-
198
- if use_qk_norm:
199
- self.q_norm = nn.RMSNorm(self.head_dim)
200
- self.k_norm = nn.RMSNorm(self.head_dim)
201
-
202
- if use_gate:
203
- self.g_proj = nn.Linear(hidden_size, hidden_size, bias=bias)
204
-
205
- self.q_proj = nn.Linear(hidden_size, hidden_size, bias=bias)
206
- self.k_proj = nn.Linear(hidden_size, self.kv_dim, bias=bias)
207
- self.v_proj = nn.Linear(hidden_size, self.kv_dim, bias=bias)
208
- self.o_proj = nn.Linear(hidden_size, hidden_size, bias=bias)
209
-
210
- def forward(
211
- self,
212
- hidden_states,
213
- kv_states=None,
214
- position_emb=None,
215
- embedding_start=0,
216
- embedding_pos=None,
217
- past_key_value=None,
218
- use_cache=False
219
- ):
220
- if kv_states is None: kv_states = hidden_states
221
- batch_size, q_len, _ = hidden_states.shape
222
- kv_len = kv_states.shape[1]
223
-
224
- if self.use_gate:
225
- G_out = torch.sigmoid(self.g_proj(hidden_states))
226
-
227
- Q = self.q_proj(hidden_states).view(batch_size, q_len, self.num_heads, self.head_dim).transpose(1, 2)
228
- K = self.k_proj(kv_states).view(batch_size, kv_len, self.num_kv_heads, self.head_dim).transpose(1, 2)
229
- V = self.v_proj(kv_states).view(batch_size, kv_len, self.num_kv_heads, self.head_dim).transpose(1, 2)
230
-
231
- if self.use_qk_norm:
232
- Q, K = self.q_norm(Q), self.k_norm(K)
233
- if position_emb is not None:
234
- Q = position_emb(Q, start_pos=embedding_start, positions=embedding_pos)
235
- K = position_emb(K, start_pos=embedding_start, positions=embedding_pos)
236
-
237
- if self.num_kv_queries > 1:
238
- K = K[:, :, None, :, :].expand(batch_size, self.num_kv_heads, self.num_kv_queries, kv_len, self.head_dim)
239
- V = V[:, :, None, :, :].expand(batch_size, self.num_kv_heads, self.num_kv_queries, kv_len, self.head_dim)
240
- K = K.reshape(batch_size, self.num_heads, kv_len, self.head_dim)
241
- V = V.reshape(batch_size, self.num_heads, kv_len, self.head_dim)
242
-
243
- Q = F.elu(Q, alpha=1.0) + 1.0
244
- K = F.elu(K, alpha=1.0) + 1.0
245
-
246
- Q = Q.contiguous()
247
- K = K.contiguous()
248
- V = V.contiguous()
249
-
250
- scale = self.head_dim ** -0.5
251
- output, current_key_value = chunk_linear_attn(
252
- q=Q,
253
- k=K,
254
- v=V,
255
- scale=scale,
256
- initial_state=past_key_value,
257
- output_final_state=use_cache
258
- )
259
-
260
- output = output.transpose(1, 2).contiguous().view(batch_size, q_len, self.hidden_size)
261
- output = self.o_proj(output)
262
-
263
- if self.use_gate: output = output * G_out
264
-
265
- return AttentionOutput(
266
- output=output,
267
- attention_weights=None,
268
- past_key_value=current_key_value
269
- )
270
-
271
-
272
- class GatedLinearAttention(BasicModel):
273
- def __init__(self, hidden_size, num_heads, num_kv_heads=None, use_qk_norm=True, dropout=0.1, is_causal=True, bias: bool=True):
274
- super().__init__()
275
- if num_kv_heads is None: num_kv_heads = num_heads
276
- assert hidden_size % num_heads == 0
277
- assert num_heads % num_kv_heads == 0
278
-
279
- self.hidden_size = hidden_size
280
- self.num_heads = num_heads
281
- self.num_kv_heads = num_kv_heads
282
- self.num_kv_queries = num_heads // num_kv_heads
283
- self.head_dim = hidden_size // num_heads
284
- self.kv_dim = self.num_kv_heads * self.head_dim
285
- self.use_qk_norm = use_qk_norm
286
- self.dropout = dropout
287
- self.is_causal = is_causal
288
-
289
- if use_qk_norm:
290
- self.q_norm = nn.RMSNorm(self.head_dim)
291
- self.k_norm = nn.RMSNorm(self.head_dim)
292
-
293
- self.q_proj = nn.Linear(hidden_size, hidden_size, bias=bias)
294
- self.k_proj = nn.Linear(hidden_size, self.kv_dim, bias=bias)
295
- self.v_proj = nn.Linear(hidden_size, self.kv_dim, bias=bias)
296
-
297
- self.g_proj = nn.Linear(hidden_size, num_heads, bias=False)
298
- self.o_proj = nn.Linear(hidden_size, hidden_size, bias=bias)
299
-
300
- def forward(
301
- self,
302
- hidden_states,
303
- kv_states=None,
304
- position_emb=None,
305
- embedding_start=0,
306
- embedding_pos=None,
307
- past_key_value=None,
308
- use_cache=False
309
- ):
310
- if kv_states is None: kv_states = hidden_states
311
- batch_size, q_len, _ = hidden_states.shape
312
- kv_len = kv_states.shape[1]
313
-
314
- Q = self.q_proj(hidden_states).view(batch_size, q_len, self.num_heads, self.head_dim).transpose(1, 2)
315
- K = self.k_proj(kv_states).view(batch_size, kv_len, self.num_kv_heads, self.head_dim).transpose(1, 2)
316
- V = self.v_proj(kv_states).view(batch_size, kv_len, self.num_kv_heads, self.head_dim).transpose(1, 2)
317
-
318
- if self.use_qk_norm:
319
- Q, K = self.q_norm(Q), self.k_norm(K)
320
- if position_emb is not None:
321
- Q = position_emb(Q, start_pos=embedding_start, positions=embedding_pos)
322
- K = position_emb(K, start_pos=embedding_start, positions=embedding_pos)
323
-
324
- if self.num_kv_queries > 1:
325
- K = K[:, :, None, :, :].expand(batch_size, self.num_kv_heads, self.num_kv_queries, kv_len, self.head_dim)
326
- V = V[:, :, None, :, :].expand(batch_size, self.num_kv_heads, self.num_kv_queries, kv_len, self.head_dim)
327
- K = K.reshape(batch_size, self.num_heads, kv_len, self.head_dim)
328
- V = V.reshape(batch_size, self.num_heads, kv_len, self.head_dim)
329
-
330
- Q = F.elu(Q, alpha=1.0) + 1.0
331
- K = F.elu(K, alpha=1.0) + 1.0
332
-
333
- Q, K, V = Q.contiguous(), K.contiguous(), V.contiguous()
334
-
335
- gate_logits = self.g_proj(hidden_states)
336
- gate_logits = gate_logits.transpose(1, 2).contiguous()
337
-
338
- log_g = F.logsigmoid(gate_logits)
339
-
340
- scale = self.head_dim ** -0.5
341
- output, current_key_value = chunk_gla(
342
- q=Q,
343
- k=K,
344
- v=V,
345
- g=log_g,
346
- scale=scale,
347
- initial_state=past_key_value,
348
- output_final_state=use_cache
349
- )
350
-
351
- output = output.transpose(1, 2).contiguous().view(batch_size, q_len, self.hidden_size)
352
- output = self.o_proj(output)
353
-
354
- return AttentionOutput(
355
- output=output,
356
- attention_weights=None,
357
- past_key_value=current_key_value
358
- )
1
+ from codon.base import *
2
+ from codon.block.embedding import BasicEmbedding
3
+ from codon.ops.attention import (
4
+ AttentionOutput,
5
+ apply_attention
6
+ )
7
+
8
+
9
+ class MultiHeadAttention(BasicModel):
10
+ '''
11
+ Multi-Head Attention module.
12
+ Supports Grouped Query Attention (GQA), QK Normalization, and Gating mechanisms.
13
+
14
+ Attributes:
15
+ q_proj (nn.Linear): Linear layer for query projection.
16
+ k_proj (nn.Linear): Linear layer for key projection.
17
+ v_proj (nn.Linear): Linear layer for value projection.
18
+ o_proj (nn.Linear): Linear layer for output projection.
19
+ q_norm (nn.RMSNorm, optional): Normalization layer for queries.
20
+ k_norm (nn.RMSNorm, optional): Normalization layer for keys.
21
+ g_proj (nn.Linear, optional): Linear layer for gating mechanism.
22
+ '''
23
+ def __init__(
24
+ self,
25
+ hidden_size,
26
+ num_heads,
27
+ num_kv_heads=None,
28
+ use_qk_norm=True,
29
+ use_gate=False,
30
+ dropout=0.1,
31
+ bias: bool=True,
32
+ is_causal=True
33
+ ):
34
+ '''
35
+ Initialize the Multi-Head Attention module.
36
+
37
+ Args:
38
+ hidden_size (int): Size of the hidden layer.
39
+ num_heads (int): Number of attention heads.
40
+ num_kv_heads (int, optional): Number of key/value heads for GQA.
41
+ If None, defaults to num_heads.
42
+ use_qk_norm (bool, optional): Whether to apply RMSNorm to queries and keys.
43
+ Defaults to True.
44
+ use_gate (bool, optional): Whether to apply a gating mechanism. Defaults to False.
45
+ dropout (float, optional): Dropout probability. Defaults to 0.1.
46
+ is_causal (bool, optional): Whether to apply a causal mask.
47
+ Defaults to True (for Decoder architectures).
48
+ '''
49
+ super(MultiHeadAttention, self).__init__()
50
+
51
+ if num_kv_heads is None: num_kv_heads = num_heads
52
+
53
+ assert hidden_size % num_heads == 0
54
+ assert num_heads % num_kv_heads == 0
55
+
56
+ self.hidden_size = hidden_size
57
+ self.num_heads = num_heads
58
+ self.num_kv_heads = num_kv_heads
59
+ self.num_kv_queries = num_heads // num_kv_heads
60
+ self.head_dim = hidden_size // num_heads
61
+ self.kv_dim = self.num_kv_heads * self.head_dim
62
+ self.use_qk_norm = use_qk_norm
63
+ self.use_gate = use_gate
64
+ self.dropout = dropout
65
+ self.is_causal = is_causal
66
+
67
+ if use_qk_norm:
68
+ self.q_norm = nn.RMSNorm(self.head_dim)
69
+ self.k_norm = nn.RMSNorm(self.head_dim)
70
+
71
+ if use_gate:
72
+ self.g_proj = nn.Linear(hidden_size, hidden_size, bias=bias)
73
+
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)
78
+
79
+ def forward(
80
+ self,
81
+ hidden_states: torch.Tensor,
82
+ kv_states: torch.Tensor = None,
83
+ attention_mask: torch.Tensor = None,
84
+ output_attentions: bool = False,
85
+ position_emb: BasicEmbedding = None,
86
+ embedding_start: int = 0,
87
+ embedding_pos: torch.Tensor = None,
88
+ past_key_value: tuple[torch.Tensor, torch.Tensor] = None,
89
+ use_cache: bool = False
90
+ ) -> AttentionOutput:
91
+ '''
92
+ Perform forward pass of Multi-Head Attention.
93
+
94
+ Args:
95
+ hidden_states (torch.Tensor): Input hidden states.
96
+ kv_states (torch.Tensor, optional): Hidden states for keys/values.
97
+ If None, uses hidden_states. Defaults to None.
98
+ attention_mask (torch.Tensor, optional): Attention mask.
99
+ Defaults to None.
100
+ output_attentions (bool, optional): Whether to output attention weights.
101
+ Defaults to False.
102
+ position_emb (BasicEmbedding, optional): Positional embedding module.
103
+ Defaults to None.
104
+ embedding_start (int, optional): Starting position for embedding. Defaults to 0.
105
+ embedding_pos (torch.Tensor, optional): Explicit position indices for positional embedding.
106
+ Defaults to None.
107
+ past_key_value (tuple[torch.Tensor, torch.Tensor], optional): Past key-value cache.
108
+ Defaults to None.
109
+ use_cache (bool, optional): Whether to use KV cache. Defaults to False.
110
+
111
+ Returns:
112
+ AttentionOutput: Object containing output, attention weights, and KV cache.
113
+ '''
114
+
115
+ if kv_states is None:
116
+ kv_states = hidden_states
117
+
118
+ batch_size, q_len, _ = hidden_states.shape
119
+ kv_len_input = kv_states.shape[1]
120
+
121
+ if self.use_gate:
122
+ G = torch.sigmoid(self.g_proj(hidden_states))
123
+
124
+ Q = self.q_proj(hidden_states)
125
+ K = self.k_proj(kv_states)
126
+ V = self.v_proj(kv_states)
127
+
128
+ Q = Q.view(batch_size, q_len, self.num_heads, self.head_dim).transpose(1, 2)
129
+ K = K.view(batch_size, kv_len_input, self.num_kv_heads, self.head_dim).transpose(1, 2)
130
+ V = V.view(batch_size, kv_len_input, self.num_kv_heads, self.head_dim).transpose(1, 2)
131
+
132
+ if self.use_qk_norm:
133
+ Q = self.q_norm(Q)
134
+ K = self.k_norm(K)
135
+
136
+ if position_emb is not None:
137
+ Q = position_emb(Q, start_pos=embedding_start, positions=embedding_pos)
138
+ K = position_emb(K, start_pos=embedding_start, positions=embedding_pos)
139
+
140
+ current_key_value = None
141
+ if use_cache:
142
+ if past_key_value is not None:
143
+ past_k, past_v = past_key_value
144
+ K = torch.cat((past_k, K), dim=2)
145
+ V = torch.cat((past_v, V), dim=2)
146
+ current_key_value = (K, V)
147
+
148
+ kv_seq_len_total = K.shape[2]
149
+
150
+ if self.num_kv_queries > 1:
151
+ # [B, H_kv, 1, L, D] -> [B, H_kv, G, L, D]
152
+ K = K[:, :, None, :, :].expand(batch_size, self.num_kv_heads, self.num_kv_queries, kv_seq_len_total, self.head_dim)
153
+ V = V[:, :, None, :, :].expand(batch_size, self.num_kv_heads, self.num_kv_queries, kv_seq_len_total, self.head_dim)
154
+
155
+ K = K.reshape(batch_size, self.num_heads, kv_seq_len_total, self.head_dim)
156
+ V = V.reshape(batch_size, self.num_heads, kv_seq_len_total, self.head_dim)
157
+
158
+ attn_output = apply_attention(
159
+ Q, K, V,
160
+ attention_mask=attention_mask,
161
+ output_attentions=output_attentions,
162
+ is_causal=self.is_causal,
163
+ dropout=self.dropout if self.training else 0.0
164
+ )
165
+
166
+ output = attn_output.output
167
+ attention_weights = attn_output.attention_weights
168
+ output = output.transpose(1, 2).contiguous().view(batch_size, q_len, self.hidden_size)
169
+ output = self.o_proj(output)
170
+
171
+ if self.use_gate: output = output * G
172
+
173
+ return AttentionOutput(
174
+ output=output,
175
+ attention_weights=attention_weights,
176
+ past_key_value=current_key_value
177
+ )
178
+