arch-space commited on
Commit
577b8f3
·
verified ·
1 Parent(s): 92a0653

Add files using upload-large-folder tool

Browse files
Files changed (37) hide show
  1. olmo3/1b/stage1/model.safetensors +3 -0
  2. olmo3/1b/stage2/model.safetensors +3 -0
  3. olmo3/1b/stage3/__init__.py +2 -0
  4. olmo3/1b/stage3/config.json +76 -0
  5. olmo3/1b/stage3/configuration_olmo3_siamese_depth.py +78 -0
  6. olmo3/1b/stage3/generation_config.json +7 -0
  7. olmo3/1b/stage3/model.safetensors +3 -0
  8. olmo3/1b/stage3/modeling_olmo3_siamese_depth.py +548 -0
  9. olmo3/1b/stage3/special_tokens_map.json +11 -0
  10. olmo3/1b/stage3/tokenizer.json +0 -0
  11. olmo3/1b/stage3/tokenizer_config.json +190 -0
  12. olmo3/1b/stage3/vocab.json +0 -0
  13. olmo3/1b/stage4/instruct/PUBLIC_FILES.SHA256 +13 -0
  14. olmo3/1b/stage4/instruct/README.md +6 -0
  15. olmo3/1b/stage4/instruct/__init__.py +2 -0
  16. olmo3/1b/stage4/instruct/chat_template.jinja +16 -0
  17. olmo3/1b/stage4/instruct/config.json +76 -0
  18. olmo3/1b/stage4/instruct/configuration_olmo3_siamese_depth.py +78 -0
  19. olmo3/1b/stage4/instruct/generation_config.json +7 -0
  20. olmo3/1b/stage4/instruct/merges.txt +0 -0
  21. olmo3/1b/stage4/instruct/model.safetensors +3 -0
  22. olmo3/1b/stage4/instruct/modeling_olmo3_siamese_depth.py +548 -0
  23. olmo3/1b/stage4/instruct/special_tokens_map.json +30 -0
  24. olmo3/1b/stage4/instruct/tokenizer.json +0 -0
  25. olmo3/1b/stage4/instruct/tokenizer_config.json +191 -0
  26. olmo3/1b/stage4/instruct/vocab.json +0 -0
  27. olmo3/1b/stage4/think/PUBLIC_FILES.SHA256 +13 -0
  28. olmo3/1b/stage4/think/README.md +6 -0
  29. olmo3/1b/stage4/think/__init__.py +2 -0
  30. olmo3/1b/stage4/think/chat_template.jinja +16 -0
  31. olmo3/1b/stage4/think/config.json +76 -0
  32. olmo3/1b/stage4/think/configuration_olmo3_siamese_depth.py +78 -0
  33. olmo3/1b/stage4/think/generation_config.json +7 -0
  34. olmo3/1b/stage4/think/merges.txt +0 -0
  35. olmo3/1b/stage4/think/model.safetensors +3 -0
  36. olmo3/1b/stage4/think/modeling_olmo3_siamese_depth.py +548 -0
  37. olmo3/1b/stage4/think/special_tokens_map.json +30 -0
