codon-model 0.0.6a1__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 (106) hide show
  1. {codon_model-0.0.6a1/codon_model.egg-info → codon_model-0.0.6a2}/PKG-INFO +8 -1
  2. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/__init__.py +1 -1
  3. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/base.py +18 -7
  4. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/block/attention.py +178 -178
  5. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/block/embedding.py +368 -350
  6. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/block/transformer.py +1 -1
  7. codon_model-0.0.6a2/codon/builtins/download.py +129 -0
  8. codon_model-0.0.6a2/codon/builtins/mixins/remote.py +142 -0
  9. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/motif/__init__.py +5 -3
  10. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/motif/base.py +57 -1
  11. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/motif/motif_a1.py +18 -1
  12. codon_model-0.0.6a2/codon/motif/onnx.py +346 -0
  13. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/ops/attention.py +21 -6
  14. codon_model-0.0.6a2/codon/utils/__init__.py +0 -0
  15. codon_model-0.0.6a2/codon/utils/layer/__init__.py +0 -0
  16. codon_model-0.0.6a2/codon/utils/onnx.py +39 -0
  17. codon_model-0.0.6a2/codon/utils/service.py +364 -0
  18. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/utils/session.py +100 -7
  19. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/utils/tokens.py +3 -1
  20. {codon_model-0.0.6a1 → codon_model-0.0.6a2/codon_model.egg-info}/PKG-INFO +8 -1
  21. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon_model.egg-info/SOURCES.txt +7 -0
  22. codon_model-0.0.6a2/codon_model.egg-info/requires.txt +15 -0
  23. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/setup.py +1 -1
  24. codon_model-0.0.6a1/codon_model.egg-info/requires.txt +0 -8
  25. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/LICENSE +0 -0
  26. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/block/__init__.py +0 -0
  27. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/block/bio/__init__.py +0 -0
  28. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/block/bio/hebian.py +0 -0
  29. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/block/bio/predictive.py +0 -0
  30. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/block/codebook.py +0 -0
  31. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/block/conv.py +0 -0
  32. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/block/film.py +0 -0
  33. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/block/fourier.py +0 -0
  34. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/block/fusion.py +0 -0
  35. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/block/lora.py +0 -0
  36. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/block/manifold.py +0 -0
  37. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/block/mlp.py +0 -0
  38. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/block/moe.py +0 -0
  39. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/block/pixelshuffle.py +0 -0
  40. {codon_model-0.0.6a1/codon/dev → codon_model-0.0.6a2/codon/builtins}/__init__.py +0 -0
  41. {codon_model-0.0.6a1/codon/exp → codon_model-0.0.6a2/codon/builtins/mixins}/__init__.py +0 -0
  42. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/cli.py +0 -0
  43. {codon_model-0.0.6a1/codon/exp/block → codon_model-0.0.6a2/codon/dev}/__init__.py +0 -0
  44. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/dev/clear.py +0 -0
  45. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/dev/hash.py +0 -0
  46. {codon_model-0.0.6a1/codon/exp/ops → codon_model-0.0.6a2/codon/exp}/__init__.py +0 -0
  47. {codon_model-0.0.6a1/codon/kit → codon_model-0.0.6a2/codon/exp/block}/__init__.py +0 -0
  48. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/exp/block/bio.py +0 -0
  49. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/exp/block/manifold.py +0 -0
  50. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/exp/block/moe.py +0 -0
  51. {codon_model-0.0.6a1/codon/utils → codon_model-0.0.6a2/codon/exp/ops}/__init__.py +0 -0
  52. {codon_model-0.0.6a1/codon/utils/layer → codon_model-0.0.6a2/codon/kit}/__init__.py +0 -0
  53. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/kit/train/__init__.py +0 -0
  54. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/kit/train/language.py +0 -0
  55. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/kit/train/vision.py +0 -0
  56. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/model/__init__.py +0 -0
  57. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/model/patch_disc.py +0 -0
  58. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/model/resnet.py +0 -0
  59. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/model/tcn.py +0 -0
  60. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/motif/data/__init__.py +0 -0
  61. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/motif/data/prev1.py +0 -0
  62. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/motif/data/sft.py +0 -0
  63. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/motif/motif_a2.py +0 -0
  64. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/motif/motif_v1.py +0 -0
  65. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/ops/__init__.py +0 -0
  66. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/ops/bio.py +0 -0
  67. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/ops/fourier.py +0 -0
  68. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/ops/manifold/__init__.py +0 -0
  69. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/ops/manifold/conv.py +0 -0
  70. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/ops/manifold/linear.py +0 -0
  71. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/ops/pixelshuffle.py +0 -0
  72. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/utils/data/__init__.py +0 -0
  73. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/utils/data/base.py +0 -0
  74. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/utils/data/chunked.py +0 -0
  75. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/utils/data/dataviewer.py +0 -0
  76. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/utils/data/flatdata.py +0 -0
  77. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/utils/data/image.py +0 -0
  78. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/utils/eval/__init__.py +0 -0
  79. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/utils/eval/activation.py +0 -0
  80. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/utils/eval/base.py +0 -0
  81. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/utils/eval/boundary.py +0 -0
  82. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/utils/eval/cka.py +0 -0
  83. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/utils/eval/confusion.py +0 -0
  84. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/utils/eval/gradcam.py +0 -0
  85. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/utils/eval/layer_rsa.py +0 -0
  86. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/utils/eval/rsa.py +0 -0
  87. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/utils/eval/selectivity.py +0 -0
  88. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/utils/eval/similarity.py +0 -0
  89. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/utils/eval/tsne.py +0 -0
  90. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/utils/generate.py +0 -0
  91. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/utils/info.py +0 -0
  92. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/utils/layer/lora.py +0 -0
  93. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/utils/layer/manifold.py +0 -0
  94. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/utils/lifecycle.py +0 -0
  95. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/utils/mask.py +0 -0
  96. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/utils/plan.py +0 -0
  97. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/utils/safecode.py +0 -0
  98. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/utils/seed.py +0 -0
  99. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/utils/split.py +0 -0
  100. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/utils/theta.py +0 -0
  101. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon/utils/transforms.py +0 -0
  102. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon_model.egg-info/dependency_links.txt +0 -0
  103. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon_model.egg-info/entry_points.txt +0 -0
  104. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/codon_model.egg-info/top_level.txt +0 -0
  105. {codon_model-0.0.6a1 → codon_model-0.0.6a2}/setup.cfg +0 -0
  106. {codon_model-0.0.6a1 → 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.6a1
3
+ Version: 0.0.6a2
4
4
  Summary: Codon model package
5
5
  Author: CodonTeam
6
6
  Requires-Python: >=3.8
@@ -13,6 +13,13 @@ Requires-Dist: pandas
13
13
  Requires-Dist: numpy
14
14
  Requires-Dist: pyarrow
15
15
  Requires-Dist: pillow
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
16
23
  Dynamic: author
17
24
  Dynamic: license-file
18
25
  Dynamic: requires-dist
@@ -1,5 +1,5 @@
1
1
  from typing import Optional
2
2
 
3
- __version__ = '0.0.6a1'
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)
@@ -1,178 +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
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
-
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
+