// Synapses: le connessioni reali tra i neuroni del modello, lette dai pesi del file GGUF. // // Il neurone i dello strato L scrive nel flusso residuo con la colonna i di ffn_down(L); // il neurone j dello strato L+1 legge il residuo, normalizzato con post_attention_norm(L+1), // attraverso la riga j di ffn_gate(L+1). La sinapsi è il loro prodotto scalare: // w(i -> j) = sum_d down_L[d, i] * norm_{L+1}[d] * gate_{L+1}[j, d] // positiva = eccitatoria, negativa = inibitoria. (La normalizzazione RMS globale è un fattore comune.) #pragma once #include typedef struct Synapses Synapses; typedef struct { int layer, idx; float w; } SynLink; Synapses *syn_open(const char *model_path, int n_layer, int n_ff, int n_embd); void syn_close(Synapses *s); // Sinapsi tra due neuroni di strati consecutivi (L -> L+1). Usa una cache: veloce per lo stream live. // Da chiamare da un solo thread. float syn_pair(Synapses *s, int L, int i, int j); // Le k sinapsi più forti in uscita (verso L+1) e in ingresso (da L-1) del neurone (L, i). // Scorre un'intera matrice: ~0.3 s. Thread-safe (non usa la cache). Ritorna false se L non è valido. bool syn_neuron(Synapses *s, int L, int i, int k, SynLink *out, int *n_out, SynLink *in, int *n_in); // Come sopra per neuroni creati, descritti dai loro vettori nello spazio residuo: // uscita: vec[v] è ciò che il neurone scrive nello strato L -> bersagli nello strato L+1 // ingresso: vec[v] è ciò che il neurone legge allo strato L -> sorgenti nello strato L-1 // Una sola passata sulla matrice per tutti i vettori. out ha n_vec * k elementi. void syn_vectors_out(Synapses *s, int L, const float *vecs, int n_vec, int k, SynLink *out); void syn_vectors_in(Synapses *s, int L, const float *vecs, int n_vec, int k, SynLink *out);