olmo3/1b/stage1/model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:dea5562210667dc24ecec56159f05b9f8f2245aa83d64bf31e95dd02fff39695
3
+ size 2969458432
olmo3/1b/stage2/model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:226d1174f58fccc681a916163eabdfb7c5c9c15990fa4f7e4d3b88d721f9f849
3
+ size 2969458432
olmo3/1b/stage3/__init__.py ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ from .configuration_olmo3_siamese_depth import Olmo3SiameseDepthConfig
2
+ from .modeling_olmo3_siamese_depth import Olmo3SiameseDepthForCausalLM, Olmo3SiameseDepthModel
olmo3/1b/stage3/config.json ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "_name_or_path": "",
3
+ "architectures": [
4
+ "Olmo3SiameseDepthForCausalLM"
5
+ ],
6
+ "attention_bias": false,
7
+ "attention_dropout": 0.0,
8
+ "auto_map": {
9
+ "AutoConfig": "configuration_olmo3_siamese_depth.Olmo3SiameseDepthConfig",
10
+ "AutoModel": "modeling_olmo3_siamese_depth.Olmo3SiameseDepthModel",
11
+ "AutoModelForCausalLM": "modeling_olmo3_siamese_depth.Olmo3SiameseDepthForCausalLM"
12
+ },
13
+ "bos_token_id": null,
14
+ "depth_attention_recent_window": 0,
15
+ "depth_attention_stride": 8,
16
+ "eos_token_id": 100257,
17
+ "hidden_act": "silu",
18
+ "hidden_dropout": 0.0,
19
+ "hidden_size": 2048,
20
+ "initializer_range": 0.02,
21
+ "intermediate_size": 8192,
22
+ "layer_types": [
23
+ "sliding_attention",
24
+ "sliding_attention",
25
+ "sliding_attention",
26
+ "full_attention",
27
+ "sliding_attention",
28
+ "sliding_attention",
29
+ "sliding_attention",
30
+ "full_attention",
31
+ "sliding_attention",
32
+ "sliding_attention",
33
+ "sliding_attention",
34
+ "full_attention",
35
+ "sliding_attention",
36
+ "sliding_attention",
37
+ "sliding_attention",
38
+ "full_attention"
39
+ ],
40
+ "max_position_embeddings": 65536,
41
+ "max_sequence_length": 65536,
42
+ "mlp_bias": false,
43
+ "model_type": "olmo3_siamese_depth",
44
+ "num_attention_heads": 16,
45
+ "num_hidden_layers": 16,
46
+ "num_key_value_heads": 16,
47
+ "olmo3_weight_decay": true,
48
+ "pad_token_id": 100277,
49
+ "padded_vocab_size": 100352,
50
+ "qk_norm": true,
51
+ "qk_norm_mode": "full_projection",
52
+ "rms_norm_eps": 1e-06,
53
+ "rope_full_precision": true,
54
+ "rope_scaling": {
55
+ "beta_fast": 32.0,
56
+ "beta_slow": 1.0,
57
+ "factor": 8.0,
58
+ "original_max_position_embeddings": 8192,
59
+ "rope_type": "yarn"
60
+ },
61
+ "rope_theta": 500000.0,
62
+ "scale_embeds": false,
63
+ "scale_output_layer_init": false,
64
+ "siamese_norm_variant": "hybrid_pre",
65
+ "sliding_window": 4096,
66
+ "tie_word_embeddings": false,
67
+ "torch_dtype": "bfloat16",
68
+ "transformers_version": "4.57.6",
69
+ "true_vocab_size": 100278,
70
+ "truncated_normal_factor": 3.0,
71
+ "use_cache": true,
72
+ "use_depth_attention": true,
73
+ "use_siamese_norm": true,
74
+ "vocab_size": 100278,
75
+ "vocab_z_loss_coeff": 1e-05
76
+ }
olmo3/1b/stage3/configuration_olmo3_siamese_depth.py ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Hugging Face configuration for the OLMo 3 Siamese-Norm/Depth-Attention model."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from transformers.models.olmo3.configuration_olmo3 import Olmo3Config
6
+
7
+
8
+ class Olmo3SiameseDepthConfig(Olmo3Config):
9
+ """OLMo 3 plus the checkpoint-compatible Siamese/Depth extensions."""
10
+
11
+ model_type = "olmo3_siamese_depth"
12
+
13
+ def __init__(
14
+ self,
15
+ *args,
16
+ vocab_size: int | None = None,
17
+ true_vocab_size: int = 100278,
18
+ padded_vocab_size: int = 100352,
19
+ qk_norm_mode: str = "full_projection",
20
+ use_siamese_norm: bool = True,
21
+ siamese_norm_variant: str = "hybrid_pre",
22
+ use_depth_attention: bool = True,
23
+ depth_attention_stride: int = 8,
24
+ depth_attention_recent_window: int = 0,
25
+ rope_full_precision: bool = True,
26
+ **kwargs,
27
+ ):
28
+ # ``PretrainedConfig.to_diff_dict()`` constructs a no-argument instance
29
+ # of this class. Make that default instance internally consistent
30
+ # instead of inheriting OLMo3's unrelated 50304-token default.
31
+ if vocab_size is None:
32
+ vocab_size = true_vocab_size
33
+ super().__init__(*args, vocab_size=vocab_size, **kwargs)
34
+ self.true_vocab_size = int(true_vocab_size)
35
+ self.padded_vocab_size = int(padded_vocab_size)
36
+ self.qk_norm = True
37
+ self.qk_norm_mode = qk_norm_mode
38
+ self.use_siamese_norm = bool(use_siamese_norm)
39
+ self.siamese_norm_variant = siamese_norm_variant
40
+ self.use_depth_attention = bool(use_depth_attention)
41
+ self.depth_attention_stride = int(depth_attention_stride)
42
+ self.depth_attention_recent_window = int(depth_attention_recent_window)
43
+ self.rope_full_precision = bool(rope_full_precision)
44
+ self._validate_siamese_depth()
45
+
46
+ def _validate_siamese_depth(self) -> None:
47
+ if self.vocab_size != self.true_vocab_size:
48
+ raise ValueError(
49
+ "HF vocab_size must equal true_vocab_size after padded-row removal; "
50
+ f"got {self.vocab_size} and {self.true_vocab_size}."
51
+ )
52
+ if self.padded_vocab_size < self.true_vocab_size:
53
+ raise ValueError("padded_vocab_size cannot be smaller than true_vocab_size.")
54
+ if self.qk_norm_mode != "full_projection":
55
+ raise ValueError("qk_norm_mode must be 'full_projection'.")
56
+ if not self.use_siamese_norm or self.siamese_norm_variant != "hybrid_pre":
57
+ raise ValueError("This remote model requires Hybrid-Pre Siamese Norm.")
58
+ if not self.use_depth_attention:
59
+ raise ValueError("This remote model requires Depth Attention.")
60
+ if self.depth_attention_stride < 1:
61
+ raise ValueError("depth_attention_stride must be positive.")
62
+ if self.depth_attention_recent_window < 0:
63
+ raise ValueError("depth_attention_recent_window must be non-negative.")
64
+ if not self.rope_full_precision:
65
+ raise ValueError("OLMo 3 requires FP32 Q/K RoPE.")
66
+ if self.hidden_size % self.num_attention_heads:
67
+ raise ValueError("hidden_size must be divisible by num_attention_heads.")
68
+ if self.num_attention_heads % self.num_key_value_heads:
69
+ raise ValueError("num_attention_heads must be divisible by num_key_value_heads.")
70
+ expected_layer_types = [
71
+ "sliding_attention" if (index + 1) % 4 else "full_attention"
72
+ for index in range(self.num_hidden_layers)
73
+ ]
74
+ if list(self.layer_types) != expected_layer_types:
75
+ raise ValueError("OLMo 3 requires the repeating SWA,SWA,SWA,Full pattern.")
76
+
77
+
78
+ __all__ = ["Olmo3SiameseDepthConfig"]
olmo3/1b/stage3/generation_config.json ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ {
2
+ "_from_model_config": true,
3
+ "bos_token_id": null,
4
+ "eos_token_id": 100257,
5
+ "pad_token_id": 100277,
6
+ "transformers_version": "4.57.6"
7
+ }
olmo3/1b/stage3/model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:0d380f9b5ff781d7c10089db0559215ad2da91443100d33e8e6fd677ff219622
3
+ size 2969458432
olmo3/1b/stage3/modeling_olmo3_siamese_depth.py ADDED
@@ -0,0 +1,548 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Transformers remote code for OLMo 3 + Siamese Norm + Depth Attention.
2
+
3
+ The Full/SWA masks, Full-only YaRN rotary embeddings, and bounded sliding KV
4
+ cache are delegated to the official Transformers OLMo 3 implementation. This
5
+ file adds only the two checkpoint-persistent mechanisms used during training:
6
+ Hybrid-Pre Siamese Norm and recursive same-position Depth Attention.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import math
12
+ from dataclasses import dataclass
13
+ from typing import Optional, Union
14
+
15
+ import torch
16
+ import torch.nn as nn
17
+ from transformers.cache_utils import Cache, DynamicCache
18
+ from transformers.generation import GenerationMixin
19
+ from transformers.masking_utils import create_causal_mask, create_sliding_window_causal_mask
20
+ from transformers.modeling_outputs import BaseModelOutputWithPast, CausalLMOutputWithPast
21
+ from transformers.modeling_utils import ALL_ATTENTION_FUNCTIONS
22
+ from transformers.models.olmo3.modeling_olmo3 import (
23
+ Olmo3MLP,
24
+ Olmo3PreTrainedModel,
25
+ Olmo3RMSNorm,
26
+ Olmo3RotaryEmbedding,
27
+ apply_rotary_pos_emb,
28
+ eager_attention_forward,
29
+ )
30
+
31
+ from .configuration_olmo3_siamese_depth import Olmo3SiameseDepthConfig
32
+
33
+
34
+ @dataclass
35
+ class _DepthSource:
36
+ layer_index: int
37
+ key: torch.Tensor
38
+ value: torch.Tensor
39
+
40
+
41
+ class _DepthContext:
42
+ def __init__(self, config: Olmo3SiameseDepthConfig):
43
+ self.num_layers = int(config.num_hidden_layers)
44
+ self.stride = int(config.depth_attention_stride)
45
+ self.recent_window = int(config.depth_attention_recent_window)
46
+ self.records: dict[int, _DepthSource] = {}
47
+
48
+ def sources_for(self, layer_index: int) -> tuple[_DepthSource, ...]:
49
+ recent_start = max(0, layer_index - self.recent_window)
50
+ return tuple(
51
+ self.records[index]
52
+ for index in sorted(self.records)
53
+ if index < layer_index
54
+ and (index % self.stride == 0 or index >= recent_start)
55
+ )
56
+
57
+ def record(self, layer_index: int, key: torch.Tensor, value: torch.Tensor) -> None:
58
+ if layer_index in self.records:
59
+ raise RuntimeError(f"Depth Attention layer {layer_index} was recorded twice.")
60
+ self.records[layer_index] = _DepthSource(layer_index, key, value)
61
+ next_recent_start = layer_index + 1 - self.recent_window
62
+ stale = [
63
+ index
64
+ for index in self.records
65
+ if index % self.stride != 0 and index < next_recent_start
66
+ ]
67
+ for index in stale:
68
+ del self.records[index]
69
+
70
+
71
+ def _depth_attention_mix(
72
+ query: torch.Tensor,
73
+ key: torch.Tensor,
74
+ value: torch.Tensor,
75
+ sources: tuple[_DepthSource, ...],
76
+ ) -> torch.Tensor:
77
+ """Mix current V with recursively mixed V from selected earlier layers.
78
+
79
+ Tensors use Transformers' ``[batch, heads, sequence, head_dim]`` layout.
80
+ """
81
+
82
+ if not sources:
83
+ return value
84
+ query_heads = query.shape[1]
85
+ kv_heads = key.shape[1]
86
+ if query_heads % kv_heads:
87
+ raise ValueError("Depth Attention requires Q heads divisible by KV heads.")
88
+ group_size = query_heads // kv_heads
89
+ grouped_query = (
90
+ query
91
+ if group_size == 1
92
+ else query.reshape(
93
+ query.shape[0],
94
+ kv_heads,
95
+ group_size,
96
+ query.shape[2],
97
+ query.shape[3],
98
+ ).mean(dim=2)
99
+ )
100
+ scale = 1.0 / math.sqrt(query.shape[-1])
101
+ scores = [
102
+ (grouped_query * source.key).sum(dim=-1, keepdim=True) * scale
103
+ for source in sources
104
+ ]
105
+ scores.append((grouped_query * key).sum(dim=-1, keepdim=True) * scale)
106
+ weights = torch.softmax(torch.cat(scores, dim=-1), dim=-1, dtype=torch.float32)
107
+ weights = weights.to(dtype=value.dtype)
108
+ mixed = weights[..., -1:].mul(value)
109
+ for source_index, source in enumerate(sources):
110
+ mixed = mixed + weights[..., source_index : source_index + 1] * source.value
111
+ return mixed
112
+
113
+
114
+ class Olmo3SiameseDepthAttention(nn.Module):
115
+ def __init__(self, config: Olmo3SiameseDepthConfig, layer_idx: int):
116
+ super().__init__()
117
+ self.config = config
118
+ self.layer_idx = int(layer_idx)
119
+ self.head_dim = getattr(
120
+ config, "head_dim", config.hidden_size // config.num_attention_heads
121
+ )
122
+ self.num_key_value_groups = (
123
+ config.num_attention_heads // config.num_key_value_heads
124
+ )
125
+ self.scaling = self.head_dim**-0.5
126
+ self.attention_dropout = float(config.attention_dropout)
127
+ self.is_causal = True
128
+ self.q_proj = nn.Linear(
129
+ config.hidden_size,
130
+ config.num_attention_heads * self.head_dim,
131
+ bias=False,
132
+ )
133
+ self.k_proj = nn.Linear(
134
+ config.hidden_size,
135
+ config.num_key_value_heads * self.head_dim,
136
+ bias=False,
137
+ )
138
+ self.v_proj = nn.Linear(
139
+ config.hidden_size,
140
+ config.num_key_value_heads * self.head_dim,
141
+ bias=False,
142
+ )
143
+ self.o_proj = nn.Linear(
144
+ config.num_attention_heads * self.head_dim,
145
+ config.hidden_size,
146
+ bias=False,
147
+ )
148
+ # These norms cover the complete Q and K projections, not one head.
149
+ self.q_norm = Olmo3RMSNorm(
150
+ config.num_attention_heads * self.head_dim, config.rms_norm_eps
151
+ )
152
+ self.k_norm = Olmo3RMSNorm(
153
+ config.num_key_value_heads * self.head_dim, config.rms_norm_eps
154
+ )
155
+ self.attention_type = config.layer_types[self.layer_idx]
156
+ self.sliding_window = (
157
+ int(config.sliding_window)
158
+ if self.attention_type == "sliding_attention"
159
+ else None
160
+ )
161
+
162
+ def forward(
163
+ self,
164
+ hidden_states: torch.Tensor,
165
+ position_embeddings: tuple[torch.Tensor, torch.Tensor],
166
+ attention_mask: Optional[torch.Tensor],
167
+ depth_context: _DepthContext,
168
+ past_key_values: Optional[Cache] = None,
169
+ cache_position: Optional[torch.LongTensor] = None,
170
+ output_attentions: bool = False,
171
+ **kwargs,
172
+ ) -> tuple[torch.Tensor, Optional[torch.Tensor]]:
173
+ batch_size, sequence_length, _ = hidden_states.shape
174
+ query = self.q_norm(self.q_proj(hidden_states)).view(
175
+ batch_size, sequence_length, self.config.num_attention_heads, self.head_dim
176
+ ).transpose(1, 2)
177
+ key = self.k_norm(self.k_proj(hidden_states)).view(
178
+ batch_size, sequence_length, self.config.num_key_value_heads, self.head_dim
179
+ ).transpose(1, 2)
180
+ value = self.v_proj(hidden_states).view(
181
+ batch_size, sequence_length, self.config.num_key_value_heads, self.head_dim
182
+ ).transpose(1, 2)
183
+
184
+ cos, sin = position_embeddings
185
+ query, key = apply_rotary_pos_emb(query.float(), key.float(), cos.float(), sin.float())
186
+ query = query.to(dtype=hidden_states.dtype)
187
+ key = key.to(dtype=hidden_states.dtype)
188
+
189
+ mixed_value = _depth_attention_mix(
190
+ query,
191
+ key,
192
+ value,
193
+ depth_context.sources_for(self.layer_idx),
194
+ )
195
+ depth_context.record(self.layer_idx, key, mixed_value)
196
+
197
+ attention_key = key
198
+ attention_value = mixed_value
199
+ if past_key_values is not None:
200
+ cache_kwargs = {
201
+ "sin": sin,
202
+ "cos": cos,
203
+ "cache_position": cache_position,
204
+ }
205
+ attention_key, attention_value = past_key_values.update(
206
+ key, mixed_value, self.layer_idx, cache_kwargs
207
+ )
208
+
209
+ attention_interface = eager_attention_forward
210
+ if self.config._attn_implementation != "eager":
211
+ attention_interface = ALL_ATTENTION_FUNCTIONS[
212
+ self.config._attn_implementation
213
+ ]
214
+ attention_output, attention_weights = attention_interface(
215
+ self,
216
+ query,
217
+ attention_key,
218
+ attention_value,
219
+ attention_mask,
220
+ dropout=0.0 if not self.training else self.attention_dropout,
221
+ scaling=self.scaling,
222
+ sliding_window=self.sliding_window,
223
+ **kwargs,
224
+ )
225
+ attention_output = attention_output.reshape(
226
+ batch_size, sequence_length, -1
227
+ ).contiguous()
228
+ attention_output = self.o_proj(attention_output)
229
+ return attention_output, attention_weights if output_attentions else None
230
+
231
+
232
+ class Olmo3SiameseDepthDecoderLayer(nn.Module):
233
+ def __init__(self, config: Olmo3SiameseDepthConfig, layer_idx: int):
234
+ super().__init__()
235
+ self.layer_idx = int(layer_idx)
236
+ self.self_attn = Olmo3SiameseDepthAttention(config, layer_idx)
237
+ self.mlp = Olmo3MLP(config)
238
+ self.pre_mlp_layernorm = Olmo3RMSNorm(
239
+ config.hidden_size, config.rms_norm_eps
240
+ )
241
+ self.siamese_attn_pre_norm = Olmo3RMSNorm(
242
+ config.hidden_size, config.rms_norm_eps
243
+ )
244
+ self.siamese_mlp_pre_norm = Olmo3RMSNorm(
245
+ config.hidden_size, config.rms_norm_eps
246
+ )
247
+ self.siamese_mlp_input_norm = Olmo3RMSNorm(
248
+ config.hidden_size, config.rms_norm_eps
249
+ )
250
+ self.siamese_hybrid_attn_scale = nn.Parameter(
251
+ torch.ones(config.hidden_size)
252
+ )
253
+ self.post_residual_scale = 1.0 / math.sqrt(2.0 * (self.layer_idx + 1))
254
+
255
+ def forward(
256
+ self,
257
+ post_stream: torch.Tensor,
258
+ pre_stream: torch.Tensor,
259
+ attention_mask: Optional[torch.Tensor],
260
+ position_embeddings: tuple[torch.Tensor, torch.Tensor],
261
+ depth_context: _DepthContext,
262
+ past_key_values: Optional[Cache],
263
+ cache_position: Optional[torch.LongTensor],
264
+ output_attentions: bool,
265
+ **kwargs,
266
+ ) -> tuple[torch.Tensor, torch.Tensor, Optional[torch.Tensor]]:
267
+ pre_normalized = self.siamese_attn_pre_norm(pre_stream)
268
+ attention_input = torch.addcmul(
269
+ pre_normalized,
270
+ post_stream,
271
+ self.siamese_hybrid_attn_scale.to(dtype=post_stream.dtype),
272
+ )
273
+ attention_output, attention_weights = self.self_attn(
274
+ hidden_states=attention_input,
275
+ position_embeddings=position_embeddings,
276
+ attention_mask=attention_mask,
277
+ depth_context=depth_context,
278
+ past_key_values=past_key_values,
279
+ cache_position=cache_position,
280
+ output_attentions=output_attentions,
281
+ **kwargs,
282
+ )
283
+ post_stream = torch.add(
284
+ post_stream, attention_output, alpha=self.post_residual_scale
285
+ )
286
+ pre_stream = pre_stream + attention_output
287
+
288
+ # The native Hybrid-Pre block advances its post stream to the
289
+ # pre-MLP-normalized value before both the MLP input construction and
290
+ # the MLP residual update. This is intentionally not a conventional
291
+ # pre-norm residual that adds the branch back to the unnormalized
292
+ # stream.
293
+ post_stream = self.pre_mlp_layernorm(post_stream)
294
+ pre_normalized = self.siamese_mlp_pre_norm(pre_stream)
295
+ mlp_input = self.siamese_mlp_input_norm(
296
+ post_stream + pre_normalized
297
+ )
298
+ mlp_output = self.mlp(mlp_input)
299
+ post_stream = torch.add(
300
+ post_stream, mlp_output, alpha=self.post_residual_scale
301
+ )
302
+ pre_stream = pre_stream + mlp_output
303
+ return post_stream, pre_stream, attention_weights
304
+
305
+
306
+ class Olmo3SiameseDepthPreTrainedModel(Olmo3PreTrainedModel):
307
+ config_class = Olmo3SiameseDepthConfig
308
+ base_model_prefix = "model"
309
+ _no_split_modules = ["Olmo3SiameseDepthDecoderLayer"]
310
+ # Whole-layer replay is invalid for the mutable cross-layer Depth context.
311
+ # The native trainer supports only its dedicated selective-MLP checkpoint
312
+ # path; do not advertise Transformers' generic layer checkpointing.
313
+ supports_gradient_checkpointing = False
314
+
315
+
316
+ class Olmo3SiameseDepthModel(Olmo3SiameseDepthPreTrainedModel):
317
+ def __init__(self, config: Olmo3SiameseDepthConfig):
318
+ super().__init__(config)
319
+ self.padding_idx = config.pad_token_id
320
+ self.vocab_size = config.vocab_size
321
+ self.embed_tokens = nn.Embedding(
322
+ config.vocab_size, config.hidden_size, self.padding_idx
323
+ )
324
+ self.layers = nn.ModuleList(
325
+ [
326
+ Olmo3SiameseDepthDecoderLayer(config, layer_idx)
327
+ for layer_idx in range(config.num_hidden_layers)
328
+ ]
329
+ )
330
+ self.siamese_post_final_layernorm = Olmo3RMSNorm(
331
+ config.hidden_size, config.rms_norm_eps
332
+ )
333
+ self.siamese_pre_final_layernorm = Olmo3RMSNorm(
334
+ config.hidden_size, config.rms_norm_eps
335
+ )
336
+ self.norm = Olmo3RMSNorm(config.hidden_size, config.rms_norm_eps)
337
+ self.rotary_embs = nn.ModuleDict(
338
+ {
339
+ "sliding_attention": Olmo3RotaryEmbedding(
340
+ config=config, rope_type="default"
341
+ ),
342
+ "full_attention": Olmo3RotaryEmbedding(config=config),
343
+ }
344
+ )
345
+ self.gradient_checkpointing = False
346
+ self.post_init()
347
+
348
+ def get_input_embeddings(self):
349
+ return self.embed_tokens
350
+
351
+ def set_input_embeddings(self, value):
352
+ self.embed_tokens = value
353
+
354
+ def forward(
355
+ self,
356
+ input_ids: Optional[torch.LongTensor] = None,
357
+ attention_mask: Optional[torch.Tensor] = None,
358
+ position_ids: Optional[torch.LongTensor] = None,
359
+ past_key_values: Optional[Cache] = None,
360
+ inputs_embeds: Optional[torch.FloatTensor] = None,
361
+ cache_position: Optional[torch.LongTensor] = None,
362
+ use_cache: Optional[bool] = None,
363
+ output_attentions: Optional[bool] = None,
364
+ output_hidden_states: Optional[bool] = None,
365
+ return_dict: Optional[bool] = None,
366
+ **kwargs,
367
+ ) -> Union[tuple, BaseModelOutputWithPast]:
368
+ if (input_ids is None) == (inputs_embeds is None):
369
+ raise ValueError("Specify exactly one of input_ids or inputs_embeds.")
370
+ output_attentions = (
371
+ self.config.output_attentions
372
+ if output_attentions is None
373
+ else output_attentions
374
+ )
375
+ output_hidden_states = (
376
+ self.config.output_hidden_states
377
+ if output_hidden_states is None
378
+ else output_hidden_states
379
+ )
380
+ return_dict = self.config.use_return_dict if return_dict is None else return_dict
381
+ if inputs_embeds is None:
382
+ inputs_embeds = self.embed_tokens(input_ids)
383
+ if use_cache and past_key_values is None:
384
+ past_key_values = DynamicCache(config=self.config)
385
+ if cache_position is None:
386
+ past_seen_tokens = (
387
+ past_key_values.get_seq_length()
388
+ if past_key_values is not None
389
+ else 0
390
+ )
391
+ cache_position = torch.arange(
392
+ past_seen_tokens,
393
+ past_seen_tokens + inputs_embeds.shape[1],
394
+ device=inputs_embeds.device,
395
+ )
396
+ if position_ids is None:
397
+ position_ids = cache_position.unsqueeze(0)
398
+
399
+ if not isinstance(attention_mask, dict):
400
+ mask_kwargs = {
401
+ "config": self.config,
402
+ "input_embeds": inputs_embeds,
403
+ "attention_mask": attention_mask,
404
+ "cache_position": cache_position,
405
+ "past_key_values": past_key_values,
406
+ "position_ids": position_ids,
407
+ }
408
+ causal_masks = {
409
+ "full_attention": create_causal_mask(**mask_kwargs),
410
+ "sliding_attention": create_sliding_window_causal_mask(
411
+ **mask_kwargs
412
+ ),
413
+ }
414
+ else:
415
+ causal_masks = attention_mask
416
+
417
+ post_stream = inputs_embeds
418
+ # The optimized training path intentionally aliases both initial streams.
419
+ pre_stream = inputs_embeds
420
+ depth_context = _DepthContext(self.config)
421
+ position_embeddings = {
422
+ kind: rotary(post_stream, position_ids)
423
+ for kind, rotary in self.rotary_embs.items()
424
+ }
425
+ hidden_history = () if output_hidden_states else None
426
+ attention_history = () if output_attentions else None
427
+ for layer in self.layers:
428
+ if output_hidden_states:
429
+ hidden_history += (post_stream,)
430
+ attention_type = layer.self_attn.attention_type
431
+ post_stream, pre_stream, attention_weights = layer(
432
+ post_stream=post_stream,
433
+ pre_stream=pre_stream,
434
+ attention_mask=causal_masks[attention_type],
435
+ position_embeddings=position_embeddings[attention_type],
436
+ depth_context=depth_context,
437
+ past_key_values=past_key_values,
438
+ cache_position=cache_position,
439
+ output_attentions=output_attentions,
440
+ **kwargs,
441
+ )
442
+ if output_attentions:
443
+ attention_history += (attention_weights,)
444
+
445
+ hidden_states = (
446
+ self.siamese_post_final_layernorm(post_stream)
447
+ + self.siamese_pre_final_layernorm(pre_stream)
448
+ )
449
+ hidden_states = self.norm(hidden_states)
450
+ if output_hidden_states:
451
+ hidden_history += (hidden_states,)
452
+ if not return_dict:
453
+ values = (hidden_states, past_key_values, hidden_history, attention_history)
454
+ return tuple(value for value in values if value is not None)
455
+ return BaseModelOutputWithPast(
456
+ last_hidden_state=hidden_states,
457
+ past_key_values=past_key_values,
458
+ hidden_states=hidden_history,
459
+ attentions=attention_history,
460
+ )
461
+
462
+
463
+ class Olmo3SiameseDepthForCausalLM(
464
+ Olmo3SiameseDepthPreTrainedModel, GenerationMixin
465
+ ):
466
+ _tied_weights_keys = []
467
+
468
+ def __init__(self, config: Olmo3SiameseDepthConfig):
469
+ super().__init__(config)
470
+ self.model = Olmo3SiameseDepthModel(config)
471
+ self.vocab_size = config.vocab_size
472
+ self.lm_head = nn.Linear(config.hidden_size, config.vocab_size, bias=False)
473
+ self.post_init()
474
+
475
+ def get_input_embeddings(self):
476
+ return self.model.embed_tokens
477
+
478
+ def set_input_embeddings(self, value):
479
+ self.model.embed_tokens = value
480
+
481
+ def get_output_embeddings(self):
482
+ return self.lm_head
483
+
484
+ def set_output_embeddings(self, value):
485
+ self.lm_head = value
486
+
487
+ def forward(
488
+ self,
489
+ input_ids: Optional[torch.LongTensor] = None,
490
+ attention_mask: Optional[torch.Tensor] = None,
491
+ position_ids: Optional[torch.LongTensor] = None,
492
+ past_key_values: Optional[Cache] = None,
493
+ inputs_embeds: Optional[torch.FloatTensor] = None,
494
+ labels: Optional[torch.LongTensor] = None,
495
+ use_cache: Optional[bool] = None,
496
+ cache_position: Optional[torch.LongTensor] = None,
497
+ logits_to_keep: Union[int, torch.Tensor] = 0,
498
+ output_attentions: Optional[bool] = None,
499
+ output_hidden_states: Optional[bool] = None,
500
+ return_dict: Optional[bool] = None,
501
+ **kwargs,
502
+ ) -> Union[tuple, CausalLMOutputWithPast]:
503
+ return_dict = self.config.use_return_dict if return_dict is None else return_dict
504
+ outputs = self.model(
505
+ input_ids=input_ids,
506
+ attention_mask=attention_mask,
507
+ position_ids=position_ids,
508
+ past_key_values=past_key_values,
509
+ inputs_embeds=inputs_embeds,
510
+ use_cache=use_cache,
511
+ cache_position=cache_position,
512
+ output_attentions=output_attentions,
513
+ output_hidden_states=output_hidden_states,
514
+ return_dict=True,
515
+ **kwargs,
516
+ )
517
+ hidden_states = outputs.last_hidden_state
518
+ indices = (
519
+ slice(-logits_to_keep, None)
520
+ if isinstance(logits_to_keep, int)
521
+ else logits_to_keep
522
+ )
523
+ logits = self.lm_head(hidden_states[:, indices, :])
524
+ loss = None
525
+ if labels is not None:
526
+ loss = self.loss_function(
527
+ logits=logits,
528
+ labels=labels,
529
+ vocab_size=self.config.vocab_size,
530
+ **kwargs,
531
+ )
532
+ if not return_dict:
533
+ result = (logits, outputs.past_key_values)
534
+ return ((loss,) + result) if loss is not None else result
535
+ return CausalLMOutputWithPast(
536
+ loss=loss,
537
+ logits=logits,
538
+ past_key_values=outputs.past_key_values,
539
+ hidden_states=outputs.hidden_states,
540
+ attentions=outputs.attentions,
541
+ )
542
+
543
+
544
+ __all__ = [
545
+ "Olmo3SiameseDepthForCausalLM",
546
+ "Olmo3SiameseDepthModel",
547
+ "Olmo3SiameseDepthPreTrainedModel",
548
+ ]
olmo3/1b/stage3/special_tokens_map.json ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "eos_token": "<|endoftext|>",
3
+ "pad_token": "<|pad|>",
4
+ "unk_token": {
5
+ "content": "<|endoftext|>",
6
+ "lstrip": false,
7
+ "normalized": false,
8
+ "rstrip": false,
9
+ "single_word": false
10
+ }
11
+ }
olmo3/1b/stage3/tokenizer.json ADDED
The diff for this file is too large to render. See raw diff
 
