cognithread-ssm / src_model_v2.py
gamer729's picture
Upload src_model_v2.py
a4af0a3 verified
Raw History Blame Contribute Delete
2.79 kB
###############################################################################
# CogniThread Model v2 — with vocabulary head for text generation
###############################################################################
class CogniThreadV2(nn.Module):
"""Full CogniThread + vocab head for next-token prediction."""
def __init__(self, d_model, d_state=16, n_heuristics=64, d_z=32,
T_diff=10, d_conv=4, expand=2, vocab_size=256, *,
rngs: nn.Rngs):
super().__init__()
self.d_model = d_model
self.d_state = d_state
self.d_z = d_z
self.vocab_size = vocab_size
# Byte-level embedding
self.embed = nn.Embed(vocab_size, d_model, rngs=rngs)
# Core CogniThread
self.ssm = CogniThreadSSM(d_model, d_state, d_conv, expand, rngs=rngs)
self.state_proj = nn.Linear(d_model, d_state, rngs=rngs)
self.fuzzy = FuzzyHeuristicRetriever(d_state, n_heuristics, 1.0, 5, rngs=rngs)
self.diffusion = LatentDiffusionSynthesizer(d_z, d_state, T_diff, rngs=rngs)
self.diff_proj = nn.Linear(d_z, d_model, rngs=rngs)
self.fuzzy_proj = nn.Linear(d_state, d_model, rngs=rngs)
self.gate = AdaptiveGate(d_model, rngs=rngs)
# Vocabulary head
self.lm_head = nn.Linear(d_model, vocab_size, rngs=rngs)
def __call__(self, input_ids, key=None):
"""input_ids: (batch, seq_len) int tokens. Returns logits."""
if key is None: key = jax.random.key(0)
x = self.embed(input_ids) # (batch, seq_len, d_model)
h_ssm = self.ssm(x)
h_t = self.state_proj(h_ssm)
retrieved, w_f, mu = self.fuzzy(h_t)
retrieved = self.fuzzy_proj(retrieved)
z_0 = self.diffusion(h_t, key=key)
generated = self.diff_proj(z_0)
y_final, var_y = self.gate(retrieved, generated, w_f)
logits = self.lm_head(y_final) # (batch, seq_len, vocab_size)
return logits
def generate(self, input_ids, max_new_tokens=64, key=None, temperature=0.8):
"""Autoregressive text generation."""
if key is None: key = jax.random.key(0)
batch, seq_len = input_ids.shape
generated = list(input_ids.T) # list of (batch,) arrays
cur_ids = input_ids
for i in range(max_new_tokens):
key, sk = jax.random.split(key)
logits = self(cur_ids, key=sk) # (batch, seq, vocab)
next_logits = logits[:, -1, :] / max(temperature, 0.01)
next_token = jax.random.categorical(sk, next_logits, axis=-1) # (batch,)
generated.append(next_token)
cur_ids = jnp.concatenate([cur_ids[:, 1:], next_token[:, None]], axis=1)
return jnp.stack(generated, axis=1) # (batch, seq_len + max_new_tokens)