olmo3/1b/stage3/tokenizer_config.json ADDED
@@ -0,0 +1,190 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "add_prefix_space": false,
3
+ "added_tokens_decoder": {
4
+ "100256": {
5
+ "content": "<|extra_id_0|>",
6
+ "lstrip": false,
7
+ "normalized": false,
8
+ "rstrip": false,
9
+ "single_word": false,
10
+ "special": false
11
+ },
12
+ "100257": {
13
+ "content": "<|endoftext|>",
14
+ "lstrip": false,
15
+ "normalized": false,
16
+ "rstrip": false,
17
+ "single_word": false,
18
+ "special": true
19
+ },
20
+ "100258": {
21
+ "content": "<|fim_prefix|>",
22
+ "lstrip": false,
23
+ "normalized": false,
24
+ "rstrip": false,
25
+ "single_word": false,
26
+ "special": true
27
+ },
28
+ "100259": {
29
+ "content": "<|fim_middle|>",
30
+ "lstrip": false,
31
+ "normalized": false,
32
+ "rstrip": false,
33
+ "single_word": false,
34
+ "special": true
35
+ },
36
+ "100260": {
37
+ "content": "<|fim_suffix|>",
38
+ "lstrip": false,
39
+ "normalized": false,
40
+ "rstrip": false,
41
+ "single_word": false,
42
+ "special": true
43
+ },
44
+ "100261": {
45
+ "content": "|||PHONE_NUMBER|||",
46
+ "lstrip": false,
47
+ "normalized": false,
48
+ "rstrip": false,
49
+ "single_word": false,
50
+ "special": false
51
+ },
52
+ "100262": {
53
+ "content": "|||EMAIL_ADDRESS|||",
54
+ "lstrip": false,
55
+ "normalized": false,
56
+ "rstrip": false,
57
+ "single_word": false,
58
+ "special": false
59
+ },
60
+ "100263": {
61
+ "content": "|||IP_ADDRESS|||",
62
+ "lstrip": false,
63
+ "normalized": false,
64
+ "rstrip": false,
65
+ "single_word": false,
66
+ "special": false
67
+ },
68
+ "100264": {
69
+ "content": "<|im_start|>",
70
+ "lstrip": false,
71
+ "normalized": false,
72
+ "rstrip": false,
73
+ "single_word": false,
74
+ "special": true
75
+ },
76
+ "100265": {
77
+ "content": "<|im_end|>",
78
+ "lstrip": false,
79
+ "normalized": false,
80
+ "rstrip": false,
81
+ "single_word": false,
82
+ "special": true
83
+ },
84
+ "100266": {
85
+ "content": "<|extra_id_1|>",
86
+ "lstrip": false,
87
+ "normalized": false,
88
+ "rstrip": false,
89
+ "single_word": false,
90
+ "special": false
91
+ },
92
+ "100267": {
93
+ "content": "<|extra_id_2|>",
94
+ "lstrip": false,
95
+ "normalized": false,
96
+ "rstrip": false,
97
+ "single_word": false,
98
+ "special": false
99
+ },
100
+ "100268": {
101
+ "content": "<|extra_id_3|>",
102
+ "lstrip": false,
103
+ "normalized": false,
104
+ "rstrip": false,
105
+ "single_word": false,
106
+ "special": false
107
+ },
108
+ "100269": {
109
+ "content": "<|extra_id_4|>",
110
+ "lstrip": false,
111
+ "normalized": false,
112
+ "rstrip": false,
113
+ "single_word": false,
114
+ "special": false
115
+ },
116
+ "100270": {
117
+ "content": "<|extra_id_5|>",
118
+ "lstrip": false,
119
+ "normalized": false,
120
+ "rstrip": false,
121
+ "single_word": false,
122
+ "special": false
123
+ },
124
+ "100271": {
125
+ "content": "<|extra_id_6|>",
126
+ "lstrip": false,
127
+ "normalized": false,
128
+ "rstrip": false,
129
+ "single_word": false,
130
+ "special": false
131
+ },
132
+ "100272": {
133
+ "content": "<|extra_id_7|>",
134
+ "lstrip": false,
135
+ "normalized": false,
136
+ "rstrip": false,
137
+ "single_word": false,
138
+ "special": false
139
+ },
140
+ "100273": {
141
+ "content": "<|extra_id_8|>",
142
+ "lstrip": false,
143
+ "normalized": false,
144
+ "rstrip": false,
145
+ "single_word": false,
146
+ "special": false
147
+ },
148
+ "100274": {
149
+ "content": "<|extra_id_9|>",
150
+ "lstrip": false,
151
+ "normalized": false,
152
+ "rstrip": false,
153
+ "single_word": false,
154
+ "special": false
155
+ },
156
+ "100275": {
157
+ "content": "<|extra_id_10|>",
158
+ "lstrip": false,
159
+ "normalized": false,
160
+ "rstrip": false,
161
+ "single_word": false,
162
+ "special": false
163
+ },
164
+ "100276": {
165
+ "content": "<|endofprompt|>",
166
+ "lstrip": false,
167
+ "normalized": false,
168
+ "rstrip": false,
169
+ "single_word": false,
170
+ "special": true
171
+ },
172
+ "100277": {
173
+ "content": "<|pad|>",
174
+ "lstrip": false,
175
+ "normalized": false,
176
+ "rstrip": false,
177
+ "single_word": false,
178
+ "special": true
179
+ }
180
+ },
181
+ "bos_token": null,
182
+ "clean_up_tokenization_spaces": false,
183
+ "eos_token": "<|endoftext|>",
184
+ "extra_special_tokens": {},
185
+ "fix_mistral_regex": false,
186
+ "model_max_length": 65536,
187
+ "pad_token": "<|pad|>",
188
+ "tokenizer_class": "GPT2Tokenizer",
189
+ "unk_token": "<|endoftext|>"
190
+ }
olmo3/1b/stage3/vocab.json ADDED
The diff for this file is too large to render. See raw diff
 
olmo3/1b/stage4/instruct/PUBLIC_FILES.SHA256 ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 6c77801731dc5611cff8478138ef3fd1d8bdd37e2b992aa034d5da66fec61eca README.md
2
+ e2144e7990128799f6eaf6430ea0a472dbb17e076bdb08b327887e59f84657be __init__.py
3
+ a3d6a7ad3fde8e26fa9953d80ac30682f7d56ac1d03f3428910a4239a4e23bef chat_template.jinja
4
+ 77c545f18298aa5960d58d0c83eb752b8559ebac016f5755a3aef50b226588c8 config.json
5
+ d66ccce18efda42443a91536bf907e7bcb6e2d0acd0c8dc70d69eb15f277d634 configuration_olmo3_siamese_depth.py
6
+ dbd4aa5dc6f7f1bdc0c181d9e5582f6571e1d2a22878dfcd98149324b9f5c4a2 generation_config.json
7
+ b6fe424e334903f7fb84d3a106d9730455f4744b9fe3c21ee136d97a00e72502 merges.txt
8
+ f0b8b78613e1b49a5f6164acefec39e06f7f938176ff23663f703802799e2497 model.safetensors
9
+ 12329a1f6cb1732bf100bda2ee2dd62761f6485aefb0a977879eb6d74f764aa6 modeling_olmo3_siamese_depth.py
10
+ 78afb564e81264029b25f9caf24bda2521d5bdaeff5cd3fdbc01d3da2e8ce2f2 special_tokens_map.json
11
+ 7738a25c46a6043a0e2e605138851baa450269ce9d800af6ca9bf6192e45510c tokenizer.json
12
+ 5f959b9c0cff767a63f22a0569e0554cce28214fb49e41479ba326f44169c5ec tokenizer_config.json
13
+ d8eb44d0d51f5e39c9b14825ca8bd10a2500f99c438ca81d4462f0263acd3b53 vocab.json
olmo3/1b/stage4/instruct/README.md ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ # Stage 4 Instruct SFT checkpoint
2
+
3
+ This subfolder contains a complete Hugging Face checkpoint with a context
4
+ length of 65536 tokens. Load it from the parent model repository using
5
+ `trust_remote_code=True`, `subfolder="olmo3/1b/stage4/instruct"`, and
6
+ `attn_implementation="sdpa"`.
olmo3/1b/stage4/instruct/__init__.py ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ from .configuration_olmo3_siamese_depth import Olmo3SiameseDepthConfig
2
+ from .modeling_olmo3_siamese_depth import Olmo3SiameseDepthForCausalLM, Olmo3SiameseDepthModel
olmo3/1b/stage4/instruct/chat_template.jinja ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {%- set has_system = messages|selectattr('role', 'equalto', 'system')|list|length > 0 -%}{%- if not has_system -%}{{- '<|im_start|>system
2
+ You are a helpful function-calling AI assistant. ' -}}{%- if tools is none or (tools | length) == 0 -%}{{- 'You do not currently have access to any functions. <functions></functions><|im_end|>
3
+ ' -}}{%- else -%}{{- 'You are provided with function signatures within <functions></functions> XML tags. You may call one or more functions to assist with the user query. Output any function calls within <function_calls></function_calls> XML tags. Do not make assumptions about what values to plug into functions.' -}}{{- '<functions>' -}}{{- tools | tojson -}}{{- '</functions><|im_end|>
4
+ ' -}}{%- endif -%}{%- endif -%}{%- for message in messages -%}{%- if message['role'] == 'system' -%}{{- '<|im_start|>system
5
+ ' + message['content'] -}}{%- if tools is not none -%}{{- '<functions>' -}}{{- tools | tojson -}}{{- '</functions>' -}}{%- elif message.get('functions', none) is not none -%}{{- ' <functions>' + message['functions'] + '</functions>' -}}{%- endif -%}{{- '<|im_end|>
6
+ ' -}}{%- elif message['role'] == 'user' -%}{{- '<|im_start|>user
7
+ ' + message['content'] + '<|im_end|>
8
+ ' -}}{%- elif message['role'] == 'assistant' -%}{{- '<|im_start|>assistant
9
+ ' -}}{%- if message.get('content', none) is not none -%}{{- message['content'] -}}{%- endif -%}{%- if message.get('function_calls', none) is not none and (message['function_calls'] | length) > 0 -%}{{- '<function_calls>' + message['function_calls'] + '</function_calls>' -}}{%- elif message.get('tool_calls', none) is not none and (message['tool_calls'] | length) > 0 -%}{{- '<function_calls>' -}}{%- for tool_call in message['tool_calls'] %}{%- if tool_call is mapping and tool_call.get('function', none) is not none %}{%- set args = tool_call['function']['arguments'] -%}{%- set ns = namespace(arguments_list=[]) -%}{%- for key, value in args.items() -%}{%- set ns.arguments_list = ns.arguments_list + [key ~ '=' ~ (value | tojson)] -%}{%- endfor -%}{%- set arguments = ns.arguments_list | join(', ') -%}{{- tool_call['function']['name'] + '(' + arguments + ')' -}}{%- if not loop.last -%}{{ '
10
+ ' }}{%- endif -%}{% else %}{{- tool_call -}}{%- endif %}{%- endfor %}{{- '</function_calls>' -}}{%- endif -%}{%- if not loop.last -%}{{- '<|im_end|>' + '
11
+ ' -}}{%- else -%}{{- eos_token -}}{%- endif -%}{%- elif message['role'] == 'environment' -%}{{- '<|im_start|>environment
12
+ ' + message['content'] + '<|im_end|>
13
+ ' -}}{%- elif message['role'] == 'tool' -%}{{- '<|im_start|>environment
14
+ ' + message['content'] + '<|im_end|>
15
+ ' -}}{%- endif -%}{%- if loop.last and add_generation_prompt -%}{{- '<|im_start|>assistant
16
+ ' -}}{%- endif -%}{%- endfor -%}
olmo3/1b/stage4/instruct/config.json ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "_name_or_path": "",
3
+ "architectures": [
4
+ "Olmo3SiameseDepthForCausalLM"
5
+ ],
6
+ "attention_bias": false,
7
+ "attention_dropout": 0.0,
8
+ "auto_map": {
9
+ "AutoConfig": "configuration_olmo3_siamese_depth.Olmo3SiameseDepthConfig",
10
+ "AutoModel": "modeling_olmo3_siamese_depth.Olmo3SiameseDepthModel",
11
+ "AutoModelForCausalLM": "modeling_olmo3_siamese_depth.Olmo3SiameseDepthForCausalLM"
12
+ },
13
+ "bos_token_id": null,
14
+ "depth_attention_recent_window": 0,
15
+ "depth_attention_stride": 8,
16
+ "eos_token_id": 100257,
17
+ "hidden_act": "silu",
18
+ "hidden_dropout": 0.0,
19
+ "hidden_size": 2048,
20
+ "initializer_range": 0.02,
21
+ "intermediate_size": 8192,
22
+ "layer_types": [
23
+ "sliding_attention",
24
+ "sliding_attention",
25
+ "sliding_attention",
26
+ "full_attention",
27
+ "sliding_attention",
28
+ "sliding_attention",
29
+ "sliding_attention",
30
+ "full_attention",
31
+ "sliding_attention",
32
+ "sliding_attention",
33
+ "sliding_attention",
34
+ "full_attention",
35
+ "sliding_attention",
36
+ "sliding_attention",
37
+ "sliding_attention",
38
+ "full_attention"
39
+ ],
40
+ "max_position_embeddings": 65536,
41
+ "max_sequence_length": 65536,
42
+ "mlp_bias": false,
43
+ "model_type": "olmo3_siamese_depth",
44
+ "num_attention_heads": 16,
45
+ "num_hidden_layers": 16,
46
+ "num_key_value_heads": 16,
47
+ "olmo3_weight_decay": true,
48
+ "pad_token_id": 100277,
49
+ "padded_vocab_size": 100352,
50
+ "qk_norm": true,
51
+ "qk_norm_mode": "full_projection",
52
+ "rms_norm_eps": 1e-06,
53
+ "rope_full_precision": true,
54
+ "rope_scaling": {
55
+ "beta_fast": 32.0,
56
+ "beta_slow": 1.0,
57
+ "factor": 8.0,
58
+ "original_max_position_embeddings": 8192,
59
+ "rope_type": "yarn"
60
+ },
61
+ "rope_theta": 500000.0,
62
+ "scale_embeds": false,
63
+ "scale_output_layer_init": false,
64
+ "siamese_norm_variant": "hybrid_pre",
65
+ "sliding_window": 4096,
66
+ "tie_word_embeddings": false,
67
+ "torch_dtype": "bfloat16",
68
+ "transformers_version": "4.57.6",
69
+ "true_vocab_size": 100278,
70
+ "truncated_normal_factor": 3.0,
71
+ "use_cache": true,
72
+ "use_depth_attention": true,
73
+ "use_siamese_norm": true,
74
+ "vocab_size": 100278,
75
+ "vocab_z_loss_coeff": 1e-05
76
+ }
olmo3/1b/stage4/instruct/configuration_olmo3_siamese_depth.py ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Hugging Face configuration for the OLMo 3 Siamese-Norm/Depth-Attention model."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from transformers.models.olmo3.configuration_olmo3 import Olmo3Config
6
+
7
+
8
+ class Olmo3SiameseDepthConfig(Olmo3Config):
9
+ """OLMo 3 plus the checkpoint-compatible Siamese/Depth extensions."""
10
+
11
+ model_type = "olmo3_siamese_depth"
12
+
13
+ def __init__(
14
+ self,
15
+ *args,
16
+ vocab_size: int | None = None,
17
+ true_vocab_size: int = 100278,
18
+ padded_vocab_size: int = 100352,
19
+ qk_norm_mode: str = "full_projection",
20
+ use_siamese_norm: bool = True,
21
+ siamese_norm_variant: str = "hybrid_pre",
22
+ use_depth_attention: bool = True,
23
+ depth_attention_stride: int = 8,
24
+ depth_attention_recent_window: int = 0,
25
+ rope_full_precision: bool = True,
26
+ **kwargs,
27
+ ):
28
+ # ``PretrainedConfig.to_diff_dict()`` constructs a no-argument instance
29
+ # of this class. Make that default instance internally consistent
30
+ # instead of inheriting OLMo3's unrelated 50304-token default.
31
+ if vocab_size is None:
32
+ vocab_size = true_vocab_size
33
+ super().__init__(*args, vocab_size=vocab_size, **kwargs)
34
+ self.true_vocab_size = int(true_vocab_size)
35
+ self.padded_vocab_size = int(padded_vocab_size)
36
+ self.qk_norm = True
37
+ self.qk_norm_mode = qk_norm_mode
38
+ self.use_siamese_norm = bool(use_siamese_norm)
39
+ self.siamese_norm_variant = siamese_norm_variant
40
+ self.use_depth_attention = bool(use_depth_attention)
41
+ self.depth_attention_stride = int(depth_attention_stride)
42
+ self.depth_attention_recent_window = int(depth_attention_recent_window)
43
+ self.rope_full_precision = bool(rope_full_precision)
44
+ self._validate_siamese_depth()
45
+
46
+ def _validate_siamese_depth(self) -> None:
47
+ if self.vocab_size != self.true_vocab_size:
48
+ raise ValueError(
49
+ "HF vocab_size must equal true_vocab_size after padded-row removal; "
50
+ f"got {self.vocab_size} and {self.true_vocab_size}."
51
+ )
52
+ if self.padded_vocab_size < self.true_vocab_size:
53
+ raise ValueError("padded_vocab_size cannot be smaller than true_vocab_size.")
54
+ if self.qk_norm_mode != "full_projection":
55
+ raise ValueError("qk_norm_mode must be 'full_projection'.")
56
+ if not self.use_siamese_norm or self.siamese_norm_variant != "hybrid_pre":
57
+ raise ValueError("This remote model requires Hybrid-Pre Siamese Norm.")
58
+ if not self.use_depth_attention:
59
+ raise ValueError("This remote model requires Depth Attention.")
60
+ if self.depth_attention_stride < 1:
61
+ raise ValueError("depth_attention_stride must be positive.")
62
+ if self.depth_attention_recent_window < 0:
63
+ raise ValueError("depth_attention_recent_window must be non-negative.")
64
+ if not self.rope_full_precision:
65
+ raise ValueError("OLMo 3 requires FP32 Q/K RoPE.")
66
+ if self.hidden_size % self.num_attention_heads:
67
+ raise ValueError("hidden_size must be divisible by num_attention_heads.")
68
+ if self.num_attention_heads % self.num_key_value_heads:
69
+ raise ValueError("num_attention_heads must be divisible by num_key_value_heads.")
70
+ expected_layer_types = [
71
+ "sliding_attention" if (index + 1) % 4 else "full_attention"
72
+ for index in range(self.num_hidden_layers)
73
+ ]
74
+ if list(self.layer_types) != expected_layer_types:
75
+ raise ValueError("OLMo 3 requires the repeating SWA,SWA,SWA,Full pattern.")
76
+
77
+
78
+ __all__ = ["Olmo3SiameseDepthConfig"]
olmo3/1b/stage4/instruct/generation_config.json ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ {
2
+ "_from_model_config": true,
3
+ "bos_token_id": null,
4
+ "eos_token_id": 100257,
5
+ "pad_token_id": 100277,
6
+ "transformers_version": "4.57.6"
7
+ }
olmo3/1b/stage4/instruct/merges.txt ADDED
The diff for this file is too large to render. See raw diff
 
olmo3/1b/stage4/instruct/model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:f0b8b78613e1b49a5f6164acefec39e06f7f938176ff23663f703802799e2497
3
+ size 2969458432
olmo3/1b/stage4/instruct/modeling_olmo3_siamese_depth.py ADDED
@@ -0,0 +1,548 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Transformers remote code for OLMo 3 + Siamese Norm + Depth Attention.
2
+
3
+ The Full/SWA masks, Full-only YaRN rotary embeddings, and bounded sliding KV
4
+ cache are delegated to the official Transformers OLMo 3 implementation. This
5
+ file adds only the two checkpoint-persistent mechanisms used during training:
6
+ Hybrid-Pre Siamese Norm and recursive same-position Depth Attention.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import math
12
+ from dataclasses import dataclass
13
+ from typing import Optional, Union
14
+
15
+ import torch
16
+ import torch.nn as nn
17
+ from transformers.cache_utils import Cache, DynamicCache
18
+ from transformers.generation import GenerationMixin
19
+ from transformers.masking_utils import create_causal_mask, create_sliding_window_causal_mask
20
+ from transformers.modeling_outputs import BaseModelOutputWithPast, CausalLMOutputWithPast
21
+ from transformers.modeling_utils import ALL_ATTENTION_FUNCTIONS
22
+ from transformers.models.olmo3.modeling_olmo3 import (
23
+ Olmo3MLP,
24
+ Olmo3PreTrainedModel,
25
+ Olmo3RMSNorm,
26
+ Olmo3RotaryEmbedding,
27
+ apply_rotary_pos_emb,
28
+ eager_attention_forward,
29
+ )
30
+
31
+ from .configuration_olmo3_siamese_depth import Olmo3SiameseDepthConfig
32
+
33
+
34
+ @dataclass
35
+ class _DepthSource:
36
+ layer_index: int
37
+ key: torch.Tensor
38
+ value: torch.Tensor
39
+
40
+
41
+ class _DepthContext:
42
+ def __init__(self, config: Olmo3SiameseDepthConfig):
43
+ self.num_layers = int(config.num_hidden_layers)
44
+ self.stride = int(config.depth_attention_stride)
45
+ self.recent_window = int(config.depth_attention_recent_window)
46
+ self.records: dict[int, _DepthSource] = {}
47
+
48
+ def sources_for(self, layer_index: int) -> tuple[_DepthSource, ...]:
49
+ recent_start = max(0, layer_index - self.recent_window)
50
+ return tuple(
51
+ self.records[index]
52
+ for index in sorted(self.records)
53
+ if index < layer_index
54
+ and (index % self.stride == 0 or index >= recent_start)
55
+ )
56
+
57
+ def record(self, layer_index: int, key: torch.Tensor, value: torch.Tensor) -> None:
58
+ if layer_index in self.records:
59
+ raise RuntimeError(f"Depth Attention layer {layer_index} was recorded twice.")
60
+ self.records[layer_index] = _DepthSource(layer_index, key, value)
61
+ next_recent_start = layer_index + 1 - self.recent_window
62
+ stale = [
63
+ index
64
+ for index in self.records
65
+ if index % self.stride != 0 and index < next_recent_start
66
+ ]
67
+ for index in stale:
68
+ del self.records[index]
69
+
70
+
71
+ def _depth_attention_mix(
72
+ query: torch.Tensor,
73
+ key: torch.Tensor,
74
+ value: torch.Tensor,
75
+ sources: tuple[_DepthSource, ...],
76
+ ) -> torch.Tensor:
77
+ """Mix current V with recursively mixed V from selected earlier layers.
78
+
79
+ Tensors use Transformers' ``[batch, heads, sequence, head_dim]`` layout.
80
+ """
81
+
82
+ if not sources:
83
+ return value
84
+ query_heads = query.shape[1]
85
+ kv_heads = key.shape[1]
86
+ if query_heads % kv_heads:
87
+ raise ValueError("Depth Attention requires Q heads divisible by KV heads.")
88
+ group_size = query_heads // kv_heads
89
+ grouped_query = (
90
+ query
91
+ if group_size == 1
92
+ else query.reshape(
93
+ query.shape[0],
94
+ kv_heads,
95
+ group_size,
96
+ query.shape[2],
97
+ query.shape[3],
98
+ ).mean(dim=2)
99
+ )
100
+ scale = 1.0 / math.sqrt(query.shape[-1])
101
+ scores = [
102
+ (grouped_query * source.key).sum(dim=-1, keepdim=True) * scale
103
+ for source in sources
104
+ ]
105
+ scores.append((grouped_query * key).sum(dim=-1, keepdim=True) * scale)
106
+ weights = torch.softmax(torch.cat(scores, dim=-1), dim=-1, dtype=torch.float32)
107
+ weights = weights.to(dtype=value.dtype)
108
+ mixed = weights[..., -1:].mul(value)
109
+ for source_index, source in enumerate(sources):
110
+ mixed = mixed + weights[..., source_index : source_index + 1] * source.value
111
+ return mixed
112
+
113
+
114
+ class Olmo3SiameseDepthAttention(nn.Module):
115
+ def __init__(self, config: Olmo3SiameseDepthConfig, layer_idx: int):
116
+ super().__init__()
117
+ self.config = config
118
+ self.layer_idx = int(layer_idx)
119
+ self.head_dim = getattr(
120
+ config, "head_dim", config.hidden_size // config.num_attention_heads
121
+ )
122
+ self.num_key_value_groups = (
123
+ config.num_attention_heads // config.num_key_value_heads
124
+ )
125
+ self.scaling = self.head_dim**-0.5
126
+ self.attention_dropout = float(config.attention_dropout)
127
+ self.is_causal = True
128
+ self.q_proj = nn.Linear(
129
+ config.hidden_size,
130
+ config.num_attention_heads * self.head_dim,
131
+ bias=False,
132
+ )
133
+ self.k_proj = nn.Linear(
134
+ config.hidden_size,
135
+ config.num_key_value_heads * self.head_dim,
136
+ bias=False,
137
+ )
138
+ self.v_proj = nn.Linear(
139
+ config.hidden_size,
140
+ config.num_key_value_heads * self.head_dim,
141
+ bias=False,
142
+ )
143
+ self.o_proj = nn.Linear(
144
+ config.num_attention_heads * self.head_dim,
145
+ config.hidden_size,
146
+ bias=False,
147
+ )
148
+ # These norms cover the complete Q and K projections, not one head.
149
+ self.q_norm = Olmo3RMSNorm(
150
+ config.num_attention_heads * self.head_dim, config.rms_norm_eps
151
+ )
152
+ self.k_norm = Olmo3RMSNorm(
153
+ config.num_key_value_heads * self.head_dim, config.rms_norm_eps
154
+ )
155
+ self.attention_type = config.layer_types[self.layer_idx]
156
+ self.sliding_window = (
157
+ int(config.sliding_window)
158
+ if self.attention_type == "sliding_attention"
159
+ else None
160
+ )
161
+
162
+ def forward(
163
+ self,
164
+ hidden_states: torch.Tensor,
165
+ position_embeddings: tuple[torch.Tensor, torch.Tensor],
166
+ attention_mask: Optional[torch.Tensor],
167
+ depth_context: _DepthContext,
168
+ past_key_values: Optional[Cache] = None,
169
+ cache_position: Optional[torch.LongTensor] = None,
170
+ output_attentions: bool = False,
171
+ **kwargs,
172
+ ) -> tuple[torch.Tensor, Optional[torch.Tensor]]:
173
+ batch_size, sequence_length, _ = hidden_states.shape
174
+ query = self.q_norm(self.q_proj(hidden_states)).view(
175
+ batch_size, sequence_length, self.config.num_attention_heads, self.head_dim
176
+ ).transpose(1, 2)
177
+ key = self.k_norm(self.k_proj(hidden_states)).view(
178
+ batch_size, sequence_length, self.config.num_key_value_heads, self.head_dim
179
+ ).transpose(1, 2)
180
+ value = self.v_proj(hidden_states).view(
181
+ batch_size, sequence_length, self.config.num_key_value_heads, self.head_dim
182
+ ).transpose(1, 2)
183
+
184
+ cos, sin = position_embeddings
185
+ query, key = apply_rotary_pos_emb(query.float(), key.float(), cos.float(), sin.float())
186
+ query = query.to(dtype=hidden_states.dtype)
187
+ key = key.to(dtype=hidden_states.dtype)
188
+
189
+ mixed_value = _depth_attention_mix(
190
+ query,
191
+ key,
192
+ value,
193
+ depth_context.sources_for(self.layer_idx),
194
+ )
195
+ depth_context.record(self.layer_idx, key, mixed_value)
196
+
197
+ attention_key = key
198
+ attention_value = mixed_value
199
+ if past_key_values is not None:
200
+ cache_kwargs = {
201
+ "sin": sin,
202
+ "cos": cos,
203
+ "cache_position": cache_position,
204
+ }
205
+ attention_key, attention_value = past_key_values.update(
206
+ key, mixed_value, self.layer_idx, cache_kwargs
207
+ )
208
+
209
+ attention_interface = eager_attention_forward
210
+ if self.config._attn_implementation != "eager":
211
+ attention_interface = ALL_ATTENTION_FUNCTIONS[
212
+ self.config._attn_implementation
213
+ ]
214
+ attention_output, attention_weights = attention_interface(
215
+ self,
216
+ query,
217
+ attention_key,
218
+ attention_value,
219
+ attention_mask,
220
+ dropout=0.0 if not self.training else self.attention_dropout,
221
+ scaling=self.scaling,
222
+ sliding_window=self.sliding_window,
223
+ **kwargs,
224
+ )
225
+ attention_output = attention_output.reshape(
226
+ batch_size, sequence_length, -1
227
+ ).contiguous()
228
+ attention_output = self.o_proj(attention_output)
229
+ return attention_output, attention_weights if output_attentions else None
230
+
231
+
232
+ class Olmo3SiameseDepthDecoderLayer(nn.Module):
233
+ def __init__(self, config: Olmo3SiameseDepthConfig, layer_idx: int):
234
+ super().__init__()
235
+ self.layer_idx = int(layer_idx)
236
+ self.self_attn = Olmo3SiameseDepthAttention(config, layer_idx)
237
+ self.mlp = Olmo3MLP(config)
238
+ self.pre_mlp_layernorm = Olmo3RMSNorm(
239
+ config.hidden_size, config.rms_norm_eps
240
+ )
241
+ self.siamese_attn_pre_norm = Olmo3RMSNorm(
242
+ config.hidden_size, config.rms_norm_eps
243
+ )
244
+ self.siamese_mlp_pre_norm = Olmo3RMSNorm(
245
+ config.hidden_size, config.rms_norm_eps
246
+ )
247
+ self.siamese_mlp_input_norm = Olmo3RMSNorm(
248
+ config.hidden_size, config.rms_norm_eps
249
+ )
250
+ self.siamese_hybrid_attn_scale = nn.Parameter(
251
+ torch.ones(config.hidden_size)
252
+ )
253
+ self.post_residual_scale = 1.0 / math.sqrt(2.0 * (self.layer_idx + 1))
254
+
255
+ def forward(
256
+ self,
257
+ post_stream: torch.Tensor,
258
+ pre_stream: torch.Tensor,
259
+ attention_mask: Optional[torch.Tensor],
260
+ position_embeddings: tuple[torch.Tensor, torch.Tensor],
261
+ depth_context: _DepthContext,
262
+ past_key_values: Optional[Cache],
263
+ cache_position: Optional[torch.LongTensor],
264
+ output_attentions: bool,
265
+ **kwargs,
266
+ ) -> tuple[torch.Tensor, torch.Tensor, Optional[torch.Tensor]]:
267
+ pre_normalized = self.siamese_attn_pre_norm(pre_stream)
268
+ attention_input = torch.addcmul(
269
+ pre_normalized,
270
+ post_stream,
271
+ self.siamese_hybrid_attn_scale.to(dtype=post_stream.dtype),
272
+ )
273
+ attention_output, attention_weights = self.self_attn(
274
+ hidden_states=attention_input,
275
+ position_embeddings=position_embeddings,
276
+ attention_mask=attention_mask,
277
+ depth_context=depth_context,
278
+ past_key_values=past_key_values,
279
+ cache_position=cache_position,
280
+ output_attentions=output_attentions,
281
+ **kwargs,
282
+ )
283
+ post_stream = torch.add(
284
+ post_stream, attention_output, alpha=self.post_residual_scale
285
+ )
286
+ pre_stream = pre_stream + attention_output
287
+
288
+ # The native Hybrid-Pre block advances its post stream to the
289
+ # pre-MLP-normalized value before both the MLP input construction and
290
+ # the MLP residual update. This is intentionally not a conventional
291
+ # pre-norm residual that adds the branch back to the unnormalized
292
+ # stream.
293
+ post_stream = self.pre_mlp_layernorm(post_stream)
294
+ pre_normalized = self.siamese_mlp_pre_norm(pre_stream)
295
+ mlp_input = self.siamese_mlp_input_norm(
296
+ post_stream + pre_normalized
297
+ )
298
+ mlp_output = self.mlp(mlp_input)
299
+ post_stream = torch.add(
300
+ post_stream, mlp_output, alpha=self.post_residual_scale
301
+ )
302
+ pre_stream = pre_stream + mlp_output
303
+ return post_stream, pre_stream, attention_weights
304
+
305
+
306
+ class Olmo3SiameseDepthPreTrainedModel(Olmo3PreTrainedModel):
307
+ config_class = Olmo3SiameseDepthConfig
308
+ base_model_prefix = "model"
309
+ _no_split_modules = ["Olmo3SiameseDepthDecoderLayer"]
310
+ # Whole-layer replay is invalid for the mutable cross-layer Depth context.
311
+ # The native trainer supports only its dedicated selective-MLP checkpoint
312
+ # path; do not advertise Transformers' generic layer checkpointing.
313
+ supports_gradient_checkpointing = False
314
+
315
+
316
+ class Olmo3SiameseDepthModel(Olmo3SiameseDepthPreTrainedModel):
317
+ def __init__(self, config: Olmo3SiameseDepthConfig):
318
+ super().__init__(config)
319
+ self.padding_idx = config.pad_token_id
320
+ self.vocab_size = config.vocab_size
321
+ self.embed_tokens = nn.Embedding(
322
+ config.vocab_size, config.hidden_size, self.padding_idx
323
+ )
324
+ self.layers = nn.ModuleList(
325
+ [
326
+ Olmo3SiameseDepthDecoderLayer(config, layer_idx)
327
+ for layer_idx in range(config.num_hidden_layers)
328
+ ]
329
+ )
330
+ self.siamese_post_final_layernorm = Olmo3RMSNorm(
331
+ config.hidden_size, config.rms_norm_eps
332
+ )
333
+ self.siamese_pre_final_layernorm = Olmo3RMSNorm(
334
+ config.hidden_size, config.rms_norm_eps
335
+ )
336
+ self.norm = Olmo3RMSNorm(config.hidden_size, config.rms_norm_eps)
337
+ self.rotary_embs = nn.ModuleDict(
338
+ {
339
+ "sliding_attention": Olmo3RotaryEmbedding(
340
+ config=config, rope_type="default"
341
+ ),
342
+ "full_attention": Olmo3RotaryEmbedding(config=config),
343
+ }
344
+ )
345
+ self.gradient_checkpointing = False
346
+ self.post_init()
347
+
348
+ def get_input_embeddings(self):
349
+ return self.embed_tokens
350
+
351
+ def set_input_embeddings(self, value):
352
+ self.embed_tokens = value
353
+
354
+ def forward(
355
+ self,
356
+ input_ids: Optional[torch.LongTensor] = None,
357
+ attention_mask: Optional[torch.Tensor] = None,
358
+ position_ids: Optional[torch.LongTensor] = None,
359
+ past_key_values: Optional[Cache] = None,
360
+ inputs_embeds: Optional[torch.FloatTensor] = None,
361
+ cache_position: Optional[torch.LongTensor] = None,
362
+ use_cache: Optional[bool] = None,
363
+ output_attentions: Optional[bool] = None,
364
+ output_hidden_states: Optional[bool] = None,
365
+ return_dict: Optional[bool] = None,
366
+ **kwargs,
367
+ ) -> Union[tuple, BaseModelOutputWithPast]:
368
+ if (input_ids is None) == (inputs_embeds is None):
369
+ raise ValueError("Specify exactly one of input_ids or inputs_embeds.")
370
+ output_attentions = (
371
+ self.config.output_attentions
372
+ if output_attentions is None
373
+ else output_attentions
374
+ )
375
+ output_hidden_states = (
376
+ self.config.output_hidden_states
377
+ if output_hidden_states is None
378
+ else output_hidden_states
379
+ )
380
+ return_dict = self.config.use_return_dict if return_dict is None else return_dict
381
+ if inputs_embeds is None:
382
+ inputs_embeds = self.embed_tokens(input_ids)
383
+ if use_cache and past_key_values is None:
384
+ past_key_values = DynamicCache(config=self.config)
385
+ if cache_position is None:
386
+ past_seen_tokens = (
387
+ past_key_values.get_seq_length()
388
+ if past_key_values is not None
389
+ else 0
390
+ )
391
+ cache_position = torch.arange(
392
+ past_seen_tokens,
393
+ past_seen_tokens + inputs_embeds.shape[1],
394
+ device=inputs_embeds.device,
395
+ )
396
+ if position_ids is None:
397
+ position_ids = cache_position.unsqueeze(0)
398
+
399
+ if not isinstance(attention_mask, dict):
400
+ mask_kwargs = {
401
+ "config": self.config,
402
+ "input_embeds": inputs_embeds,
403
+ "attention_mask": attention_mask,
404
+ "cache_position": cache_position,
405
+ "past_key_values": past_key_values,
406
+ "position_ids": position_ids,
407
+ }
408
+ causal_masks = {
409
+ "full_attention": create_causal_mask(**mask_kwargs),
410
+ "sliding_attention": create_sliding_window_causal_mask(
411
+ **mask_kwargs
412
+ ),
413
+ }
414
+ else:
415
+ causal_masks = attention_mask
416
+
417
+ post_stream = inputs_embeds
418
+ # The optimized training path intentionally aliases both initial streams.
419
+ pre_stream = inputs_embeds
420
+ depth_context = _DepthContext(self.config)
421
+ position_embeddings = {
422
+ kind: rotary(post_stream, position_ids)
423
+ for kind, rotary in self.rotary_embs.items()
424
+ }
425
+ hidden_history = () if output_hidden_states else None
426
+ attention_history = () if output_attentions else None
427
+ for layer in self.layers:
428
+ if output_hidden_states:
429
+ hidden_history += (post_stream,)
430
+ attention_type = layer.self_attn.attention_type
431
+ post_stream, pre_stream, attention_weights = layer(
432
+ post_stream=post_stream,
433
+ pre_stream=pre_stream,
434
+ attention_mask=causal_masks[attention_type],
435
+ position_embeddings=position_embeddings[attention_type],
436
+ depth_context=depth_context,
437
+ past_key_values=past_key_values,
438
+ cache_position=cache_position,
439
+ output_attentions=output_attentions,
440
+ **kwargs,
441
+ )
442
+ if output_attentions:
443
+ attention_history += (attention_weights,)
444
+
445
+ hidden_states = (
446
+ self.siamese_post_final_layernorm(post_stream)
447
+ + self.siamese_pre_final_layernorm(pre_stream)
448
+ )
449
+ hidden_states = self.norm(hidden_states)
450
+ if output_hidden_states:
451
+ hidden_history += (hidden_states,)
452
+ if not return_dict:
453
+ values = (hidden_states, past_key_values, hidden_history, attention_history)
454
+ return tuple(value for value in values if value is not None)
455
+ return BaseModelOutputWithPast(
456
+ last_hidden_state=hidden_states,
457
+ past_key_values=past_key_values,
458
+ hidden_states=hidden_history,
459
+ attentions=attention_history,
460
+ )
461
+
462
+
463
+ class Olmo3SiameseDepthForCausalLM(
464
+ Olmo3SiameseDepthPreTrainedModel, GenerationMixin
465
+ ):
466
+ _tied_weights_keys = []
467
+
468
+ def __init__(self, config: Olmo3SiameseDepthConfig):
469
+ super().__init__(config)
470
+ self.model = Olmo3SiameseDepthModel(config)
471
+ self.vocab_size = config.vocab_size
472
+ self.lm_head = nn.Linear(config.hidden_size, config.vocab_size, bias=False)
473
+ self.post_init()
474
+
475
+ def get_input_embeddings(self):
476
+ return self.model.embed_tokens
477
+
478
+ def set_input_embeddings(self, value):
479
+ self.model.embed_tokens = value
480
+
481
+ def get_output_embeddings(self):
482
+ return self.lm_head
483
+
484
+ def set_output_embeddings(self, value):
485
+ self.lm_head = value
486
+
487
+ def forward(
488
+ self,
489
+ input_ids: Optional[torch.LongTensor] = None,
490
+ attention_mask: Optional[torch.Tensor] = None,
491
+ position_ids: Optional[torch.LongTensor] = None,
492
+ past_key_values: Optional[Cache] = None,
493
+ inputs_embeds: Optional[torch.FloatTensor] = None,
494
+ labels: Optional[torch.LongTensor] = None,
495
+ use_cache: Optional[bool] = None,
496
+ cache_position: Optional[torch.LongTensor] = None,
497
+ logits_to_keep: Union[int, torch.Tensor] = 0,
498
+ output_attentions: Optional[bool] = None,
499
+ output_hidden_states: Optional[bool] = None,
500
+ return_dict: Optional[bool] = None,
501
+ **kwargs,
502
+ ) -> Union[tuple, CausalLMOutputWithPast]:
503
+ return_dict = self.config.use_return_dict if return_dict is None else return_dict
504
+ outputs = self.model(
505
+ input_ids=input_ids,
506
+ attention_mask=attention_mask,
507
+ position_ids=position_ids,
508
+ past_key_values=past_key_values,
509
+ inputs_embeds=inputs_embeds,
510
+ use_cache=use_cache,
511
+ cache_position=cache_position,
512
+ output_attentions=output_attentions,
513
+ output_hidden_states=output_hidden_states,
514
+ return_dict=True,
515
+ **kwargs,
516
+ )
517
+ hidden_states = outputs.last_hidden_state
518
+ indices = (
519
+ slice(-logits_to_keep, None)
520
+ if isinstance(logits_to_keep, int)
521
+ else logits_to_keep
522
+ )
523
+ logits = self.lm_head(hidden_states[:, indices, :])
524
+ loss = None
525
+ if labels is not None:
526
+ loss = self.loss_function(
527
+ logits=logits,
528
+ labels=labels,
529
+ vocab_size=self.config.vocab_size,
530
+ **kwargs,
531
+ )
532
+ if not return_dict:
533
+ result = (logits, outputs.past_key_values)
534
+ return ((loss,) + result) if loss is not None else result
535
+ return CausalLMOutputWithPast(
536
+ loss=loss,
537
+ logits=logits,
538
+ past_key_values=outputs.past_key_values,
539
+ hidden_states=outputs.hidden_states,
540
+ attentions=outputs.attentions,
541
+ )
542
+
543
+
544
+ __all__ = [
545
+ "Olmo3SiameseDepthForCausalLM",
546
+ "Olmo3SiameseDepthModel",
547
+ "Olmo3SiameseDepthPreTrainedModel",
548
+ ]
olmo3/1b/stage4/instruct/special_tokens_map.json ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "bos_token": {
3
+ "content": "<|endoftext|>",
4
+ "lstrip": false,
5
+ "normalized": false,
6
+ "rstrip": false,
7
+ "single_word": false
8
+ },
9
+ "eos_token": {
10
+ "content": "<|endoftext|>",
11
+ "lstrip": false,
12
+ "normalized": false,
13
+ "rstrip": false,
14
+ "single_word": false
15
+ },
16
+ "pad_token": {
17
+ "content": "<|pad|>",
18
+ "lstrip": false,
19
+ "normalized": false,
20
+ "rstrip": false,
21
+ "single_word": false
22
+ },
23
+ "unk_token": {
24
+ "content": "<|endoftext|>",
25
+ "lstrip": false,
26
+ "normalized": false,
27
+ "rstrip": false,
28
+ "single_word": false
29
+ }
30
+ }
olmo3/1b/stage4/instruct/tokenizer.json ADDED
The diff for this file is too large to render. See raw diff
 
olmo3/1b/stage4/instruct/tokenizer_config.json ADDED
@@ -0,0 +1,191 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "add_prefix_space": false,
3
+ "added_tokens_decoder": {
4
+ "100256": {
5
+ "content": "<|extra_id_0|>",
6
+ "lstrip": false,
7
+ "normalized": false,
8
+ "rstrip": false,
9
+ "single_word": false,
10
+ "special": false
11
+ },
12
+ "100257": {
13
+ "content": "<|endoftext|>",
14
+ "lstrip": false,
15
+ "normalized": false,
16
+ "rstrip": false,
17
+ "single_word": false,
18
+ "special": true
19
+ },
20
+ "100258": {
21
+ "content": "<|fim_prefix|>",
22
+ "lstrip": false,
23
+ "normalized": false,
24
+ "rstrip": false,
25
+ "single_word": false,
26
+ "special": true
27
+ },
28
+ "100259": {
29
+ "content": "<|fim_middle|>",
30
+ "lstrip": false,
31
+ "normalized": false,
32
+ "rstrip": false,
33
+ "single_word": false,
34
+ "special": true
35
+ },
36
+ "100260": {
37
+ "content": "<|fim_suffix|>",
38
+ "lstrip": false,
39
+ "normalized": false,
40
+ "rstrip": false,
41
+ "single_word": false,
42
+ "special": true
43
+ },
44
+ "100261": {
45
+ "content": "|||PHONE_NUMBER|||",
46
+ "lstrip": false,
47
+ "normalized": false,
48
+ "rstrip": false,
49
+ "single_word": false,
50
+ "special": false
51
+ },
52
+ "100262": {
53
+ "content": "|||EMAIL_ADDRESS|||",
54
+ "lstrip": false,
55
+ "normalized": false,
56
+ "rstrip": false,
57
+ "single_word": false,
58
+ "special": false
59
+ },
60
+ "100263": {
61
+ "content": "|||IP_ADDRESS|||",
62
+ "lstrip": false,
63
+ "normalized": false,
64
+ "rstrip": false,
65
+ "single_word": false,
66
+ "special": false
67
+ },
68
+ "100264": {
69
+ "content": "<|im_start|>",
70
+ "lstrip": false,
71
+ "normalized": false,
72
+ "rstrip": false,
73
+ "single_word": false,
74
+ "special": true
75
+ },
76
+ "100265": {
77
+ "content": "<|im_end|>",
78
+ "lstrip": false,
79
+ "normalized": false,
80
+ "rstrip": false,
81
+ "single_word": false,
82
+ "special": true
83
+ },
84
+ "100266": {
85
+ "content": "<functions>",
86
+ "lstrip": false,
87
+ "normalized": false,
88
+ "rstrip": false,
89
+ "single_word": false,
90
+ "special": false
91
+ },
92
+ "100267": {
93
+ "content": "</functions>",
94
+ "lstrip": false,
95
+ "normalized": false,
96
+ "rstrip": false,
97
+ "single_word": false,
98
+ "special": false
99
+ },
100
+ "100268": {
101
+ "content": "<function_calls>",
102
+ "lstrip": false,
103
+ "normalized": false,
104
+ "rstrip": false,
105
+ "single_word": false,
106
+ "special": false
107
+ },
108
+ "100269": {
109
+ "content": "</function_calls>",
110
+ "lstrip": false,
111
+ "normalized": false,
112
+ "rstrip": false,
113
+ "single_word": false,
114
+ "special": false
115
+ },
116
+ "100270": {
117
+ "content": "<|extra_id_1|>",
118
+ "lstrip": false,
119
+ "normalized": false,
120
+ "rstrip": false,
121
+ "single_word": false,
122
+ "special": false
123
+ },
124
+ "100271": {
125
+ "content": "<|extra_id_2|>",
126
+ "lstrip": false,
127
+ "normalized": false,
128
+ "rstrip": false,
129
+ "single_word": false,
130
+ "special": false
131
+ },
132
+ "100272": {
133
+ "content": "<|extra_id_3|>",
134
+ "lstrip": false,
135
+ "normalized": false,
136
+ "rstrip": false,
137
+ "single_word": false,
138
+ "special": false
139
+ },
140
+ "100273": {
141
+ "content": "<|extra_id_4|>",
142
+ "lstrip": false,
143
+ "normalized": false,
144
+ "rstrip": false,
145
+ "single_word": false,
146
+ "special": false
147
+ },
148
+ "100274": {
149
+ "content": "<|extra_id_5|>",
150
+ "lstrip": false,
151
+ "normalized": false,
152
+ "rstrip": false,
153
+ "single_word": false,
154
+ "special": false
155
+ },
156
+ "100275": {
157
+ "content": "<|extra_id_6|>",
158
+ "lstrip": false,
159
+ "normalized": false,
160
+ "rstrip": false,
161
+ "single_word": false,
162
+ "special": false
163
+ },
164
+ "100276": {
165
+ "content": "<|endofprompt|>",
166
+ "lstrip": false,
167
+ "normalized": false,
168
+ "rstrip": false,
169
+ "single_word": false,
170
+ "special": true
171
+ },
172
+ "100277": {
173
+ "content": "<|pad|>",
174
+ "lstrip": false,
175
+ "normalized": false,
176
+ "rstrip": false,
177
+ "single_word": false,
178
+ "special": true
179
+ }
180
+ },
181
+ "bos_token": "<|endoftext|>",
182
+ "chat_template": "{%- set has_system = messages|selectattr('role', 'equalto', 'system')|list|length > 0 -%}{%- if not has_system -%}{{- '<|im_start|>system\nYou are a helpful function-calling AI assistant. ' -}}{%- if tools is none or (tools | length) == 0 -%}{{- 'You do not currently have access to any functions. <functions></functions><|im_end|>\n' -}}{%- else -%}{{- 'You are provided with function signatures within <functions></functions> XML tags. You may call one or more functions to assist with the user query. Output any function calls within <function_calls></function_calls> XML tags. Do not make assumptions about what values to plug into functions.' -}}{{- '<functions>' -}}{{- tools | tojson -}}{{- '</functions><|im_end|>\n' -}}{%- endif -%}{%- endif -%}{%- for message in messages -%}{%- if message['role'] == 'system' -%}{{- '<|im_start|>system\n' + message['content'] -}}{%- if tools is not none -%}{{- '<functions>' -}}{{- tools | tojson -}}{{- '</functions>' -}}{%- elif message.get('functions', none) is not none -%}{{- ' <functions>' + message['functions'] + '</functions>' -}}{%- endif -%}{{- '<|im_end|>\n' -}}{%- elif message['role'] == 'user' -%}{{- '<|im_start|>user\n' + message['content'] + '<|im_end|>\n' -}}{%- elif message['role'] == 'assistant' -%}{{- '<|im_start|>assistant\n' -}}{%- if message.get('content', none) is not none -%}{{- message['content'] -}}{%- endif -%}{%- if message.get('function_calls', none) is not none and (message['function_calls'] | length) > 0 -%}{{- '<function_calls>' + message['function_calls'] + '</function_calls>' -}}{%- elif message.get('tool_calls', none) is not none and (message['tool_calls'] | length) > 0 -%}{{- '<function_calls>' -}}{%- for tool_call in message['tool_calls'] %}{%- if tool_call is mapping and tool_call.get('function', none) is not none %}{%- set args = tool_call['function']['arguments'] -%}{%- set ns = namespace(arguments_list=[]) -%}{%- for key, value in args.items() -%}{%- set ns.arguments_list = ns.arguments_list + [key ~ '=' ~ (value | tojson)] -%}{%- endfor -%}{%- set arguments = ns.arguments_list | join(', ') -%}{{- tool_call['function']['name'] + '(' + arguments + ')' -}}{%- if not loop.last -%}{{ '\n' }}{%- endif -%}{% else %}{{- tool_call -}}{%- endif %}{%- endfor %}{{- '</function_calls>' -}}{%- endif -%}{%- if not loop.last -%}{{- '<|im_end|>' + '\n' -}}{%- else -%}{{- eos_token -}}{%- endif -%}{%- elif message['role'] == 'environment' -%}{{- '<|im_start|>environment\n' + message['content'] + '<|im_end|>\n' -}}{%- elif message['role'] == 'tool' -%}{{- '<|im_start|>environment\n' + message['content'] + '<|im_end|>\n' -}}{%- endif -%}{%- if loop.last and add_generation_prompt -%}{{- '<|im_start|>assistant\n' -}}{%- endif -%}{%- endfor -%}",
183
+ "clean_up_tokenization_spaces": false,
184
+ "eos_token": "<|endoftext|>",
185
+ "extra_special_tokens": {},
186
+ "fix_mistral_regex": false,
187
+ "model_max_length": 65536,
188
+ "pad_token": "<|pad|>",
189
+ "tokenizer_class": "GPT2Tokenizer",
190
+ "unk_token": "<|endoftext|>"
191
+ }
olmo3/1b/stage4/instruct/vocab.json ADDED
The diff for this file is too large to render. See raw diff
 
olmo3/1b/stage4/think/PUBLIC_FILES.SHA256 ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 7ad9734423206b9dc3ddc76b320d5fe29f142245ef0df47981d69bdebe148556 README.md
2
+ e2144e7990128799f6eaf6430ea0a472dbb17e076bdb08b327887e59f84657be __init__.py
3
+ a3d6a7ad3fde8e26fa9953d80ac30682f7d56ac1d03f3428910a4239a4e23bef chat_template.jinja
4
+ 77c545f18298aa5960d58d0c83eb752b8559ebac016f5755a3aef50b226588c8 config.json
5
+ d66ccce18efda42443a91536bf907e7bcb6e2d0acd0c8dc70d69eb15f277d634 configuration_olmo3_siamese_depth.py
6
+ dbd4aa5dc6f7f1bdc0c181d9e5582f6571e1d2a22878dfcd98149324b9f5c4a2 generation_config.json
7
+ b6fe424e334903f7fb84d3a106d9730455f4744b9fe3c21ee136d97a00e72502 merges.txt
8
+ 29c4567bcbcaf74acfca88df34c23fd23604f1ad66b933ff92bf72991c01ed58 model.safetensors
9
+ 12329a1f6cb1732bf100bda2ee2dd62761f6485aefb0a977879eb6d74f764aa6 modeling_olmo3_siamese_depth.py
10
+ 78afb564e81264029b25f9caf24bda2521d5bdaeff5cd3fdbc01d3da2e8ce2f2 special_tokens_map.json
11
+ 7738a25c46a6043a0e2e605138851baa450269ce9d800af6ca9bf6192e45510c tokenizer.json
12
+ 5f959b9c0cff767a63f22a0569e0554cce28214fb49e41479ba326f44169c5ec tokenizer_config.json
13
+ d8eb44d0d51f5e39c9b14825ca8bd10a2500f99c438ca81d4462f0263acd3b53 vocab.json
olmo3/1b/stage4/think/README.md ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ # Stage 4 Think SFT checkpoint
2
+
3
+ This subfolder contains a complete Hugging Face checkpoint with a context
4
+ length of 65536 tokens. Load it from the parent model repository using
5
+ `trust_remote_code=True`, `subfolder="olmo3/1b/stage4/think"`, and
6
+ `attn_implementation="sdpa"`.
olmo3/1b/stage4/think/__init__.py ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ from .configuration_olmo3_siamese_depth import Olmo3SiameseDepthConfig
2
+ from .modeling_olmo3_siamese_depth import Olmo3SiameseDepthForCausalLM, Olmo3SiameseDepthModel
olmo3/1b/stage4/think/chat_template.jinja ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {%- set has_system = messages|selectattr('role', 'equalto', 'system')|list|length > 0 -%}{%- if not has_system -%}{{- '<|im_start|>system
2
+ You are a helpful function-calling AI assistant. ' -}}{%- if tools is none or (tools | length) == 0 -%}{{- 'You do not currently have access to any functions. <functions></functions><|im_end|>
3
+ ' -}}{%- else -%}{{- 'You are provided with function signatures within <functions></functions> XML tags. You may call one or more functions to assist with the user query. Output any function calls within <function_calls></function_calls> XML tags. Do not make assumptions about what values to plug into functions.' -}}{{- '<functions>' -}}{{- tools | tojson -}}{{- '</functions><|im_end|>
4
+ ' -}}{%- endif -%}{%- endif -%}{%- for message in messages -%}{%- if message['role'] == 'system' -%}{{- '<|im_start|>system
5
+ ' + message['content'] -}}{%- if tools is not none -%}{{- '<functions>' -}}{{- tools | tojson -}}{{- '</functions>' -}}{%- elif message.get('functions', none) is not none -%}{{- ' <functions>' + message['functions'] + '</functions>' -}}{%- endif -%}{{- '<|im_end|>
6
+ ' -}}{%- elif message['role'] == 'user' -%}{{- '<|im_start|>user
7
+ ' + message['content'] + '<|im_end|>
8
+ ' -}}{%- elif message['role'] == 'assistant' -%}{{- '<|im_start|>assistant
9
+ ' -}}{%- if message.get('content', none) is not none -%}{{- message['content'] -}}{%- endif -%}{%- if message.get('function_calls', none) is not none and (message['function_calls'] | length) > 0 -%}{{- '<function_calls>' + message['function_calls'] + '</function_calls>' -}}{%- elif message.get('tool_calls', none) is not none and (message['tool_calls'] | length) > 0 -%}{{- '<function_calls>' -}}{%- for tool_call in message['tool_calls'] %}{%- if tool_call is mapping and tool_call.get('function', none) is not none %}{%- set args = tool_call['function']['arguments'] -%}{%- set ns = namespace(arguments_list=[]) -%}{%- for key, value in args.items() -%}{%- set ns.arguments_list = ns.arguments_list + [key ~ '=' ~ (value | tojson)] -%}{%- endfor -%}{%- set arguments = ns.arguments_list | join(', ') -%}{{- tool_call['function']['name'] + '(' + arguments + ')' -}}{%- if not loop.last -%}{{ '
10
+ ' }}{%- endif -%}{% else %}{{- tool_call -}}{%- endif %}{%- endfor %}{{- '</function_calls>' -}}{%- endif -%}{%- if not loop.last -%}{{- '<|im_end|>' + '
11
+ ' -}}{%- else -%}{{- eos_token -}}{%- endif -%}{%- elif message['role'] == 'environment' -%}{{- '<|im_start|>environment
12
+ ' + message['content'] + '<|im_end|>
13
+ ' -}}{%- elif message['role'] == 'tool' -%}{{- '<|im_start|>environment
14
+ ' + message['content'] + '<|im_end|>
15
+ ' -}}{%- endif -%}{%- if loop.last and add_generation_prompt -%}{{- '<|im_start|>assistant
16
+ ' -}}{%- endif -%}{%- endfor -%}
olmo3/1b/stage4/think/config.json ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "_name_or_path": "",
3
+ "architectures": [
4
+ "Olmo3SiameseDepthForCausalLM"
5
+ ],
6
+ "attention_bias": false,
7
+ "attention_dropout": 0.0,
8
+ "auto_map": {
9
+ "AutoConfig": "configuration_olmo3_siamese_depth.Olmo3SiameseDepthConfig",
10
+ "AutoModel": "modeling_olmo3_siamese_depth.Olmo3SiameseDepthModel",
11
+ "AutoModelForCausalLM": "modeling_olmo3_siamese_depth.Olmo3SiameseDepthForCausalLM"
12
+ },
13
+ "bos_token_id": null,
14
+ "depth_attention_recent_window": 0,
15
+ "depth_attention_stride": 8,
16
+ "eos_token_id": 100257,
17
+ "hidden_act": "silu",
18
+ "hidden_dropout": 0.0,
19
+ "hidden_size": 2048,
20
+ "initializer_range": 0.02,
21
+ "intermediate_size": 8192,
22
+ "layer_types": [
23
+ "sliding_attention",
24
+ "sliding_attention",
25
+ "sliding_attention",
26
+ "full_attention",
27
+ "sliding_attention",
28
+ "sliding_attention",
29
+ "sliding_attention",
30
+ "full_attention",
31
+ "sliding_attention",
32
+ "sliding_attention",
33
+ "sliding_attention",
34
+ "full_attention",
35
+ "sliding_attention",
36
+ "sliding_attention",
37
+ "sliding_attention",
38
+ "full_attention"
39
+ ],
40
+ "max_position_embeddings": 65536,
41
+ "max_sequence_length": 65536,
42
+ "mlp_bias": false,
43
+ "model_type": "olmo3_siamese_depth",
44
+ "num_attention_heads": 16,
45
+ "num_hidden_layers": 16,
46
+ "num_key_value_heads": 16,
47
+ "olmo3_weight_decay": true,
48
+ "pad_token_id": 100277,
49
+ "padded_vocab_size": 100352,
50
+ "qk_norm": true,
51
+ "qk_norm_mode": "full_projection",
52
+ "rms_norm_eps": 1e-06,
53
+ "rope_full_precision": true,
54
+ "rope_scaling": {
55
+ "beta_fast": 32.0,
56
+ "beta_slow": 1.0,
57
+ "factor": 8.0,
58
+ "original_max_position_embeddings": 8192,
59
+ "rope_type": "yarn"
60
+ },
61
+ "rope_theta": 500000.0,
62
+ "scale_embeds": false,
63
+ "scale_output_layer_init": false,
64
+ "siamese_norm_variant": "hybrid_pre",
65
+ "sliding_window": 4096,
66
+ "tie_word_embeddings": false,
67
+ "torch_dtype": "bfloat16",
68
+ "transformers_version": "4.57.6",
69
+ "true_vocab_size": 100278,
70
+ "truncated_normal_factor": 3.0,
71
+ "use_cache": true,
72
+ "use_depth_attention": true,
73
+ "use_siamese_norm": true,
74
+ "vocab_size": 100278,
75
+ "vocab_z_loss_coeff": 1e-05
76
+ }
olmo3/1b/stage4/think/configuration_olmo3_siamese_depth.py ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Hugging Face configuration for the OLMo 3 Siamese-Norm/Depth-Attention model."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from transformers.models.olmo3.configuration_olmo3 import Olmo3Config
6
+
7
+
8
+ class Olmo3SiameseDepthConfig(Olmo3Config):
9
+ """OLMo 3 plus the checkpoint-compatible Siamese/Depth extensions."""
10
+
11
+ model_type = "olmo3_siamese_depth"
12
+
13
+ def __init__(
14
+ self,
15
+ *args,
16
+ vocab_size: int | None = None,
17
+ true_vocab_size: int = 100278,
18
+ padded_vocab_size: int = 100352,
19
+ qk_norm_mode: str = "full_projection",
20
+ use_siamese_norm: bool = True,
21
+ siamese_norm_variant: str = "hybrid_pre",
22
+ use_depth_attention: bool = True,
23
+ depth_attention_stride: int = 8,
24
+ depth_attention_recent_window: int = 0,
25
+ rope_full_precision: bool = True,
26
+ **kwargs,
27
+ ):
28
+ # ``PretrainedConfig.to_diff_dict()`` constructs a no-argument instance
29
+ # of this class. Make that default instance internally consistent
30
+ # instead of inheriting OLMo3's unrelated 50304-token default.
31
+ if vocab_size is None:
32
+ vocab_size = true_vocab_size
33
+ super().__init__(*args, vocab_size=vocab_size, **kwargs)
34
+ self.true_vocab_size = int(true_vocab_size)
35
+ self.padded_vocab_size = int(padded_vocab_size)
36
+ self.qk_norm = True
37
+ self.qk_norm_mode = qk_norm_mode
38
+ self.use_siamese_norm = bool(use_siamese_norm)
39
+ self.siamese_norm_variant = siamese_norm_variant
40
+ self.use_depth_attention = bool(use_depth_attention)
41
+ self.depth_attention_stride = int(depth_attention_stride)
42
+ self.depth_attention_recent_window = int(depth_attention_recent_window)
43
+ self.rope_full_precision = bool(rope_full_precision)
44
+ self._validate_siamese_depth()
45
+
46
+ def _validate_siamese_depth(self) -> None:
47
+ if self.vocab_size != self.true_vocab_size:
48
+ raise ValueError(
49
+ "HF vocab_size must equal true_vocab_size after padded-row removal; "
50
+ f"got {self.vocab_size} and {self.true_vocab_size}."
51
+ )
52
+ if self.padded_vocab_size < self.true_vocab_size:
53
+ raise ValueError("padded_vocab_size cannot be smaller than true_vocab_size.")
54
+ if self.qk_norm_mode != "full_projection":
55
+ raise ValueError("qk_norm_mode must be 'full_projection'.")
56
+ if not self.use_siamese_norm or self.siamese_norm_variant != "hybrid_pre":
57
+ raise ValueError("This remote model requires Hybrid-Pre Siamese Norm.")
58
+ if not self.use_depth_attention:
59
+ raise ValueError("This remote model requires Depth Attention.")
60
+ if self.depth_attention_stride < 1:
61
+ raise ValueError("depth_attention_stride must be positive.")
62
+ if self.depth_attention_recent_window < 0:
63
+ raise ValueError("depth_attention_recent_window must be non-negative.")
64
+ if not self.rope_full_precision:
65
+ raise ValueError("OLMo 3 requires FP32 Q/K RoPE.")
66
+ if self.hidden_size % self.num_attention_heads:
67
+ raise ValueError("hidden_size must be divisible by num_attention_heads.")
68
+ if self.num_attention_heads % self.num_key_value_heads:
69
+ raise ValueError("num_attention_heads must be divisible by num_key_value_heads.")
70
+ expected_layer_types = [
71
+ "sliding_attention" if (index + 1) % 4 else "full_attention"
72
+ for index in range(self.num_hidden_layers)
73
+ ]
74
+ if list(self.layer_types) != expected_layer_types:
75
+ raise ValueError("OLMo 3 requires the repeating SWA,SWA,SWA,Full pattern.")
76
+
77
+
78
+ __all__ = ["Olmo3SiameseDepthConfig"]
olmo3/1b/stage4/think/generation_config.json ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ {
2
+ "_from_model_config": true,
3
+ "bos_token_id": null,
4
+ "eos_token_id": 100257,
5
+ "pad_token_id": 100277,
6
+ "transformers_version": "4.57.6"
7
+ }
olmo3/1b/stage4/think/merges.txt ADDED
The diff for this file is too large to render. See raw diff
 
olmo3/1b/stage4/think/model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:29c4567bcbcaf74acfca88df34c23fd23604f1ad66b933ff92bf72991c01ed58
3
+ size 2969458432
olmo3/1b/stage4/think/modeling_olmo3_siamese_depth.py ADDED
@@ -0,0 +1,548 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Transformers remote code for OLMo 3 + Siamese Norm + Depth Attention.
2
+
3
+ The Full/SWA masks, Full-only YaRN rotary embeddings, and bounded sliding KV
4
+ cache are delegated to the official Transformers OLMo 3 implementation. This
5
+ file adds only the two checkpoint-persistent mechanisms used during training:
6
+ Hybrid-Pre Siamese Norm and recursive same-position Depth Attention.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import math
12
+ from dataclasses import dataclass
13
+ from typing import Optional, Union
14
+
15
+ import torch
16
+ import torch.nn as nn
17
+ from transformers.cache_utils import Cache, DynamicCache
18
+ from transformers.generation import GenerationMixin
19
+ from transformers.masking_utils import create_causal_mask, create_sliding_window_causal_mask
20
+ from transformers.modeling_outputs import BaseModelOutputWithPast, CausalLMOutputWithPast
21
+ from transformers.modeling_utils import ALL_ATTENTION_FUNCTIONS
22
+ from transformers.models.olmo3.modeling_olmo3 import (
23
+ Olmo3MLP,
24
+ Olmo3PreTrainedModel,
25
+ Olmo3RMSNorm,
26
+ Olmo3RotaryEmbedding,
27
+ apply_rotary_pos_emb,
28
+ eager_attention_forward,
29
+ )
30
+
31
+ from .configuration_olmo3_siamese_depth import Olmo3SiameseDepthConfig
32
+
33
+
34
+ @dataclass
35
+ class _DepthSource:
36
+ layer_index: int
37
+ key: torch.Tensor
38
+ value: torch.Tensor
39
+
40
+
41
+ class _DepthContext:
42
+ def __init__(self, config: Olmo3SiameseDepthConfig):
43
+ self.num_layers = int(config.num_hidden_layers)
44
+ self.stride = int(config.depth_attention_stride)
45
+ self.recent_window = int(config.depth_attention_recent_window)
46
+ self.records: dict[int, _DepthSource] = {}
47
+
48
+ def sources_for(self, layer_index: int) -> tuple[_DepthSource, ...]:
49
+ recent_start = max(0, layer_index - self.recent_window)
50
+ return tuple(
51
+ self.records[index]
52
+ for index in sorted(self.records)
53
+ if index < layer_index
54
+ and (index % self.stride == 0 or index >= recent_start)
55
+ )
56
+
57
+ def record(self, layer_index: int, key: torch.Tensor, value: torch.Tensor) -> None:
58
+ if layer_index in self.records:
59
+ raise RuntimeError(f"Depth Attention layer {layer_index} was recorded twice.")
60
+ self.records[layer_index] = _DepthSource(layer_index, key, value)
61
+ next_recent_start = layer_index + 1 - self.recent_window
62
+ stale = [
63
+ index
64
+ for index in self.records
65
+ if index % self.stride != 0 and index < next_recent_start
66
+ ]
67
+ for index in stale:
68
+ del self.records[index]
69
+
70
+
71
+ def _depth_attention_mix(
72
+ query: torch.Tensor,
73
+ key: torch.Tensor,
74
+ value: torch.Tensor,
75
+ sources: tuple[_DepthSource, ...],
76
+ ) -> torch.Tensor:
77
+ """Mix current V with recursively mixed V from selected earlier layers.
78
+
79
+ Tensors use Transformers' ``[batch, heads, sequence, head_dim]`` layout.
80
+ """
81
+
82
+ if not sources:
83
+ return value
84
+ query_heads = query.shape[1]
85
+ kv_heads = key.shape[1]
86
+ if query_heads % kv_heads:
87
+ raise ValueError("Depth Attention requires Q heads divisible by KV heads.")
88
+ group_size = query_heads // kv_heads
89
+ grouped_query = (
90
+ query
91
+ if group_size == 1
92
+ else query.reshape(
93
+ query.shape[0],
94
+ kv_heads,
95
+ group_size,
96
+ query.shape[2],
97
+ query.shape[3],
98
+ ).mean(dim=2)
99
+ )
100
+ scale = 1.0 / math.sqrt(query.shape[-1])
101
+ scores = [
102
+ (grouped_query * source.key).sum(dim=-1, keepdim=True) * scale
103
+ for source in sources
104
+ ]
105
+ scores.append((grouped_query * key).sum(dim=-1, keepdim=True) * scale)
106
+ weights = torch.softmax(torch.cat(scores, dim=-1), dim=-1, dtype=torch.float32)
107
+ weights = weights.to(dtype=value.dtype)
108
+ mixed = weights[..., -1:].mul(value)
109
+ for source_index, source in enumerate(sources):
110
+ mixed = mixed + weights[..., source_index : source_index + 1] * source.value
111
+ return mixed
112
+
113
+
114
+ class Olmo3SiameseDepthAttention(nn.Module):
115
+ def __init__(self, config: Olmo3SiameseDepthConfig, layer_idx: int):
116
+ super().__init__()
117
+ self.config = config
118
+ self.layer_idx = int(layer_idx)
119
+ self.head_dim = getattr(
120
+ config, "head_dim", config.hidden_size // config.num_attention_heads
121
+ )
122
+ self.num_key_value_groups = (
123
+ config.num_attention_heads // config.num_key_value_heads
124
+ )
125
+ self.scaling = self.head_dim**-0.5
126
+ self.attention_dropout = float(config.attention_dropout)
127
+ self.is_causal = True
128
+ self.q_proj = nn.Linear(
129
+ config.hidden_size,
130
+ config.num_attention_heads * self.head_dim,
131
+ bias=False,
132
+ )
133
+ self.k_proj = nn.Linear(
134
+ config.hidden_size,
135
+ config.num_key_value_heads * self.head_dim,
136
+ bias=False,
137
+ )
138
+ self.v_proj = nn.Linear(
139
+ config.hidden_size,
140
+ config.num_key_value_heads * self.head_dim,
141
+ bias=False,
142
+ )
143
+ self.o_proj = nn.Linear(
144
+ config.num_attention_heads * self.head_dim,
145
+ config.hidden_size,
146
+ bias=False,
147
+ )
148
+ # These norms cover the complete Q and K projections, not one head.
149
+ self.q_norm = Olmo3RMSNorm(
150
+ config.num_attention_heads * self.head_dim, config.rms_norm_eps
151
+ )
152
+ self.k_norm = Olmo3RMSNorm(
153
+ config.num_key_value_heads * self.head_dim, config.rms_norm_eps
154
+ )
155
+ self.attention_type = config.layer_types[self.layer_idx]
156
+ self.sliding_window = (
157
+ int(config.sliding_window)
158
+ if self.attention_type == "sliding_attention"
159
+ else None
160
+ )
161
+
162
+ def forward(
163
+ self,
164
+ hidden_states: torch.Tensor,
165
+ position_embeddings: tuple[torch.Tensor, torch.Tensor],
166
+ attention_mask: Optional[torch.Tensor],
167
+ depth_context: _DepthContext,
168
+ past_key_values: Optional[Cache] = None,
169
+ cache_position: Optional[torch.LongTensor] = None,
170
+ output_attentions: bool = False,
171
+ **kwargs,
172
+ ) -> tuple[torch.Tensor, Optional[torch.Tensor]]:
173
+ batch_size, sequence_length, _ = hidden_states.shape
174
+ query = self.q_norm(self.q_proj(hidden_states)).view(
175
+ batch_size, sequence_length, self.config.num_attention_heads, self.head_dim
176
+ ).transpose(1, 2)
177
+ key = self.k_norm(self.k_proj(hidden_states)).view(
178
+ batch_size, sequence_length, self.config.num_key_value_heads, self.head_dim
179
+ ).transpose(1, 2)
180
+ value = self.v_proj(hidden_states).view(
181
+ batch_size, sequence_length, self.config.num_key_value_heads, self.head_dim
182
+ ).transpose(1, 2)
183
+
184
+ cos, sin = position_embeddings
185
+ query, key = apply_rotary_pos_emb(query.float(), key.float(), cos.float(), sin.float())
186
+ query = query.to(dtype=hidden_states.dtype)
187
+ key = key.to(dtype=hidden_states.dtype)
188
+
189
+ mixed_value = _depth_attention_mix(
190
+ query,
191
+ key,
192
+ value,
193
+ depth_context.sources_for(self.layer_idx),
194
+ )
195
+ depth_context.record(self.layer_idx, key, mixed_value)
196
+
197
+ attention_key = key
198
+ attention_value = mixed_value
199
+ if past_key_values is not None:
200
+ cache_kwargs = {
201
+ "sin": sin,
202
+ "cos": cos,
203
+ "cache_position": cache_position,
204
+ }
205
+ attention_key, attention_value = past_key_values.update(
206
+ key, mixed_value, self.layer_idx, cache_kwargs
207
+ )
208
+
209
+ attention_interface = eager_attention_forward
210
+ if self.config._attn_implementation != "eager":
211
+ attention_interface = ALL_ATTENTION_FUNCTIONS[
212
+ self.config._attn_implementation
213
+ ]
214
+ attention_output, attention_weights = attention_interface(
215
+ self,
216
+ query,
217
+ attention_key,
218
+ attention_value,
219
+ attention_mask,
220
+ dropout=0.0 if not self.training else self.attention_dropout,
221
+ scaling=self.scaling,
222
+ sliding_window=self.sliding_window,
223
+ **kwargs,
224
+ )
225
+ attention_output = attention_output.reshape(
226
+ batch_size, sequence_length, -1
227
+ ).contiguous()
228
+ attention_output = self.o_proj(attention_output)
229
+ return attention_output, attention_weights if output_attentions else None
230
+
231
+
232
+ class Olmo3SiameseDepthDecoderLayer(nn.Module):
233
+ def __init__(self, config: Olmo3SiameseDepthConfig, layer_idx: int):
234
+ super().__init__()
235
+ self.layer_idx = int(layer_idx)
236
+ self.self_attn = Olmo3SiameseDepthAttention(config, layer_idx)
237
+ self.mlp = Olmo3MLP(config)
238
+ self.pre_mlp_layernorm = Olmo3RMSNorm(
239
+ config.hidden_size, config.rms_norm_eps
240
+ )
241
+ self.siamese_attn_pre_norm = Olmo3RMSNorm(
242
+ config.hidden_size, config.rms_norm_eps
243
+ )
244
+ self.siamese_mlp_pre_norm = Olmo3RMSNorm(
245
+ config.hidden_size, config.rms_norm_eps
246
+ )
247
+ self.siamese_mlp_input_norm = Olmo3RMSNorm(
248
+ config.hidden_size, config.rms_norm_eps
249
+ )
250
+ self.siamese_hybrid_attn_scale = nn.Parameter(
251
+ torch.ones(config.hidden_size)
252
+ )
253
+ self.post_residual_scale = 1.0 / math.sqrt(2.0 * (self.layer_idx + 1))
254
+
255
+ def forward(
256
+ self,
257
+ post_stream: torch.Tensor,
258
+ pre_stream: torch.Tensor,
259
+ attention_mask: Optional[torch.Tensor],
260
+ position_embeddings: tuple[torch.Tensor, torch.Tensor],
261
+ depth_context: _DepthContext,
262
+ past_key_values: Optional[Cache],
263
+ cache_position: Optional[torch.LongTensor],
264
+ output_attentions: bool,
265
+ **kwargs,
266
+ ) -> tuple[torch.Tensor, torch.Tensor, Optional[torch.Tensor]]:
267
+ pre_normalized = self.siamese_attn_pre_norm(pre_stream)
268
+ attention_input = torch.addcmul(
269
+ pre_normalized,
270
+ post_stream,
271
+ self.siamese_hybrid_attn_scale.to(dtype=post_stream.dtype),
272
+ )
273
+ attention_output, attention_weights = self.self_attn(
274
+ hidden_states=attention_input,
275
+ position_embeddings=position_embeddings,
276
+ attention_mask=attention_mask,
277
+ depth_context=depth_context,
278
+ past_key_values=past_key_values,
279
+ cache_position=cache_position,
280
+ output_attentions=output_attentions,
281
+ **kwargs,
282
+ )
283
+ post_stream = torch.add(
284
+ post_stream, attention_output, alpha=self.post_residual_scale
285
+ )
286
+ pre_stream = pre_stream + attention_output
287
+
288
+ # The native Hybrid-Pre block advances its post stream to the
289
+ # pre-MLP-normalized value before both the MLP input construction and
290
+ # the MLP residual update. This is intentionally not a conventional
291
+ # pre-norm residual that adds the branch back to the unnormalized
292
+ # stream.
293
+ post_stream = self.pre_mlp_layernorm(post_stream)
294
+ pre_normalized = self.siamese_mlp_pre_norm(pre_stream)
295
+ mlp_input = self.siamese_mlp_input_norm(
296
+ post_stream + pre_normalized
297
+ )
298
+ mlp_output = self.mlp(mlp_input)
299
+ post_stream = torch.add(
300
+ post_stream, mlp_output, alpha=self.post_residual_scale
301
+ )
302
+ pre_stream = pre_stream + mlp_output
303
+ return post_stream, pre_stream, attention_weights
304
+
305
+
306
+ class Olmo3SiameseDepthPreTrainedModel(Olmo3PreTrainedModel):
307
+ config_class = Olmo3SiameseDepthConfig
308
+ base_model_prefix = "model"
309
+ _no_split_modules = ["Olmo3SiameseDepthDecoderLayer"]
310
+ # Whole-layer replay is invalid for the mutable cross-layer Depth context.
311
+ # The native trainer supports only its dedicated selective-MLP checkpoint
312
+ # path; do not advertise Transformers' generic layer checkpointing.
313
+ supports_gradient_checkpointing = False
314
+
315
+
316
+ class Olmo3SiameseDepthModel(Olmo3SiameseDepthPreTrainedModel):
317
+ def __init__(self, config: Olmo3SiameseDepthConfig):
318
+ super().__init__(config)
319
+ self.padding_idx = config.pad_token_id
320
+ self.vocab_size = config.vocab_size
321
+ self.embed_tokens = nn.Embedding(
322
+ config.vocab_size, config.hidden_size, self.padding_idx
323
+ )
324
+ self.layers = nn.ModuleList(
325
+ [
326
+ Olmo3SiameseDepthDecoderLayer(config, layer_idx)
327
+ for layer_idx in range(config.num_hidden_layers)
328
+ ]
329
+ )
330
+ self.siamese_post_final_layernorm = Olmo3RMSNorm(
331
+ config.hidden_size, config.rms_norm_eps
332
+ )
333
+ self.siamese_pre_final_layernorm = Olmo3RMSNorm(
334
+ config.hidden_size, config.rms_norm_eps
335
+ )
336
+ self.norm = Olmo3RMSNorm(config.hidden_size, config.rms_norm_eps)
337
+ self.rotary_embs = nn.ModuleDict(
338
+ {
339
+ "sliding_attention": Olmo3RotaryEmbedding(
340
+ config=config, rope_type="default"
341
+ ),
342
+ "full_attention": Olmo3RotaryEmbedding(config=config),
343
+ }
344
+ )
345
+ self.gradient_checkpointing = False
346
+ self.post_init()
347
+
348
+ def get_input_embeddings(self):
349
+ return self.embed_tokens
350
+
351
+ def set_input_embeddings(self, value):
352
+ self.embed_tokens = value
353
+
354
+ def forward(
355
+ self,
356
+ input_ids: Optional[torch.LongTensor] = None,
357
+ attention_mask: Optional[torch.Tensor] = None,
358
+ position_ids: Optional[torch.LongTensor] = None,
359
+ past_key_values: Optional[Cache] = None,
360
+ inputs_embeds: Optional[torch.FloatTensor] = None,
361
+ cache_position: Optional[torch.LongTensor] = None,
362
+ use_cache: Optional[bool] = None,
363
+ output_attentions: Optional[bool] = None,
364
+ output_hidden_states: Optional[bool] = None,
365
+ return_dict: Optional[bool] = None,
366
+ **kwargs,
367
+ ) -> Union[tuple, BaseModelOutputWithPast]:
368
+ if (input_ids is None) == (inputs_embeds is None):
369
+ raise ValueError("Specify exactly one of input_ids or inputs_embeds.")
370
+ output_attentions = (
371
+ self.config.output_attentions
372
+ if output_attentions is None
373
+ else output_attentions
374
+ )
375
+ output_hidden_states = (
376
+ self.config.output_hidden_states
377
+ if output_hidden_states is None
378
+ else output_hidden_states
379
+ )
380
+ return_dict = self.config.use_return_dict if return_dict is None else return_dict
381
+ if inputs_embeds is None:
382
+ inputs_embeds = self.embed_tokens(input_ids)
383
+ if use_cache and past_key_values is None:
384
+ past_key_values = DynamicCache(config=self.config)
385
+ if cache_position is None:
386
+ past_seen_tokens = (
387
+ past_key_values.get_seq_length()
388
+ if past_key_values is not None
389
+ else 0
390
+ )
391
+ cache_position = torch.arange(
392
+ past_seen_tokens,
393
+ past_seen_tokens + inputs_embeds.shape[1],
394
+ device=inputs_embeds.device,
395
+ )
396
+ if position_ids is None:
397
+ position_ids = cache_position.unsqueeze(0)
398
+
399
+ if not isinstance(attention_mask, dict):
400
+ mask_kwargs = {
401
+ "config": self.config,
402
+ "input_embeds": inputs_embeds,
403
+ "attention_mask": attention_mask,
404
+ "cache_position": cache_position,
405
+ "past_key_values": past_key_values,
406
+ "position_ids": position_ids,
407
+ }
408
+ causal_masks = {
409
+ "full_attention": create_causal_mask(**mask_kwargs),
410
+ "sliding_attention": create_sliding_window_causal_mask(
411
+ **mask_kwargs
412
+ ),
413
+ }
414
+ else:
415
+ causal_masks = attention_mask
416
+
417
+ post_stream = inputs_embeds
418
+ # The optimized training path intentionally aliases both initial streams.
419
+ pre_stream = inputs_embeds
420
+ depth_context = _DepthContext(self.config)
421
+ position_embeddings = {
422
+ kind: rotary(post_stream, position_ids)
423
+ for kind, rotary in self.rotary_embs.items()
424
+ }
425
+ hidden_history = () if output_hidden_states else None
426
+ attention_history = () if output_attentions else None
427
+ for layer in self.layers:
428
+ if output_hidden_states:
429
+ hidden_history += (post_stream,)
430
+ attention_type = layer.self_attn.attention_type
431
+ post_stream, pre_stream, attention_weights = layer(
432
+ post_stream=post_stream,
433
+ pre_stream=pre_stream,
434
+ attention_mask=causal_masks[attention_type],
435
+ position_embeddings=position_embeddings[attention_type],
436
+ depth_context=depth_context,
437
+ past_key_values=past_key_values,
438
+ cache_position=cache_position,
439
+ output_attentions=output_attentions,
440
+ **kwargs,
441
+ )
442
+ if output_attentions:
443
+ attention_history += (attention_weights,)
444
+
445
+ hidden_states = (
446
+ self.siamese_post_final_layernorm(post_stream)
447
+ + self.siamese_pre_final_layernorm(pre_stream)
448
+ )
449
+ hidden_states = self.norm(hidden_states)
450
+ if output_hidden_states:
451
+ hidden_history += (hidden_states,)
452
+ if not return_dict:
453
+ values = (hidden_states, past_key_values, hidden_history, attention_history)
454
+ return tuple(value for value in values if value is not None)
455
+ return BaseModelOutputWithPast(
456
+ last_hidden_state=hidden_states,
457
+ past_key_values=past_key_values,
458
+ hidden_states=hidden_history,
459
+ attentions=attention_history,
460
+ )
461
+
462
+
463
+ class Olmo3SiameseDepthForCausalLM(
464
+ Olmo3SiameseDepthPreTrainedModel, GenerationMixin
465
+ ):
466
+ _tied_weights_keys = []
467
+
468
+ def __init__(self, config: Olmo3SiameseDepthConfig):
469
+ super().__init__(config)
470
+ self.model = Olmo3SiameseDepthModel(config)
471
+ self.vocab_size = config.vocab_size
472
+ self.lm_head = nn.Linear(config.hidden_size, config.vocab_size, bias=False)
473
+ self.post_init()
474
+
475
+ def get_input_embeddings(self):
476
+ return self.model.embed_tokens
477
+
478
+ def set_input_embeddings(self, value):
479
+ self.model.embed_tokens = value
480
+
481
+ def get_output_embeddings(self):
482
+ return self.lm_head
483
+
484
+ def set_output_embeddings(self, value):
485
+ self.lm_head = value
486
+
487
+ def forward(
488
+ self,
489
+ input_ids: Optional[torch.LongTensor] = None,
490
+ attention_mask: Optional[torch.Tensor] = None,
491
+ position_ids: Optional[torch.LongTensor] = None,
492
+ past_key_values: Optional[Cache] = None,
493
+ inputs_embeds: Optional[torch.FloatTensor] = None,
494
+ labels: Optional[torch.LongTensor] = None,
495
+ use_cache: Optional[bool] = None,
496
+ cache_position: Optional[torch.LongTensor] = None,
497
+ logits_to_keep: Union[int, torch.Tensor] = 0,
498
+ output_attentions: Optional[bool] = None,
499
+ output_hidden_states: Optional[bool] = None,
500
+ return_dict: Optional[bool] = None,
501
+ **kwargs,
502
+ ) -> Union[tuple, CausalLMOutputWithPast]:
503
+ return_dict = self.config.use_return_dict if return_dict is None else return_dict
504
+ outputs = self.model(
505
+ input_ids=input_ids,
506
+ attention_mask=attention_mask,
507
+ position_ids=position_ids,
508
+ past_key_values=past_key_values,
509
+ inputs_embeds=inputs_embeds,
510
+ use_cache=use_cache,
511
+ cache_position=cache_position,
512
+ output_attentions=output_attentions,
513
+ output_hidden_states=output_hidden_states,
514
+ return_dict=True,
515
+ **kwargs,
516
+ )
517
+ hidden_states = outputs.last_hidden_state
518
+ indices = (
519
+ slice(-logits_to_keep, None)
520
+ if isinstance(logits_to_keep, int)
521
+ else logits_to_keep
522
+ )
523
+ logits = self.lm_head(hidden_states[:, indices, :])
524
+ loss = None
525
+ if labels is not None:
526
+ loss = self.loss_function(
527
+ logits=logits,
528
+ labels=labels,
529
+ vocab_size=self.config.vocab_size,
530
+ **kwargs,
531
+ )
532
+ if not return_dict:
533
+ result = (logits, outputs.past_key_values)
534
+ return ((loss,) + result) if loss is not None else result
535
+ return CausalLMOutputWithPast(
536
+ loss=loss,
537
+ logits=logits,
538
+ past_key_values=outputs.past_key_values,
539
+ hidden_states=outputs.hidden_states,
540
+ attentions=outputs.attentions,
541
+ )
542
+
543
+
544
+ __all__ = [
545
+ "Olmo3SiameseDepthForCausalLM",
546
+ "Olmo3SiameseDepthModel",
547
+ "Olmo3SiameseDepthPreTrainedModel",
548
+ ]
olmo3/1b/stage4/think/special_tokens_map.json ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "bos_token": {
3
+ "content": "<|endoftext|>",
4
+ "lstrip": false,
5
+ "normalized": false,
6
+ "rstrip": false,
7
+ "single_word": false
8
+ },
9
+ "eos_token": {
10
+ "content": "<|endoftext|>",
11
+ "lstrip": false,
12
+ "normalized": false,
13
+ "rstrip": false,
14
+ "single_word": false
15
+ },
16
+ "pad_token": {
17
+ "content": "<|pad|>",
18
+ "lstrip": false,
19
+ "normalized": false,
20
+ "rstrip": false,
21
+ "single_word": false
22
+ },
23
+ "unk_token": {
24
+ "content": "<|endoftext|>",
25
+ "lstrip": false,
26
+ "normalized": false,
27
+ "rstrip": false,
28
+ "single_word": false
29
+ }
30
+ }